@wdprlib/parser 5.1.5 → 5.2.0
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.
- package/LICENSE +661 -0
- package/README.md +1 -1
- package/THIRD-PARTY-LICENSES.md +23 -0
- package/dist/index.cjs +655 -436
- package/dist/index.d.cts +11 -4
- package/dist/index.d.ts +11 -4
- package/dist/index.js +653 -435
- package/licenses/LGPL-2.1.txt +501 -0
- package/package.json +6 -3
- package/src/build-info.generated.ts +11 -0
- package/src/index.ts +2 -0
- package/src/lexer/lexer.ts +6 -4
- package/src/lexer/punctuation.ts +2 -1
- package/src/lexer/spacing-actions.ts +15 -0
- package/src/lexer/state.ts +30 -4
- package/src/lexer/token-factory.ts +15 -2
- package/src/lexer/tokens.ts +4 -3
- package/src/parser/rules/block/blockquote/build.ts +81 -37
- package/src/parser/rules/block/blockquote/index.ts +5 -6
- package/src/parser/rules/block/blockquote/line.ts +11 -10
- package/src/parser/rules/block/blockquote/lines.ts +102 -4
- package/src/parser/rules/block/code/content.ts +0 -3
- package/src/parser/rules/block/code/index.ts +14 -10
- package/src/parser/rules/block/definition-list/index.ts +4 -10
- package/src/parser/rules/block/definition-list/item-value.ts +2 -11
- package/src/parser/rules/block/definition-list/items.ts +1 -2
- package/src/parser/rules/block/embed-block/index.ts +30 -30
- package/src/parser/rules/block/heading/index.ts +7 -0
- package/src/parser/rules/block/paragraph/index.ts +41 -10
- package/src/parser/rules/block/parsing/content.ts +18 -1
- package/src/parser/rules/block/table/pipe/cell.ts +36 -1
- package/src/parser/rules/block/table/pipe/row.ts +21 -1
- package/src/parser/rules/block/toc/element.ts +2 -2
- package/src/parser/rules/block/toc/index.ts +2 -2
- package/src/parser/rules/block/toc/open.ts +5 -18
- package/src/parser/rules/contracts/scope.ts +4 -0
- package/src/parser/rules/inline/bold.ts +5 -5
- package/src/parser/rules/inline/color/syntax.ts +5 -8
- package/src/parser/rules/inline/formatting/close.ts +39 -0
- package/src/parser/rules/inline/formatting/container.ts +7 -4
- package/src/parser/rules/inline/index.ts +2 -0
- package/src/parser/rules/inline/italic.ts +5 -5
- package/src/parser/rules/inline/monospace.ts +5 -5
- package/src/parser/rules/inline/parsing/block-start-predicates.ts +2 -0
- package/src/parser/rules/inline/parsing/inline-content.ts +58 -4
- package/src/parser/rules/inline/raw/end.ts +28 -0
- package/src/parser/rules/inline/span/content.ts +32 -1
- package/src/parser/rules/inline/strikethrough/index.ts +1 -1
- package/src/parser/rules/inline/strikethrough/parse.ts +2 -9
- package/src/parser/rules/inline/strikethrough/syntax.ts +3 -20
- package/src/parser/rules/inline/subscript.ts +5 -5
- package/src/parser/rules/inline/superscript.ts +5 -5
- package/src/parser/rules/inline/underline/index.ts +5 -78
- package/src/parser/rules/tokens.ts +6 -15
- package/src/parser/rules/inline/underline/child.ts +0 -26
- package/src/parser/rules/inline/underline/content.ts +0 -29
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { Token } from "../../../../lexer";
|
|
2
|
+
|
|
3
|
+
/** Exclusive end of a complete single-line raw region, or the original position. */
|
|
4
|
+
export function rawRegionEnd(tokens: readonly Token[], start: number, end: number): number {
|
|
5
|
+
const type = tokens[start]?.type;
|
|
6
|
+
const close =
|
|
7
|
+
type === "RAW_OPEN" ? "RAW_OPEN" : type === "RAW_BLOCK_OPEN" ? "RAW_BLOCK_CLOSE" : null;
|
|
8
|
+
if (!close) return start;
|
|
9
|
+
for (let pos = start + 1; pos < end; pos++) {
|
|
10
|
+
if (tokens[pos]?.type === "NEWLINE" || tokens[pos]?.type === "EOF") break;
|
|
11
|
+
if (tokens[pos]?.type === close) return pos + 1;
|
|
12
|
+
}
|
|
13
|
+
return start;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/** Raw text and complete comments shield delimiters from their enclosing rule. */
|
|
17
|
+
export function protectedInlineRegionEnd(
|
|
18
|
+
tokens: readonly Token[],
|
|
19
|
+
start: number,
|
|
20
|
+
end: number,
|
|
21
|
+
): number {
|
|
22
|
+
const rawEnd = rawRegionEnd(tokens, start, end);
|
|
23
|
+
if (rawEnd > start || tokens[start]?.type !== "COMMENT_OPEN") return rawEnd;
|
|
24
|
+
for (let pos = start + 1; pos < end; pos++) {
|
|
25
|
+
if (tokens[pos]?.type === "COMMENT_CLOSE") return pos + 1;
|
|
26
|
+
}
|
|
27
|
+
return start;
|
|
28
|
+
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { rawRegionEnd } from "../raw/end";
|
|
1
2
|
import type { Element } from "@wdprlib/ast";
|
|
2
3
|
import type { ParseContext } from "../../types";
|
|
3
4
|
import { inlineRules } from "../../index";
|
|
@@ -24,16 +25,21 @@ export function parseSpanContent(
|
|
|
24
25
|
const escapedChildren: Element[] = [];
|
|
25
26
|
const splitSpans: Element[][] = [];
|
|
26
27
|
let foundClose = false;
|
|
28
|
+
let forcedClose = false;
|
|
27
29
|
let afterBlankLine = false;
|
|
28
30
|
let consumed = 0;
|
|
29
31
|
let pos = startPos;
|
|
30
32
|
|
|
31
|
-
while (pos < ctx.tokens.length) {
|
|
33
|
+
while (pos < (ctx.scope.inlineEnd ?? ctx.tokens.length)) {
|
|
32
34
|
const token = ctx.tokens[pos];
|
|
33
35
|
if (!token || token.type === "EOF") {
|
|
34
36
|
break;
|
|
35
37
|
}
|
|
36
38
|
|
|
39
|
+
if (ctx.scope.tableFormatting?.suppressedClosers.has(pos)) {
|
|
40
|
+
forcedClose = true;
|
|
41
|
+
break;
|
|
42
|
+
}
|
|
37
43
|
const close = parseCloseSpan(ctx, pos);
|
|
38
44
|
if (close.success) {
|
|
39
45
|
pos += close.consumed;
|
|
@@ -70,6 +76,31 @@ export function parseSpanContent(
|
|
|
70
76
|
consumed += parsed.consumed;
|
|
71
77
|
}
|
|
72
78
|
|
|
79
|
+
if (!foundClose && ctx.scope.tableFormatting && (pos === ctx.scope.inlineEnd || forcedClose)) {
|
|
80
|
+
let depth = 0;
|
|
81
|
+
for (let next = pos; next < ctx.scope.tableFormatting.end; next++) {
|
|
82
|
+
const rawEnd = rawRegionEnd(ctx.tokens, next, ctx.scope.tableFormatting.end);
|
|
83
|
+
if (rawEnd > next) {
|
|
84
|
+
next = rawEnd - 1;
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
if (
|
|
88
|
+
ctx.tokens[next]?.type === "BLOCK_OPEN" &&
|
|
89
|
+
/^span_?$/i.test(ctx.tokens[next + 1]?.value ?? "")
|
|
90
|
+
)
|
|
91
|
+
depth++;
|
|
92
|
+
const close = parseCloseSpan(ctx, next);
|
|
93
|
+
if (!close.success) continue;
|
|
94
|
+
if (depth > 0) {
|
|
95
|
+
depth--;
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
for (let offset = 0; offset < close.consumed; offset++)
|
|
99
|
+
ctx.scope.tableFormatting.suppressedClosers.add(next + offset);
|
|
100
|
+
foundClose = true;
|
|
101
|
+
break;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
73
104
|
return { children, escapedChildren, splitSpans, consumed, foundClose };
|
|
74
105
|
}
|
|
75
106
|
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* token has dual meaning in Wikidot: it can be either a strikethrough
|
|
7
7
|
* marker or an em-dash. The disambiguation rule is:
|
|
8
8
|
*
|
|
9
|
-
* - If a matching closing `--` is found
|
|
9
|
+
* - If a matching closing `--` is found within the same paragraph AND the closing
|
|
10
10
|
* marker is NOT preceded by whitespace, it is treated as strikethrough.
|
|
11
11
|
* - Otherwise, the `--` is converted to an em-dash character (U+2014).
|
|
12
12
|
*
|
|
@@ -1,14 +1,7 @@
|
|
|
1
1
|
import type { Element } from "@wdprlib/ast";
|
|
2
2
|
import type { ParseContext, RuleResult } from "../../types";
|
|
3
|
-
import {
|
|
4
|
-
import { parseInlineUntil } from "../utils";
|
|
3
|
+
import { parseDelimitedContainer } from "../formatting/container";
|
|
5
4
|
|
|
6
5
|
export function parseStrikethroughContent(ctx: ParseContext): RuleResult<Element> {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
return {
|
|
10
|
-
success: true,
|
|
11
|
-
elements: [createInlineContainer("strikethrough", result.elements)],
|
|
12
|
-
consumed: 1 + result.consumed + 1,
|
|
13
|
-
};
|
|
6
|
+
return parseDelimitedContainer(ctx, "STRIKE_MARKER", "strikethrough");
|
|
14
7
|
}
|
|
@@ -1,24 +1,7 @@
|
|
|
1
1
|
import type { ParseContext } from "../../types";
|
|
2
|
+
import { findFormattingClose } from "../formatting/close";
|
|
2
3
|
|
|
3
|
-
/**
|
|
4
|
-
* Returns true when the current `--` can be parsed as strikethrough.
|
|
5
|
-
*/
|
|
6
4
|
export function hasValidStrikethroughClose(ctx: ParseContext): boolean {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
while (pos < ctx.tokens.length) {
|
|
11
|
-
const token = ctx.tokens[pos];
|
|
12
|
-
if (!token || token.type === "NEWLINE" || token.type === "EOF") {
|
|
13
|
-
return false;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
if (token.type === "STRIKE_MARKER") {
|
|
17
|
-
return !prevWasWhitespace;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
prevWasWhitespace = token.type === "WHITESPACE";
|
|
21
|
-
pos++;
|
|
22
|
-
}
|
|
23
|
-
return false;
|
|
5
|
+
const close = findFormattingClose(ctx, ctx.pos + 1, "STRIKE_MARKER");
|
|
6
|
+
return close !== null && close > ctx.pos + 1 && ctx.tokens[close - 1]?.type !== "WHITESPACE";
|
|
24
7
|
}
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
* Parses the Wikidot subscript formatting syntax: `,,text,,`.
|
|
4
4
|
*
|
|
5
5
|
* Subscript text is delimited by double commas. The opening and closing
|
|
6
|
-
* markers must appear
|
|
7
|
-
* before a
|
|
6
|
+
* markers must appear within the same paragraph. If no closing `,,` is found
|
|
7
|
+
* before a block boundary, the opening marker is emitted as literal text.
|
|
8
8
|
*
|
|
9
9
|
* Empty subscript (`,,,,`) is silently discarded by Wikidot (produces
|
|
10
10
|
* no output), matching the behavior of bold and superscript.
|
|
@@ -17,13 +17,13 @@
|
|
|
17
17
|
*/
|
|
18
18
|
import type { Element } from "@wdprlib/ast";
|
|
19
19
|
import type { InlineRule, ParseContext, RuleResult } from "../types";
|
|
20
|
-
import {
|
|
20
|
+
import { parseDelimitedContainer } from "./formatting/container";
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
23
|
* Inline rule for parsing `,,subscript,,` formatting.
|
|
24
24
|
*
|
|
25
25
|
* Triggered by a `SUB_MARKER` token (`,,`). Checks for a matching
|
|
26
|
-
* closing marker
|
|
26
|
+
* closing marker within the same paragraph, then recursively parses inline
|
|
27
27
|
* content between the markers.
|
|
28
28
|
*
|
|
29
29
|
* When no closing marker is found, the opening `,,` is treated as
|
|
@@ -42,6 +42,6 @@ export const subscriptRule: InlineRule = {
|
|
|
42
42
|
* text fallback for unmatched markers
|
|
43
43
|
*/
|
|
44
44
|
parse(ctx: ParseContext): RuleResult<Element> {
|
|
45
|
-
return
|
|
45
|
+
return parseDelimitedContainer(ctx, "SUB_MARKER", "subscript", { discardEmpty: true });
|
|
46
46
|
},
|
|
47
47
|
};
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
* Parses the Wikidot superscript formatting syntax: `^^text^^`.
|
|
4
4
|
*
|
|
5
5
|
* Superscript text is delimited by double carets. The opening and
|
|
6
|
-
* closing markers must appear
|
|
7
|
-
* is found before a
|
|
6
|
+
* closing markers must appear within the same paragraph. If no closing `^^`
|
|
7
|
+
* is found before a block boundary, the opening marker is emitted as literal text.
|
|
8
8
|
*
|
|
9
9
|
* Empty superscript (`^^^^`) is silently discarded by Wikidot (produces
|
|
10
10
|
* no output), matching the behavior of bold and subscript.
|
|
@@ -17,13 +17,13 @@
|
|
|
17
17
|
*/
|
|
18
18
|
import type { Element } from "@wdprlib/ast";
|
|
19
19
|
import type { InlineRule, ParseContext, RuleResult } from "../types";
|
|
20
|
-
import {
|
|
20
|
+
import { parseDelimitedContainer } from "./formatting/container";
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
23
|
* Inline rule for parsing `^^superscript^^` formatting.
|
|
24
24
|
*
|
|
25
25
|
* Triggered by a `SUPER_MARKER` token (`^^`). Checks for a matching
|
|
26
|
-
* closing marker
|
|
26
|
+
* closing marker within the same paragraph, then recursively parses inline
|
|
27
27
|
* content between the markers.
|
|
28
28
|
*
|
|
29
29
|
* When no closing marker is found, the opening `^^` is treated as
|
|
@@ -42,7 +42,7 @@ export const superscriptRule: InlineRule = {
|
|
|
42
42
|
* text fallback for unmatched markers
|
|
43
43
|
*/
|
|
44
44
|
parse(ctx: ParseContext): RuleResult<Element> {
|
|
45
|
-
return
|
|
45
|
+
return parseDelimitedContainer(ctx, "SUPER_MARKER", "superscript", {
|
|
46
46
|
discardEmpty: true,
|
|
47
47
|
});
|
|
48
48
|
},
|
|
@@ -1,84 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
* Parses the Wikidot underline formatting syntax: `__text__`.
|
|
4
|
-
*
|
|
5
|
-
* Underline text is delimited by double underscores. Unlike most
|
|
6
|
-
* inline formatting markers (bold, italic, etc.) which require the
|
|
7
|
-
* closing marker on the same line, underline markers can span
|
|
8
|
-
* multiple lines within the same paragraph. The closing marker
|
|
9
|
-
* must appear before a paragraph break (blank line).
|
|
10
|
-
*
|
|
11
|
-
* Single newlines within underlined content are converted to
|
|
12
|
-
* `<br />` elements, matching Wikidot's multiline underline behavior.
|
|
13
|
-
*
|
|
14
|
-
* If no closing `__` is found before a paragraph break, the opening
|
|
15
|
-
* marker is emitted as literal text.
|
|
16
|
-
*
|
|
17
|
-
* Empty underline (`____`) is silently discarded by Wikidot (produces
|
|
18
|
-
* no output).
|
|
19
|
-
*
|
|
20
|
-
* Renders as a `<u>` element in HTML.
|
|
21
|
-
*
|
|
22
|
-
* Produces a `"container"` AST element with `type: "underline"`.
|
|
23
|
-
*
|
|
24
|
-
* @module
|
|
25
|
-
*/
|
|
26
|
-
import type { Element } from "@wdprlib/ast";
|
|
27
|
-
import type { InlineRule, ParseContext, RuleResult } from "../../types";
|
|
28
|
-
import { currentToken, hasClosingMarkerBeforeParagraphBreak } from "../../types";
|
|
29
|
-
import { createInlineContainer } from "../formatting/container";
|
|
30
|
-
import { parseUnderlineContent } from "./content";
|
|
1
|
+
import type { InlineRule } from "../../types";
|
|
2
|
+
import { parseDelimitedContainer } from "../formatting/container";
|
|
31
3
|
|
|
32
|
-
/**
|
|
33
|
-
* Inline rule for parsing `__underline__` formatting.
|
|
34
|
-
*
|
|
35
|
-
* Triggered by an `UNDERLINE_MARKER` token (`__`). Uses
|
|
36
|
-
* {@link hasClosingMarkerBeforeParagraphBreak} instead of the
|
|
37
|
-
* single-line variant because Wikidot allows underline to span
|
|
38
|
-
* multiple lines within a paragraph.
|
|
39
|
-
*
|
|
40
|
-
* When no closing marker is found before a paragraph break, the
|
|
41
|
-
* opening `__` is treated as literal text.
|
|
42
|
-
*/
|
|
4
|
+
/** Underline can span ordinary newlines, but cannot cross its enclosing block. */
|
|
43
5
|
export const underlineRule: InlineRule = {
|
|
44
6
|
name: "underline",
|
|
45
7
|
startTokens: ["UNDERLINE_MARKER"],
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
* Attempts to parse underline formatting at the current position.
|
|
49
|
-
*
|
|
50
|
-
* @param ctx - Parse context with token stream and current position
|
|
51
|
-
* @returns A successful result containing either a `"container"` element
|
|
52
|
-
* with `type: "underline"`, an empty array (for `____`), or a
|
|
53
|
-
* text fallback for unmatched markers
|
|
54
|
-
*/
|
|
55
|
-
parse(ctx: ParseContext): RuleResult<Element> {
|
|
56
|
-
const startToken = currentToken(ctx);
|
|
57
|
-
|
|
58
|
-
// Check if closing marker exists before paragraph break
|
|
59
|
-
if (!hasClosingMarkerBeforeParagraphBreak({ ...ctx, pos: ctx.pos + 1 }, "UNDERLINE_MARKER")) {
|
|
60
|
-
return {
|
|
61
|
-
success: true,
|
|
62
|
-
elements: [{ element: "text", data: startToken.value }],
|
|
63
|
-
consumed: 1,
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
const { children, consumed } = parseUnderlineContent(ctx, ctx.pos + 1);
|
|
68
|
-
|
|
69
|
-
// Empty underline (____) is discarded entirely in Wikidot
|
|
70
|
-
if (children.length === 0) {
|
|
71
|
-
return {
|
|
72
|
-
success: true,
|
|
73
|
-
elements: [],
|
|
74
|
-
consumed,
|
|
75
|
-
};
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
return {
|
|
79
|
-
success: true,
|
|
80
|
-
elements: [createInlineContainer("underline", children)],
|
|
81
|
-
consumed,
|
|
82
|
-
};
|
|
8
|
+
parse(ctx) {
|
|
9
|
+
return parseDelimitedContainer(ctx, "UNDERLINE_MARKER", "underline", { discardEmpty: true });
|
|
83
10
|
},
|
|
84
11
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Token, TokenType } from "../../lexer";
|
|
2
2
|
import type { ParseContext } from "./contracts";
|
|
3
|
+
import { getParagraphNewlineBoundary } from "./inline/parsing/paragraph-boundary";
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* Helper to get current token
|
|
@@ -51,7 +52,7 @@ export function hasClosingMarkerBeforeNewline(
|
|
|
51
52
|
markerValue?: string,
|
|
52
53
|
): boolean {
|
|
53
54
|
let pos = ctx.pos;
|
|
54
|
-
while (pos < ctx.tokens.length) {
|
|
55
|
+
while (pos < (ctx.scope.inlineEnd ?? ctx.tokens.length)) {
|
|
55
56
|
const token = ctx.tokens[pos];
|
|
56
57
|
if (!token || token.type === "NEWLINE" || token.type === "EOF") {
|
|
57
58
|
return false;
|
|
@@ -76,24 +77,14 @@ export function hasClosingMarkerBeforeParagraphBreak(
|
|
|
76
77
|
markerValue?: string,
|
|
77
78
|
): boolean {
|
|
78
79
|
let pos = ctx.pos;
|
|
79
|
-
while (pos < ctx.tokens.length) {
|
|
80
|
+
while (pos < (ctx.scope.inlineEnd ?? ctx.tokens.length)) {
|
|
80
81
|
const token = ctx.tokens[pos];
|
|
81
82
|
if (!token || token.type === "EOF") {
|
|
82
83
|
return false;
|
|
83
84
|
}
|
|
84
|
-
|
|
85
|
-
if (token.type === "NEWLINE") {
|
|
86
|
-
|
|
87
|
-
while (ctx.tokens[pos + lookAhead]?.type === "WHITESPACE") {
|
|
88
|
-
lookAhead++;
|
|
89
|
-
}
|
|
90
|
-
if (
|
|
91
|
-
ctx.tokens[pos + lookAhead]?.type === "NEWLINE" ||
|
|
92
|
-
ctx.tokens[pos + lookAhead]?.type === "EOF" ||
|
|
93
|
-
!ctx.tokens[pos + lookAhead]
|
|
94
|
-
) {
|
|
95
|
-
return false;
|
|
96
|
-
}
|
|
85
|
+
if (ctx.scope.blockCloseCondition?.({ ...ctx, pos })) return false;
|
|
86
|
+
if (token.type === "NEWLINE" && getParagraphNewlineBoundary(ctx, pos, true).shouldBreak) {
|
|
87
|
+
return false;
|
|
97
88
|
}
|
|
98
89
|
if (token.type === markerType) {
|
|
99
90
|
if (markerValue === undefined || token.value === markerValue) {
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import type { Element } from "@wdprlib/ast";
|
|
2
|
-
import type { ParseContext } from "../../types";
|
|
3
|
-
import { parseInlineUntil } from "../utils";
|
|
4
|
-
|
|
5
|
-
export interface UnderlineChildResult {
|
|
6
|
-
elements: Element[];
|
|
7
|
-
consumed: number;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export function parseUnderlineChild(ctx: ParseContext, pos: number): UnderlineChildResult {
|
|
11
|
-
const token = ctx.tokens[pos];
|
|
12
|
-
if (!token) {
|
|
13
|
-
return { elements: [], consumed: 0 };
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
if (token.type === "NEWLINE") {
|
|
17
|
-
return { elements: [{ element: "line-break" }], consumed: 1 };
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
const result = parseInlineUntil({ ...ctx, pos }, "UNDERLINE_MARKER");
|
|
21
|
-
if (result.elements.length > 0) {
|
|
22
|
-
return { elements: result.elements, consumed: result.consumed };
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
return { elements: [{ element: "text", data: token.value }], consumed: 1 };
|
|
26
|
-
}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import type { Element } from "@wdprlib/ast";
|
|
2
|
-
import type { ParseContext } from "../../types";
|
|
3
|
-
import { parseUnderlineChild } from "./child";
|
|
4
|
-
|
|
5
|
-
export function parseUnderlineContent(
|
|
6
|
-
ctx: ParseContext,
|
|
7
|
-
startPos: number,
|
|
8
|
-
): { children: Element[]; consumed: number } {
|
|
9
|
-
const children: Element[] = [];
|
|
10
|
-
let pos = startPos;
|
|
11
|
-
let consumed = 1;
|
|
12
|
-
|
|
13
|
-
while (pos < ctx.tokens.length) {
|
|
14
|
-
const token = ctx.tokens[pos];
|
|
15
|
-
if (!token || token.type === "EOF") break;
|
|
16
|
-
|
|
17
|
-
if (token.type === "UNDERLINE_MARKER") {
|
|
18
|
-
consumed++;
|
|
19
|
-
break;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const child = parseUnderlineChild(ctx, pos);
|
|
23
|
-
children.push(...child.elements);
|
|
24
|
-
pos += child.consumed;
|
|
25
|
-
consumed += child.consumed;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
return { children, consumed };
|
|
29
|
-
}
|