mirror of
https://github.com/livebook-dev/livebook.git
synced 2025-09-09 22:44:38 +08:00
Add support for math formulas (#151)
* Add support for LaTeX equations * Mention math support in the introductory notebook
This commit is contained in:
parent
121eec784d
commit
d68c271aae
6 changed files with 78 additions and 1 deletions
|
@ -124,6 +124,10 @@
|
|||
@apply mb-0;
|
||||
}
|
||||
|
||||
.markdown .katex-display {
|
||||
@apply my-8;
|
||||
}
|
||||
|
||||
/* Overrides for user-entered markdown */
|
||||
|
||||
[data-element="cell"] .markdown h1,
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import "../css/app.css";
|
||||
import "remixicon/fonts/remixicon.css";
|
||||
import "katex/dist/katex.min.css";
|
||||
|
||||
import "@fontsource/inter";
|
||||
import "@fontsource/inter/500.css";
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import marked from "marked";
|
||||
import morphdom from "morphdom";
|
||||
import DOMPurify from "dompurify";
|
||||
import katex from "katex";
|
||||
import monaco from "./live_editor/monaco";
|
||||
|
||||
// Reuse Monaco highlighter for Markdown code blocks
|
||||
|
@ -51,7 +52,16 @@ class Markdown {
|
|||
// Marked requires a trailing slash in the base URL
|
||||
const opts = { baseUrl: this.baseUrl + "/" };
|
||||
|
||||
marked(this.content, opts, (error, html) => {
|
||||
// Render math formulas using KaTeX.
|
||||
// The resulting <span> tags will pass through
|
||||
// marked.js and sanitization unchanged.
|
||||
//
|
||||
// We render math before anything else, because passing
|
||||
// TeX through markdown renderer may have undesired
|
||||
// effects like rendering \\ as \.
|
||||
const contentWithRenderedMath = this.__renderMathInString(this.content);
|
||||
|
||||
marked(contentWithRenderedMath, opts, (error, html) => {
|
||||
const sanitizedHtml = DOMPurify.sanitize(html);
|
||||
|
||||
if (sanitizedHtml) {
|
||||
|
@ -66,6 +76,22 @@ class Markdown {
|
|||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Replaces TeX formulas in string with rendered HTML using KaTeX.
|
||||
__renderMathInString(string) {
|
||||
const options = {
|
||||
throwOnError: false,
|
||||
errorColor: "inherit",
|
||||
};
|
||||
|
||||
return string
|
||||
.replace(/\$\$([\s\S]*?)\$\$/g, (match, math) => {
|
||||
return katex.renderToString(math, { ...options, displayMode: true });
|
||||
})
|
||||
.replace(/\$([\s\S]*?)\$/g, (match, math) => {
|
||||
return katex.renderToString(math, options);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default Markdown;
|
||||
|
|
35
assets/package-lock.json
generated
35
assets/package-lock.json
generated
|
@ -10,6 +10,7 @@
|
|||
"@fontsource/jetbrains-mono": "^4.2.2",
|
||||
"dompurify": "^2.2.6",
|
||||
"hyperlist": "^1.0.0",
|
||||
"katex": "^0.13.2",
|
||||
"marked": "^1.2.8",
|
||||
"monaco-editor": "^0.23.0",
|
||||
"morphdom": "^2.6.1",
|
||||
|
@ -9296,6 +9297,25 @@
|
|||
"verror": "1.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/katex": {
|
||||
"version": "0.13.2",
|
||||
"resolved": "https://registry.npmjs.org/katex/-/katex-0.13.2.tgz",
|
||||
"integrity": "sha512-u/KhjFDhyPr+70aiBn9SL/9w/QlLagIXBi2NZSbNnBUp2tR8dCjQplyEMkEzniem5gOeSCBjlBUg4VaiWs1JJg==",
|
||||
"dependencies": {
|
||||
"commander": "^6.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"katex": "cli.js"
|
||||
}
|
||||
},
|
||||
"node_modules/katex/node_modules/commander": {
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz",
|
||||
"integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==",
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/kind-of": {
|
||||
"version": "6.0.3",
|
||||
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
|
||||
|
@ -23464,6 +23484,21 @@
|
|||
"verror": "1.10.0"
|
||||
}
|
||||
},
|
||||
"katex": {
|
||||
"version": "0.13.2",
|
||||
"resolved": "https://registry.npmjs.org/katex/-/katex-0.13.2.tgz",
|
||||
"integrity": "sha512-u/KhjFDhyPr+70aiBn9SL/9w/QlLagIXBi2NZSbNnBUp2tR8dCjQplyEMkEzniem5gOeSCBjlBUg4VaiWs1JJg==",
|
||||
"requires": {
|
||||
"commander": "^6.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"commander": {
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz",
|
||||
"integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"kind-of": {
|
||||
"version": "6.0.3",
|
||||
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
"@fontsource/jetbrains-mono": "^4.2.2",
|
||||
"dompurify": "^2.2.6",
|
||||
"hyperlist": "^1.0.0",
|
||||
"katex": "^0.13.2",
|
||||
"marked": "^1.2.8",
|
||||
"monaco-editor": "^0.23.0",
|
||||
"morphdom": "^2.6.1",
|
||||
|
|
|
@ -164,6 +164,16 @@ defmodule Livebook.Notebook.Welcome do
|
|||
per runtime, so if you need to modify the dependencies, you should
|
||||
go to the notebook runtime configuration and **reconnect** the current runtime.
|
||||
|
||||
## Math
|
||||
|
||||
Livebook supports both inline formulas like $e^{\\pi i} + 1 = 0$, as well as block formulas:
|
||||
|
||||
$$
|
||||
S(x) = \\frac{1}{1 + e^{-x}} = \\frac{e^{x}}{e^{x} + 1}
|
||||
$$
|
||||
|
||||
You can explore all supported expressions [here](https://katex.org/docs/supported.html).
|
||||
|
||||
## Stepping up your workflow
|
||||
|
||||
Once you start using notebooks more, it's gonna be beneficial
|
||||
|
|
Loading…
Add table
Reference in a new issue