remark-math.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534
  1. import {
  2. codes,
  3. constants,
  4. factorySpace,
  5. markdownLineEnding,
  6. ok,
  7. types
  8. } from "./chunk-EIBGEDEJ.js";
  9. import {
  10. katex
  11. } from "./chunk-REIMVYFT.js";
  12. import "./chunk-DC5AMYBS.js";
  13. // node_modules/longest-streak/index.js
  14. function longestStreak(value, substring) {
  15. const source = String(value);
  16. let index = source.indexOf(substring);
  17. let expected = index;
  18. let count = 0;
  19. let max = 0;
  20. if (typeof substring !== "string") {
  21. throw new TypeError("Expected substring");
  22. }
  23. while (index !== -1) {
  24. if (index === expected) {
  25. if (++count > max) {
  26. max = count;
  27. }
  28. } else {
  29. count = 1;
  30. }
  31. expected = index + substring.length;
  32. index = source.indexOf(substring, expected);
  33. }
  34. return max;
  35. }
  36. // node_modules/mdast-util-math/lib/index.js
  37. function mathFromMarkdown() {
  38. return {
  39. enter: {
  40. mathFlow: enterMathFlow,
  41. mathFlowFenceMeta: enterMathFlowMeta,
  42. mathText: enterMathText
  43. },
  44. exit: {
  45. mathFlow: exitMathFlow,
  46. mathFlowFence: exitMathFlowFence,
  47. mathFlowFenceMeta: exitMathFlowMeta,
  48. mathFlowValue: exitMathData,
  49. mathText: exitMathText,
  50. mathTextData: exitMathData
  51. }
  52. };
  53. function enterMathFlow(token) {
  54. const code = {
  55. type: "element",
  56. tagName: "code",
  57. properties: { className: ["language-math", "math-display"] },
  58. children: []
  59. };
  60. this.enter(
  61. {
  62. type: "math",
  63. meta: null,
  64. value: "",
  65. data: { hName: "pre", hChildren: [code] }
  66. },
  67. token
  68. );
  69. }
  70. function enterMathFlowMeta() {
  71. this.buffer();
  72. }
  73. function exitMathFlowMeta() {
  74. const data = this.resume();
  75. const node = this.stack[this.stack.length - 1];
  76. ok(node.type === "math");
  77. node.meta = data;
  78. }
  79. function exitMathFlowFence() {
  80. if (this.data.mathFlowInside) return;
  81. this.buffer();
  82. this.data.mathFlowInside = true;
  83. }
  84. function exitMathFlow(token) {
  85. const data = this.resume().replace(/^(\r?\n|\r)|(\r?\n|\r)$/g, "");
  86. const node = this.stack[this.stack.length - 1];
  87. ok(node.type === "math");
  88. this.exit(token);
  89. node.value = data;
  90. const code = (
  91. /** @type {HastElement} */
  92. node.data.hChildren[0]
  93. );
  94. ok(code.type === "element");
  95. ok(code.tagName === "code");
  96. code.children.push({ type: "text", value: data });
  97. this.data.mathFlowInside = void 0;
  98. }
  99. function enterMathText(token) {
  100. this.enter(
  101. {
  102. type: "inlineMath",
  103. value: "",
  104. data: {
  105. hName: "code",
  106. hProperties: { className: ["language-math", "math-inline"] },
  107. hChildren: []
  108. }
  109. },
  110. token
  111. );
  112. this.buffer();
  113. }
  114. function exitMathText(token) {
  115. const data = this.resume();
  116. const node = this.stack[this.stack.length - 1];
  117. ok(node.type === "inlineMath");
  118. this.exit(token);
  119. node.value = data;
  120. const children = (
  121. /** @type {Array<HastElementContent>} */
  122. // @ts-expect-error: we defined it in `enterMathFlow`.
  123. node.data.hChildren
  124. );
  125. children.push({ type: "text", value: data });
  126. }
  127. function exitMathData(token) {
  128. this.config.enter.data.call(this, token);
  129. this.config.exit.data.call(this, token);
  130. }
  131. }
  132. function mathToMarkdown(options) {
  133. let single = (options || {}).singleDollarTextMath;
  134. if (single === null || single === void 0) {
  135. single = true;
  136. }
  137. inlineMath.peek = inlineMathPeek;
  138. return {
  139. unsafe: [
  140. { character: "\r", inConstruct: "mathFlowMeta" },
  141. { character: "\n", inConstruct: "mathFlowMeta" },
  142. {
  143. character: "$",
  144. after: single ? void 0 : "\\$",
  145. inConstruct: "phrasing"
  146. },
  147. { character: "$", inConstruct: "mathFlowMeta" },
  148. { atBreak: true, character: "$", after: "\\$" }
  149. ],
  150. handlers: { math: math2, inlineMath }
  151. };
  152. function math2(node, _, state, info) {
  153. const raw = node.value || "";
  154. const tracker = state.createTracker(info);
  155. const sequence = "$".repeat(Math.max(longestStreak(raw, "$") + 1, 2));
  156. const exit = state.enter("mathFlow");
  157. let value = tracker.move(sequence);
  158. if (node.meta) {
  159. const subexit = state.enter("mathFlowMeta");
  160. value += tracker.move(
  161. state.safe(node.meta, {
  162. after: "\n",
  163. before: value,
  164. encode: ["$"],
  165. ...tracker.current()
  166. })
  167. );
  168. subexit();
  169. }
  170. value += tracker.move("\n");
  171. if (raw) {
  172. value += tracker.move(raw + "\n");
  173. }
  174. value += tracker.move(sequence);
  175. exit();
  176. return value;
  177. }
  178. function inlineMath(node, _, state) {
  179. let value = node.value || "";
  180. let size = 1;
  181. if (!single) size++;
  182. while (new RegExp("(^|[^$])" + "\\$".repeat(size) + "([^$]|$)").test(value)) {
  183. size++;
  184. }
  185. const sequence = "$".repeat(size);
  186. if (
  187. // Contains non-space.
  188. /[^ \r\n]/.test(value) && // Starts with space and ends with space.
  189. (/^[ \r\n]/.test(value) && /[ \r\n]$/.test(value) || // Starts or ends with dollar.
  190. /^\$|\$$/.test(value))
  191. ) {
  192. value = " " + value + " ";
  193. }
  194. let index = -1;
  195. while (++index < state.unsafe.length) {
  196. const pattern = state.unsafe[index];
  197. if (!pattern.atBreak) continue;
  198. const expression = state.compilePattern(pattern);
  199. let match;
  200. while (match = expression.exec(value)) {
  201. let position = match.index;
  202. if (value.codePointAt(position) === 10 && value.codePointAt(position - 1) === 13) {
  203. position--;
  204. }
  205. value = value.slice(0, position) + " " + value.slice(match.index + 1);
  206. }
  207. }
  208. return sequence + value + sequence;
  209. }
  210. function inlineMathPeek() {
  211. return "$";
  212. }
  213. }
  214. // node_modules/micromark-extension-math/dev/lib/math-flow.js
  215. var mathFlow = {
  216. tokenize: tokenizeMathFenced,
  217. concrete: true,
  218. name: "mathFlow"
  219. };
  220. var nonLazyContinuation = {
  221. tokenize: tokenizeNonLazyContinuation,
  222. partial: true
  223. };
  224. function tokenizeMathFenced(effects, ok2, nok) {
  225. const self = this;
  226. const tail = self.events[self.events.length - 1];
  227. const initialSize = tail && tail[1].type === types.linePrefix ? tail[2].sliceSerialize(tail[1], true).length : 0;
  228. let sizeOpen = 0;
  229. return start;
  230. function start(code) {
  231. ok(code === codes.dollarSign, "expected `$`");
  232. effects.enter("mathFlow");
  233. effects.enter("mathFlowFence");
  234. effects.enter("mathFlowFenceSequence");
  235. return sequenceOpen(code);
  236. }
  237. function sequenceOpen(code) {
  238. if (code === codes.dollarSign) {
  239. effects.consume(code);
  240. sizeOpen++;
  241. return sequenceOpen;
  242. }
  243. if (sizeOpen < 2) {
  244. return nok(code);
  245. }
  246. effects.exit("mathFlowFenceSequence");
  247. return factorySpace(effects, metaBefore, types.whitespace)(code);
  248. }
  249. function metaBefore(code) {
  250. if (code === codes.eof || markdownLineEnding(code)) {
  251. return metaAfter(code);
  252. }
  253. effects.enter("mathFlowFenceMeta");
  254. effects.enter(types.chunkString, { contentType: constants.contentTypeString });
  255. return meta(code);
  256. }
  257. function meta(code) {
  258. if (code === codes.eof || markdownLineEnding(code)) {
  259. effects.exit(types.chunkString);
  260. effects.exit("mathFlowFenceMeta");
  261. return metaAfter(code);
  262. }
  263. if (code === codes.dollarSign) {
  264. return nok(code);
  265. }
  266. effects.consume(code);
  267. return meta;
  268. }
  269. function metaAfter(code) {
  270. effects.exit("mathFlowFence");
  271. if (self.interrupt) {
  272. return ok2(code);
  273. }
  274. return effects.attempt(
  275. nonLazyContinuation,
  276. beforeNonLazyContinuation,
  277. after
  278. )(code);
  279. }
  280. function beforeNonLazyContinuation(code) {
  281. return effects.attempt(
  282. { tokenize: tokenizeClosingFence, partial: true },
  283. after,
  284. contentStart
  285. )(code);
  286. }
  287. function contentStart(code) {
  288. return (initialSize ? factorySpace(
  289. effects,
  290. beforeContentChunk,
  291. types.linePrefix,
  292. initialSize + 1
  293. ) : beforeContentChunk)(code);
  294. }
  295. function beforeContentChunk(code) {
  296. if (code === codes.eof) {
  297. return after(code);
  298. }
  299. if (markdownLineEnding(code)) {
  300. return effects.attempt(
  301. nonLazyContinuation,
  302. beforeNonLazyContinuation,
  303. after
  304. )(code);
  305. }
  306. effects.enter("mathFlowValue");
  307. return contentChunk(code);
  308. }
  309. function contentChunk(code) {
  310. if (code === codes.eof || markdownLineEnding(code)) {
  311. effects.exit("mathFlowValue");
  312. return beforeContentChunk(code);
  313. }
  314. effects.consume(code);
  315. return contentChunk;
  316. }
  317. function after(code) {
  318. effects.exit("mathFlow");
  319. return ok2(code);
  320. }
  321. function tokenizeClosingFence(effects2, ok3, nok2) {
  322. let size = 0;
  323. ok(self.parser.constructs.disable.null, "expected `disable.null`");
  324. return factorySpace(
  325. effects2,
  326. beforeSequenceClose,
  327. types.linePrefix,
  328. self.parser.constructs.disable.null.includes("codeIndented") ? void 0 : constants.tabSize
  329. );
  330. function beforeSequenceClose(code) {
  331. effects2.enter("mathFlowFence");
  332. effects2.enter("mathFlowFenceSequence");
  333. return sequenceClose(code);
  334. }
  335. function sequenceClose(code) {
  336. if (code === codes.dollarSign) {
  337. size++;
  338. effects2.consume(code);
  339. return sequenceClose;
  340. }
  341. if (size < sizeOpen) {
  342. return nok2(code);
  343. }
  344. effects2.exit("mathFlowFenceSequence");
  345. return factorySpace(effects2, afterSequenceClose, types.whitespace)(code);
  346. }
  347. function afterSequenceClose(code) {
  348. if (code === codes.eof || markdownLineEnding(code)) {
  349. effects2.exit("mathFlowFence");
  350. return ok3(code);
  351. }
  352. return nok2(code);
  353. }
  354. }
  355. }
  356. function tokenizeNonLazyContinuation(effects, ok2, nok) {
  357. const self = this;
  358. return start;
  359. function start(code) {
  360. if (code === null) {
  361. return ok2(code);
  362. }
  363. ok(markdownLineEnding(code), "expected eol");
  364. effects.enter(types.lineEnding);
  365. effects.consume(code);
  366. effects.exit(types.lineEnding);
  367. return lineStart;
  368. }
  369. function lineStart(code) {
  370. return self.parser.lazy[self.now().line] ? nok(code) : ok2(code);
  371. }
  372. }
  373. // node_modules/micromark-extension-math/dev/lib/math-text.js
  374. function mathText(options) {
  375. const options_ = options || {};
  376. let single = options_.singleDollarTextMath;
  377. if (single === null || single === void 0) {
  378. single = true;
  379. }
  380. return {
  381. tokenize: tokenizeMathText,
  382. resolve: resolveMathText,
  383. previous,
  384. name: "mathText"
  385. };
  386. function tokenizeMathText(effects, ok2, nok) {
  387. const self = this;
  388. let sizeOpen = 0;
  389. let size;
  390. let token;
  391. return start;
  392. function start(code) {
  393. ok(code === codes.dollarSign, "expected `$`");
  394. ok(previous.call(self, self.previous), "expected correct previous");
  395. effects.enter("mathText");
  396. effects.enter("mathTextSequence");
  397. return sequenceOpen(code);
  398. }
  399. function sequenceOpen(code) {
  400. if (code === codes.dollarSign) {
  401. effects.consume(code);
  402. sizeOpen++;
  403. return sequenceOpen;
  404. }
  405. if (sizeOpen < 2 && !single) {
  406. return nok(code);
  407. }
  408. effects.exit("mathTextSequence");
  409. return between(code);
  410. }
  411. function between(code) {
  412. if (code === codes.eof) {
  413. return nok(code);
  414. }
  415. if (code === codes.dollarSign) {
  416. token = effects.enter("mathTextSequence");
  417. size = 0;
  418. return sequenceClose(code);
  419. }
  420. if (code === codes.space) {
  421. effects.enter("space");
  422. effects.consume(code);
  423. effects.exit("space");
  424. return between;
  425. }
  426. if (markdownLineEnding(code)) {
  427. effects.enter(types.lineEnding);
  428. effects.consume(code);
  429. effects.exit(types.lineEnding);
  430. return between;
  431. }
  432. effects.enter("mathTextData");
  433. return data(code);
  434. }
  435. function data(code) {
  436. if (code === codes.eof || code === codes.space || code === codes.dollarSign || markdownLineEnding(code)) {
  437. effects.exit("mathTextData");
  438. return between(code);
  439. }
  440. effects.consume(code);
  441. return data;
  442. }
  443. function sequenceClose(code) {
  444. if (code === codes.dollarSign) {
  445. effects.consume(code);
  446. size++;
  447. return sequenceClose;
  448. }
  449. if (size === sizeOpen) {
  450. effects.exit("mathTextSequence");
  451. effects.exit("mathText");
  452. return ok2(code);
  453. }
  454. token.type = "mathTextData";
  455. return data(code);
  456. }
  457. }
  458. }
  459. function resolveMathText(events) {
  460. let tailExitIndex = events.length - 4;
  461. let headEnterIndex = 3;
  462. let index;
  463. let enter;
  464. if ((events[headEnterIndex][1].type === types.lineEnding || events[headEnterIndex][1].type === "space") && (events[tailExitIndex][1].type === types.lineEnding || events[tailExitIndex][1].type === "space")) {
  465. index = headEnterIndex;
  466. while (++index < tailExitIndex) {
  467. if (events[index][1].type === "mathTextData") {
  468. events[tailExitIndex][1].type = "mathTextPadding";
  469. events[headEnterIndex][1].type = "mathTextPadding";
  470. headEnterIndex += 2;
  471. tailExitIndex -= 2;
  472. break;
  473. }
  474. }
  475. }
  476. index = headEnterIndex - 1;
  477. tailExitIndex++;
  478. while (++index <= tailExitIndex) {
  479. if (enter === void 0) {
  480. if (index !== tailExitIndex && events[index][1].type !== types.lineEnding) {
  481. enter = index;
  482. }
  483. } else if (index === tailExitIndex || events[index][1].type === types.lineEnding) {
  484. events[enter][1].type = "mathTextData";
  485. if (index !== enter + 2) {
  486. events[enter][1].end = events[index - 1][1].end;
  487. events.splice(enter + 2, index - enter - 2);
  488. tailExitIndex -= index - enter - 2;
  489. index = enter + 2;
  490. }
  491. enter = void 0;
  492. }
  493. }
  494. return events;
  495. }
  496. function previous(code) {
  497. return code !== codes.dollarSign || this.events[this.events.length - 1][1].type === types.characterEscape;
  498. }
  499. // node_modules/micromark-extension-math/dev/lib/syntax.js
  500. function math(options) {
  501. return {
  502. flow: { [codes.dollarSign]: mathFlow },
  503. text: { [codes.dollarSign]: mathText(options) }
  504. };
  505. }
  506. // node_modules/micromark-extension-math/dev/lib/html.js
  507. var renderToString = katex.renderToString;
  508. // node_modules/remark-math/lib/index.js
  509. var emptyOptions = {};
  510. function remarkMath(options) {
  511. const self = (
  512. /** @type {Processor} */
  513. this
  514. );
  515. const settings = options || emptyOptions;
  516. const data = self.data();
  517. const micromarkExtensions = data.micromarkExtensions || (data.micromarkExtensions = []);
  518. const fromMarkdownExtensions = data.fromMarkdownExtensions || (data.fromMarkdownExtensions = []);
  519. const toMarkdownExtensions = data.toMarkdownExtensions || (data.toMarkdownExtensions = []);
  520. micromarkExtensions.push(math(settings));
  521. fromMarkdownExtensions.push(mathFromMarkdown());
  522. toMarkdownExtensions.push(mathToMarkdown(settings));
  523. }
  524. export {
  525. remarkMath as default
  526. };
  527. //# sourceMappingURL=remark-math.js.map