@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
package/dist/index.cjs
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
var import_node_module = require("node:module");
|
|
2
1
|
var __defProp = Object.defineProperty;
|
|
3
2
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
@@ -72,6 +71,7 @@ __export(exports_src, {
|
|
|
72
71
|
container: () => import_ast9.container,
|
|
73
72
|
compileTemplate: () => compileTemplate,
|
|
74
73
|
compileListUsersTemplate: () => compileListUsersTemplate,
|
|
74
|
+
buildInfo: () => buildInfo,
|
|
75
75
|
bold: () => import_ast9.bold,
|
|
76
76
|
STYLE_SLOT_PREFIX: () => import_ast4.STYLE_SLOT_PREFIX,
|
|
77
77
|
Parser: () => Parser,
|
|
@@ -79,6 +79,15 @@ __export(exports_src, {
|
|
|
79
79
|
DEFAULT_SETTINGS: () => import_ast10.DEFAULT_SETTINGS
|
|
80
80
|
});
|
|
81
81
|
module.exports = __toCommonJS(exports_src);
|
|
82
|
+
|
|
83
|
+
// packages/parser/src/build-info.generated.ts
|
|
84
|
+
var buildInfo = Object.freeze({
|
|
85
|
+
version: "5.2.0",
|
|
86
|
+
sha: "cc290b0d882de3ed9ea33ec060ddfc8a7b9da59a",
|
|
87
|
+
dirty: false
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
// packages/parser/src/index.ts
|
|
82
91
|
var import_ast9 = require("@wdprlib/ast");
|
|
83
92
|
var import_ast10 = require("@wdprlib/ast");
|
|
84
93
|
|
|
@@ -86,49 +95,6 @@ var import_ast10 = require("@wdprlib/ast");
|
|
|
86
95
|
function createToken(type, value, position, lineStart = false) {
|
|
87
96
|
return { type, value, position, lineStart };
|
|
88
97
|
}
|
|
89
|
-
// packages/parser/src/lexer/token-factory.ts
|
|
90
|
-
var ZERO_POSITION = {
|
|
91
|
-
start: { line: 0, column: 0, offset: 0 },
|
|
92
|
-
end: { line: 0, column: 0, offset: 0 }
|
|
93
|
-
};
|
|
94
|
-
function createLexerToken(state, type, value, trackPositions) {
|
|
95
|
-
return {
|
|
96
|
-
type,
|
|
97
|
-
value,
|
|
98
|
-
position: trackPositions ? currentTokenPosition(state, value) : ZERO_POSITION,
|
|
99
|
-
lineStart: isTokenAtLineStart(state)
|
|
100
|
-
};
|
|
101
|
-
}
|
|
102
|
-
function updateLastNonWhitespaceType(current, type) {
|
|
103
|
-
return type === "WHITESPACE" ? current : type;
|
|
104
|
-
}
|
|
105
|
-
function nextBlockOpenerDepth(current, type) {
|
|
106
|
-
if (type === "BLOCK_OPEN" || type === "BLOCK_END_OPEN") {
|
|
107
|
-
return current + 1;
|
|
108
|
-
}
|
|
109
|
-
if (type === "BLOCK_CLOSE" && current > 0) {
|
|
110
|
-
return current - 1;
|
|
111
|
-
}
|
|
112
|
-
return current;
|
|
113
|
-
}
|
|
114
|
-
function currentTokenPosition(state, value) {
|
|
115
|
-
return {
|
|
116
|
-
start: {
|
|
117
|
-
line: state.line,
|
|
118
|
-
column: state.column - value.length,
|
|
119
|
-
offset: state.pos - value.length
|
|
120
|
-
},
|
|
121
|
-
end: {
|
|
122
|
-
line: state.line,
|
|
123
|
-
column: state.column,
|
|
124
|
-
offset: state.pos
|
|
125
|
-
}
|
|
126
|
-
};
|
|
127
|
-
}
|
|
128
|
-
function isTokenAtLineStart(state) {
|
|
129
|
-
return state.tokens.length === 0 || state.tokens[state.tokens.length - 1]?.type === "NEWLINE";
|
|
130
|
-
}
|
|
131
|
-
|
|
132
98
|
// packages/parser/src/lexer/state.ts
|
|
133
99
|
function createInitialLexerState(source) {
|
|
134
100
|
return {
|
|
@@ -137,9 +103,16 @@ function createInitialLexerState(source) {
|
|
|
137
103
|
line: 1,
|
|
138
104
|
column: 1,
|
|
139
105
|
lineStart: true,
|
|
106
|
+
quoteContentStart: false,
|
|
140
107
|
tokens: []
|
|
141
108
|
};
|
|
142
109
|
}
|
|
110
|
+
function isSyntaxLineStart(state) {
|
|
111
|
+
return state.lineStart || state.quoteContentStart;
|
|
112
|
+
}
|
|
113
|
+
function isLineStartQuoteMarker(token) {
|
|
114
|
+
return token?.type === "BLOCKQUOTE_MARKER" && token.lineStart;
|
|
115
|
+
}
|
|
143
116
|
function isAtEnd(state) {
|
|
144
117
|
return state.pos >= state.source.length;
|
|
145
118
|
}
|
|
@@ -153,18 +126,25 @@ function advance(state, n = 1) {
|
|
|
153
126
|
updatePosition(state, start, end);
|
|
154
127
|
return value;
|
|
155
128
|
}
|
|
156
|
-
function advanceByToken(state, type, length) {
|
|
129
|
+
function advanceByToken(state, type, length, value = "") {
|
|
130
|
+
const afterQuoteMarker = isLineStartQuoteMarker(state.tokens[state.tokens.length - 1]);
|
|
157
131
|
state.pos += length;
|
|
158
132
|
if (type === "NEWLINE") {
|
|
159
133
|
state.line++;
|
|
160
134
|
state.column = 1;
|
|
161
135
|
state.lineStart = true;
|
|
136
|
+
state.quoteContentStart = false;
|
|
162
137
|
return;
|
|
163
138
|
}
|
|
164
139
|
state.column += length;
|
|
165
|
-
if (type
|
|
166
|
-
|
|
140
|
+
if (type === "WHITESPACE") {
|
|
141
|
+
if (afterQuoteMarker && value === " ") {
|
|
142
|
+
state.quoteContentStart = true;
|
|
143
|
+
}
|
|
144
|
+
return;
|
|
167
145
|
}
|
|
146
|
+
state.lineStart = false;
|
|
147
|
+
state.quoteContentStart = false;
|
|
168
148
|
}
|
|
169
149
|
function updatePosition(state, start, end) {
|
|
170
150
|
state.pos = end;
|
|
@@ -175,8 +155,9 @@ function updatePositionFromValue(state, value) {
|
|
|
175
155
|
`);
|
|
176
156
|
if (firstNewline === -1) {
|
|
177
157
|
state.column += value.length;
|
|
178
|
-
if (
|
|
158
|
+
if (hasNonLineStartSpacing(value, 0)) {
|
|
179
159
|
state.lineStart = false;
|
|
160
|
+
state.quoteContentStart = false;
|
|
180
161
|
}
|
|
181
162
|
return;
|
|
182
163
|
}
|
|
@@ -195,6 +176,7 @@ function updatePositionFromValue(state, value) {
|
|
|
195
176
|
state.line += newlineCount;
|
|
196
177
|
state.column = value.length - lastNewline;
|
|
197
178
|
state.lineStart = !hasNonLineStartSpacing(value, lastNewline + 1);
|
|
179
|
+
state.quoteContentStart = false;
|
|
198
180
|
}
|
|
199
181
|
function hasNonLineStartSpacing(value, start) {
|
|
200
182
|
for (let i = start;i < value.length; i++) {
|
|
@@ -206,6 +188,56 @@ function hasNonLineStartSpacing(value, start) {
|
|
|
206
188
|
return false;
|
|
207
189
|
}
|
|
208
190
|
|
|
191
|
+
// packages/parser/src/lexer/token-factory.ts
|
|
192
|
+
var ZERO_POSITION = {
|
|
193
|
+
start: { line: 0, column: 0, offset: 0 },
|
|
194
|
+
end: { line: 0, column: 0, offset: 0 }
|
|
195
|
+
};
|
|
196
|
+
function createLexerToken(state, type, value, trackPositions) {
|
|
197
|
+
return {
|
|
198
|
+
type,
|
|
199
|
+
value,
|
|
200
|
+
position: trackPositions ? currentTokenPosition(state, value) : ZERO_POSITION,
|
|
201
|
+
lineStart: isTokenAtLineStart(state)
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
function updateLastNonWhitespaceType(current2, type) {
|
|
205
|
+
return type === "WHITESPACE" ? current2 : type;
|
|
206
|
+
}
|
|
207
|
+
function nextBlockOpenerDepth(current2, type) {
|
|
208
|
+
if (type === "BLOCK_OPEN" || type === "BLOCK_END_OPEN") {
|
|
209
|
+
return current2 + 1;
|
|
210
|
+
}
|
|
211
|
+
if (type === "BLOCK_CLOSE" && current2 > 0) {
|
|
212
|
+
return current2 - 1;
|
|
213
|
+
}
|
|
214
|
+
return current2;
|
|
215
|
+
}
|
|
216
|
+
function currentTokenPosition(state, value) {
|
|
217
|
+
return {
|
|
218
|
+
start: {
|
|
219
|
+
line: state.line,
|
|
220
|
+
column: state.column - value.length,
|
|
221
|
+
offset: state.pos - value.length
|
|
222
|
+
},
|
|
223
|
+
end: {
|
|
224
|
+
line: state.line,
|
|
225
|
+
column: state.column,
|
|
226
|
+
offset: state.pos
|
|
227
|
+
}
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
function isTokenAtLineStart(state) {
|
|
231
|
+
if (state.tokens.length === 0) {
|
|
232
|
+
return true;
|
|
233
|
+
}
|
|
234
|
+
const last = state.tokens[state.tokens.length - 1];
|
|
235
|
+
if (last?.type === "NEWLINE") {
|
|
236
|
+
return true;
|
|
237
|
+
}
|
|
238
|
+
return last?.type === "WHITESPACE" && last.value === " " && isLineStartQuoteMarker(state.tokens[state.tokens.length - 2]);
|
|
239
|
+
}
|
|
240
|
+
|
|
209
241
|
// packages/parser/src/lexer/anchor.ts
|
|
210
242
|
function findInvalidAnchorNameEnd(src, pos) {
|
|
211
243
|
if (src[pos] !== "[" || src[pos + 1] !== "[" || src[pos + 2] !== "#") {
|
|
@@ -522,7 +554,7 @@ function scanPunctuationToken(input) {
|
|
|
522
554
|
case "@":
|
|
523
555
|
return { handled: true, actions: scanAtToken(source, pos) };
|
|
524
556
|
case ">":
|
|
525
|
-
return { handled: true, actions: scanGreaterToken(source, pos,
|
|
557
|
+
return { handled: true, actions: scanGreaterToken(source, pos, input.physicalLineStart) };
|
|
526
558
|
case "-":
|
|
527
559
|
return { handled: true, actions: scanDashToken(source, pos, lineStart) };
|
|
528
560
|
case "~": {
|
|
@@ -564,6 +596,15 @@ function runToken3(src, pos, end, type) {
|
|
|
564
596
|
}
|
|
565
597
|
|
|
566
598
|
// packages/parser/src/lexer/spacing-actions.ts
|
|
599
|
+
function limitBlockquotePrefixSpace(action, previous) {
|
|
600
|
+
if (!isLineStartQuoteMarker(previous) || action.type !== "WHITESPACE") {
|
|
601
|
+
return action;
|
|
602
|
+
}
|
|
603
|
+
if (action.length <= 1 || !action.value.startsWith(" ")) {
|
|
604
|
+
return action;
|
|
605
|
+
}
|
|
606
|
+
return { type: "WHITESPACE", value: " ", length: 1 };
|
|
607
|
+
}
|
|
567
608
|
function scanSpacingToken(src, pos) {
|
|
568
609
|
const char = src[pos];
|
|
569
610
|
if (char === `
|
|
@@ -625,7 +666,7 @@ class Lexer {
|
|
|
625
666
|
this.blockOpenerDepth = nextBlockOpenerDepth(this.blockOpenerDepth, type);
|
|
626
667
|
}
|
|
627
668
|
emitTokenAction(action) {
|
|
628
|
-
advanceByToken(this.state, action.type, action.length);
|
|
669
|
+
advanceByToken(this.state, action.type, action.length, action.value);
|
|
629
670
|
this.addToken(action.type, action.value);
|
|
630
671
|
}
|
|
631
672
|
emitTokenActions(actions) {
|
|
@@ -639,11 +680,11 @@ class Lexer {
|
|
|
639
680
|
}
|
|
640
681
|
scanToken() {
|
|
641
682
|
const char = this.current();
|
|
642
|
-
const isLineStart = this.state
|
|
683
|
+
const isLineStart = isSyntaxLineStart(this.state);
|
|
643
684
|
const src = this.state.source;
|
|
644
685
|
const spacingAction = scanSpacingToken(src, this.state.pos);
|
|
645
686
|
if (spacingAction) {
|
|
646
|
-
this.emitTokenAction(spacingAction);
|
|
687
|
+
this.emitTokenAction(limitBlockquotePrefixSpace(spacingAction, this.state.tokens.at(-1)));
|
|
647
688
|
return;
|
|
648
689
|
}
|
|
649
690
|
const punctuation = scanPunctuationToken({
|
|
@@ -651,6 +692,7 @@ class Lexer {
|
|
|
651
692
|
source: src,
|
|
652
693
|
pos: this.state.pos,
|
|
653
694
|
lineStart: isLineStart,
|
|
695
|
+
physicalLineStart: this.state.lineStart,
|
|
654
696
|
splitBlockClose: this.splitBlockClosePositions.has(this.state.pos),
|
|
655
697
|
findInvalidAnchorNameEnd: () => this.findInvalidAnchorNameEnd()
|
|
656
698
|
});
|
|
@@ -867,7 +909,7 @@ function parseBlocksUntil(ctx, closeCondition, options) {
|
|
|
867
909
|
const elements = [];
|
|
868
910
|
let consumed = 0;
|
|
869
911
|
let pos = ctx.pos;
|
|
870
|
-
const excluded = options?.excludedBlockNames;
|
|
912
|
+
const excluded = mergeExcludedBlockNames(ctx.scope.excludedBlockNames, options?.excludedBlockNames);
|
|
871
913
|
const blockRules = excluded ? getExcludedBlockRules(ctx.blockRules, excluded) : ctx.blockRules;
|
|
872
914
|
const blockScope = {
|
|
873
915
|
...ctx.scope,
|
|
@@ -909,6 +951,13 @@ function parseBlocksUntil(ctx, closeCondition, options) {
|
|
|
909
951
|
}
|
|
910
952
|
return { elements, consumed };
|
|
911
953
|
}
|
|
954
|
+
function mergeExcludedBlockNames(inherited, added) {
|
|
955
|
+
if (!inherited?.size)
|
|
956
|
+
return added;
|
|
957
|
+
if (!added?.size)
|
|
958
|
+
return inherited;
|
|
959
|
+
return new Set([...inherited, ...added]);
|
|
960
|
+
}
|
|
912
961
|
function getExcludedBlockRules(blockRules, excluded) {
|
|
913
962
|
let byExcluded = excludedBlockRulesCache.get(blockRules);
|
|
914
963
|
if (!byExcluded) {
|
|
@@ -945,6 +994,31 @@ function getCandidateInlineRules(inlineRules, tokenType) {
|
|
|
945
994
|
byType.set(tokenType, candidates);
|
|
946
995
|
return candidates;
|
|
947
996
|
}
|
|
997
|
+
// packages/parser/src/parser/rules/inline/raw/end.ts
|
|
998
|
+
function rawRegionEnd(tokens, start, end) {
|
|
999
|
+
const type = tokens[start]?.type;
|
|
1000
|
+
const close = type === "RAW_OPEN" ? "RAW_OPEN" : type === "RAW_BLOCK_OPEN" ? "RAW_BLOCK_CLOSE" : null;
|
|
1001
|
+
if (!close)
|
|
1002
|
+
return start;
|
|
1003
|
+
for (let pos = start + 1;pos < end; pos++) {
|
|
1004
|
+
if (tokens[pos]?.type === "NEWLINE" || tokens[pos]?.type === "EOF")
|
|
1005
|
+
break;
|
|
1006
|
+
if (tokens[pos]?.type === close)
|
|
1007
|
+
return pos + 1;
|
|
1008
|
+
}
|
|
1009
|
+
return start;
|
|
1010
|
+
}
|
|
1011
|
+
function protectedInlineRegionEnd(tokens, start, end) {
|
|
1012
|
+
const rawEnd = rawRegionEnd(tokens, start, end);
|
|
1013
|
+
if (rawEnd > start || tokens[start]?.type !== "COMMENT_OPEN")
|
|
1014
|
+
return rawEnd;
|
|
1015
|
+
for (let pos = start + 1;pos < end; pos++) {
|
|
1016
|
+
if (tokens[pos]?.type === "COMMENT_CLOSE")
|
|
1017
|
+
return pos + 1;
|
|
1018
|
+
}
|
|
1019
|
+
return start;
|
|
1020
|
+
}
|
|
1021
|
+
|
|
948
1022
|
// packages/parser/src/parser/rules/inline/parsing/plain-text.ts
|
|
949
1023
|
var MIN_INLINE_TEXT_RUN_LENGTH = 32;
|
|
950
1024
|
var MIN_INLINE_TEXT_RUN_DOCUMENT_TOKENS = 1e5;
|
|
@@ -987,6 +1061,135 @@ function isPlainTextRunToken(ctx, pos) {
|
|
|
987
1061
|
return token5.value !== "(";
|
|
988
1062
|
}
|
|
989
1063
|
|
|
1064
|
+
// packages/parser/src/parser/rules/inline/image/attributes.ts
|
|
1065
|
+
function parseImageAttributes(ctx, startPos) {
|
|
1066
|
+
const result = parseAttributesRaw(ctx, startPos, false);
|
|
1067
|
+
const link = result.attrs.link ?? null;
|
|
1068
|
+
const { link: _link, ...htmlAttributes } = result.attrs;
|
|
1069
|
+
return {
|
|
1070
|
+
attributes: filterUnsafeAttributes(htmlAttributes),
|
|
1071
|
+
link,
|
|
1072
|
+
consumed: result.consumed
|
|
1073
|
+
};
|
|
1074
|
+
}
|
|
1075
|
+
|
|
1076
|
+
// packages/parser/src/parser/rules/inline/image/body.ts
|
|
1077
|
+
function parseImageSourceText(ctx, startPos) {
|
|
1078
|
+
let pos = startPos;
|
|
1079
|
+
let consumed = 0;
|
|
1080
|
+
while (ctx.tokens[pos]?.type === "WHITESPACE") {
|
|
1081
|
+
pos++;
|
|
1082
|
+
consumed++;
|
|
1083
|
+
}
|
|
1084
|
+
let sourceText = "";
|
|
1085
|
+
while (pos < ctx.tokens.length) {
|
|
1086
|
+
const token5 = ctx.tokens[pos];
|
|
1087
|
+
if (!token5 || token5.type === "WHITESPACE" || token5.type === "BLOCK_CLOSE" || token5.type === "NEWLINE" || token5.type === "EOF") {
|
|
1088
|
+
break;
|
|
1089
|
+
}
|
|
1090
|
+
sourceText += token5.value;
|
|
1091
|
+
pos++;
|
|
1092
|
+
consumed++;
|
|
1093
|
+
}
|
|
1094
|
+
return { sourceText, consumed };
|
|
1095
|
+
}
|
|
1096
|
+
|
|
1097
|
+
// packages/parser/src/parser/rules/inline/image/syntax.ts
|
|
1098
|
+
var IMAGE_BLOCK_NAMES = new Set([
|
|
1099
|
+
"image",
|
|
1100
|
+
"=image",
|
|
1101
|
+
"<image",
|
|
1102
|
+
">image",
|
|
1103
|
+
"f<image",
|
|
1104
|
+
"f>image",
|
|
1105
|
+
"f=image"
|
|
1106
|
+
]);
|
|
1107
|
+
function parseImageBlockName(ctx, startPos) {
|
|
1108
|
+
let pos = startPos;
|
|
1109
|
+
let consumed = 0;
|
|
1110
|
+
while (ctx.tokens[pos]?.type === "WHITESPACE") {
|
|
1111
|
+
pos++;
|
|
1112
|
+
consumed++;
|
|
1113
|
+
}
|
|
1114
|
+
const prefixResult = parseImagePrefix(ctx, pos);
|
|
1115
|
+
const prefix = prefixResult.prefix;
|
|
1116
|
+
pos += prefixResult.consumed;
|
|
1117
|
+
consumed += prefixResult.consumed;
|
|
1118
|
+
const nameToken = ctx.tokens[pos];
|
|
1119
|
+
if (!nameToken || nameToken.type !== "TEXT" && nameToken.type !== "IDENTIFIER") {
|
|
1120
|
+
return null;
|
|
1121
|
+
}
|
|
1122
|
+
return { name: prefix + nameToken.value.toLowerCase(), consumed: consumed + 1 };
|
|
1123
|
+
}
|
|
1124
|
+
function isImageBlockName(blockName) {
|
|
1125
|
+
return IMAGE_BLOCK_NAMES.has(blockName);
|
|
1126
|
+
}
|
|
1127
|
+
function parseImagePrefix(ctx, pos) {
|
|
1128
|
+
const token5 = ctx.tokens[pos];
|
|
1129
|
+
if (token5?.type === "EQUALS") {
|
|
1130
|
+
return { prefix: "=", consumed: 1 };
|
|
1131
|
+
}
|
|
1132
|
+
if (token5?.type === "TEXT" && token5.value === "<") {
|
|
1133
|
+
return { prefix: "<", consumed: 1 };
|
|
1134
|
+
}
|
|
1135
|
+
if ((token5?.type === "TEXT" || token5?.type === "BLOCKQUOTE_MARKER") && token5.value === ">") {
|
|
1136
|
+
return { prefix: ">", consumed: 1 };
|
|
1137
|
+
}
|
|
1138
|
+
if (token5?.type === "IDENTIFIER" && token5.value.toLowerCase() === "f") {
|
|
1139
|
+
return parseFloatPrefix(ctx, pos + 1);
|
|
1140
|
+
}
|
|
1141
|
+
return { prefix: "", consumed: 0 };
|
|
1142
|
+
}
|
|
1143
|
+
function parseFloatPrefix(ctx, pos) {
|
|
1144
|
+
const token5 = ctx.tokens[pos];
|
|
1145
|
+
if (token5?.type === "TEXT" && token5.value === "<") {
|
|
1146
|
+
return { prefix: "f<", consumed: 2 };
|
|
1147
|
+
}
|
|
1148
|
+
if ((token5?.type === "TEXT" || token5?.type === "BLOCKQUOTE_MARKER") && token5.value === ">") {
|
|
1149
|
+
return { prefix: "f>", consumed: 2 };
|
|
1150
|
+
}
|
|
1151
|
+
if (token5?.type === "EQUALS") {
|
|
1152
|
+
return { prefix: "f=", consumed: 2 };
|
|
1153
|
+
}
|
|
1154
|
+
return { prefix: "", consumed: 0 };
|
|
1155
|
+
}
|
|
1156
|
+
|
|
1157
|
+
// packages/parser/src/parser/rules/inline/image/open.ts
|
|
1158
|
+
function parseImageOpen(ctx) {
|
|
1159
|
+
if (ctx.tokens[ctx.pos]?.type !== "BLOCK_OPEN") {
|
|
1160
|
+
return null;
|
|
1161
|
+
}
|
|
1162
|
+
let pos = ctx.pos + 1;
|
|
1163
|
+
let consumed = 1;
|
|
1164
|
+
const nameResult = parseImageBlockName(ctx, pos);
|
|
1165
|
+
if (!nameResult || !isImageBlockName(nameResult.name)) {
|
|
1166
|
+
return null;
|
|
1167
|
+
}
|
|
1168
|
+
pos += nameResult.consumed;
|
|
1169
|
+
consumed += nameResult.consumed;
|
|
1170
|
+
const sourceText = parseImageSourceText(ctx, pos);
|
|
1171
|
+
pos += sourceText.consumed;
|
|
1172
|
+
consumed += sourceText.consumed;
|
|
1173
|
+
const attrs = parseImageAttributes(ctx, pos);
|
|
1174
|
+
pos += attrs.consumed;
|
|
1175
|
+
consumed += attrs.consumed;
|
|
1176
|
+
if (ctx.tokens[pos]?.type !== "BLOCK_CLOSE") {
|
|
1177
|
+
return null;
|
|
1178
|
+
}
|
|
1179
|
+
pos++;
|
|
1180
|
+
consumed++;
|
|
1181
|
+
if (!sourceText.sourceText) {
|
|
1182
|
+
return null;
|
|
1183
|
+
}
|
|
1184
|
+
return {
|
|
1185
|
+
blockName: nameResult.name,
|
|
1186
|
+
sourceText: sourceText.sourceText,
|
|
1187
|
+
link: attrs.link,
|
|
1188
|
+
attributes: attrs.attributes,
|
|
1189
|
+
consumed
|
|
1190
|
+
};
|
|
1191
|
+
}
|
|
1192
|
+
|
|
990
1193
|
// packages/parser/src/parser/constants.ts
|
|
991
1194
|
var BLOCK_START_TOKENS = [
|
|
992
1195
|
"BLOCKQUOTE_MARKER",
|
|
@@ -1117,7 +1320,7 @@ function isParagraphBreakingBlockStart(ctx, newlinePos, lookAhead) {
|
|
|
1117
1320
|
if (!nextMeaningfulToken.lineStart && !isIndentedBlockOpener) {
|
|
1118
1321
|
return false;
|
|
1119
1322
|
}
|
|
1120
|
-
return !isOrphanCloseSpan(ctx, nextPos) && !isAnchorName(ctx, nextPos) && !isInvalidBlockOpen(ctx, nextPos) && !isInvalidHeading(ctx, nextPos) && !isExcludedBlockStart(ctx, nextPos) && !isUnknownBlockStart(ctx, nextPos);
|
|
1323
|
+
return !parseImageOpen({ ...ctx, pos: nextPos }) && !isOrphanCloseSpan(ctx, nextPos) && !isAnchorName(ctx, nextPos) && !isInvalidBlockOpen(ctx, nextPos) && !isInvalidHeading(ctx, nextPos) && !isExcludedBlockStart(ctx, nextPos) && !isUnknownBlockStart(ctx, nextPos);
|
|
1121
1324
|
}
|
|
1122
1325
|
function isOrphanCloseSpan(ctx, blockEndOpenPos) {
|
|
1123
1326
|
const token5 = ctx.tokens[blockEndOpenPos];
|
|
@@ -1227,27 +1430,45 @@ function parseInlineUntil(ctx, endType) {
|
|
|
1227
1430
|
let consumed = 0;
|
|
1228
1431
|
let pos = ctx.pos;
|
|
1229
1432
|
const paragraphMode = endType === "PARAGRAPH_BREAK";
|
|
1433
|
+
const multiline = paragraphMode || FORMATTING_CLOSE_TOKENS.has(endType);
|
|
1434
|
+
let inlineEnd = ctx.scope.inlineEnd ?? ctx.tokens.length;
|
|
1435
|
+
if (!multiline) {
|
|
1436
|
+
for (let end = ctx.pos;end < inlineEnd; end++) {
|
|
1437
|
+
const protectedEnd = protectedInlineRegionEnd(ctx.tokens, end, inlineEnd);
|
|
1438
|
+
if (protectedEnd > end) {
|
|
1439
|
+
end = protectedEnd - 1;
|
|
1440
|
+
continue;
|
|
1441
|
+
}
|
|
1442
|
+
if (ctx.tokens[end]?.type === "NEWLINE" && ctx.tokens[end - 1]?.type === "UNDERSCORE" && ctx.tokens[end - 2]?.type === "WHITESPACE")
|
|
1443
|
+
continue;
|
|
1444
|
+
if (ctx.tokens[end]?.type === "NEWLINE" || ctx.tokens[end]?.type === endType) {
|
|
1445
|
+
inlineEnd = end;
|
|
1446
|
+
break;
|
|
1447
|
+
}
|
|
1448
|
+
}
|
|
1449
|
+
}
|
|
1230
1450
|
const { inlineRules } = ctx;
|
|
1231
1451
|
const inlineCtx = {
|
|
1232
1452
|
...ctx,
|
|
1233
|
-
pos
|
|
1453
|
+
pos,
|
|
1454
|
+
scope: { ...ctx.scope, inlineEnd }
|
|
1234
1455
|
};
|
|
1235
1456
|
const canCollectLongPlainTextRuns = ctx.tokens.length >= MIN_INLINE_TEXT_RUN_DOCUMENT_TOKENS;
|
|
1236
|
-
while (pos <
|
|
1457
|
+
while (pos < inlineEnd) {
|
|
1237
1458
|
const token5 = ctx.tokens[pos];
|
|
1238
1459
|
if (!token5 || token5.type === "EOF") {
|
|
1239
1460
|
break;
|
|
1240
1461
|
}
|
|
1241
|
-
if (
|
|
1462
|
+
if (ctx.scope.blockCloseCondition) {
|
|
1242
1463
|
const checkCtx = { ...ctx, pos };
|
|
1243
1464
|
if (ctx.scope.blockCloseCondition(checkCtx)) {
|
|
1244
1465
|
break;
|
|
1245
1466
|
}
|
|
1246
1467
|
}
|
|
1247
|
-
if (!
|
|
1468
|
+
if (!multiline && token5.type === "NEWLINE") {
|
|
1248
1469
|
break;
|
|
1249
1470
|
}
|
|
1250
|
-
if (
|
|
1471
|
+
if (multiline && token5.type === "NEWLINE" && !ctx.scope.tableFormatting) {
|
|
1251
1472
|
const boundary = getParagraphNewlineBoundary(ctx, pos, nodes.length > 0);
|
|
1252
1473
|
if (boundary.shouldBreak) {
|
|
1253
1474
|
if (boundary.preservePrecedingLineBreak) {
|
|
@@ -1257,6 +1478,11 @@ function parseInlineUntil(ctx, endType) {
|
|
|
1257
1478
|
break;
|
|
1258
1479
|
}
|
|
1259
1480
|
}
|
|
1481
|
+
if (ctx.scope.tableFormatting?.suppressedClosers.has(pos)) {
|
|
1482
|
+
pos++;
|
|
1483
|
+
consumed++;
|
|
1484
|
+
continue;
|
|
1485
|
+
}
|
|
1260
1486
|
if (token5.type === endType) {
|
|
1261
1487
|
break;
|
|
1262
1488
|
}
|
|
@@ -1281,6 +1507,24 @@ function parseInlineUntil(ctx, endType) {
|
|
|
1281
1507
|
for (const rule of getCandidateInlineRules(inlineRules, token5.type)) {
|
|
1282
1508
|
const result = rule.parse(inlineCtx);
|
|
1283
1509
|
if (result.success) {
|
|
1510
|
+
if (rule.name === "comment") {
|
|
1511
|
+
let after = pos + result.consumed;
|
|
1512
|
+
while (ctx.tokens[after]?.type === "WHITESPACE")
|
|
1513
|
+
after++;
|
|
1514
|
+
if (ctx.tokens[after]?.type === "NEWLINE" || ctx.tokens[after]?.type === "EOF") {
|
|
1515
|
+
while (nodes.at(-1)?.element === "text") {
|
|
1516
|
+
const last = nodes.at(-1);
|
|
1517
|
+
if (last.element !== "text")
|
|
1518
|
+
break;
|
|
1519
|
+
last.data = last.data.trimEnd();
|
|
1520
|
+
if (last.data)
|
|
1521
|
+
break;
|
|
1522
|
+
nodes.pop();
|
|
1523
|
+
}
|
|
1524
|
+
if (nodes.at(-1)?.element === "line-break")
|
|
1525
|
+
nodes.pop();
|
|
1526
|
+
}
|
|
1527
|
+
}
|
|
1284
1528
|
nodes.push(...result.elements);
|
|
1285
1529
|
consumed += result.consumed;
|
|
1286
1530
|
pos += result.consumed;
|
|
@@ -1296,6 +1540,16 @@ function parseInlineUntil(ctx, endType) {
|
|
|
1296
1540
|
}
|
|
1297
1541
|
return { elements: nodes, consumed };
|
|
1298
1542
|
}
|
|
1543
|
+
var FORMATTING_CLOSE_TOKENS = new Set([
|
|
1544
|
+
"BOLD_MARKER",
|
|
1545
|
+
"ITALIC_MARKER",
|
|
1546
|
+
"UNDERLINE_MARKER",
|
|
1547
|
+
"STRIKE_MARKER",
|
|
1548
|
+
"SUPER_MARKER",
|
|
1549
|
+
"SUB_MARKER",
|
|
1550
|
+
"MONO_CLOSE",
|
|
1551
|
+
"COLOR_MARKER"
|
|
1552
|
+
]);
|
|
1299
1553
|
// packages/parser/src/parser/rules/block/parsing/attributes/names.ts
|
|
1300
1554
|
function consumeAttributeName(ctx, startPos, startConsumed, startName, options) {
|
|
1301
1555
|
if (startName === "_" && isAttributeWordToken(ctx.tokens[startPos])) {
|
|
@@ -1471,7 +1725,7 @@ function eofToken() {
|
|
|
1471
1725
|
}
|
|
1472
1726
|
function hasClosingMarkerBeforeNewline(ctx, markerType, markerValue) {
|
|
1473
1727
|
let pos = ctx.pos;
|
|
1474
|
-
while (pos < ctx.tokens.length) {
|
|
1728
|
+
while (pos < (ctx.scope.inlineEnd ?? ctx.tokens.length)) {
|
|
1475
1729
|
const token5 = ctx.tokens[pos];
|
|
1476
1730
|
if (!token5 || token5.type === "NEWLINE" || token5.type === "EOF") {
|
|
1477
1731
|
return false;
|
|
@@ -1485,31 +1739,6 @@ function hasClosingMarkerBeforeNewline(ctx, markerType, markerValue) {
|
|
|
1485
1739
|
}
|
|
1486
1740
|
return false;
|
|
1487
1741
|
}
|
|
1488
|
-
function hasClosingMarkerBeforeParagraphBreak(ctx, markerType, markerValue) {
|
|
1489
|
-
let pos = ctx.pos;
|
|
1490
|
-
while (pos < ctx.tokens.length) {
|
|
1491
|
-
const token5 = ctx.tokens[pos];
|
|
1492
|
-
if (!token5 || token5.type === "EOF") {
|
|
1493
|
-
return false;
|
|
1494
|
-
}
|
|
1495
|
-
if (token5.type === "NEWLINE") {
|
|
1496
|
-
let lookAhead = 1;
|
|
1497
|
-
while (ctx.tokens[pos + lookAhead]?.type === "WHITESPACE") {
|
|
1498
|
-
lookAhead++;
|
|
1499
|
-
}
|
|
1500
|
-
if (ctx.tokens[pos + lookAhead]?.type === "NEWLINE" || ctx.tokens[pos + lookAhead]?.type === "EOF" || !ctx.tokens[pos + lookAhead]) {
|
|
1501
|
-
return false;
|
|
1502
|
-
}
|
|
1503
|
-
}
|
|
1504
|
-
if (token5.type === markerType) {
|
|
1505
|
-
if (markerValue === undefined || token5.value === markerValue) {
|
|
1506
|
-
return true;
|
|
1507
|
-
}
|
|
1508
|
-
}
|
|
1509
|
-
pos++;
|
|
1510
|
-
}
|
|
1511
|
-
return false;
|
|
1512
|
-
}
|
|
1513
1742
|
// packages/parser/src/parser/rules/block/heading/open.ts
|
|
1514
1743
|
function parseHeadingOpen(ctx) {
|
|
1515
1744
|
const marker = ctx.tokens[ctx.pos];
|
|
@@ -1576,6 +1805,15 @@ var headingRule = {
|
|
|
1576
1805
|
const inlineCtx = { ...ctx, pos };
|
|
1577
1806
|
const inlineResult = parseInlineUntil(inlineCtx, "NEWLINE");
|
|
1578
1807
|
const children = inlineResult.elements;
|
|
1808
|
+
while (children.at(-1)?.element === "text") {
|
|
1809
|
+
const last = children.at(-1);
|
|
1810
|
+
if (last.element !== "text")
|
|
1811
|
+
break;
|
|
1812
|
+
last.data = last.data.trimEnd();
|
|
1813
|
+
if (last.data)
|
|
1814
|
+
break;
|
|
1815
|
+
children.pop();
|
|
1816
|
+
}
|
|
1579
1817
|
consumed += inlineResult.consumed;
|
|
1580
1818
|
pos += inlineResult.consumed;
|
|
1581
1819
|
if (ctx.tokens[pos]?.type === "NEWLINE") {
|
|
@@ -2375,17 +2613,15 @@ function parseBlockquoteLine(ctx, startPos) {
|
|
|
2375
2613
|
if (ctx.tokens[pos]?.type !== "WHITESPACE") {
|
|
2376
2614
|
return { kind: "skipped", consumed: consumeLineRemainder(ctx, pos) + consumed };
|
|
2377
2615
|
}
|
|
2378
|
-
|
|
2616
|
+
pos++;
|
|
2617
|
+
consumed++;
|
|
2618
|
+
const contentStart = pos;
|
|
2619
|
+
while (pos < ctx.tokens.length && ctx.tokens[pos]?.type !== "NEWLINE" && ctx.tokens[pos]?.type !== "EOF") {
|
|
2379
2620
|
pos++;
|
|
2380
2621
|
consumed++;
|
|
2381
2622
|
}
|
|
2382
|
-
const inlineCtx = { ...ctx, pos };
|
|
2383
|
-
const inlineResult = parseInlineUntil(inlineCtx, "NEWLINE");
|
|
2384
|
-
consumed += inlineResult.consumed;
|
|
2385
|
-
pos += inlineResult.consumed;
|
|
2386
|
-
let hasLineBreak = false;
|
|
2387
2623
|
if (ctx.tokens[pos]?.type === "NEWLINE") {
|
|
2388
|
-
|
|
2624
|
+
pos++;
|
|
2389
2625
|
consumed++;
|
|
2390
2626
|
}
|
|
2391
2627
|
return {
|
|
@@ -2393,7 +2629,7 @@ function parseBlockquoteLine(ctx, startPos) {
|
|
|
2393
2629
|
line: {
|
|
2394
2630
|
depth: depth - 1,
|
|
2395
2631
|
ltype: null,
|
|
2396
|
-
value: {
|
|
2632
|
+
value: { start: contentStart, end: pos }
|
|
2397
2633
|
},
|
|
2398
2634
|
consumed
|
|
2399
2635
|
};
|
|
@@ -2412,47 +2648,43 @@ function consumeLineRemainder(ctx, startPos) {
|
|
|
2412
2648
|
}
|
|
2413
2649
|
|
|
2414
2650
|
// packages/parser/src/parser/rules/block/blockquote/build.ts
|
|
2415
|
-
|
|
2651
|
+
var EXCLUDED_BLOCK_NAMES = new Set([
|
|
2652
|
+
"bibliography",
|
|
2653
|
+
"code",
|
|
2654
|
+
"html",
|
|
2655
|
+
"include",
|
|
2656
|
+
"math",
|
|
2657
|
+
"module"
|
|
2658
|
+
]);
|
|
2659
|
+
var NEVER_CLOSES = () => false;
|
|
2660
|
+
function buildBlockquoteElements(ctx, lines) {
|
|
2416
2661
|
const depthTrees = processDepths(null, lines);
|
|
2417
|
-
return depthTrees.map(({ list }) => buildBlockquoteElement(list));
|
|
2662
|
+
return depthTrees.map(({ list }) => buildBlockquoteElement(ctx, list)).filter((element) => element !== null);
|
|
2418
2663
|
}
|
|
2419
|
-
function buildBlockquoteElement(list) {
|
|
2664
|
+
function buildBlockquoteElement(ctx, list) {
|
|
2420
2665
|
const children = [];
|
|
2421
|
-
let
|
|
2422
|
-
function
|
|
2423
|
-
if (
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
if (currentParagraphChildren.length > 0) {
|
|
2428
|
-
children.push({
|
|
2429
|
-
element: "container",
|
|
2430
|
-
data: {
|
|
2431
|
-
type: "paragraph",
|
|
2432
|
-
attributes: {},
|
|
2433
|
-
elements: currentParagraphChildren
|
|
2434
|
-
}
|
|
2435
|
-
});
|
|
2436
|
-
}
|
|
2437
|
-
currentParagraphChildren = [];
|
|
2438
|
-
}
|
|
2666
|
+
let pending = [];
|
|
2667
|
+
function flushPending() {
|
|
2668
|
+
if (pending.length === 0)
|
|
2669
|
+
return;
|
|
2670
|
+
children.push(...parseLines(ctx, pending));
|
|
2671
|
+
pending = [];
|
|
2439
2672
|
}
|
|
2440
2673
|
for (const item of list) {
|
|
2441
2674
|
if (item.kind === "item") {
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
continue;
|
|
2445
|
-
}
|
|
2446
|
-
currentParagraphChildren.push(...item.value.elements);
|
|
2447
|
-
if (item.value.hasLineBreak) {
|
|
2448
|
-
currentParagraphChildren.push({ element: "line-break" });
|
|
2449
|
-
}
|
|
2450
|
-
} else {
|
|
2451
|
-
flushParagraph();
|
|
2452
|
-
children.push(buildBlockquoteElement(item.children));
|
|
2675
|
+
pending.push(item.value);
|
|
2676
|
+
continue;
|
|
2453
2677
|
}
|
|
2678
|
+
flushPending();
|
|
2679
|
+
const nested = buildBlockquoteElement(ctx, item.children);
|
|
2680
|
+
if (nested) {
|
|
2681
|
+
children.push(nested);
|
|
2682
|
+
}
|
|
2683
|
+
}
|
|
2684
|
+
flushPending();
|
|
2685
|
+
if (children.length === 0) {
|
|
2686
|
+
return null;
|
|
2454
2687
|
}
|
|
2455
|
-
flushParagraph();
|
|
2456
2688
|
return {
|
|
2457
2689
|
element: "container",
|
|
2458
2690
|
data: {
|
|
@@ -2462,6 +2694,31 @@ function buildBlockquoteElement(list) {
|
|
|
2462
2694
|
}
|
|
2463
2695
|
};
|
|
2464
2696
|
}
|
|
2697
|
+
function parseLines(ctx, lines) {
|
|
2698
|
+
const tokens = sliceLineTokens(ctx, lines);
|
|
2699
|
+
const lineCtx = { ...ctx, tokens, pos: 0 };
|
|
2700
|
+
return parseBlocksUntil(lineCtx, NEVER_CLOSES, {
|
|
2701
|
+
excludedBlockNames: EXCLUDED_BLOCK_NAMES
|
|
2702
|
+
}).elements;
|
|
2703
|
+
}
|
|
2704
|
+
function sliceLineTokens(ctx, lines) {
|
|
2705
|
+
const tokens = [];
|
|
2706
|
+
for (const { start, end } of lines) {
|
|
2707
|
+
for (let pos = start;pos < end; pos++) {
|
|
2708
|
+
const token5 = ctx.tokens[pos];
|
|
2709
|
+
if (token5) {
|
|
2710
|
+
tokens.push(token5);
|
|
2711
|
+
}
|
|
2712
|
+
}
|
|
2713
|
+
}
|
|
2714
|
+
const last = tokens[tokens.length - 1];
|
|
2715
|
+
tokens.push(createToken("EOF", "", last?.position ?? ZERO_POSITION2));
|
|
2716
|
+
return tokens;
|
|
2717
|
+
}
|
|
2718
|
+
var ZERO_POSITION2 = {
|
|
2719
|
+
start: { line: 0, column: 0, offset: 0 },
|
|
2720
|
+
end: { line: 0, column: 0, offset: 0 }
|
|
2721
|
+
};
|
|
2465
2722
|
|
|
2466
2723
|
// packages/parser/src/parser/rules/block/blockquote/lines.ts
|
|
2467
2724
|
function collectBlockquoteLines(ctx) {
|
|
@@ -2470,16 +2727,90 @@ function collectBlockquoteLines(ctx) {
|
|
|
2470
2727
|
let consumed = 0;
|
|
2471
2728
|
while (pos < ctx.tokens.length) {
|
|
2472
2729
|
const result = parseBlockquoteLine(ctx, pos);
|
|
2473
|
-
if (result.kind === "stop")
|
|
2474
|
-
|
|
2730
|
+
if (result.kind === "stop") {
|
|
2731
|
+
const resumed = extendToCommentClose(ctx, lines, pos);
|
|
2732
|
+
if (resumed === pos)
|
|
2733
|
+
break;
|
|
2734
|
+
consumed += resumed - pos;
|
|
2735
|
+
pos = resumed;
|
|
2736
|
+
continue;
|
|
2737
|
+
}
|
|
2475
2738
|
pos += result.consumed;
|
|
2476
2739
|
consumed += result.consumed;
|
|
2477
2740
|
if (result.kind === "parsed") {
|
|
2478
2741
|
lines.push(result.line);
|
|
2479
2742
|
}
|
|
2480
2743
|
}
|
|
2744
|
+
blankCommentOnlyLines(ctx, lines);
|
|
2481
2745
|
return { lines, consumed };
|
|
2482
2746
|
}
|
|
2747
|
+
function extendToCommentClose(ctx, lines, stopPos) {
|
|
2748
|
+
const last = lines[lines.length - 1];
|
|
2749
|
+
if (!last || !endsInsideComment(ctx, lines)) {
|
|
2750
|
+
return stopPos;
|
|
2751
|
+
}
|
|
2752
|
+
let pos = stopPos;
|
|
2753
|
+
while (pos < ctx.tokens.length && ctx.tokens[pos]?.type !== "COMMENT_CLOSE") {
|
|
2754
|
+
if (ctx.tokens[pos]?.type === "EOF")
|
|
2755
|
+
return stopPos;
|
|
2756
|
+
pos++;
|
|
2757
|
+
}
|
|
2758
|
+
while (pos < ctx.tokens.length && ctx.tokens[pos]?.type !== "EOF") {
|
|
2759
|
+
pos++;
|
|
2760
|
+
if (ctx.tokens[pos - 1]?.type === "NEWLINE")
|
|
2761
|
+
break;
|
|
2762
|
+
}
|
|
2763
|
+
last.value.end = pos;
|
|
2764
|
+
return pos;
|
|
2765
|
+
}
|
|
2766
|
+
function endsInsideComment(ctx, lines) {
|
|
2767
|
+
let open = false;
|
|
2768
|
+
for (const { value } of lines) {
|
|
2769
|
+
for (let pos = value.start;pos < value.end; pos++) {
|
|
2770
|
+
const type = ctx.tokens[pos]?.type;
|
|
2771
|
+
if (type === "COMMENT_OPEN")
|
|
2772
|
+
open = true;
|
|
2773
|
+
else if (type === "COMMENT_CLOSE")
|
|
2774
|
+
open = false;
|
|
2775
|
+
}
|
|
2776
|
+
}
|
|
2777
|
+
return open;
|
|
2778
|
+
}
|
|
2779
|
+
function blankCommentOnlyLines(ctx, lines) {
|
|
2780
|
+
const positions = [];
|
|
2781
|
+
lines.forEach((line, index) => {
|
|
2782
|
+
for (let pos = line.value.start;pos < line.value.end; pos++) {
|
|
2783
|
+
if (ctx.tokens[pos]?.type !== "NEWLINE") {
|
|
2784
|
+
positions.push({ line: index, pos });
|
|
2785
|
+
}
|
|
2786
|
+
}
|
|
2787
|
+
});
|
|
2788
|
+
const commented = Array.from({ length: positions.length }, () => false);
|
|
2789
|
+
for (let open = 0;open < positions.length; open++) {
|
|
2790
|
+
if (ctx.tokens[positions[open].pos]?.type !== "COMMENT_OPEN")
|
|
2791
|
+
continue;
|
|
2792
|
+
let close = open + 1;
|
|
2793
|
+
while (close < positions.length && ctx.tokens[positions[close].pos]?.type !== "COMMENT_CLOSE") {
|
|
2794
|
+
close++;
|
|
2795
|
+
}
|
|
2796
|
+
if (close === positions.length)
|
|
2797
|
+
break;
|
|
2798
|
+
commented.fill(true, open, close + 1);
|
|
2799
|
+
open = close;
|
|
2800
|
+
}
|
|
2801
|
+
const hasContent = Array.from({ length: lines.length }, () => false);
|
|
2802
|
+
positions.forEach(({ line, pos }, index) => {
|
|
2803
|
+
if (commented[index] || ctx.tokens[pos]?.type === "WHITESPACE")
|
|
2804
|
+
return;
|
|
2805
|
+
hasContent[line] = true;
|
|
2806
|
+
});
|
|
2807
|
+
lines.forEach((line, index) => {
|
|
2808
|
+
if (hasContent[index])
|
|
2809
|
+
return;
|
|
2810
|
+
const { end } = line.value;
|
|
2811
|
+
line.value.start = ctx.tokens[end - 1]?.type === "NEWLINE" ? end - 1 : end;
|
|
2812
|
+
});
|
|
2813
|
+
}
|
|
2483
2814
|
|
|
2484
2815
|
// packages/parser/src/parser/rules/block/blockquote/index.ts
|
|
2485
2816
|
var blockquoteRule = {
|
|
@@ -2498,9 +2829,9 @@ var blockquoteRule = {
|
|
|
2498
2829
|
}
|
|
2499
2830
|
return { success: false };
|
|
2500
2831
|
}
|
|
2501
|
-
const blockquotes = buildBlockquoteElements(blockquoteLines.lines);
|
|
2832
|
+
const blockquotes = buildBlockquoteElements(ctx, blockquoteLines.lines);
|
|
2502
2833
|
if (blockquotes.length === 0) {
|
|
2503
|
-
return { success:
|
|
2834
|
+
return { success: true, elements: [], consumed: blockquoteLines.consumed };
|
|
2504
2835
|
}
|
|
2505
2836
|
return {
|
|
2506
2837
|
success: true,
|
|
@@ -2595,17 +2926,8 @@ function parseDefinitionItemValue(ctx, startPos) {
|
|
|
2595
2926
|
break;
|
|
2596
2927
|
}
|
|
2597
2928
|
if (token5.type === "NEWLINE") {
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
pos++;
|
|
2601
|
-
consumed++;
|
|
2602
|
-
break;
|
|
2603
|
-
}
|
|
2604
|
-
if (nextToken?.type === "NEWLINE" || !nextToken || nextToken.type === "EOF") {
|
|
2605
|
-
pos++;
|
|
2606
|
-
consumed++;
|
|
2607
|
-
break;
|
|
2608
|
-
}
|
|
2929
|
+
consumed++;
|
|
2930
|
+
break;
|
|
2609
2931
|
}
|
|
2610
2932
|
const inlineCtx = { ...ctx, pos };
|
|
2611
2933
|
const result = parseInlineUntil(inlineCtx, "NEWLINE");
|
|
@@ -2683,14 +3005,10 @@ var definitionListRule = {
|
|
|
2683
3005
|
if (result.items.length === 0) {
|
|
2684
3006
|
return { success: false };
|
|
2685
3007
|
}
|
|
3008
|
+
const items = toDefinitionListItems(result.items.filter((item) => item.value.length > 0));
|
|
2686
3009
|
return {
|
|
2687
3010
|
success: true,
|
|
2688
|
-
elements: [
|
|
2689
|
-
{
|
|
2690
|
-
element: "definition-list",
|
|
2691
|
-
data: toDefinitionListItems(result.items)
|
|
2692
|
-
}
|
|
2693
|
-
],
|
|
3011
|
+
elements: items.length > 0 ? [{ element: "definition-list", data: items }] : [],
|
|
2694
3012
|
consumed: result.consumed
|
|
2695
3013
|
};
|
|
2696
3014
|
}
|
|
@@ -2795,20 +3113,49 @@ var paragraphRule = {
|
|
|
2795
3113
|
}
|
|
2796
3114
|
return {
|
|
2797
3115
|
success: true,
|
|
2798
|
-
elements:
|
|
2799
|
-
{
|
|
2800
|
-
element: "container",
|
|
2801
|
-
data: {
|
|
2802
|
-
type: "paragraph",
|
|
2803
|
-
attributes: {},
|
|
2804
|
-
elements
|
|
2805
|
-
}
|
|
2806
|
-
}
|
|
2807
|
-
],
|
|
3116
|
+
elements: wrapParagraphElements(elements),
|
|
2808
3117
|
consumed: result.consumed
|
|
2809
3118
|
};
|
|
2810
3119
|
}
|
|
2811
3120
|
};
|
|
3121
|
+
function wrapParagraphElements(elements) {
|
|
3122
|
+
const output = [];
|
|
3123
|
+
let group = [];
|
|
3124
|
+
let bare = false;
|
|
3125
|
+
const flush = (trimBreaks = false) => {
|
|
3126
|
+
const content = trimBreaks ? normalizeParagraphElements(group) : group;
|
|
3127
|
+
while (content[0]?.element === "line-break")
|
|
3128
|
+
content.shift();
|
|
3129
|
+
while (content.length) {
|
|
3130
|
+
const last = content.at(-1);
|
|
3131
|
+
if (last.element !== "text" || last.data.trim() !== "")
|
|
3132
|
+
break;
|
|
3133
|
+
content.pop();
|
|
3134
|
+
}
|
|
3135
|
+
while (content[0]?.element === "text" && content[0].data.trim() === "")
|
|
3136
|
+
content.shift();
|
|
3137
|
+
if (content[0]?.element === "text")
|
|
3138
|
+
content[0] = { element: "text", data: content[0].data.trimStart() };
|
|
3139
|
+
if (content.length)
|
|
3140
|
+
output.push(...bare || content.some((el) => el.element === "image") ? content : [
|
|
3141
|
+
{
|
|
3142
|
+
element: "container",
|
|
3143
|
+
data: { type: "paragraph", attributes: {}, elements: content }
|
|
3144
|
+
}
|
|
3145
|
+
]);
|
|
3146
|
+
group = [];
|
|
3147
|
+
};
|
|
3148
|
+
for (const el of elements) {
|
|
3149
|
+
if (el.element === "image" && el.data.alignment !== null || el.element === "embed-block") {
|
|
3150
|
+
flush(el.element === "image");
|
|
3151
|
+
output.push(el);
|
|
3152
|
+
bare = el.element === "embed-block";
|
|
3153
|
+
} else
|
|
3154
|
+
group.push(el);
|
|
3155
|
+
}
|
|
3156
|
+
flush();
|
|
3157
|
+
return output;
|
|
3158
|
+
}
|
|
2812
3159
|
|
|
2813
3160
|
// packages/parser/src/parser/rules/block/div/close.ts
|
|
2814
3161
|
function isDivClose(ctx) {
|
|
@@ -3174,9 +3521,6 @@ function consumeCodeClose(ctx, startPos, closeNameConsumed) {
|
|
|
3174
3521
|
pos++;
|
|
3175
3522
|
consumed++;
|
|
3176
3523
|
}
|
|
3177
|
-
if (ctx.tokens[pos]?.type === "NEWLINE") {
|
|
3178
|
-
consumed++;
|
|
3179
|
-
}
|
|
3180
3524
|
return consumed;
|
|
3181
3525
|
}
|
|
3182
3526
|
|
|
@@ -3233,16 +3577,13 @@ var codeBlockRule = {
|
|
|
3233
3577
|
name: attrResult.attrs.name ?? null
|
|
3234
3578
|
};
|
|
3235
3579
|
ctx.codeBlocks.push(codeBlockData);
|
|
3236
|
-
|
|
3237
|
-
|
|
3238
|
-
|
|
3239
|
-
|
|
3240
|
-
|
|
3241
|
-
|
|
3242
|
-
|
|
3243
|
-
],
|
|
3244
|
-
consumed
|
|
3245
|
-
};
|
|
3580
|
+
const elements = [{ element: "code", data: codeBlockData }];
|
|
3581
|
+
if (ctx.tokens[pos]?.type === "NEWLINE" && !getParagraphNewlineBoundary(ctx, pos, false).shouldBreak && !ctx.scope.blockCloseCondition?.({ ...ctx, pos: pos + 1 })) {
|
|
3582
|
+
const after = parseInlineUntil({ ...ctx, pos: pos + 1 }, "PARAGRAPH_BREAK");
|
|
3583
|
+
elements.push({ element: "line-break" }, ...normalizeParagraphElements(after.elements));
|
|
3584
|
+
consumed += 1 + after.consumed;
|
|
3585
|
+
}
|
|
3586
|
+
return { success: true, elements, consumed };
|
|
3246
3587
|
}
|
|
3247
3588
|
};
|
|
3248
3589
|
|
|
@@ -3621,7 +3962,30 @@ function parseTableCell(ctx, startPos, cellStart) {
|
|
|
3621
3962
|
consumed++;
|
|
3622
3963
|
}
|
|
3623
3964
|
const { inlineRules } = ctx;
|
|
3624
|
-
|
|
3965
|
+
let inlineEnd = pos;
|
|
3966
|
+
while (inlineEnd < ctx.tokens.length) {
|
|
3967
|
+
const rawEnd = protectedInlineRegionEnd(ctx.tokens, inlineEnd, ctx.tokens.length);
|
|
3968
|
+
if (rawEnd > inlineEnd) {
|
|
3969
|
+
inlineEnd = rawEnd;
|
|
3970
|
+
continue;
|
|
3971
|
+
}
|
|
3972
|
+
const token5 = ctx.tokens[inlineEnd];
|
|
3973
|
+
if (!token5 || token5.type === "EOF" || token5.type === "NEWLINE" || isPipeTableToken(token5.type))
|
|
3974
|
+
break;
|
|
3975
|
+
if (token5.type === "WHITESPACE" && ctx.tokens[inlineEnd + 1]?.type === "UNDERSCORE" && ctx.tokens[inlineEnd + 2]?.type === "NEWLINE")
|
|
3976
|
+
inlineEnd += 3;
|
|
3977
|
+
else
|
|
3978
|
+
inlineEnd++;
|
|
3979
|
+
}
|
|
3980
|
+
const inlineCtx = {
|
|
3981
|
+
...ctx,
|
|
3982
|
+
pos,
|
|
3983
|
+
scope: {
|
|
3984
|
+
...ctx.scope,
|
|
3985
|
+
inlineEnd,
|
|
3986
|
+
tableFormatting: isPipeTableToken(ctx.tokens[inlineEnd]?.type ?? "EOF") ? ctx.scope.tableFormatting : undefined
|
|
3987
|
+
}
|
|
3988
|
+
};
|
|
3625
3989
|
while (pos < ctx.tokens.length) {
|
|
3626
3990
|
const token5 = ctx.tokens[pos];
|
|
3627
3991
|
if (!token5 || token5.type === "NEWLINE" || token5.type === "EOF") {
|
|
@@ -3630,6 +3994,11 @@ function parseTableCell(ctx, startPos, cellStart) {
|
|
|
3630
3994
|
if (isPipeTableToken(token5.type)) {
|
|
3631
3995
|
break;
|
|
3632
3996
|
}
|
|
3997
|
+
if (ctx.scope.tableFormatting?.suppressedClosers.has(pos)) {
|
|
3998
|
+
pos++;
|
|
3999
|
+
consumed++;
|
|
4000
|
+
continue;
|
|
4001
|
+
}
|
|
3633
4002
|
if (tryConsumeUnderscoreLineBreak(ctx, pos, children)) {
|
|
3634
4003
|
pos += 3;
|
|
3635
4004
|
consumed += 3;
|
|
@@ -3689,6 +4058,21 @@ function tryConsumeUnderscoreLineBreak(ctx, pos, children) {
|
|
|
3689
4058
|
|
|
3690
4059
|
// packages/parser/src/parser/rules/block/table/pipe/row.ts
|
|
3691
4060
|
function parsePipeTableRows(ctx, startPos) {
|
|
4061
|
+
let end = startPos;
|
|
4062
|
+
while (end < ctx.tokens.length && ctx.tokens[end]?.type !== "EOF") {
|
|
4063
|
+
const protectedEnd = protectedInlineRegionEnd(ctx.tokens, end, ctx.tokens.length);
|
|
4064
|
+
if (protectedEnd > end) {
|
|
4065
|
+
end = protectedEnd;
|
|
4066
|
+
continue;
|
|
4067
|
+
}
|
|
4068
|
+
if (ctx.tokens[end]?.type === "NEWLINE" && !isPipeTableToken(ctx.tokens[end + 1]?.type ?? "EOF") && !(ctx.tokens[end - 1]?.type === "UNDERSCORE" && ctx.tokens[end - 2]?.type === "WHITESPACE"))
|
|
4069
|
+
break;
|
|
4070
|
+
end++;
|
|
4071
|
+
}
|
|
4072
|
+
const tableCtx = {
|
|
4073
|
+
...ctx,
|
|
4074
|
+
scope: { ...ctx.scope, tableFormatting: { end, suppressedClosers: new Set } }
|
|
4075
|
+
};
|
|
3692
4076
|
const rows = [];
|
|
3693
4077
|
let pos = startPos;
|
|
3694
4078
|
let consumed = 0;
|
|
@@ -3697,7 +4081,7 @@ function parsePipeTableRows(ctx, startPos) {
|
|
|
3697
4081
|
if (!token5 || !token5.lineStart || !isPipeTableToken(token5.type)) {
|
|
3698
4082
|
break;
|
|
3699
4083
|
}
|
|
3700
|
-
const rowResult = parseTableRow(
|
|
4084
|
+
const rowResult = parseTableRow(tableCtx, pos);
|
|
3701
4085
|
rows.push(rowResult.row);
|
|
3702
4086
|
pos += rowResult.consumed;
|
|
3703
4087
|
consumed += rowResult.consumed;
|
|
@@ -9125,6 +9509,8 @@ var embedBlockRule = {
|
|
|
9125
9509
|
name: "embed-block",
|
|
9126
9510
|
startTokens: ["BLOCK_OPEN"],
|
|
9127
9511
|
requiresLineStart: false,
|
|
9512
|
+
preservesPrecedingLineBreak: true,
|
|
9513
|
+
isStartPattern: (ctx, pos) => parseEmbedBlockOpen(ctx, pos) !== null,
|
|
9128
9514
|
parse(ctx) {
|
|
9129
9515
|
const openToken = currentToken(ctx);
|
|
9130
9516
|
if (openToken.type !== "BLOCK_OPEN") {
|
|
@@ -9140,38 +9526,30 @@ var embedBlockRule = {
|
|
|
9140
9526
|
pos += contentResult.consumed;
|
|
9141
9527
|
consumed += contentResult.consumed;
|
|
9142
9528
|
if (!contentResult.foundClose) {
|
|
9143
|
-
ctx.diagnostics.
|
|
9144
|
-
|
|
9145
|
-
|
|
9146
|
-
|
|
9147
|
-
|
|
9148
|
-
|
|
9529
|
+
if (!ctx.diagnostics.some((d) => d.code === "unclosed-block" && d.position === openToken.position))
|
|
9530
|
+
ctx.diagnostics.push({
|
|
9531
|
+
severity: "warning",
|
|
9532
|
+
code: "unclosed-block",
|
|
9533
|
+
message: `Missing closing tag [[/${openResult.blockName}]] for [[${openResult.blockName}]]`,
|
|
9534
|
+
position: openToken.position
|
|
9535
|
+
});
|
|
9149
9536
|
return { success: false };
|
|
9150
9537
|
}
|
|
9151
9538
|
const closeConsumed = consumeEmbedClose(ctx, pos);
|
|
9152
9539
|
pos += closeConsumed;
|
|
9153
9540
|
consumed += closeConsumed;
|
|
9154
|
-
|
|
9155
|
-
|
|
9156
|
-
|
|
9157
|
-
|
|
9158
|
-
|
|
9159
|
-
|
|
9160
|
-
|
|
9161
|
-
|
|
9162
|
-
|
|
9163
|
-
|
|
9164
|
-
|
|
9165
|
-
|
|
9166
|
-
contents: contentResult.contents.trim()
|
|
9167
|
-
}
|
|
9168
|
-
}
|
|
9169
|
-
]
|
|
9170
|
-
}
|
|
9171
|
-
}
|
|
9172
|
-
],
|
|
9173
|
-
consumed
|
|
9174
|
-
};
|
|
9541
|
+
const elements = [
|
|
9542
|
+
{ element: "embed-block", data: { contents: contentResult.contents.trim() } }
|
|
9543
|
+
];
|
|
9544
|
+
if (ctx.scope.inlineEnd === undefined && ctx.tokens[pos]?.type !== "NEWLINE" && ctx.tokens[pos]?.type !== "EOF") {
|
|
9545
|
+
const after = parseInlineUntil({ ...ctx, pos }, "PARAGRAPH_BREAK");
|
|
9546
|
+
const tail = normalizeParagraphElements(after.elements);
|
|
9547
|
+
if (tail[0]?.element === "text")
|
|
9548
|
+
tail[0].data = tail[0].data.trimStart();
|
|
9549
|
+
elements.push(...tail);
|
|
9550
|
+
consumed += after.consumed;
|
|
9551
|
+
}
|
|
9552
|
+
return { success: true, elements, consumed };
|
|
9175
9553
|
}
|
|
9176
9554
|
};
|
|
9177
9555
|
|
|
@@ -9485,11 +9863,11 @@ var iftagsRule = {
|
|
|
9485
9863
|
};
|
|
9486
9864
|
|
|
9487
9865
|
// packages/parser/src/parser/rules/block/toc/element.ts
|
|
9488
|
-
function createTocElement(align) {
|
|
9866
|
+
function createTocElement(align, title) {
|
|
9489
9867
|
return {
|
|
9490
9868
|
element: "table-of-contents",
|
|
9491
9869
|
data: {
|
|
9492
|
-
attributes: {},
|
|
9870
|
+
attributes: title === undefined ? {} : { title },
|
|
9493
9871
|
align
|
|
9494
9872
|
}
|
|
9495
9873
|
};
|
|
@@ -9532,26 +9910,17 @@ function parseTocOpen(ctx, startPos) {
|
|
|
9532
9910
|
} else {
|
|
9533
9911
|
return null;
|
|
9534
9912
|
}
|
|
9535
|
-
|
|
9913
|
+
const attributes = parseAttributes(ctx, pos);
|
|
9914
|
+
pos += attributes.consumed;
|
|
9536
9915
|
if (ctx.tokens[pos]?.type !== "BLOCK_CLOSE") {
|
|
9537
9916
|
return null;
|
|
9538
9917
|
}
|
|
9539
9918
|
return {
|
|
9540
9919
|
align,
|
|
9920
|
+
title: attributes.attrs.title,
|
|
9541
9921
|
consumed: pos + 1 - startPos
|
|
9542
9922
|
};
|
|
9543
9923
|
}
|
|
9544
|
-
function skipUntilClose(ctx, startPos) {
|
|
9545
|
-
let pos = startPos;
|
|
9546
|
-
while (pos < ctx.tokens.length) {
|
|
9547
|
-
const token5 = ctx.tokens[pos];
|
|
9548
|
-
if (!token5 || token5.type === "BLOCK_CLOSE" || token5.type === "NEWLINE" || token5.type === "EOF") {
|
|
9549
|
-
break;
|
|
9550
|
-
}
|
|
9551
|
-
pos++;
|
|
9552
|
-
}
|
|
9553
|
-
return pos;
|
|
9554
|
-
}
|
|
9555
9924
|
function isNameToken(token5) {
|
|
9556
9925
|
return token5?.type === "TEXT" || token5?.type === "IDENTIFIER";
|
|
9557
9926
|
}
|
|
@@ -9575,7 +9944,7 @@ var tocRule = {
|
|
|
9575
9944
|
}
|
|
9576
9945
|
return {
|
|
9577
9946
|
success: true,
|
|
9578
|
-
elements: [createTocElement(openResult.align)],
|
|
9947
|
+
elements: [createTocElement(openResult.align, openResult.title)],
|
|
9579
9948
|
consumed: openResult.consumed
|
|
9580
9949
|
};
|
|
9581
9950
|
}
|
|
@@ -10176,6 +10545,31 @@ var blockRules = [
|
|
|
10176
10545
|
galleryRule,
|
|
10177
10546
|
divRule
|
|
10178
10547
|
];
|
|
10548
|
+
// packages/parser/src/parser/rules/inline/formatting/close.ts
|
|
10549
|
+
function findFormattingClose(ctx, start, marker) {
|
|
10550
|
+
const table = ctx.scope.tableFormatting;
|
|
10551
|
+
const end = table?.end ?? ctx.scope.inlineEnd ?? ctx.tokens.length;
|
|
10552
|
+
for (let pos = start;pos < end; pos++) {
|
|
10553
|
+
const token5 = ctx.tokens[pos];
|
|
10554
|
+
if (!token5 || token5.type === "EOF" || ctx.scope.blockCloseCondition?.({ ...ctx, pos }))
|
|
10555
|
+
return null;
|
|
10556
|
+
if (!table && token5.type === "NEWLINE" && getParagraphNewlineBoundary(ctx, pos, true).shouldBreak)
|
|
10557
|
+
return null;
|
|
10558
|
+
if (token5.type === marker && !table?.suppressedClosers.has(pos))
|
|
10559
|
+
return pos;
|
|
10560
|
+
const protectedEnd = protectedInlineRegionEnd(ctx.tokens, pos, end);
|
|
10561
|
+
if (protectedEnd > pos)
|
|
10562
|
+
pos = protectedEnd - 1;
|
|
10563
|
+
}
|
|
10564
|
+
return null;
|
|
10565
|
+
}
|
|
10566
|
+
function consumeFormattingClose(ctx, close, contentEnd) {
|
|
10567
|
+
if (close === contentEnd)
|
|
10568
|
+
return 1;
|
|
10569
|
+
ctx.scope.tableFormatting?.suppressedClosers.add(close);
|
|
10570
|
+
return 0;
|
|
10571
|
+
}
|
|
10572
|
+
|
|
10179
10573
|
// packages/parser/src/parser/rules/inline/formatting/container.ts
|
|
10180
10574
|
function createInlineContainer(type, elements) {
|
|
10181
10575
|
return {
|
|
@@ -10187,9 +10581,10 @@ function createInlineContainer(type, elements) {
|
|
|
10187
10581
|
}
|
|
10188
10582
|
};
|
|
10189
10583
|
}
|
|
10190
|
-
function
|
|
10584
|
+
function parseDelimitedContainer(ctx, closeToken, type, options = {}) {
|
|
10191
10585
|
const startToken = currentToken(ctx);
|
|
10192
|
-
|
|
10586
|
+
const close = findFormattingClose(ctx, ctx.pos + 1, closeToken);
|
|
10587
|
+
if (close === null) {
|
|
10193
10588
|
return {
|
|
10194
10589
|
success: true,
|
|
10195
10590
|
elements: [{ element: "text", data: startToken.value }],
|
|
@@ -10197,7 +10592,7 @@ function parseSameLineDelimitedContainer(ctx, closeToken, type, options = {}) {
|
|
|
10197
10592
|
};
|
|
10198
10593
|
}
|
|
10199
10594
|
const result = parseInlineUntil({ ...ctx, pos: ctx.pos + 1 }, closeToken);
|
|
10200
|
-
const consumed = 1 + result.consumed + 1;
|
|
10595
|
+
const consumed = 1 + result.consumed + consumeFormattingClose(ctx, close, ctx.pos + 1 + result.consumed);
|
|
10201
10596
|
if (options.discardEmpty === true && result.elements.length === 0) {
|
|
10202
10597
|
return {
|
|
10203
10598
|
success: true,
|
|
@@ -10217,7 +10612,7 @@ var boldRule = {
|
|
|
10217
10612
|
name: "bold",
|
|
10218
10613
|
startTokens: ["BOLD_MARKER"],
|
|
10219
10614
|
parse(ctx) {
|
|
10220
|
-
return
|
|
10615
|
+
return parseDelimitedContainer(ctx, "BOLD_MARKER", "bold", { discardEmpty: true });
|
|
10221
10616
|
}
|
|
10222
10617
|
};
|
|
10223
10618
|
|
|
@@ -10226,102 +10621,28 @@ var italicRule = {
|
|
|
10226
10621
|
name: "italic",
|
|
10227
10622
|
startTokens: ["ITALIC_MARKER"],
|
|
10228
10623
|
parse(ctx) {
|
|
10229
|
-
return
|
|
10624
|
+
return parseDelimitedContainer(ctx, "ITALIC_MARKER", "italics");
|
|
10230
10625
|
}
|
|
10231
10626
|
};
|
|
10232
10627
|
|
|
10233
|
-
// packages/parser/src/parser/rules/inline/underline/child.ts
|
|
10234
|
-
function parseUnderlineChild(ctx, pos) {
|
|
10235
|
-
const token5 = ctx.tokens[pos];
|
|
10236
|
-
if (!token5) {
|
|
10237
|
-
return { elements: [], consumed: 0 };
|
|
10238
|
-
}
|
|
10239
|
-
if (token5.type === "NEWLINE") {
|
|
10240
|
-
return { elements: [{ element: "line-break" }], consumed: 1 };
|
|
10241
|
-
}
|
|
10242
|
-
const result = parseInlineUntil({ ...ctx, pos }, "UNDERLINE_MARKER");
|
|
10243
|
-
if (result.elements.length > 0) {
|
|
10244
|
-
return { elements: result.elements, consumed: result.consumed };
|
|
10245
|
-
}
|
|
10246
|
-
return { elements: [{ element: "text", data: token5.value }], consumed: 1 };
|
|
10247
|
-
}
|
|
10248
|
-
|
|
10249
|
-
// packages/parser/src/parser/rules/inline/underline/content.ts
|
|
10250
|
-
function parseUnderlineContent(ctx, startPos) {
|
|
10251
|
-
const children = [];
|
|
10252
|
-
let pos = startPos;
|
|
10253
|
-
let consumed = 1;
|
|
10254
|
-
while (pos < ctx.tokens.length) {
|
|
10255
|
-
const token5 = ctx.tokens[pos];
|
|
10256
|
-
if (!token5 || token5.type === "EOF")
|
|
10257
|
-
break;
|
|
10258
|
-
if (token5.type === "UNDERLINE_MARKER") {
|
|
10259
|
-
consumed++;
|
|
10260
|
-
break;
|
|
10261
|
-
}
|
|
10262
|
-
const child = parseUnderlineChild(ctx, pos);
|
|
10263
|
-
children.push(...child.elements);
|
|
10264
|
-
pos += child.consumed;
|
|
10265
|
-
consumed += child.consumed;
|
|
10266
|
-
}
|
|
10267
|
-
return { children, consumed };
|
|
10268
|
-
}
|
|
10269
|
-
|
|
10270
10628
|
// packages/parser/src/parser/rules/inline/underline/index.ts
|
|
10271
10629
|
var underlineRule = {
|
|
10272
10630
|
name: "underline",
|
|
10273
10631
|
startTokens: ["UNDERLINE_MARKER"],
|
|
10274
10632
|
parse(ctx) {
|
|
10275
|
-
|
|
10276
|
-
if (!hasClosingMarkerBeforeParagraphBreak({ ...ctx, pos: ctx.pos + 1 }, "UNDERLINE_MARKER")) {
|
|
10277
|
-
return {
|
|
10278
|
-
success: true,
|
|
10279
|
-
elements: [{ element: "text", data: startToken.value }],
|
|
10280
|
-
consumed: 1
|
|
10281
|
-
};
|
|
10282
|
-
}
|
|
10283
|
-
const { children, consumed } = parseUnderlineContent(ctx, ctx.pos + 1);
|
|
10284
|
-
if (children.length === 0) {
|
|
10285
|
-
return {
|
|
10286
|
-
success: true,
|
|
10287
|
-
elements: [],
|
|
10288
|
-
consumed
|
|
10289
|
-
};
|
|
10290
|
-
}
|
|
10291
|
-
return {
|
|
10292
|
-
success: true,
|
|
10293
|
-
elements: [createInlineContainer("underline", children)],
|
|
10294
|
-
consumed
|
|
10295
|
-
};
|
|
10633
|
+
return parseDelimitedContainer(ctx, "UNDERLINE_MARKER", "underline", { discardEmpty: true });
|
|
10296
10634
|
}
|
|
10297
10635
|
};
|
|
10298
10636
|
|
|
10299
10637
|
// packages/parser/src/parser/rules/inline/strikethrough/parse.ts
|
|
10300
10638
|
function parseStrikethroughContent(ctx) {
|
|
10301
|
-
|
|
10302
|
-
return {
|
|
10303
|
-
success: true,
|
|
10304
|
-
elements: [createInlineContainer("strikethrough", result.elements)],
|
|
10305
|
-
consumed: 1 + result.consumed + 1
|
|
10306
|
-
};
|
|
10639
|
+
return parseDelimitedContainer(ctx, "STRIKE_MARKER", "strikethrough");
|
|
10307
10640
|
}
|
|
10308
10641
|
|
|
10309
10642
|
// packages/parser/src/parser/rules/inline/strikethrough/syntax.ts
|
|
10310
10643
|
function hasValidStrikethroughClose(ctx) {
|
|
10311
|
-
|
|
10312
|
-
|
|
10313
|
-
while (pos < ctx.tokens.length) {
|
|
10314
|
-
const token5 = ctx.tokens[pos];
|
|
10315
|
-
if (!token5 || token5.type === "NEWLINE" || token5.type === "EOF") {
|
|
10316
|
-
return false;
|
|
10317
|
-
}
|
|
10318
|
-
if (token5.type === "STRIKE_MARKER") {
|
|
10319
|
-
return !prevWasWhitespace;
|
|
10320
|
-
}
|
|
10321
|
-
prevWasWhitespace = token5.type === "WHITESPACE";
|
|
10322
|
-
pos++;
|
|
10323
|
-
}
|
|
10324
|
-
return false;
|
|
10644
|
+
const close = findFormattingClose(ctx, ctx.pos + 1, "STRIKE_MARKER");
|
|
10645
|
+
return close !== null && close > ctx.pos + 1 && ctx.tokens[close - 1]?.type !== "WHITESPACE";
|
|
10325
10646
|
}
|
|
10326
10647
|
|
|
10327
10648
|
// packages/parser/src/parser/rules/inline/strikethrough/index.ts
|
|
@@ -10345,7 +10666,7 @@ var superscriptRule = {
|
|
|
10345
10666
|
name: "superscript",
|
|
10346
10667
|
startTokens: ["SUPER_MARKER"],
|
|
10347
10668
|
parse(ctx) {
|
|
10348
|
-
return
|
|
10669
|
+
return parseDelimitedContainer(ctx, "SUPER_MARKER", "superscript", {
|
|
10349
10670
|
discardEmpty: true
|
|
10350
10671
|
});
|
|
10351
10672
|
}
|
|
@@ -10356,7 +10677,7 @@ var subscriptRule = {
|
|
|
10356
10677
|
name: "subscript",
|
|
10357
10678
|
startTokens: ["SUB_MARKER"],
|
|
10358
10679
|
parse(ctx) {
|
|
10359
|
-
return
|
|
10680
|
+
return parseDelimitedContainer(ctx, "SUB_MARKER", "subscript", { discardEmpty: true });
|
|
10360
10681
|
}
|
|
10361
10682
|
};
|
|
10362
10683
|
|
|
@@ -10365,7 +10686,7 @@ var monospaceRule = {
|
|
|
10365
10686
|
name: "monospace",
|
|
10366
10687
|
startTokens: ["MONO_MARKER"],
|
|
10367
10688
|
parse(ctx) {
|
|
10368
|
-
return
|
|
10689
|
+
return parseDelimitedContainer(ctx, "MONO_CLOSE", "monospace");
|
|
10369
10690
|
}
|
|
10370
10691
|
};
|
|
10371
10692
|
|
|
@@ -10726,13 +11047,14 @@ var linkStarRule = {
|
|
|
10726
11047
|
|
|
10727
11048
|
// packages/parser/src/parser/rules/inline/color/syntax.ts
|
|
10728
11049
|
function parseColorContent(ctx) {
|
|
10729
|
-
|
|
11050
|
+
const close = findFormattingClose(ctx, ctx.pos + 1, "COLOR_MARKER");
|
|
11051
|
+
if (close === null) {
|
|
10730
11052
|
return null;
|
|
10731
11053
|
}
|
|
10732
11054
|
let pos = ctx.pos + 1;
|
|
10733
11055
|
let consumed = 1;
|
|
10734
11056
|
let colorSpec = "";
|
|
10735
|
-
while (pos < ctx.tokens.length) {
|
|
11057
|
+
while (pos < (ctx.scope.inlineEnd ?? ctx.tokens.length)) {
|
|
10736
11058
|
const token5 = ctx.tokens[pos];
|
|
10737
11059
|
if (!token5 || token5.type === "PIPE" || token5.type === "COLOR_MARKER" || token5.type === "NEWLINE" || token5.type === "EOF") {
|
|
10738
11060
|
break;
|
|
@@ -10749,14 +11071,11 @@ function parseColorContent(ctx) {
|
|
|
10749
11071
|
const contentResult = parseInlineUntil({ ...ctx, pos }, "COLOR_MARKER");
|
|
10750
11072
|
pos += contentResult.consumed;
|
|
10751
11073
|
consumed += contentResult.consumed;
|
|
10752
|
-
if (ctx.tokens[pos]?.type !== "COLOR_MARKER") {
|
|
10753
|
-
return null;
|
|
10754
|
-
}
|
|
10755
|
-
consumed++;
|
|
10756
11074
|
const color = colorSpec.trim();
|
|
10757
11075
|
if (color === "" || contentResult.elements.length === 0) {
|
|
10758
11076
|
return null;
|
|
10759
11077
|
}
|
|
11078
|
+
consumed += consumeFormattingClose(ctx, close, pos);
|
|
10760
11079
|
return {
|
|
10761
11080
|
color: hexifyColor(color),
|
|
10762
11081
|
elements: contentResult.elements,
|
|
@@ -11379,14 +11698,19 @@ function parseSpanContent(ctx, startPos, blockName) {
|
|
|
11379
11698
|
const escapedChildren = [];
|
|
11380
11699
|
const splitSpans = [];
|
|
11381
11700
|
let foundClose = false;
|
|
11701
|
+
let forcedClose = false;
|
|
11382
11702
|
let afterBlankLine = false;
|
|
11383
11703
|
let consumed = 0;
|
|
11384
11704
|
let pos = startPos;
|
|
11385
|
-
while (pos < ctx.tokens.length) {
|
|
11705
|
+
while (pos < (ctx.scope.inlineEnd ?? ctx.tokens.length)) {
|
|
11386
11706
|
const token5 = ctx.tokens[pos];
|
|
11387
11707
|
if (!token5 || token5.type === "EOF") {
|
|
11388
11708
|
break;
|
|
11389
11709
|
}
|
|
11710
|
+
if (ctx.scope.tableFormatting?.suppressedClosers.has(pos)) {
|
|
11711
|
+
forcedClose = true;
|
|
11712
|
+
break;
|
|
11713
|
+
}
|
|
11390
11714
|
const close = parseCloseSpan(ctx, pos);
|
|
11391
11715
|
if (close.success) {
|
|
11392
11716
|
pos += close.consumed;
|
|
@@ -11411,6 +11735,29 @@ function parseSpanContent(ctx, startPos, blockName) {
|
|
|
11411
11735
|
pos += parsed.consumed;
|
|
11412
11736
|
consumed += parsed.consumed;
|
|
11413
11737
|
}
|
|
11738
|
+
if (!foundClose && ctx.scope.tableFormatting && (pos === ctx.scope.inlineEnd || forcedClose)) {
|
|
11739
|
+
let depth = 0;
|
|
11740
|
+
for (let next = pos;next < ctx.scope.tableFormatting.end; next++) {
|
|
11741
|
+
const rawEnd = rawRegionEnd(ctx.tokens, next, ctx.scope.tableFormatting.end);
|
|
11742
|
+
if (rawEnd > next) {
|
|
11743
|
+
next = rawEnd - 1;
|
|
11744
|
+
continue;
|
|
11745
|
+
}
|
|
11746
|
+
if (ctx.tokens[next]?.type === "BLOCK_OPEN" && /^span_?$/i.test(ctx.tokens[next + 1]?.value ?? ""))
|
|
11747
|
+
depth++;
|
|
11748
|
+
const close = parseCloseSpan(ctx, next);
|
|
11749
|
+
if (!close.success)
|
|
11750
|
+
continue;
|
|
11751
|
+
if (depth > 0) {
|
|
11752
|
+
depth--;
|
|
11753
|
+
continue;
|
|
11754
|
+
}
|
|
11755
|
+
for (let offset = 0;offset < close.consumed; offset++)
|
|
11756
|
+
ctx.scope.tableFormatting.suppressedClosers.add(next + offset);
|
|
11757
|
+
foundClose = true;
|
|
11758
|
+
break;
|
|
11759
|
+
}
|
|
11760
|
+
}
|
|
11414
11761
|
return { children, escapedChildren, splitSpans, consumed, foundClose };
|
|
11415
11762
|
}
|
|
11416
11763
|
function parseOneSpanChild(ctx, pos, targetChildren) {
|
|
@@ -11822,135 +12169,6 @@ var footnoteRule = {
|
|
|
11822
12169
|
}
|
|
11823
12170
|
};
|
|
11824
12171
|
|
|
11825
|
-
// packages/parser/src/parser/rules/inline/image/attributes.ts
|
|
11826
|
-
function parseImageAttributes(ctx, startPos) {
|
|
11827
|
-
const result = parseAttributesRaw(ctx, startPos, false);
|
|
11828
|
-
const link = result.attrs.link ?? null;
|
|
11829
|
-
const { link: _link, ...htmlAttributes } = result.attrs;
|
|
11830
|
-
return {
|
|
11831
|
-
attributes: filterUnsafeAttributes(htmlAttributes),
|
|
11832
|
-
link,
|
|
11833
|
-
consumed: result.consumed
|
|
11834
|
-
};
|
|
11835
|
-
}
|
|
11836
|
-
|
|
11837
|
-
// packages/parser/src/parser/rules/inline/image/body.ts
|
|
11838
|
-
function parseImageSourceText(ctx, startPos) {
|
|
11839
|
-
let pos = startPos;
|
|
11840
|
-
let consumed = 0;
|
|
11841
|
-
while (ctx.tokens[pos]?.type === "WHITESPACE") {
|
|
11842
|
-
pos++;
|
|
11843
|
-
consumed++;
|
|
11844
|
-
}
|
|
11845
|
-
let sourceText = "";
|
|
11846
|
-
while (pos < ctx.tokens.length) {
|
|
11847
|
-
const token5 = ctx.tokens[pos];
|
|
11848
|
-
if (!token5 || token5.type === "WHITESPACE" || token5.type === "BLOCK_CLOSE" || token5.type === "NEWLINE" || token5.type === "EOF") {
|
|
11849
|
-
break;
|
|
11850
|
-
}
|
|
11851
|
-
sourceText += token5.value;
|
|
11852
|
-
pos++;
|
|
11853
|
-
consumed++;
|
|
11854
|
-
}
|
|
11855
|
-
return { sourceText, consumed };
|
|
11856
|
-
}
|
|
11857
|
-
|
|
11858
|
-
// packages/parser/src/parser/rules/inline/image/syntax.ts
|
|
11859
|
-
var IMAGE_BLOCK_NAMES = new Set([
|
|
11860
|
-
"image",
|
|
11861
|
-
"=image",
|
|
11862
|
-
"<image",
|
|
11863
|
-
">image",
|
|
11864
|
-
"f<image",
|
|
11865
|
-
"f>image",
|
|
11866
|
-
"f=image"
|
|
11867
|
-
]);
|
|
11868
|
-
function parseImageBlockName(ctx, startPos) {
|
|
11869
|
-
let pos = startPos;
|
|
11870
|
-
let consumed = 0;
|
|
11871
|
-
while (ctx.tokens[pos]?.type === "WHITESPACE") {
|
|
11872
|
-
pos++;
|
|
11873
|
-
consumed++;
|
|
11874
|
-
}
|
|
11875
|
-
const prefixResult = parseImagePrefix(ctx, pos);
|
|
11876
|
-
const prefix = prefixResult.prefix;
|
|
11877
|
-
pos += prefixResult.consumed;
|
|
11878
|
-
consumed += prefixResult.consumed;
|
|
11879
|
-
const nameToken = ctx.tokens[pos];
|
|
11880
|
-
if (!nameToken || nameToken.type !== "TEXT" && nameToken.type !== "IDENTIFIER") {
|
|
11881
|
-
return null;
|
|
11882
|
-
}
|
|
11883
|
-
return { name: prefix + nameToken.value.toLowerCase(), consumed: consumed + 1 };
|
|
11884
|
-
}
|
|
11885
|
-
function isImageBlockName(blockName) {
|
|
11886
|
-
return IMAGE_BLOCK_NAMES.has(blockName);
|
|
11887
|
-
}
|
|
11888
|
-
function parseImagePrefix(ctx, pos) {
|
|
11889
|
-
const token5 = ctx.tokens[pos];
|
|
11890
|
-
if (token5?.type === "EQUALS") {
|
|
11891
|
-
return { prefix: "=", consumed: 1 };
|
|
11892
|
-
}
|
|
11893
|
-
if (token5?.type === "TEXT" && token5.value === "<") {
|
|
11894
|
-
return { prefix: "<", consumed: 1 };
|
|
11895
|
-
}
|
|
11896
|
-
if ((token5?.type === "TEXT" || token5?.type === "BLOCKQUOTE_MARKER") && token5.value === ">") {
|
|
11897
|
-
return { prefix: ">", consumed: 1 };
|
|
11898
|
-
}
|
|
11899
|
-
if (token5?.type === "IDENTIFIER" && token5.value.toLowerCase() === "f") {
|
|
11900
|
-
return parseFloatPrefix(ctx, pos + 1);
|
|
11901
|
-
}
|
|
11902
|
-
return { prefix: "", consumed: 0 };
|
|
11903
|
-
}
|
|
11904
|
-
function parseFloatPrefix(ctx, pos) {
|
|
11905
|
-
const token5 = ctx.tokens[pos];
|
|
11906
|
-
if (token5?.type === "TEXT" && token5.value === "<") {
|
|
11907
|
-
return { prefix: "f<", consumed: 2 };
|
|
11908
|
-
}
|
|
11909
|
-
if ((token5?.type === "TEXT" || token5?.type === "BLOCKQUOTE_MARKER") && token5.value === ">") {
|
|
11910
|
-
return { prefix: "f>", consumed: 2 };
|
|
11911
|
-
}
|
|
11912
|
-
if (token5?.type === "EQUALS") {
|
|
11913
|
-
return { prefix: "f=", consumed: 2 };
|
|
11914
|
-
}
|
|
11915
|
-
return { prefix: "", consumed: 0 };
|
|
11916
|
-
}
|
|
11917
|
-
|
|
11918
|
-
// packages/parser/src/parser/rules/inline/image/open.ts
|
|
11919
|
-
function parseImageOpen(ctx) {
|
|
11920
|
-
if (ctx.tokens[ctx.pos]?.type !== "BLOCK_OPEN") {
|
|
11921
|
-
return null;
|
|
11922
|
-
}
|
|
11923
|
-
let pos = ctx.pos + 1;
|
|
11924
|
-
let consumed = 1;
|
|
11925
|
-
const nameResult = parseImageBlockName(ctx, pos);
|
|
11926
|
-
if (!nameResult || !isImageBlockName(nameResult.name)) {
|
|
11927
|
-
return null;
|
|
11928
|
-
}
|
|
11929
|
-
pos += nameResult.consumed;
|
|
11930
|
-
consumed += nameResult.consumed;
|
|
11931
|
-
const sourceText = parseImageSourceText(ctx, pos);
|
|
11932
|
-
pos += sourceText.consumed;
|
|
11933
|
-
consumed += sourceText.consumed;
|
|
11934
|
-
const attrs = parseImageAttributes(ctx, pos);
|
|
11935
|
-
pos += attrs.consumed;
|
|
11936
|
-
consumed += attrs.consumed;
|
|
11937
|
-
if (ctx.tokens[pos]?.type !== "BLOCK_CLOSE") {
|
|
11938
|
-
return null;
|
|
11939
|
-
}
|
|
11940
|
-
pos++;
|
|
11941
|
-
consumed++;
|
|
11942
|
-
if (!sourceText.sourceText) {
|
|
11943
|
-
return null;
|
|
11944
|
-
}
|
|
11945
|
-
return {
|
|
11946
|
-
blockName: nameResult.name,
|
|
11947
|
-
sourceText: sourceText.sourceText,
|
|
11948
|
-
link: attrs.link,
|
|
11949
|
-
attributes: attrs.attributes,
|
|
11950
|
-
consumed
|
|
11951
|
-
};
|
|
11952
|
-
}
|
|
11953
|
-
|
|
11954
12172
|
// packages/parser/src/parser/rules/inline/image/source.ts
|
|
11955
12173
|
function parseImageSource(src) {
|
|
11956
12174
|
if (src.startsWith("http://") || src.startsWith("https://") || src.startsWith("/")) {
|
|
@@ -13001,6 +13219,7 @@ var inlineRules = [
|
|
|
13001
13219
|
htmlInlineRule,
|
|
13002
13220
|
rawRule,
|
|
13003
13221
|
imageRule,
|
|
13222
|
+
embedBlockRule,
|
|
13004
13223
|
sizeRule,
|
|
13005
13224
|
footnoteRule,
|
|
13006
13225
|
spanRule,
|