tsondb 0.11.2 → 0.11.3
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.
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
const emptyLinePattern = /^ *$$/;
|
|
2
|
+
export const detectIndentation = (text, excludeFirstLineForDetection) => {
|
|
3
|
+
const nonEmptyLines = text.split("\n").filter(line => !emptyLinePattern.test(line));
|
|
4
|
+
return nonEmptyLines[excludeFirstLineForDetection ? 1 : 0]?.match(/^ +/)?.[0].length ?? 0;
|
|
5
|
+
};
|
|
6
|
+
const mapLines = (text, lineMapper) => text.split("\n").map(lineMapper).join("\n");
|
|
7
|
+
export const removeIndentation = (text, excludeFirstLineForDetection, fixedIndentation) => {
|
|
8
|
+
const indentation = fixedIndentation ?? detectIndentation(text, excludeFirstLineForDetection);
|
|
9
|
+
if (indentation < 1) {
|
|
10
|
+
return text;
|
|
11
|
+
}
|
|
12
|
+
const regex = new RegExp(`^ {${indentation.toString()}}`);
|
|
13
|
+
return mapLines(text, line => line.replace(regex, ""));
|
|
14
|
+
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { chunk } from "./array.js";
|
|
2
|
+
import { detectIndentation, removeIndentation } from "./markdown/indentation.js";
|
|
2
3
|
import { omitUndefinedKeys } from "./object.js";
|
|
3
4
|
import { assertExhaustive } from "./typeSafety.js";
|
|
4
5
|
const codeRule = {
|
|
@@ -229,26 +230,56 @@ const nodesForTrailingWhitespace = (text) => {
|
|
|
229
230
|
return trailingWhitespace.length === 0 ? [] : [textNode(trailingWhitespace)];
|
|
230
231
|
};
|
|
231
232
|
const listRule = {
|
|
232
|
-
pattern: /^((?:(?:\d+\.|[-*]) [^\n]+?)(?:\n(?:\d+\.|[-*]) [^\n]+?)*)(\n{2,}|\s*$)/,
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
kind
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
233
|
+
// pattern: /^((?:(?:\d+\.|[-*]) [^\n]+?)(?:\n(?:\d+\.|[-*]) [^\n]+?)*)(\n{2,}|\s*$)/,
|
|
234
|
+
pattern: /^((?:(?:\d+\. +[^\n]+(?:\n\d+\. +[^\n]+|\n {2,}[^\n]+|\n)*)|(?:- +[^\n]+(?:\n- +[^\n]+|\n {2,}[^\n]+|\n)*)))(\n{2,}|\s*$)/,
|
|
235
|
+
map: result => {
|
|
236
|
+
const listItemPairs = (result[1] ?? "").split(/(?:^|\n)(?:\d+\.|-)/).slice(1);
|
|
237
|
+
const listItems = listItemPairs.map((itemText) => {
|
|
238
|
+
const [primaryContent = "", _separator, ...additionalContents] = itemText.split(/(\n *\n|\n(?= +(?:\d+\.|-) ))/);
|
|
239
|
+
const additionalContent = additionalContents.join("");
|
|
240
|
+
const primaryContentNodes = parseInlineMarkdown(primaryContent.trim());
|
|
241
|
+
const additionalContentNodes = additionalContent
|
|
242
|
+
? parseBlockMarkdown(removeIndentation(additionalContent))
|
|
243
|
+
: [];
|
|
244
|
+
if (additionalContentNodes.length < 2 &&
|
|
245
|
+
(additionalContentNodes[0] === undefined || additionalContentNodes[0].kind === "list")) {
|
|
246
|
+
return omitUndefinedKeys({
|
|
247
|
+
kind: "listItem",
|
|
248
|
+
inlineLabel: primaryContentNodes,
|
|
249
|
+
content: [additionalContentNodes[0]].filter(element => element !== undefined),
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
else {
|
|
253
|
+
return omitUndefinedKeys({
|
|
254
|
+
kind: "listItem",
|
|
255
|
+
content: additionalContentNodes,
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
});
|
|
259
|
+
return {
|
|
260
|
+
kind: "list",
|
|
261
|
+
ordered: /^\d+\. /.test(result[0]),
|
|
262
|
+
content: listItems,
|
|
263
|
+
};
|
|
264
|
+
},
|
|
265
|
+
mapHighlighting: result => {
|
|
266
|
+
const listItemPairs = chunk((result[1] ?? "").split(/(?:^|\n)(\d+\.|-)/).slice(1), 2);
|
|
267
|
+
const listItems = listItemPairs.flatMap(([marker = "", itemText = ""], itemIndex, itemArray) => {
|
|
268
|
+
const [primaryContent = "", separator, ...additionalContents] = itemText.split(/(\n *\n|\n(?= +(?:\d+\.|-) ))/);
|
|
269
|
+
const additionalContent = additionalContents.join("");
|
|
270
|
+
return [
|
|
271
|
+
{
|
|
272
|
+
kind: "listItemMarker",
|
|
273
|
+
content: marker,
|
|
274
|
+
},
|
|
275
|
+
...parseInlineMarkdownForSyntaxHighlighting(primaryContent),
|
|
276
|
+
...(separator ? [textNode(separator)] : []),
|
|
277
|
+
...addIndentationToSyntax(parseBlockMarkdownForSyntaxHighlighting(removeIndentation(additionalContent)), detectIndentation(additionalContent)),
|
|
278
|
+
...(itemIndex < itemArray.length - 1 ? [textNode("\n")] : []),
|
|
279
|
+
];
|
|
280
|
+
});
|
|
281
|
+
return [...listItems, ...nodesForTrailingWhitespace(result[2])];
|
|
282
|
+
},
|
|
252
283
|
};
|
|
253
284
|
const paragraphRule = {
|
|
254
285
|
pattern: /^((?:[^\n]+?)(?:\n[^\n]+?)*)(\n{2,}|\s*$)/,
|
|
@@ -444,10 +475,6 @@ const containerRule = {
|
|
|
444
475
|
...nodesForTrailingWhitespace(trailingWhitespace),
|
|
445
476
|
],
|
|
446
477
|
};
|
|
447
|
-
const removeIndentation = (text) => text
|
|
448
|
-
.split("\n")
|
|
449
|
-
.map(line => line.replace(/^ {2}/, ""))
|
|
450
|
-
.join("\n");
|
|
451
478
|
export const syntaxNodeToString = (node) => {
|
|
452
479
|
switch (node.kind) {
|
|
453
480
|
case "bold":
|
|
@@ -471,7 +498,7 @@ export const syntaxNodeToString = (node) => {
|
|
|
471
498
|
return assertExhaustive(node);
|
|
472
499
|
}
|
|
473
500
|
};
|
|
474
|
-
const addIndentationToSyntax = (nodes,
|
|
501
|
+
const addIndentationToSyntax = (nodes, indentation, excludeFirstLine = false) => nodes.reduce((accNodes, currentNode) => {
|
|
475
502
|
switch (currentNode.kind) {
|
|
476
503
|
case "bold":
|
|
477
504
|
case "italic":
|
|
@@ -482,7 +509,7 @@ const addIndentationToSyntax = (nodes, nextUpperNode) => nodes.reduce((accNodes,
|
|
|
482
509
|
...accNodes,
|
|
483
510
|
{
|
|
484
511
|
...currentNode,
|
|
485
|
-
content: addIndentationToSyntax(currentNode.content,
|
|
512
|
+
content: addIndentationToSyntax(currentNode.content, indentation, excludeFirstLine),
|
|
486
513
|
},
|
|
487
514
|
];
|
|
488
515
|
case "text":
|
|
@@ -493,15 +520,12 @@ const addIndentationToSyntax = (nodes, nextUpperNode) => nodes.reduce((accNodes,
|
|
|
493
520
|
case "sectionMarker":
|
|
494
521
|
case "footnoteMarker":
|
|
495
522
|
case "definitionMarker": {
|
|
496
|
-
const nextNode = nodes[index + 1] ?? nextUpperNode;
|
|
497
|
-
const currentContent = currentNode.content.endsWith("\n") &&
|
|
498
|
-
nextNode &&
|
|
499
|
-
/^[^\n]*?\S+?/.test(syntaxNodeToString(nextNode))
|
|
500
|
-
? currentNode.content + " "
|
|
501
|
-
: currentNode.content;
|
|
502
523
|
return [
|
|
503
524
|
...accNodes,
|
|
504
|
-
{
|
|
525
|
+
{
|
|
526
|
+
...currentNode,
|
|
527
|
+
content: currentNode.content.replace(/\n(?!\n)/g, "\n" + " ".repeat(indentation)),
|
|
528
|
+
},
|
|
505
529
|
];
|
|
506
530
|
}
|
|
507
531
|
case "footnoteRef":
|
|
@@ -509,18 +533,18 @@ const addIndentationToSyntax = (nodes, nextUpperNode) => nodes.reduce((accNodes,
|
|
|
509
533
|
default:
|
|
510
534
|
return assertExhaustive(currentNode);
|
|
511
535
|
}
|
|
512
|
-
}, []);
|
|
536
|
+
}, excludeFirstLine ? [] : [textNode(" ".repeat(indentation))]);
|
|
513
537
|
const footnoteRule = {
|
|
514
538
|
pattern: /^\[\^([a-zA-Z0-9]+?)\]: (.+?(?:\n(?: {2}.+)?)*)(\n{2,}|\s*$)/,
|
|
515
539
|
map: ([_match, label = "", content = "", _trailingWhitespace]) => ({
|
|
516
540
|
kind: "footnote",
|
|
517
541
|
label: label,
|
|
518
|
-
content: parseBlockMarkdown(removeIndentation(content)),
|
|
542
|
+
content: parseBlockMarkdown(removeIndentation(content, true)),
|
|
519
543
|
}),
|
|
520
544
|
mapHighlighting: ([_match, label = "", content = "", trailingWhitespace,]) => [
|
|
521
545
|
{ kind: "footnoteMarker", content: `[^${label}]:` },
|
|
522
546
|
textNode(" "),
|
|
523
|
-
...addIndentationToSyntax(parseBlockMarkdownForSyntaxHighlighting(removeIndentation(content))),
|
|
547
|
+
...addIndentationToSyntax(parseBlockMarkdownForSyntaxHighlighting(removeIndentation(content, true)), detectIndentation(content, true), true),
|
|
524
548
|
...nodesForTrailingWhitespace(trailingWhitespace),
|
|
525
549
|
],
|
|
526
550
|
};
|
|
@@ -537,7 +561,7 @@ const definitionListRule = {
|
|
|
537
561
|
const definitions = definitionsText
|
|
538
562
|
.split("\n:")
|
|
539
563
|
.slice(1)
|
|
540
|
-
.map(definition => parseBlockMarkdown(removeIndentation(definition.trim())));
|
|
564
|
+
.map(definition => parseBlockMarkdown(removeIndentation(definition.trim(), true)));
|
|
541
565
|
return {
|
|
542
566
|
kind: "definitionListItem",
|
|
543
567
|
terms,
|
|
@@ -562,7 +586,7 @@ const definitionListRule = {
|
|
|
562
586
|
.slice(1)
|
|
563
587
|
.flatMap((definition, defIndex, defArray) => [
|
|
564
588
|
{ kind: "definitionMarker", content: ":" },
|
|
565
|
-
...addIndentationToSyntax(parseBlockMarkdownForSyntaxHighlighting(removeIndentation(definition))),
|
|
589
|
+
...addIndentationToSyntax(parseBlockMarkdownForSyntaxHighlighting(removeIndentation(definition, true)), detectIndentation(definition, true), true),
|
|
566
590
|
...(defIndex < defArray.length - 1 ? [textNode("\n")] : []),
|
|
567
591
|
]);
|
|
568
592
|
return [...terms, textNode("\n"), ...definitions];
|
|
@@ -11,13 +11,12 @@ export const BlockMarkdown = ({ node, outerHeadingLevel = 0, insertBefore, footn
|
|
|
11
11
|
case "heading":
|
|
12
12
|
const Tag = `h${(node.level + outerHeadingLevel).toString()}`;
|
|
13
13
|
return (_jsxs(Tag, { children: [insertBefore, node.content.map((inline, ii) => (_jsx(InlineMarkdown, { node: inline }, ii)))] }));
|
|
14
|
-
case "list":
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
}
|
|
14
|
+
case "list": {
|
|
15
|
+
const Tag = node.ordered ? "ol" : "ul";
|
|
16
|
+
return (_jsxs(_Fragment, { children: [insertBefore, _jsx(Tag, { children: node.content.map((item, ii) => (_jsxs("li", { children: [item.inlineLabel && item.inlineLabel.length > 0
|
|
17
|
+
? item.inlineLabel.map((inline, iii) => (_jsx(InlineMarkdown, { node: inline }, iii)))
|
|
18
|
+
: null, item.content.map((content, iii) => (_jsx(BlockMarkdown, { node: content }, iii)))] }, ii))) })] }));
|
|
19
|
+
}
|
|
21
20
|
case "table":
|
|
22
21
|
return (_jsxs(_Fragment, { children: [insertBefore, _jsxs("table", { children: [node.caption !== undefined && (_jsx("caption", { children: node.caption.map((inline, ci) => (_jsx(InlineMarkdown, { node: inline }, ci))) })), _jsx("thead", { children: _jsx(TableRow, { columns: node.columns, cells: node.header, cellType: "th" }) }), checkTableRowsAreSections(node.rows) ? (node.rows.map((section, si) => (_jsxs("tbody", { children: [section.header && (_jsx(TableRow, { columns: node.columns, cells: section.header, cellType: "th" })), section.rows.map((row, ri) => (_jsx(TableRow, { columns: node.columns, cells: row.cells }, ri)))] }, si)))) : (_jsx("tbody", { children: node.rows.map((row, ri) => (_jsx(TableRow, { columns: node.columns, cells: row.cells }, ri))) }))] })] }));
|
|
23
22
|
case "container":
|