New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to use myst-parser in browser to generate html from myst markdown string? #824
Comments
Thanks for opening your first issue here! Engagement like this is essential for open source projects! 🤗 |
Hi @fhg-isi, thanks for opening this issue! It looks like our documentation is slightly out of date. I'm new to the nitty-gritty of getting this up and running, but did some digging around. I can provide a solution, but do keep an eye on this thread in case one of the team provides a superior alternative. The error that you're seeing is caused by missing JS dependencies. You need to ensure that your script is being executed in a context where those modules have been loaded. The easiest solution in most modern browsers is to use a <html>
<head>
<link rel="stylesheet" type="text/css" href="myst.css">
</head>
<div id="output"></div>
<script type="module">
import { unified } from 'https://esm.sh/unified@10.1.2?bundle'
import { mystParser } from 'https://esm.sh/myst-parser@1.0.21?bundle'
import { State, transform, mystToHast, formatHtml } from 'https://esm.sh/myst-to-html@1.0.21?bundle'
import rehypeStringify from 'https://esm.sh/rehype-stringify@9.0.3?bundle'
const pipe = unified()
.use(mystParser)
.use(transform, new State())
.use(mystToHast)
.use(formatHtml)
.use(rehypeStringify);
const result = pipe.processSync(':::{important}\nHello to the world!\n:::');
document.getElementById('output').innerHTML = result.value;
</script>
</body>
</html> You can see that this is very close to what the documentation already suggests, but it's a mix of the Node and browser examples. You'll also need a stylesheet, (here, |
@agoose77 , this is great! Any chance you can add an example with a LaTeX equation? |
So (again), there might be a better way, but here's a start. You can load KaTeX and massage the equations to be picked up by KaTeX's auto renderer: import { unified } from 'unified'
import { mystParser } from 'myst-parser'
import rehypeDocument from 'rehype-document'
import { State, transform, mystToHast, formatHtml } from 'myst-to-html'
import rehypeStringify from 'rehype-stringify'
import mystToMd from 'myst-to-md';
import { selectAll } from 'unist-util-select';
// Prepare math for KaTeX auto renderer by wrapping in `$$`
function mathTransform(tree, file, opts) {
const inlineNodes = selectAll('inlineMath', tree);
inlineNodes.forEach((node) => {
node.value = `$${node.value}$`
});
const displayNodes = selectAll('math', tree);
displayNodes.forEach((node) => {
node.value = `$$${node.value}$$`
});
}
const mathPlugin =
(opts) => (tree, file) => {
mathTransform(tree, file, opts);
};
// Create a AST document, or parse using mystmd
const pipe = unified()
.use(mystParser)
.use(transform, new State())
.use(mathPlugin)
.use(mystToHast)
.use(formatHtml)
// Load KaTeX
.use(rehypeDocument, {
css: ['myst.css', 'https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css'],
js: ["https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.js", "https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/contrib/auto-render.min.js"],
script: `document.addEventListener("DOMContentLoaded", (event) => {
renderMathInElement(document.body, {
delimiters: [{
left: "$$",
right: "$$",
display: true
},
{
left: "$",
right: "$",
display: false
}
]
});
});`
})
.use(rehypeStringify);
// Demo
const result = pipe.processSync(`
:::{important}
Hello to the world!
:::
The math says {math}\`x + y \\frac{x}{y}\`
`);
console.log(result.value); You don't have to use KaTeX, but I just knew it would be easy to get up and running with it. |
Thanks @agoose77 ! This is great! I made some tweaks (see below) to make it a standalone HTML file. FYI, it doesn't look like the table alignment is working, but I believe this is a known issue: #238 <!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="myst.css">
<link rel="stylesheet" type="text/css" href='https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css'>
</head>
<div id="output"></div>
<script type="module">
import { unified } from 'https://esm.sh/unified@10.1.2?bundle';
import { mystParser } from 'https://esm.sh/myst-parser@1.0.21?bundle';
import { State, transform, mystToHast, formatHtml } from 'https://esm.sh/myst-to-html@1.0.21?bundle';
import rehypeStringify from 'https://esm.sh/rehype-stringify@9.0.3?bundle';
import { selectAll } from 'https://esm.sh/unist-util-select@5.1.0?bundle';
import renderMathInElement from "https://esm.sh/katex@0.16.9/dist/contrib/auto-render.mjs";
// Prepare math for KaTeX auto renderer by wrapping in `$$`
function mathTransform(tree, file, opts) {
const inlineNodes = selectAll('inlineMath', tree);
inlineNodes.forEach((node) => {
node.value = `$${node.value}$`
});
const displayNodes = selectAll('math', tree);
displayNodes.forEach((node) => {
node.value = `$$${node.value}$$`
});
}
const mathPlugin =
(opts) => (tree, file) => {
mathTransform(tree, file, opts);
};
// Create a AST document, or parse using mystmd
const pipe = unified()
.use(mystParser)
.use(transform, new State())
.use(mathPlugin)
.use(mystToHast)
.use(formatHtml)
// Load KaTeX
.use(rehypeStringify);
// Demo
const result = pipe.processSync(`
# Myst Example
:::{important}
Hello to the world!
:::
| left | center | right |
| :--- | :----: | ----: |
| a | b | c |
:::{figure} https://source.unsplash.com/random/500x200/?mountain
:name: my-fig
:align: center
My **bold** mountain 🏔🚠.
:::
The math says $x^2 + \\big( y \\frac{x}{y} \\big)$
`);
document.getElementById('output').innerHTML = result.value;
// console.log(result.value);
document.addEventListener("DOMContentLoaded", function () {
renderMathInElement(document.body, {
// customised options
// • auto-render specific keys, e.g.:
delimiters: [
{ left: '$$', right: '$$', display: true },
{ left: '$', right: '$', display: false },
{ left: '\\(', right: '\\)', display: false },
{ left: '\\[', right: '\\]', display: true }
],
// • rendering keys, e.g.:
throwOnError: false
});
});
</script>
</body>
</html> |
I asked here another follow up question: How to resolve relative links? |
@fhg-isi , I think for something sophisticated involving multiple markdown documents you may want to use the If you can't use the |
Thank you. Solved it using regular expressions, see https://github.com/orgs/executablebooks/discussions/1125 |
If I try to use the html example given at
https://github.com/executablebooks/mystmd/tree/main/packages/myst-parser
I get the error
Uncaught ReferenceError: unified is not defined
a) Could you please give a full example on how to use myst-parser in the browser to generate html from myst markdown string?
b) Also see https://stackoverflow.com/questions/77707969/how-to-use-myst-parser-for-sharepoint-web-part
The text was updated successfully, but these errors were encountered: