Gatsby: Whats the best way to add KaTex support in markdown

Created on 16 Jul 2017  Â·  20Comments  Â·  Source: gatsbyjs/gatsby

I see Remake has a plugin for KaTex that can be used, with that in mind should I create a seprate plugin for this or edit the gatsby-transformer-remark

question or discussion

All 20 comments

Yeah, you should create a new plugin (gatsby-remark-katex). Check out the source of the other remark plugins on how to do this.

Thanks @KyleAMathews I will do that, mind if I add a pull request with the plugin, also any clues on a good way to include the katex.css stylesheet.

How about using modifyWebpackConfig in the gatsby-remark-katex to include the katex stylesheet.

Haha, I just started working on one yesterday as well. Feel free to have at it.

Are you using remark-math? That seemed like it was a little better supported than the other option.

Regarding the css, I would venture to say that it makes sense to keep it partially manual. The remark-prism plugin does it this way:

To load a theme, just require its CSS file in your layouts/index.js file, e.g.

// layouts/index.js
require('prismjs/themes/prism-solarizedlight.css')

The prism plugin does this because there's lots of themes and a user naturally would want to pick their own theme.

If the plugin you create requires certain css to work it should load it directly as otherwise you're making users do busywork.

A plugin that does this is https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-remark-autolink-headers/src/gatsby-ssr.js

@KyleAMathews It probably does make sense to provide a default, but the KaTeX uses .less and is built to let you modify the fonts / css and make a new .min.css. I would venture to guess there is a veeery small minority that would care about that though.

@sparshy I used katex in markdown by creating a custom markdown syntax that gets rendered into a custom component which renders the katex formula.

https://github.com/christianalfoni/markdown-to-react-components

https://github.com/xurban42/react-in-markdown

check out these two repos... I used them in my project to render katex using markdown

@jbolda then yeah, I'd say just provide default styles in the options for the plugin, let people override the styles. Or actually, even easier, just don't let people override styles until someone comes along that needs it :-) adding options is a lot of work and best avoided unless you're sure they're needed.

I have managed to do this, but this requires some changes in the gatsby-transformer-remark plugin, i.e adding the remark-math plugin to be used by the remark parser.

new Remark().use(require('remark-math'))

This creates two nodes math (for block maths) and inlineMaths (for inline maths), then I use the gatsby-remark-katex to convert the node value to html using katex.renderToString and node type to html

Earlier I tried using RegExp on text nodes to get content between $'s example $ x^2 $ this worked fine but I ran into a problem in a corner case. Consider the following KaTex syntax $ a_1 + b_1 $, the remark parser parses it and creates a node emphasis, messing up the content before I can actually get the maths content.

maybe a functionality where a user can manually add remark plugins would be useful.

Remark's plugin model is incompatible with Gatsby's as we cache the result of AST transforms where remark wants to do the whole parse/transform/compile flow everytime.

You can often use the plugin code directly on the AST that's passed to Gatsby remark plugins.

@KyleAMathews hi, what's passed to Gatsby remark plugins is just AST, and remark-math needs to parse the raw text to AST(some node type of 'math') in parse phase, so how can I use remark-math plugin?

And I don't know why

Remark's plugin model is incompatible with Gatsby's

can you give more details, so may be I could give some help. thanks~

You can use this util to find various types of nodes https://github.com/syntax-tree/unist-util-visit

I think the problem is that different ASTs are created when you do use(require('remark-math')) vs. when you don't, because new type of nodes are created (inlineMath).

Here's an an example: https://gist.github.com/jeffrey-xiao/1c5a52d84a6a011097b2007416478053

Ah ok, so this plugin adds new parsing logic. Hmmm we don't support that yet for our Remark implementation. It also looks like we'd need to add support for rehype plugins.

I went away from using the normal Remark plugin architecture because many of the Gatsby/Remark plugins use Gatsby-specific data.

I'm not entirely sure how to reconcile that with what remark-math is doing. Perhaps the easiest thing to do would be to port its logic + the Katex plugin to a new Gatsby-specific plugin?

Happy to support this if one of you want to do some research and prototyping on possible solutions.

I would be willing to work on this as I will be heavily using LaTeX in my blog. Do you think having gatsby-remark-plugins export a list of remark parser dependencies that will be used here would be okay?

@jeffrey-xiao best thing to do to move the conversation forward is to put up a quick PR with some ideas for how this could work along with an example site with things setup and working.

@KyleAMathews looks like you can close this one right? Because of https://github.com/gatsbyjs/gatsby/pull/1731

@ahfarmer Yep, plugin is at https://github.com/gatsbyjs/gatsby/tree/master/packages/gatsby-remark-katex, demo at https://using-remark.gatsbyjs.org/katex/ … but it's currently not showing on https://www.gatsbyjs.org/docs/plugins/ because it doesn't have a README yet.

Closing, will add a README now.

How come the gatsby-remark-katex plugin ended up leaving the css import

import 'katex/dist/katex.min.css'

to the user? To me this really seems like something the plugin should handle.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

dustinhorton picture dustinhorton  Â·  3Comments

magicly picture magicly  Â·  3Comments

andykais picture andykais  Â·  3Comments

Oppenheimer1 picture Oppenheimer1  Â·  3Comments

benstr picture benstr  Â·  3Comments