@bytemd/plugin-math
Advanced tools
+701
| "use strict"; | ||
| var __create = Object.create; | ||
| var __defProp = Object.defineProperty; | ||
| var __getOwnPropDesc = Object.getOwnPropertyDescriptor; | ||
| var __getOwnPropNames = Object.getOwnPropertyNames; | ||
| var __getProtoOf = Object.getPrototypeOf; | ||
| var __hasOwnProp = Object.prototype.hasOwnProperty; | ||
| var __copyProps = (to, from, except, desc) => { | ||
| if (from && typeof from === "object" || typeof from === "function") { | ||
| for (let key of __getOwnPropNames(from)) | ||
| if (!__hasOwnProp.call(to, key) && key !== except) | ||
| __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); | ||
| } | ||
| return to; | ||
| }; | ||
| var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( | ||
| isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, | ||
| mod | ||
| )); | ||
| const block = "Block formula"; | ||
| const blockText = "formula"; | ||
| const inline = "Inline formula"; | ||
| const inlineText = "formula"; | ||
| const en = { | ||
| block, | ||
| blockText, | ||
| inline, | ||
| inlineText | ||
| }; | ||
| const icons = { | ||
| Formula: '<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="none" viewBox="0 0 48 48"><path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="4" d="m40 9-3-3H8l18 18L8 42h29l3-3"/></svg>', | ||
| Inline: '<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="none" viewBox="0 0 48 48"><path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="4" d="m37 9-3-3H8l17 18L8 42h26l3-3M5 24h10M33 24h10"/></svg>', | ||
| Block: '<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="none" viewBox="0 0 48 48"><path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="4" d="m36 11-3-3H12l16 16-16 16h21l3-3M6 5v38M42 5v38"/></svg>' | ||
| }; | ||
| function getMathActions(locale) { | ||
| return [ | ||
| { | ||
| icon: icons.Formula, | ||
| handler: { | ||
| type: "dropdown", | ||
| actions: [ | ||
| { | ||
| title: locale.inline, | ||
| icon: icons.Inline, | ||
| cheatsheet: `$${locale.inlineText}$`, | ||
| handler: { | ||
| type: "action", | ||
| click({ wrapText, editor }) { | ||
| wrapText("$"); | ||
| editor.focus(); | ||
| } | ||
| } | ||
| }, | ||
| { | ||
| title: locale.block, | ||
| icon: icons.Block, | ||
| cheatsheet: `$$↵${locale.blockText}↵$$`, | ||
| handler: { | ||
| type: "action", | ||
| click({ appendBlock, editor, codemirror }) { | ||
| const { line } = appendBlock("$$\n\\TeX\n$$"); | ||
| editor.setSelection( | ||
| codemirror.Pos(line + 1, 0), | ||
| codemirror.Pos(line + 1, 4) | ||
| ); | ||
| editor.focus(); | ||
| } | ||
| } | ||
| } | ||
| ] | ||
| } | ||
| } | ||
| ]; | ||
| } | ||
| const unicodePunctuationRegex = /[!-/:-@[-`{-~\u00A1\u00A7\u00AB\u00B6\u00B7\u00BB\u00BF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061E\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u09FD\u0A76\u0AF0\u0C77\u0C84\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u2308-\u230B\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E4F\u2E52\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65]/; | ||
| function markdownLineEnding(code) { | ||
| return code !== null && code < -2; | ||
| } | ||
| function markdownSpace(code) { | ||
| return code === -2 || code === -1 || code === 32; | ||
| } | ||
| regexCheck(unicodePunctuationRegex); | ||
| function regexCheck(regex) { | ||
| return check; | ||
| function check(code) { | ||
| return code !== null && regex.test(String.fromCharCode(code)); | ||
| } | ||
| } | ||
| function factorySpace(effects, ok, type, max) { | ||
| const limit = max ? max - 1 : Number.POSITIVE_INFINITY; | ||
| let size = 0; | ||
| return start; | ||
| function start(code) { | ||
| if (markdownSpace(code)) { | ||
| effects.enter(type); | ||
| return prefix(code); | ||
| } | ||
| return ok(code); | ||
| } | ||
| function prefix(code) { | ||
| if (markdownSpace(code) && size++ < limit) { | ||
| effects.consume(code); | ||
| return prefix; | ||
| } | ||
| effects.exit(type); | ||
| return ok(code); | ||
| } | ||
| } | ||
| const mathFlow = { | ||
| tokenize: tokenizeMathFenced, | ||
| concrete: true | ||
| }; | ||
| const nonLazyLine = { | ||
| tokenize: tokenizeNonLazyLine, | ||
| partial: true | ||
| }; | ||
| function tokenizeMathFenced(effects, ok, nok) { | ||
| const self = this; | ||
| const tail = self.events[self.events.length - 1]; | ||
| const initialSize = tail && tail[1].type === "linePrefix" ? tail[2].sliceSerialize(tail[1], true).length : 0; | ||
| let sizeOpen = 0; | ||
| return start; | ||
| function start(code) { | ||
| effects.enter("mathFlow"); | ||
| effects.enter("mathFlowFence"); | ||
| effects.enter("mathFlowFenceSequence"); | ||
| return sequenceOpen(code); | ||
| } | ||
| function sequenceOpen(code) { | ||
| if (code === 36) { | ||
| effects.consume(code); | ||
| sizeOpen++; | ||
| return sequenceOpen; | ||
| } | ||
| effects.exit("mathFlowFenceSequence"); | ||
| return sizeOpen < 2 ? nok(code) : factorySpace(effects, metaOpen, "whitespace")(code); | ||
| } | ||
| function metaOpen(code) { | ||
| if (code === null || markdownLineEnding(code)) { | ||
| return openAfter(code); | ||
| } | ||
| effects.enter("mathFlowFenceMeta"); | ||
| effects.enter("chunkString", { | ||
| contentType: "string" | ||
| }); | ||
| return meta(code); | ||
| } | ||
| function meta(code) { | ||
| if (code === null || markdownLineEnding(code)) { | ||
| effects.exit("chunkString"); | ||
| effects.exit("mathFlowFenceMeta"); | ||
| return openAfter(code); | ||
| } | ||
| if (code === 36) | ||
| return nok(code); | ||
| effects.consume(code); | ||
| return meta; | ||
| } | ||
| function openAfter(code) { | ||
| effects.exit("mathFlowFence"); | ||
| return self.interrupt ? ok(code) : contentStart(code); | ||
| } | ||
| function contentStart(code) { | ||
| if (code === null) { | ||
| return after(code); | ||
| } | ||
| if (markdownLineEnding(code)) { | ||
| return effects.attempt( | ||
| nonLazyLine, | ||
| effects.attempt( | ||
| { | ||
| tokenize: tokenizeClosingFence, | ||
| partial: true | ||
| }, | ||
| after, | ||
| initialSize ? factorySpace(effects, contentStart, "linePrefix", initialSize + 1) : contentStart | ||
| ), | ||
| after | ||
| )(code); | ||
| } | ||
| effects.enter("mathFlowValue"); | ||
| return contentContinue(code); | ||
| } | ||
| function contentContinue(code) { | ||
| if (code === null || markdownLineEnding(code)) { | ||
| effects.exit("mathFlowValue"); | ||
| return contentStart(code); | ||
| } | ||
| effects.consume(code); | ||
| return contentContinue; | ||
| } | ||
| function after(code) { | ||
| effects.exit("mathFlow"); | ||
| return ok(code); | ||
| } | ||
| function tokenizeClosingFence(effects2, ok2, nok2) { | ||
| let size = 0; | ||
| return factorySpace(effects2, closingPrefixAfter, "linePrefix", 4); | ||
| function closingPrefixAfter(code) { | ||
| effects2.enter("mathFlowFence"); | ||
| effects2.enter("mathFlowFenceSequence"); | ||
| return closingSequence(code); | ||
| } | ||
| function closingSequence(code) { | ||
| if (code === 36) { | ||
| effects2.consume(code); | ||
| size++; | ||
| return closingSequence; | ||
| } | ||
| if (size < sizeOpen) | ||
| return nok2(code); | ||
| effects2.exit("mathFlowFenceSequence"); | ||
| return factorySpace(effects2, closingSequenceEnd, "whitespace")(code); | ||
| } | ||
| function closingSequenceEnd(code) { | ||
| if (code === null || markdownLineEnding(code)) { | ||
| effects2.exit("mathFlowFence"); | ||
| return ok2(code); | ||
| } | ||
| return nok2(code); | ||
| } | ||
| } | ||
| } | ||
| function tokenizeNonLazyLine(effects, ok, nok) { | ||
| const self = this; | ||
| return start; | ||
| function start(code) { | ||
| effects.enter("lineEnding"); | ||
| effects.consume(code); | ||
| effects.exit("lineEnding"); | ||
| return lineStart; | ||
| } | ||
| function lineStart(code) { | ||
| return self.parser.lazy[self.now().line] ? nok(code) : ok(code); | ||
| } | ||
| } | ||
| function mathText(options = {}) { | ||
| let single = options.singleDollarTextMath; | ||
| if (single === null || single === void 0) { | ||
| single = true; | ||
| } | ||
| return { | ||
| tokenize: tokenizeMathText, | ||
| resolve: resolveMathText, | ||
| previous | ||
| }; | ||
| function tokenizeMathText(effects, ok, nok) { | ||
| let sizeOpen = 0; | ||
| let size; | ||
| let token; | ||
| return start; | ||
| function start(code) { | ||
| effects.enter("mathText"); | ||
| effects.enter("mathTextSequence"); | ||
| return openingSequence(code); | ||
| } | ||
| function openingSequence(code) { | ||
| if (code === 36) { | ||
| effects.consume(code); | ||
| sizeOpen++; | ||
| return openingSequence; | ||
| } | ||
| if (sizeOpen < 2 && !single) | ||
| return nok(code); | ||
| effects.exit("mathTextSequence"); | ||
| return gap(code); | ||
| } | ||
| function gap(code) { | ||
| if (code === null) { | ||
| return nok(code); | ||
| } | ||
| if (code === 36) { | ||
| token = effects.enter("mathTextSequence"); | ||
| size = 0; | ||
| return closingSequence(code); | ||
| } | ||
| if (code === 32) { | ||
| effects.enter("space"); | ||
| effects.consume(code); | ||
| effects.exit("space"); | ||
| return gap; | ||
| } | ||
| if (markdownLineEnding(code)) { | ||
| effects.enter("lineEnding"); | ||
| effects.consume(code); | ||
| effects.exit("lineEnding"); | ||
| return gap; | ||
| } | ||
| effects.enter("mathTextData"); | ||
| return data(code); | ||
| } | ||
| function data(code) { | ||
| if (code === null || code === 32 || code === 36 || markdownLineEnding(code)) { | ||
| effects.exit("mathTextData"); | ||
| return gap(code); | ||
| } | ||
| effects.consume(code); | ||
| return data; | ||
| } | ||
| function closingSequence(code) { | ||
| if (code === 36) { | ||
| effects.consume(code); | ||
| size++; | ||
| return closingSequence; | ||
| } | ||
| if (size === sizeOpen) { | ||
| effects.exit("mathTextSequence"); | ||
| effects.exit("mathText"); | ||
| return ok(code); | ||
| } | ||
| token.type = "mathTextData"; | ||
| return data(code); | ||
| } | ||
| } | ||
| } | ||
| function resolveMathText(events) { | ||
| let tailExitIndex = events.length - 4; | ||
| let headEnterIndex = 3; | ||
| let index; | ||
| let enter; | ||
| if ((events[headEnterIndex][1].type === "lineEnding" || events[headEnterIndex][1].type === "space") && (events[tailExitIndex][1].type === "lineEnding" || events[tailExitIndex][1].type === "space")) { | ||
| index = headEnterIndex; | ||
| while (++index < tailExitIndex) { | ||
| if (events[index][1].type === "mathTextData") { | ||
| events[tailExitIndex][1].type = "mathTextPadding"; | ||
| events[headEnterIndex][1].type = "mathTextPadding"; | ||
| headEnterIndex += 2; | ||
| tailExitIndex -= 2; | ||
| break; | ||
| } | ||
| } | ||
| } | ||
| index = headEnterIndex - 1; | ||
| tailExitIndex++; | ||
| while (++index <= tailExitIndex) { | ||
| if (enter === void 0) { | ||
| if (index !== tailExitIndex && events[index][1].type !== "lineEnding") { | ||
| enter = index; | ||
| } | ||
| } else if (index === tailExitIndex || events[index][1].type === "lineEnding") { | ||
| events[enter][1].type = "mathTextData"; | ||
| if (index !== enter + 2) { | ||
| events[enter][1].end = events[index - 1][1].end; | ||
| events.splice(enter + 2, index - enter - 2); | ||
| tailExitIndex -= index - enter - 2; | ||
| index = enter + 2; | ||
| } | ||
| enter = void 0; | ||
| } | ||
| } | ||
| return events; | ||
| } | ||
| function previous(code) { | ||
| return code !== 36 || this.events[this.events.length - 1][1].type === "characterEscape"; | ||
| } | ||
| function math$1(options) { | ||
| return { | ||
| flow: { | ||
| [36]: mathFlow | ||
| }, | ||
| text: { | ||
| [36]: mathText(options) | ||
| } | ||
| }; | ||
| } | ||
| function longestStreak(value, character) { | ||
| const source = String(value); | ||
| let index = source.indexOf(character); | ||
| let expected = index; | ||
| let count = 0; | ||
| let max = 0; | ||
| if (typeof character !== "string" || character.length !== 1) { | ||
| throw new Error("Expected character"); | ||
| } | ||
| while (index !== -1) { | ||
| if (index === expected) { | ||
| if (++count > max) { | ||
| max = count; | ||
| } | ||
| } else { | ||
| count = 1; | ||
| } | ||
| expected = index + 1; | ||
| index = source.indexOf(character, expected); | ||
| } | ||
| return max; | ||
| } | ||
| function patternCompile(pattern) { | ||
| if (!pattern._compiled) { | ||
| const before = (pattern.atBreak ? "[\\r\\n][\\t ]*" : "") + (pattern.before ? "(?:" + pattern.before + ")" : ""); | ||
| pattern._compiled = new RegExp( | ||
| (before ? "(" + before + ")" : "") + (/[|\\{}()[\]^$+*?.-]/.test(pattern.character) ? "\\" : "") + pattern.character + (pattern.after ? "(?:" + pattern.after + ")" : ""), | ||
| "g" | ||
| ); | ||
| } | ||
| return pattern._compiled; | ||
| } | ||
| function patternInScope(stack, pattern) { | ||
| return listInScope(stack, pattern.inConstruct, true) && !listInScope(stack, pattern.notInConstruct, false); | ||
| } | ||
| function listInScope(stack, list, none) { | ||
| if (!list) { | ||
| return none; | ||
| } | ||
| if (typeof list === "string") { | ||
| list = [list]; | ||
| } | ||
| let index = -1; | ||
| while (++index < list.length) { | ||
| if (stack.includes(list[index])) { | ||
| return true; | ||
| } | ||
| } | ||
| return false; | ||
| } | ||
| function safe(context, input, config) { | ||
| const value = (config.before || "") + (input || "") + (config.after || ""); | ||
| const positions = []; | ||
| const result = []; | ||
| const infos = {}; | ||
| let index = -1; | ||
| while (++index < context.unsafe.length) { | ||
| const pattern = context.unsafe[index]; | ||
| if (!patternInScope(context.stack, pattern)) { | ||
| continue; | ||
| } | ||
| const expression = patternCompile(pattern); | ||
| let match; | ||
| while (match = expression.exec(value)) { | ||
| const before = "before" in pattern || Boolean(pattern.atBreak); | ||
| const after = "after" in pattern; | ||
| const position = match.index + (before ? match[1].length : 0); | ||
| if (positions.includes(position)) { | ||
| if (infos[position].before && !before) { | ||
| infos[position].before = false; | ||
| } | ||
| if (infos[position].after && !after) { | ||
| infos[position].after = false; | ||
| } | ||
| } else { | ||
| positions.push(position); | ||
| infos[position] = { before, after }; | ||
| } | ||
| } | ||
| } | ||
| positions.sort(numerical); | ||
| let start = config.before ? config.before.length : 0; | ||
| const end = value.length - (config.after ? config.after.length : 0); | ||
| index = -1; | ||
| while (++index < positions.length) { | ||
| const position = positions[index]; | ||
| if (position < start || position >= end) { | ||
| continue; | ||
| } | ||
| if (position + 1 < end && positions[index + 1] === position + 1 && infos[position].after && !infos[position + 1].before && !infos[position + 1].after || positions[index - 1] === position - 1 && infos[position].before && !infos[position - 1].before && !infos[position - 1].after) { | ||
| continue; | ||
| } | ||
| if (start !== position) { | ||
| result.push(escapeBackslashes(value.slice(start, position), "\\")); | ||
| } | ||
| start = position; | ||
| if (/[!-/:-@[-`{-~]/.test(value.charAt(position)) && (!config.encode || !config.encode.includes(value.charAt(position)))) { | ||
| result.push("\\"); | ||
| } else { | ||
| result.push( | ||
| "&#x" + value.charCodeAt(position).toString(16).toUpperCase() + ";" | ||
| ); | ||
| start++; | ||
| } | ||
| } | ||
| result.push(escapeBackslashes(value.slice(start, end), config.after)); | ||
| return result.join(""); | ||
| } | ||
| function numerical(a, b) { | ||
| return a - b; | ||
| } | ||
| function escapeBackslashes(value, after) { | ||
| const expression = /\\(?=[!-/:-@[-`{-~])/g; | ||
| const positions = []; | ||
| const results = []; | ||
| const whole = value + after; | ||
| let index = -1; | ||
| let start = 0; | ||
| let match; | ||
| while (match = expression.exec(whole)) { | ||
| positions.push(match.index); | ||
| } | ||
| while (++index < positions.length) { | ||
| if (start !== positions[index]) { | ||
| results.push(value.slice(start, positions[index])); | ||
| } | ||
| results.push("\\"); | ||
| start = positions[index]; | ||
| } | ||
| results.push(value.slice(start)); | ||
| return results.join(""); | ||
| } | ||
| function track(options_) { | ||
| const options = options_ || {}; | ||
| const now = options.now || {}; | ||
| let lineShift = options.lineShift || 0; | ||
| let line = now.line || 1; | ||
| let column = now.column || 1; | ||
| return { move, current, shift }; | ||
| function current() { | ||
| return { now: { line, column }, lineShift }; | ||
| } | ||
| function shift(value) { | ||
| lineShift += value; | ||
| } | ||
| function move(value = "") { | ||
| const chunks = value.split(/\r?\n|\r/g); | ||
| const tail = chunks[chunks.length - 1]; | ||
| line += chunks.length - 1; | ||
| column = chunks.length === 1 ? column + tail.length : 1 + tail.length + lineShift; | ||
| return value; | ||
| } | ||
| } | ||
| function mathFromMarkdown() { | ||
| return { | ||
| enter: { | ||
| mathFlow: enterMathFlow, | ||
| mathFlowFenceMeta: enterMathFlowMeta, | ||
| mathText: enterMathText | ||
| }, | ||
| exit: { | ||
| mathFlow: exitMathFlow, | ||
| mathFlowFence: exitMathFlowFence, | ||
| mathFlowFenceMeta: exitMathFlowMeta, | ||
| mathFlowValue: exitMathData, | ||
| mathText: exitMathText, | ||
| mathTextData: exitMathData | ||
| } | ||
| }; | ||
| function enterMathFlow(token) { | ||
| this.enter( | ||
| { | ||
| type: "math", | ||
| meta: null, | ||
| value: "", | ||
| data: { | ||
| hName: "div", | ||
| hProperties: { className: ["math", "math-display"] }, | ||
| hChildren: [{ type: "text", value: "" }] | ||
| } | ||
| }, | ||
| token | ||
| ); | ||
| } | ||
| function enterMathFlowMeta() { | ||
| this.buffer(); | ||
| } | ||
| function exitMathFlowMeta() { | ||
| const data = this.resume(); | ||
| const node = this.stack[this.stack.length - 1]; | ||
| node.meta = data; | ||
| } | ||
| function exitMathFlowFence() { | ||
| if (this.getData("mathFlowInside")) | ||
| return; | ||
| this.buffer(); | ||
| this.setData("mathFlowInside", true); | ||
| } | ||
| function exitMathFlow(token) { | ||
| const data = this.resume().replace(/^(\r?\n|\r)|(\r?\n|\r)$/g, ""); | ||
| const node = this.exit(token); | ||
| node.value = data; | ||
| node.data.hChildren[0].value = data; | ||
| this.setData("mathFlowInside"); | ||
| } | ||
| function enterMathText(token) { | ||
| this.enter( | ||
| { | ||
| type: "inlineMath", | ||
| value: "", | ||
| data: { | ||
| hName: "span", | ||
| hProperties: { className: ["math", "math-inline"] }, | ||
| hChildren: [{ type: "text", value: "" }] | ||
| } | ||
| }, | ||
| token | ||
| ); | ||
| this.buffer(); | ||
| } | ||
| function exitMathText(token) { | ||
| const data = this.resume(); | ||
| const node = this.exit(token); | ||
| node.value = data; | ||
| node.data.hChildren[0].value = data; | ||
| } | ||
| function exitMathData(token) { | ||
| this.config.enter.data.call(this, token); | ||
| this.config.exit.data.call(this, token); | ||
| } | ||
| } | ||
| function mathToMarkdown(options = {}) { | ||
| let single = options.singleDollarTextMath; | ||
| if (single === null || single === void 0) { | ||
| single = true; | ||
| } | ||
| inlineMath.peek = inlineMathPeek; | ||
| return { | ||
| unsafe: [ | ||
| { character: "\r", inConstruct: ["mathFlowMeta"] }, | ||
| { character: "\r", inConstruct: ["mathFlowMeta"] }, | ||
| single ? { character: "$", inConstruct: ["mathFlowMeta", "phrasing"] } : { | ||
| character: "$", | ||
| after: "\\$", | ||
| inConstruct: ["mathFlowMeta", "phrasing"] | ||
| }, | ||
| { atBreak: true, character: "$", after: "\\$" } | ||
| ], | ||
| handlers: { math: math2, inlineMath } | ||
| }; | ||
| function math2(node, _, context, safeOptions) { | ||
| const raw = node.value || ""; | ||
| const sequence = "$".repeat(Math.max(longestStreak(raw, "$") + 1, 2)); | ||
| const exit = context.enter("mathFlow"); | ||
| const tracker = track(safeOptions); | ||
| let value = tracker.move(sequence); | ||
| if (node.meta) { | ||
| const subexit = context.enter("mathFlowMeta"); | ||
| value += tracker.move( | ||
| safe(context, node.meta, { | ||
| ...tracker.current(), | ||
| before: value, | ||
| after: " ", | ||
| encode: ["$"] | ||
| }) | ||
| ); | ||
| subexit(); | ||
| } | ||
| value += tracker.move("\n"); | ||
| if (raw) { | ||
| value += tracker.move(raw + "\n"); | ||
| } | ||
| value += tracker.move(sequence); | ||
| exit(); | ||
| return value; | ||
| } | ||
| function inlineMath(node) { | ||
| const value = node.value || ""; | ||
| let size = 1; | ||
| let pad = ""; | ||
| if (!single) | ||
| size++; | ||
| while (new RegExp("(^|[^$])" + "\\$".repeat(size) + "([^$]|$)").test(value)) { | ||
| size++; | ||
| } | ||
| if (/[^ \r\n]/.test(value) && (/[ \r\n$]/.test(value.charAt(0)) || /[ \r\n$]/.test(value.charAt(value.length - 1)))) { | ||
| pad = " "; | ||
| } | ||
| const sequence = "$".repeat(size); | ||
| return sequence + pad + value + pad + sequence; | ||
| } | ||
| function inlineMathPeek() { | ||
| return "$"; | ||
| } | ||
| } | ||
| function remarkMath(options = {}) { | ||
| const data = this.data(); | ||
| add("micromarkExtensions", math$1(options)); | ||
| add("fromMarkdownExtensions", mathFromMarkdown()); | ||
| add("toMarkdownExtensions", mathToMarkdown(options)); | ||
| function add(field, value) { | ||
| const list = data[field] ? data[field] : data[field] = []; | ||
| list.push(value); | ||
| } | ||
| } | ||
| function math({ | ||
| locale: _locale, | ||
| katexOptions | ||
| } = {}) { | ||
| const locale = { ...en, ..._locale }; | ||
| let katex; | ||
| return { | ||
| remark: (processor) => processor.use(remarkMath), | ||
| viewerEffect({ markdownBody }) { | ||
| const renderMath = async (selector, displayMode) => { | ||
| const els = markdownBody.querySelectorAll(selector); | ||
| if (els.length === 0) | ||
| return; | ||
| if (!katex) { | ||
| katex = await import("katex").then((m) => m.default); | ||
| } | ||
| els.forEach((el) => { | ||
| katex.render(el.innerText, el, { | ||
| ...katexOptions, | ||
| throwOnError: false, | ||
| displayMode | ||
| }); | ||
| }); | ||
| }; | ||
| renderMath(".math.math-inline", false); | ||
| renderMath(".math.math-display", true); | ||
| }, | ||
| actions: getMathActions(locale) | ||
| }; | ||
| } | ||
| module.exports = math; |
| export declare const icons: { | ||
| Formula: string; | ||
| Inline: string; | ||
| Block: string; | ||
| }; |
| import type { BytemdAction } from 'bytemd'; | ||
| export type MathLocale = { | ||
| inline: string; | ||
| inlineText: string; | ||
| block: string; | ||
| blockText: string; | ||
| }; | ||
| export declare function getMathActions(locale: MathLocale): BytemdAction[]; |
+3
-14
@@ -0,19 +1,8 @@ | ||
| import { MathLocale } from './utils'; | ||
| import type { BytemdPlugin } from 'bytemd'; | ||
| import type { KatexOptions } from 'katex'; | ||
| export declare interface BytemdPluginMathOptions { | ||
| export interface BytemdPluginMathOptions { | ||
| locale?: Partial<MathLocale>; | ||
| katexOptions?: Omit<KatexOptions, 'displayMode'>; | ||
| } | ||
| declare function math({ locale: _locale, katexOptions, }?: BytemdPluginMathOptions): BytemdPlugin; | ||
| export default math; | ||
| declare type MathLocale = { | ||
| inline: string; | ||
| inlineText: string; | ||
| block: string; | ||
| blockText: string; | ||
| }; | ||
| export { } | ||
| export default function math({ locale: _locale, katexOptions, }?: BytemdPluginMathOptions): BytemdPlugin; |
+3
-3
| { | ||
| "name": "@bytemd/plugin-math", | ||
| "version": "1.20.1", | ||
| "version": "1.20.2", | ||
| "description": "ByteMD plugin to support math formula", | ||
@@ -36,3 +36,3 @@ "repository": { | ||
| "devDependencies": { | ||
| "bytemd": "1.20.1" | ||
| "bytemd": "1.20.2" | ||
| }, | ||
@@ -42,3 +42,3 @@ "peerDependencies": { | ||
| }, | ||
| "gitHead": "34c931fafd890af7806ad9f78ba125cf77bb47e0" | ||
| "gitHead": "5341fc66607cf079145e3116ba101e57d1569b0f" | ||
| } |
325731
7.26%23
15%2836
33.52%