This is my first Obsidian Plugin, and I haven’t been able to figure out how all things work. What I would like my plugin to do is embed the WGo.js SGF player. The WGo.js package has been published on NPM but I’ve never been able to make it work for some reason — the docs seem outdated, you can see it in action on my website here.
This is what I have so far for this project.
I’ve also posted about this on Obsidian Discourse.
If using the <script>
method, I imagine the necessary steps as:
- An SGF file is linked with custom syntax, e.g.
!![game1.sgf]
. - Under the hood, this is replaced by its respective WGo.js
<div>
by the plugin. - The plugin will use
<script>
tags to bring WGo.js into showing an embedded viewer with the game.
How do I do this through an Obsidian plugin?
<script type="text/javascript" src="../../assets/wgo/wgo.js"></script>
<script type="text/javascript" src="../../assets/wgo/kifu.js"></script>
<script type="text/javascript" src="../../assets/wgo/sgfparser.js"></script>
<script type="text/javascript" src="../../assets/wgo/player.js"></script>
<script
type="text/javascript"
src="../../assets/wgo/basicplayer.js"
></script>
<script
type="text/javascript"
src="../../assets/wgo/basicplayer.component.js"
></script>
<script
type="text/javascript"
src="../../assets/wgo/basicplayer.infobox.js"
></script>
<script
type="text/javascript"
src="../../assets/wgo/basicplayer.commentbox.js"
></script>
<script
type="text/javascript"
src="../../assets/wgo/basicplayer.control.js"
></script>
<script
type="text/javascript"
src="../../assets/wgo/player.editable.js"
></script>
<script type="text/javascript" src="../../assets/wgo/scoremode.js"></script>
<script
type="text/javascript"
src="../../assets/wgo/player.permalink.js"
></script>
<link
rel="stylesheet"
type="text/css"
href="../../assets/wgo/wgo.player.css"
/>
<!-- This would be the replacement of a custom syntax, e.g. `!![AncientGame.sgf]` -->
<div
data-wgo="AncientGame.sgf"
data-wgo-board="stoneHandler: WGo.Board.drawHandlers.NORMAL,
background: '../../assets/wgo/textures/wood2.jpg'"
class="SGF"
>
<p>
Your browser doesn't support the WGo.js Player. Please use a more
modern browser, like Brave, Chrome, Firefox or Edge.
</p>
</div>
2
Answers
Incomplete answer over here, but I thought I would share the progress I've had so far.
I've managed to make WGo.js work imperatively through JS while also adding the
<div>
element to the document's body:I don't know yet how to properly place this in Obsidian's editor, and I doubt this is supposed to be how plugins should interact with it. And there's also the problem of customizing WGo.js a little bit more, not to mention that the SGF is hardcoded so far. But overall this is a solid direction, I think.
As per Obsidian docs, you shouldn’t fixate on building a plugin, lest you might need an extension instead for your use case.
Pro Solution
If you’re looking to build a full-blown plugin, which when encounters the markdown
!![game1.sgf]
, it should show the WGo.js SGF player, in the reading view and live preview, you’ll have to write an extension (registered with an Obsidian plugin) to extend CodeMirror’s capability to process the markdown. CodeMirror, under the hood uses @codemirror/lang-markdown package for this, which in-turn makes use of @lezer/markdown. The latter (@lezer/markdown) can be extended using it’s own extensions, to add a particular processor for some markdown. For e.g., the package by default includes an extension to parse GitHub flavored strike-through markdown, which is what you’ll need to do for showing a live preview for an SGF player, but then a little issue that ensues is that it’s not apparent, as to how to register this with the CodeMirror instance used by obsidian. For that you’ll have to use unexposed Obisidian API.Just Get By Solution
For having the Obisdian show an SGF player in the reading view only (not live preview), you can simply register a markdown post processor, with that you’ll have to manipulate already html converted markdown for
!![game1.sgf]
to show the SGF player.Better Than Just Get By Solution
Instead of muddling your way to "Pro Solution", to get everything right, you can consider changing the syntax for SGF player to use a code fence block, and register a markdown code block processor, then you’ll be able to get this in reading mode and live preview. For e.g., you can use this syntax –
get the source of the game, load it in the element provided by obsidian. Ideally, you should allow only one link in an
sgf
code fence.Something to consider
Instead of loading the
wgo
throughscript
tags, just bundle it with your plugin. In theonload
callback, add it toWindow
object and remove it fromWindow
object in theonunload
callback. Obsidian itself adds many functions and objects onWindow
object.NOTE: If you need to get some elaboration on a particular part or clarification, add a comment and I’ll update the answer.