import { MathParser } from '../inline'; import { Backtrack, Recursion } from '../context'; import { Node } from '../../combinator/parser'; import { union, some, recursion, precedence, backtrack, rewrite, surround, lazy } from '../../combinator'; import { escsource, str } from '../source'; import { invalid } from '../util'; import { html } from 'typed-dom/dom'; const forbiddenCommand = /\\(?:begin|tiny|huge|large)(?![a-z])/i; export const math: MathParser = lazy(() => rewrite( union([ surround( /\$(?={)/y, precedence(4, bracket), '$', false, [3 | Backtrack.escapable]), surround( /\$(?![\s{}])/y, precedence(2, some(union([ some(escsource, /[`"{}$\r\n]|(?<=[0-9A-Za-z]):\/\/[[0-9A-Za-z]/y), precedence(4, bracket), ]))), /(? output.append( new Node(cache?.get(source)?.cloneNode(true) || html('span', !forbiddenCommand.test(source) ? { class: 'math', translate: 'no', 'data-src': source } : { class: 'invalid', translate: 'no', ...invalid('math', 'content', `"${source.match(forbiddenCommand)![0]}" command is forbidden`), }, source))))); const bracket: MathParser.BracketParser = lazy(() => backtrack(surround( str('{'), recursion(Recursion.bracket, some(union([ bracket, some(escsource, /[{}$\r\n]|(?<=[0-9A-Za-z]):\/\/[[0-9A-Za-z]/y), ]))), str('}'), true)));