Skip to content

Commit 7271a95

Browse files
authoredSep 16, 2023
feat: mathjax support (#2977)
1 parent fd46dc9 commit 7271a95

File tree

11 files changed

+472
-1
lines changed

11 files changed

+472
-1
lines changed
 

‎docs/.vitepress/config.ts

+4
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ export default defineConfig({
1212
lastUpdated: true,
1313
cleanUrls: true,
1414

15+
markdown: {
16+
math: true
17+
},
18+
1519
sitemap: {
1620
hostname: 'https://vitepress.dev',
1721
transformItems(items) {

‎docs/guide/markdown.md

+45
Original file line numberDiff line numberDiff line change
@@ -795,6 +795,51 @@ The format of the selected line range can be: `{3,}`, `{,10}`, `{1,10}`
795795
Note that this does not throw errors if your file is not present. Hence, when using this feature make sure that the contents are being rendered as expected.
796796
:::
797797

798+
## Math Equations
799+
800+
This is currently opt-in. To enable it, you need to install `markdown-it-mathjax3` and set `markdown.math` to `true` in your config file:
801+
802+
```sh
803+
npm add -D markdown-it-mathjax3
804+
```
805+
806+
```ts
807+
// .vitepress/config.ts
808+
export default {
809+
markdown: {
810+
math: true
811+
}
812+
}
813+
```
814+
815+
**Input**
816+
817+
```md
818+
When $a \ne 0$, there are two solutions to $(ax^2 + bx + c = 0)$ and they are
819+
$$ x = {-b \pm \sqrt{b^2-4ac} \over 2a} $$
820+
821+
**Maxwell's equations:**
822+
823+
| equation | description |
824+
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- |
825+
| $\nabla \cdot \vec{\mathbf{B}} = 0$ | divergence of $\vec{\mathbf{B}}$ is zero |
826+
| $\nabla \times \vec{\mathbf{E}}\, +\, \frac1c\, \frac{\partial\vec{\mathbf{B}}}{\partial t} = \vec{\mathbf{0}}$ | curl of $\vec{\mathbf{E}}$ is proportional to the rate of change of $\vec{\mathbf{B}}$ |
827+
| $\nabla \times \vec{\mathbf{B}} -\, \frac1c\, \frac{\partial\vec{\mathbf{E}}}{\partial t} = \frac{4\pi}{c}\vec{\mathbf{j}} \nabla \cdot \vec{\mathbf{E}} = 4 \pi \rho$ | _wha?_ |
828+
```
829+
830+
**Output**
831+
832+
When $a \ne 0$, there are two solutions to $(ax^2 + bx + c = 0)$ and they are
833+
$$ x = {-b \pm \sqrt{b^2-4ac} \over 2a} $$
834+
835+
**Maxwell's equations:**
836+
837+
| equation | description |
838+
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- |
839+
| $\nabla \cdot \vec{\mathbf{B}} = 0$ | divergence of $\vec{\mathbf{B}}$ is zero |
840+
| $\nabla \times \vec{\mathbf{E}}\, +\, \frac1c\, \frac{\partial\vec{\mathbf{B}}}{\partial t} = \vec{\mathbf{0}}$ | curl of $\vec{\mathbf{E}}$ is proportional to the rate of change of $\vec{\mathbf{B}}$ |
841+
| $\nabla \times \vec{\mathbf{B}} -\, \frac1c\, \frac{\partial\vec{\mathbf{E}}}{\partial t} = \frac{4\pi}{c}\vec{\mathbf{j}} \nabla \cdot \vec{\mathbf{E}} = 4 \pi \rho$ | _wha?_ |
842+
798843
## Advanced Configuration
799844

800845
VitePress uses [markdown-it](https://github.com/markdown-it/markdown-it) as the Markdown renderer. A lot of the extensions above are implemented via custom plugins. You can further customize the `markdown-it` instance using the `markdown` option in `.vitepress/config.js`:

‎docs/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
"preview": "vitepress preview"
99
},
1010
"devDependencies": {
11+
"markdown-it-mathjax3": "^4.3.2",
1112
"vitepress": "workspace:*"
1213
}
1314
}

‎docs/reference/site-config.md

+16
Original file line numberDiff line numberDiff line change
@@ -525,8 +525,24 @@ interface MarkdownOptions extends MarkdownIt.Options {
525525
// See: https://github.com/mdit-vue/mdit-vue/tree/main/packages/plugin-toc#options
526526
toc?: TocPluginOptions
527527

528+
// @mdit-vue/plugin-component plugin options.
529+
// See: https://github.com/mdit-vue/mdit-vue/tree/main/packages/plugin-component#options
530+
component?: ComponentPluginOptions
531+
528532
// Configure the Markdown-it instance.
529533
config?: (md: MarkdownIt) => void
534+
535+
// Same as `config` but will be applied before all other plugins.
536+
preConfig?: (md: MarkdownIt) => void
537+
538+
// Disable cache (experimental)
539+
cache?: boolean
540+
541+
// Math support (experimental)
542+
// You need to install `markdown-it-mathjax3` and set `math` to `true` to enable it.
543+
// You can also pass options to `markdown-it-mathjax3` here.
544+
// See: https://github.com/tani/markdown-it-mathjax3#customization
545+
math?: any
530546
}
531547
```
532548

‎package.json

+9
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,14 @@
102102
"vite": "^4.4.9",
103103
"vue": "^3.3.4"
104104
},
105+
"peerDependencies": {
106+
"markdown-it-mathjax3": "^4.3.2"
107+
},
108+
"peerDependenciesMeta": {
109+
"markdown-it-mathjax3": {
110+
"optional": true
111+
}
112+
},
105113
"devDependencies": {
106114
"@clack/prompts": "^0.7.0",
107115
"@mdit-vue/plugin-component": "^0.12.1",
@@ -154,6 +162,7 @@
154162
"markdown-it-attrs": "^4.1.6",
155163
"markdown-it-container": "^3.0.0",
156164
"markdown-it-emoji": "^2.0.2",
165+
"markdown-it-mathjax3": "^4.3.2",
157166
"micromatch": "^4.0.5",
158167
"minimist": "^1.2.8",
159168
"nanoid": "^4.0.2",

‎pnpm-lock.yaml

+263
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎rollup.config.ts

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ const r = (p: string) => resolve(ROOT, '..', p)
2222

2323
const external = [
2424
...Object.keys(pkg.dependencies),
25+
...Object.keys(pkg.peerDependencies),
2526
...builtinModules.flatMap((m) =>
2627
m.includes('punycode') ? [] : [m, `node:${m}`]
2728
)

‎src/client/theme-default/styles/base.css

+9
Original file line numberDiff line numberDiff line change
@@ -241,3 +241,12 @@ p {
241241
vite-error-overlay {
242242
z-index: 9999;
243243
}
244+
245+
mjx-container {
246+
display: inline-block;
247+
margin: auto 2px -2px;
248+
}
249+
250+
mjx-container > svg {
251+
margin: auto;
252+
}

‎src/node/markdown/index.ts

+14
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ export interface MarkdownOptions extends MarkdownIt.Options {
5656
externalLinks?: Record<string, string>
5757
cache?: boolean
5858
component?: ComponentPluginOptions
59+
math?: boolean | any
5960
}
6061

6162
export type MarkdownRenderer = MarkdownIt
@@ -149,6 +150,19 @@ export const createMarkdownRenderer = async (
149150
...options.toc
150151
} as TocPluginOptions)
151152

153+
if (options.math) {
154+
try {
155+
const mathPlugin = await import('markdown-it-mathjax3')
156+
md.use(mathPlugin.default ?? mathPlugin, {
157+
...(typeof options.math === 'boolean' ? {} : options.math)
158+
})
159+
} catch (error) {
160+
throw new Error(
161+
'You need to install `markdown-it-mathjax3` to use math support.'
162+
)
163+
}
164+
}
165+
152166
// apply user config
153167
if (options.config) {
154168
options.config(md)

‎src/node/markdown/math.ts

+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
export const mathjaxElements = [
2+
'mjx-container',
3+
'mjx-assistive-mml',
4+
'math',
5+
'maction',
6+
'maligngroup',
7+
'malignmark',
8+
'menclose',
9+
'merror',
10+
'mfenced',
11+
'mfrac',
12+
'mi',
13+
'mlongdiv',
14+
'mmultiscripts',
15+
'mn',
16+
'mo',
17+
'mover',
18+
'mpadded',
19+
'mphantom',
20+
'mroot',
21+
'mrow',
22+
'ms',
23+
'mscarries',
24+
'mscarry',
25+
'mscarries',
26+
'msgroup',
27+
'mstack',
28+
'mlongdiv',
29+
'msline',
30+
'mstack',
31+
'mspace',
32+
'msqrt',
33+
'msrow',
34+
'mstack',
35+
'mstack',
36+
'mstyle',
37+
'msub',
38+
'msup',
39+
'msubsup',
40+
'mtable',
41+
'mtd',
42+
'mtext',
43+
'mtr',
44+
'munder',
45+
'munderover',
46+
'semantics',
47+
'math',
48+
'mi',
49+
'mn',
50+
'mo',
51+
'ms',
52+
'mspace',
53+
'mtext',
54+
'menclose',
55+
'merror',
56+
'mfenced',
57+
'mfrac',
58+
'mpadded',
59+
'mphantom',
60+
'mroot',
61+
'mrow',
62+
'msqrt',
63+
'mstyle',
64+
'mmultiscripts',
65+
'mover',
66+
'mprescripts',
67+
'msub',
68+
'msubsup',
69+
'msup',
70+
'munder',
71+
'munderover',
72+
'none',
73+
'maligngroup',
74+
'malignmark',
75+
'mtable',
76+
'mtd',
77+
'mtr',
78+
'mlongdiv',
79+
'mscarries',
80+
'mscarry',
81+
'msgroup',
82+
'msline',
83+
'msrow',
84+
'mstack',
85+
'maction',
86+
'semantics',
87+
'annotation',
88+
'annotation-xml'
89+
]

‎src/node/plugin.ts

+21-1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
resolveAliases
1616
} from './alias'
1717
import { resolvePages, resolveUserConfig, type SiteConfig } from './config'
18+
import { mathjaxElements } from './markdown/math'
1819
import {
1920
clearCache,
2021
createMarkdownToVueRenderFn,
@@ -80,12 +81,31 @@ export async function createVitePressPlugin(
8081
} = siteConfig
8182

8283
let markdownToVue: Awaited<ReturnType<typeof createMarkdownToVueRenderFn>>
84+
const userCustomElementChecker =
85+
userVuePluginOptions?.template?.compilerOptions?.isCustomElement
86+
let isCustomElement = userCustomElementChecker
87+
88+
if (markdown?.math) {
89+
isCustomElement = (tag) => {
90+
if (mathjaxElements.includes(tag)) {
91+
return true
92+
}
93+
return userCustomElementChecker?.(tag) ?? false
94+
}
95+
}
8396

8497
// lazy require plugin-vue to respect NODE_ENV in @vue/compiler-x
8598
const vuePlugin = await import('@vitejs/plugin-vue').then((r) =>
8699
r.default({
87100
include: [/\.vue$/, /\.md$/],
88-
...userVuePluginOptions
101+
...userVuePluginOptions,
102+
template: {
103+
...userVuePluginOptions?.template,
104+
compilerOptions: {
105+
...userVuePluginOptions?.template?.compilerOptions,
106+
isCustomElement
107+
}
108+
}
89109
})
90110
)
91111

0 commit comments

Comments
 (0)
Please sign in to comment.