kivikakk / comrak

CommonMark + GFM compatible Markdown parser and renderer

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Would you support a PR that adds basic AST support for Markdoc?

gjtorikian opened this issue · comments

In my neverending quest to find simpler and powerfuler authoring syntaxes, I’ve been looking at Stripe’s recent Markdoc. In a nutshell, it’s Commonmark, plus support for extra tags and variables that can be passed in at buildtime:

{% if $x > 4 %}
There are *four* lights!
{% else %}
All good.
{% end %}

These additions have their own spec: https://markdoc.dev/spec

What I would like to do is add these glyphs to the AST generated by comrak. Assuming you accept that proposal, there’s another catch that I haven’t quite resolved. Part of this spec revolves around support for functions:

# {% titleCase($someVar) %}

Supporting these would push comrak towards becoming a sort of templating language system; if Markdoc decides to add standard functions, comrak will need to add those to maintain spec compliance.

Instead, the best idea I have is for comrak to construct the AST, and then do nothing with it as part of the render. No variable substitution, no function calls. A consumer of comrak would need to walk the AST themselves, and essentially build a custom renderer whenever they see a Markdoc node. This essentially opens up comrak to the potential for supporting Markdoc, with all Markdoc customizations handled by the caller, not this lib.

What do you think? Does this make sense to be included here, or is it better suited outside this project?

It occurs to me now that a system like this exists already in the form of self.plugins.render for syntax highlighting, so I would latch onto that.

To be honest, I don't hate the idea of pushing it a little bit. Say we add support for Markdoc that goes beyond just the AST, i.e. we implement the core logic and six built-ins defined so far. If it starts feeling unwieldy to have that much coupling, we can just split the AST from the rest then, keeping the former in Comrak core and the latter in a separate repo and crate. I imagine it'd probably also develop a nicer API that way, as one refactored out of the existing use-case, and if it doesn't ever come to pass, we've saved some effort.

I took a look at implementing this. While the parsing logic is simple enough, I couldn't figure out how to implement attributes; that is, in Markdoc,

# Some title {% .foo #id %}

is supposed to go back to the <h1> and add the attributes class="foo" id="id". Doing this would require me to check for the existence of {% tags everywhere and...I got lazy. Like, I know I won't have time to implement that or thoroughly test its edge cases.

I'm going to close this out for now because I'm not going to work on it. Thank you for entertaining the idea and I hope someone else picks it up!