@minamorl/markdown-next 2.0.1 → 2.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/lib/src/parser.js +21 -9
  2. package/package.json +1 -1
package/lib/src/parser.js CHANGED
@@ -118,7 +118,12 @@ class Parser {
118
118
  return mapper(tag)(join(children));
119
119
  });
120
120
  });
121
- const inline = P.alt(pluginInline, aozoraRuby, anchor, img, em, strong, code, htmlElement, htmlSelfClosing, P.regexp(/[^\r\n<=-\[\]\*\`\@|]+/), P.regexp(/./));
121
+ // Math expressions (KaTeX-compatible)
122
+ // Inline math: $...$
123
+ const mathInline = P.seqMap(P.string("$").notFollowedBy(P.string("$")), P.regexp(/[^\$\r\n]+/), P.string("$"), (_1, content, _3) => {
124
+ return mapper("span", { class: "math math-inline", "data-math": content })(content);
125
+ });
126
+ const inline = P.alt(pluginInline, aozoraRuby, anchor, img, em, strong, code, mathInline, htmlSelfClosing, htmlElement, P.regexp(/[^\r\n<=-\[\]\*\`\@|\$]+/), P.regexp(/./));
122
127
  // Table cell content - supports inline elements
123
128
  const tableCellInline = P.alt(anchor, img, em, strong, code, P.regexp(/[^\r\n\[\]\*|`]+/));
124
129
  // Parse a single table row: |cell|cell|cell| with flexible spacing
@@ -163,10 +168,9 @@ class Parser {
163
168
  if (headerCells.length === 0) {
164
169
  return P.makeFailure(0, 'No header cells');
165
170
  }
166
- return mapper("table")(join([
167
- mapper("tr")(join(headerCells.map(h => mapper("th")(parseCellContent(h))))),
168
- join(bodyCells.map(row => mapper("tr")(join(row.map(cell => mapper("td")(parseCellContent(cell)))))))
169
- ]));
171
+ const headerRow = mapper("tr")(join(headerCells.map(h => mapper("th")(parseCellContent(h)))));
172
+ const bodyRows = bodyCells.map(row => mapper("tr")(join(row.map(cell => mapper("td")(parseCellContent(cell))))));
173
+ return mapper("table")(join([headerRow, ...bodyRows]));
170
174
  });
171
175
  const inlines = inline.atLeast(1).map(join);
172
176
  const paragraphBegin = inlines;
@@ -175,7 +179,9 @@ class Parser {
175
179
  const paragraph = paragraphLine
176
180
  .map(mapper("p"));
177
181
  const listIndent = P.string(" ");
178
- const liSingleLine = P.regexp(/[^`\r\n]*/);
182
+ // List item content - supports inline elements including math
183
+ const liInlineContent = P.alt(mathInline, anchor, img, em, strong, code, P.regexp(/[^\r\n\[\]\*\`\$]+/), P.regexp(/./));
184
+ const liSingleLine = liInlineContent.atLeast(0).map(join);
179
185
  const ulStart = P.string("- ").or(P.string("* "));
180
186
  const olStart = P.regexp(/[0-9]+\. /);
181
187
  let liLevel = [1];
@@ -284,8 +290,8 @@ class Parser {
284
290
  return mapper("pre", { "data-language": definition })(mapper("code")(join(code)));
285
291
  });
286
292
  const blockquoteBegin = P.string("> ");
287
- // Parse blockquote content using inlines to support HTML tags and ruby
288
- const blockquoteInline = P.alt(pluginInline, aozoraRuby, anchor, img, em, strong, code, htmlElement, htmlSelfClosing, P.regexp(/[^\r\n<|\[\]\*\`\@]+/), P.regexp(/./));
293
+ // Parse blockquote content using inlines to support HTML tags, ruby, and math
294
+ const blockquoteInline = P.alt(pluginInline, aozoraRuby, anchor, img, em, strong, code, mathInline, htmlSelfClosing, htmlElement, P.regexp(/[^\r\n<|\[\]\*\`\@\$]+/), P.regexp(/./));
289
295
  const blockquoteContent = blockquoteInline.atLeast(1).map(join);
290
296
  const blockquoteLine = P.lazy(() => {
291
297
  let blockquoteLevel = 0;
@@ -352,7 +358,13 @@ class Parser {
352
358
  return this.opts.plugins && this.opts.plugins[pluginName] ? this.opts.plugins[pluginName](args, content, mapper, join)
353
359
  : join([_1, pluginName, args, _2, content]);
354
360
  });
355
- const block = P.alt(P.regexp(/\s+/).result(""), pluginBlock, h1Special, h2Special, h6, h5, h4, h3, h2, h1, table, codeBlock, lists, blockquote, paragraph, linebreak.result(""));
361
+ // Block math: $$...$$ (must be on its own line or surrounded by newlines)
362
+ // Content can include anything except $$ (including single $, newlines, etc.)
363
+ const mathBlockContent = P.regexp(/[\s\S]*?(?=\$\$)/);
364
+ const mathBlock = P.seqMap(P.regexp(/^\$\$/), mathBlockContent, P.string("$$"), P.alt(linebreak, P.eof), (_1, content, _3, _4) => {
365
+ return mapper("div", { class: "math math-display", "data-math": content.trim() })(content.trim());
366
+ });
367
+ const block = P.alt(P.regexp(/\s+/).result(""), pluginBlock, h1Special, h2Special, h6, h5, h4, h3, h2, h1, table, codeBlock, mathBlock, lists, blockquote, paragraph, linebreak.result(""));
356
368
  this.acceptables = P.alt(block).many().map(join);
357
369
  }
358
370
  parse(s) {
package/package.json CHANGED
@@ -37,5 +37,5 @@
37
37
  "url": "https://github.com/minamorl/markdown-next/issues"
38
38
  },
39
39
  "homepage": "https://github.com/minamorl/markdown-next#readme",
40
- "version": "2.0.1"
40
+ "version": "2.1.1"
41
41
  }