executablebooks / markdown-it-docutils

A markdown-it plugin for implementing docutils style roles/directives.
https://executablebooks.github.io/markdown-it-docutils/
MIT License
12 stars 8 forks source link

Consistently handle storage of target/reference labels #10

Open chrisjsewell opened 3 years ago

chrisjsewell commented 3 years ago

Most directives allow for a name option for referencing them, then for roles we have e.g. {ref}`text<label>` and the equivalent Markdown syntax like [text](label).

Then we also have the target syntax in myst: (label)= (a reference implementation is currently here: https://github.com/executablebooks/myst-vs-code/blob/83460fc5f14517e8d6c6b7eb5581d814389fbc7c/src/mdPlugins.ts#L32, but perhaps we should move that into this package, they also get a little trick as we also need to "propogate" them down to the next block token, see: https://github.com/chrisjsewell/rst-language-server#transformsreferencespropagatetargets).

Essentially we want to be able to easily "scan" down the markdown-it token stream, and pull out all these targets and references, along with their map (a.k.a. position in the source text) and probably index in the token stream

cc @rowanc1

chrisjsewell commented 3 years ago

Maybe something like storing them in Token.meta as { docutils: { name: [], refname: [] } }, and we would also want logic to go through all the link tokens, and decide if their href are external links (e.g. https://example.com), or internal ones (and if so add the appropriate Token.meta. We would also want to have consistency e.g. in markdown-it-dollarmath, for labelled equations.

chrisjsewell commented 3 years ago

Note one thing from docutils I found a little confusing, is that nodes can have both fields: ids; https://docutils.sourceforge.io/docs/ref/doctree.html#ids and names: https://docutils.sourceforge.io/docs/ref/doctree.html#names. Names is the one we are interested in here, and this is how they are normalised: https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#reference-names

Then for references, in transforms refname is eventually turned into refid or refuri (again see https://github.com/chrisjsewell/rst-language-server#docutils-transforms)

I'm not sure just yet, how much of this kind of logic we should be thinking to use.

rowanc1 commented 3 years ago

I have taken a first crack at this. I used the concept of targets and references in a dict/list, respectively. I am just using the name at the moment, but if we need to map between name --> id we can add that indirection in a centralized place in the state.

I have stored the target object on the token as you suggest, but it also needs to be accessible from the state. I have a used a namespaced env for this (state.env.docutils).