landakram / remark-wiki-link

Parse and render wiki links.
MIT License
87 stars 14 forks source link

remark@next (13) #5

Closed wooorm closed 3 years ago

wooorm commented 3 years ago

Hi!

remark is switching to a new parser (and compiler) internally (micromark, remarkjs/remark#536), which will break this plugin. I have created micromark and mdast extensions for footnotes already, which will today or tomorrow land in remark-footnotes, which I believe is somewhat similar to what you’re doing here. That should be a good inspiration on how to create extensions for the new parser. Feel free to ask me questions!

landakram commented 3 years ago

@wooorm I'm almost there (https://github.com/landakram/remark-wiki-link/pull/6/files), but ran into a snag.

I've created a micromark extension (https://github.com/landakram/micromark-extension-wiki-link) and an mdast util (https://github.com/landakram/mdast-util-wiki-link/) to power the remark plugin in this repo. Both of those plugins work well with tests passing.

However, when I integrated them in this repo, I saw the following test failure:

  2 failing

  1) remark-wiki-link
       stringifies wiki links:

      AssertionError [ERR_ASSERTION]: '\\[[Wiki Link]]' == '[[Wiki Link]]'
      + expected - actual

      -\[[Wiki Link]]
      +[[Wiki Link]]

      at Context.equal (test/index_test.js:104:12)
      at processImmediate (internal/timers.js:456:21)

When I print the AST, I see the following:

{
  type: 'paragraph',
  children: [
    { type: 'text', value: '[', position: [Position] },
    {
      type: 'linkReference',
      identifier: 'wiki link',
      referenceType: 'shortcut',
      children: [Array],
      position: [Position]
    },
    { type: 'text', value: ']', position: [Position] }
  ],
  position: Position {
    start: { line: 1, column: 1, offset: 0 },
    end: { line: 1, column: 14, offset: 13 },
    indent: []
  }
}

So it looks like a linkReference is taking precedent over my wikiLink. Previously, I inserted my tokenizer into the chain right before link like so:

const inlineTokenizers = Parser.prototype.inlineTokenizers
const inlineMethods = Parser.prototype.inlineMethods
inlineTokenizers.wikiLink = inlineTokenizer
inlineMethods.splice(inlineMethods.indexOf('link'), 0, 'wikiLink')

I'm guessing that the problem here is that I've lost precedence during micromark's tokenization (both tokens start with [)... I haven't been able to confirm this, but seems likely given this https://github.com/micromark/micromark/blob/b4c25337bea21c21dee59e982fe5e1847392815b/lib/parse.js#L16-L18

Do you know an easy way to get the same precedence (e.g. insert my tokenizer before link)? Or can you confirm this? It seems a little strange given that tests pass completely fine with the lower level packages (which implement both micromark to html and from-markdown)...

wooorm commented 3 years ago

https://github.com/micromark/micromark-extension-footnote/blob/74848e32baf5e477cbf443e23116e5e26944610b/index.js#L18

https://github.com/micromark/micromark/blob/main/lib/util/combine-extensions.js#L43

I believe though, that the default is to give extensions higher precedence (default: 'before'), but lower precedence is achieved with 'after'. So it sounds like this might be a different problem?

If it works in the micromark extension test, it should also work here 🤔 Is it because remark-parse is on v3 instead of v9? https://github.com/landakram/remark-wiki-link/pull/6/files#diff-7ae45ad102eab3b6d7e7896acd08c427a9b25b346470d7bc6507b6481575d519R37

landakram commented 3 years ago

😬 that was exactly the problem. Thank you for the second pair of eyes! I published v1.0.0, which supports micromark and remark 13. Really appreciate your comments on the supporting packages as well! I'll have a look over and refactor over the next few days.

wooorm commented 3 years ago

Awesome work!! 👍

And yes, I do think I found a couple of bugs in there, feel free to ask me Qs there if you have any!