wooorm / markdown-rs

CommonMark compliant markdown parser in Rust with ASTs and extensions
https://docs.rs/markdown/1.0.0-alpha.18/markdown/
MIT License
836 stars 41 forks source link

How to get math working #94

Closed zkwinkle closed 5 months ago

zkwinkle commented 6 months ago

Hello I need help getting the math extension working. I'm using the following options:

Options {
    parse: ParseOptions {
        constructs: Constructs {
            attention: true,
            autolink: true,
            block_quote: true,
            character_escape: true,
            character_reference: true,
            code_indented: true,
            code_fenced: true,
            code_text: true,
            definition: true,
            frontmatter: false,
            gfm_autolink_literal: true,
            gfm_footnote_definition: true,
            gfm_label_start_footnote: true,
            gfm_strikethrough: true,
            gfm_table: true,
            gfm_task_list_item: true,
            hard_break_escape: true,
            hard_break_trailing: true,
            heading_atx: true,
            heading_setext: true,
            html_flow: true,
            html_text: true,
            label_start_image: true,
            label_start_link: true,
            label_end: true,
            list_item: true,
            math_flow: true,
            math_text: true,
            mdx_esm: false,
            mdx_expression_flow: false,
            mdx_expression_text: false,
            mdx_jsx_flow: false,
            mdx_jsx_text: false,
            thematic_break: true,
        },
        gfm_strikethrough_single_tilde: false,
        math_text_single_dollar: true,
        mdx_esm_parse: None,
        mdx_expression_parse: None,
    },
    compile: CompileOptions {
        allow_dangerous_html: false,
        allow_dangerous_protocol: false,
        default_line_ending: LineEnding::LineFeed,
        gfm_footnote_label: None,
        gfm_footnote_label_tag_name: None,
        gfm_footnote_label_attributes: None,
        gfm_footnote_back_label: None,
        gfm_footnote_clobber_prefix: None,
        gfm_task_list_item_checkable: false,
        gfm_tagfilter: false,
    },
}

Notably math_flow: true and math_text: true.

The options are doing something because writing

$$
\frac{1}{2}
$$

generates the following HTML:

<pre><code class="language-math math-display">\frac{1}{2}</code></pre>

I guess from here I'd have to style the language-math and math-display classes on my own? Any example CSS I can use?

From issue #1 I see that the math extension is (inspired?) https://github.com/micromark/micromark-extension-math. Which has a section on CSS. But adding their stylesheet like <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.4/dist/katex.min.css"> didn't help either.

Also just wanted to add that this crate is awesome and perfect for my use case 😁. Thanks for your work!

wooorm commented 6 months ago

Hey! Thanks for your kind words :)

Not just style. You need JavaSript.

Same with how you do syntax highlighting: if you only add CSS, it doesn’t yet do anything. As nothing cuts up the programming code into tokens for particular programming languages with classes.

You’d still need to load code to select the math. And pass it through a function to generate more things.

micromark-extension-math can do more work because it is JavaScript itself. So it can use the KaTeX JavaScript library when doing its thing.

So, something like this pseudocode:

import katex from 'https://esm.sh/katex@0.16?bundle'

const nodes = Array.from(document.body.querySelectorAll('code.language-math'))

for (const node of nodes) {
  katex.render(node.textContent, node, { throwOnError: false })
}
zkwinkle commented 6 months ago

Okay so because I'm doing SSR I'd have to do this as part of the markdown->html compilation right? Which I believe makes this fall under the "needs plugins" category ( #32 )?

wooorm commented 6 months ago

SSR is unrelated to this. JavaScript can also run in browsers. In fact, type setting of math might be problematic on the server side, as different users will have different fonts and different other settings.

wooorm commented 5 months ago

I think this Q was answered.