| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657 |
- import { InlineContext, MarkdownConfig, InlineParser } from '@lezer/markdown'
- const DOLLAR = 36 /* '$' */
- // Whitespace (including the start/end of the inline section, where `char`
- // returns -1).
- const isSpace = (code: number) =>
- code === -1 || code === 32 || code === 9 || code === 10 || code === 13
- const isDigit = (code: number) => code >= 48 && code <= 57
- const InlineMathDelim = { resolve: 'InlineMath', mark: 'InlineMathMark' }
- const BlockMathDelim = { resolve: 'BlockMath', mark: 'BlockMathMark' }
- // Inline parsing runs over the whole paragraph, so `$$…$$` handles multi-line
- // equations as long as there is no blank line inside them.
- const blockMathParser: InlineParser = {
- name: 'BlockMath',
- parse(cx: InlineContext, next: number, pos: number) {
- if (next !== DOLLAR || cx.char(pos + 1) !== DOLLAR) {
- return -1
- }
- return cx.addDelimiter(BlockMathDelim, pos, pos + 2, true, true)
- },
- // Run before the default `Emphasis` parser, and (via `InlineMath`'s `after`)
- // before the single-dollar inline parser, so `$$` is matched as a display
- // delimiter rather than two empty inline ones.
- before: 'Emphasis',
- }
- const inlineMathParser: InlineParser = {
- name: 'InlineMath',
- parse(cx: InlineContext, next: number, pos: number) {
- if (next !== DOLLAR) {
- return -1
- }
- const before = cx.char(pos - 1)
- const after = cx.char(pos + 1)
- const canOpen = !isSpace(after)
- const canClose = !isSpace(before) && !isDigit(after)
- if (!canOpen && !canClose) {
- return -1
- }
- return cx.addDelimiter(InlineMathDelim, pos, pos + 1, canOpen, canClose)
- },
- // Run after `BlockMath` so `$$` is tried as a display delimiter first, but
- // still before `Emphasis`. The default `Escape` parser consumes `\$` first.
- after: 'BlockMath',
- }
- export const Math: MarkdownConfig = {
- // No `style` is set on these nodes: math is rendered by the visual editor
- // (which slices the raw source), so the grammar change stays inert for
- // source-mode syntax highlighting and non-experiment users.
- defineNodes: ['InlineMath', 'InlineMathMark', 'BlockMath', 'BlockMathMark'],
- parseInline: [blockMathParser, inlineMathParser],
- }
|