@wdprlib/parser 5.1.6 → 5.3.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/dist/index.cjs +764 -452
- package/dist/index.d.cts +24 -4
- package/dist/index.d.ts +24 -4
- package/dist/index.js +762 -452
- package/package.json +2 -2
- 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/module/listpages/resolution/items.ts +2 -2
- package/src/parser/rules/block/module/listpages/resolution/pager.ts +43 -0
- package/src/parser/rules/block/module/listpages/resolution/wrapper.ts +6 -1
- package/src/parser/rules/block/module/listpages/resolve.ts +1 -1
- package/src/parser/rules/block/module/listpages/types/external-data.ts +13 -0
- package/src/parser/rules/block/module/listpages/url-resolution/params.ts +5 -4
- package/src/parser/rules/block/module/resolution/data-maps.ts +75 -3
- package/src/parser/rules/block/module/resolution/resolve-async.ts +12 -3
- 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/pipeline/process.ts +8 -1
- 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
|
@@ -71,6 +71,7 @@ __export(exports_src, {
|
|
|
71
71
|
container: () => import_ast9.container,
|
|
72
72
|
compileTemplate: () => compileTemplate,
|
|
73
73
|
compileListUsersTemplate: () => compileListUsersTemplate,
|
|
74
|
+
buildInfo: () => buildInfo,
|
|
74
75
|
bold: () => import_ast9.bold,
|
|
75
76
|
STYLE_SLOT_PREFIX: () => import_ast4.STYLE_SLOT_PREFIX,
|
|
76
77
|
Parser: () => Parser,
|
|
@@ -78,6 +79,15 @@ __export(exports_src, {
|
|
|
78
79
|
DEFAULT_SETTINGS: () => import_ast10.DEFAULT_SETTINGS
|
|
79
80
|
});
|
|
80
81
|
module.exports = __toCommonJS(exports_src);
|
|
82
|
+
|
|
83
|
+
// packages/parser/src/build-info.generated.ts
|
|
84
|
+
var buildInfo = Object.freeze({
|
|
85
|
+
version: "5.3.0",
|
|
86
|
+
sha: "b71b84c705e05717f5ea12fd89684a91b669dbff",
|
|
87
|
+
dirty: false
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
// packages/parser/src/index.ts
|
|
81
91
|
var import_ast9 = require("@wdprlib/ast");
|
|
82
92
|
var import_ast10 = require("@wdprlib/ast");
|
|
83
93
|
|
|
@@ -85,49 +95,6 @@ var import_ast10 = require("@wdprlib/ast");
|
|
|
85
95
|
function createToken(type, value, position, lineStart = false) {
|
|
86
96
|
return { type, value, position, lineStart };
|
|
87
97
|
}
|
|
88
|
-
// packages/parser/src/lexer/token-factory.ts
|
|
89
|
-
var ZERO_POSITION = {
|
|
90
|
-
start: { line: 0, column: 0, offset: 0 },
|
|
91
|
-
end: { line: 0, column: 0, offset: 0 }
|
|
92
|
-
};
|
|
93
|
-
function createLexerToken(state, type, value, trackPositions) {
|
|
94
|
-
return {
|
|
95
|
-
type,
|
|
96
|
-
value,
|
|
97
|
-
position: trackPositions ? currentTokenPosition(state, value) : ZERO_POSITION,
|
|
98
|
-
lineStart: isTokenAtLineStart(state)
|
|
99
|
-
};
|
|
100
|
-
}
|
|
101
|
-
function updateLastNonWhitespaceType(current, type) {
|
|
102
|
-
return type === "WHITESPACE" ? current : type;
|
|
103
|
-
}
|
|
104
|
-
function nextBlockOpenerDepth(current, type) {
|
|
105
|
-
if (type === "BLOCK_OPEN" || type === "BLOCK_END_OPEN") {
|
|
106
|
-
return current + 1;
|
|
107
|
-
}
|
|
108
|
-
if (type === "BLOCK_CLOSE" && current > 0) {
|
|
109
|
-
return current - 1;
|
|
110
|
-
}
|
|
111
|
-
return current;
|
|
112
|
-
}
|
|
113
|
-
function currentTokenPosition(state, value) {
|
|
114
|
-
return {
|
|
115
|
-
start: {
|
|
116
|
-
line: state.line,
|
|
117
|
-
column: state.column - value.length,
|
|
118
|
-
offset: state.pos - value.length
|
|
119
|
-
},
|
|
120
|
-
end: {
|
|
121
|
-
line: state.line,
|
|
122
|
-
column: state.column,
|
|
123
|
-
offset: state.pos
|
|
124
|
-
}
|
|
125
|
-
};
|
|
126
|
-
}
|
|
127
|
-
function isTokenAtLineStart(state) {
|
|
128
|
-
return state.tokens.length === 0 || state.tokens[state.tokens.length - 1]?.type === "NEWLINE";
|
|
129
|
-
}
|
|
130
|
-
|
|
131
98
|
// packages/parser/src/lexer/state.ts
|
|
132
99
|
function createInitialLexerState(source) {
|
|
133
100
|
return {
|
|
@@ -136,9 +103,16 @@ function createInitialLexerState(source) {
|
|
|
136
103
|
line: 1,
|
|
137
104
|
column: 1,
|
|
138
105
|
lineStart: true,
|
|
106
|
+
quoteContentStart: false,
|
|
139
107
|
tokens: []
|
|
140
108
|
};
|
|
141
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
|
+
}
|
|
142
116
|
function isAtEnd(state) {
|
|
143
117
|
return state.pos >= state.source.length;
|
|
144
118
|
}
|
|
@@ -152,18 +126,25 @@ function advance(state, n = 1) {
|
|
|
152
126
|
updatePosition(state, start, end);
|
|
153
127
|
return value;
|
|
154
128
|
}
|
|
155
|
-
function advanceByToken(state, type, length) {
|
|
129
|
+
function advanceByToken(state, type, length, value = "") {
|
|
130
|
+
const afterQuoteMarker = isLineStartQuoteMarker(state.tokens[state.tokens.length - 1]);
|
|
156
131
|
state.pos += length;
|
|
157
132
|
if (type === "NEWLINE") {
|
|
158
133
|
state.line++;
|
|
159
134
|
state.column = 1;
|
|
160
135
|
state.lineStart = true;
|
|
136
|
+
state.quoteContentStart = false;
|
|
161
137
|
return;
|
|
162
138
|
}
|
|
163
139
|
state.column += length;
|
|
164
|
-
if (type
|
|
165
|
-
|
|
140
|
+
if (type === "WHITESPACE") {
|
|
141
|
+
if (afterQuoteMarker && value === " ") {
|
|
142
|
+
state.quoteContentStart = true;
|
|
143
|
+
}
|
|
144
|
+
return;
|
|
166
145
|
}
|
|
146
|
+
state.lineStart = false;
|
|
147
|
+
state.quoteContentStart = false;
|
|
167
148
|
}
|
|
168
149
|
function updatePosition(state, start, end) {
|
|
169
150
|
state.pos = end;
|
|
@@ -174,8 +155,9 @@ function updatePositionFromValue(state, value) {
|
|
|
174
155
|
`);
|
|
175
156
|
if (firstNewline === -1) {
|
|
176
157
|
state.column += value.length;
|
|
177
|
-
if (
|
|
158
|
+
if (hasNonLineStartSpacing(value, 0)) {
|
|
178
159
|
state.lineStart = false;
|
|
160
|
+
state.quoteContentStart = false;
|
|
179
161
|
}
|
|
180
162
|
return;
|
|
181
163
|
}
|
|
@@ -194,6 +176,7 @@ function updatePositionFromValue(state, value) {
|
|
|
194
176
|
state.line += newlineCount;
|
|
195
177
|
state.column = value.length - lastNewline;
|
|
196
178
|
state.lineStart = !hasNonLineStartSpacing(value, lastNewline + 1);
|
|
179
|
+
state.quoteContentStart = false;
|
|
197
180
|
}
|
|
198
181
|
function hasNonLineStartSpacing(value, start) {
|
|
199
182
|
for (let i = start;i < value.length; i++) {
|
|
@@ -205,6 +188,56 @@ function hasNonLineStartSpacing(value, start) {
|
|
|
205
188
|
return false;
|
|
206
189
|
}
|
|
207
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
|
+
|
|
208
241
|
// packages/parser/src/lexer/anchor.ts
|
|
209
242
|
function findInvalidAnchorNameEnd(src, pos) {
|
|
210
243
|
if (src[pos] !== "[" || src[pos + 1] !== "[" || src[pos + 2] !== "#") {
|
|
@@ -521,7 +554,7 @@ function scanPunctuationToken(input) {
|
|
|
521
554
|
case "@":
|
|
522
555
|
return { handled: true, actions: scanAtToken(source, pos) };
|
|
523
556
|
case ">":
|
|
524
|
-
return { handled: true, actions: scanGreaterToken(source, pos,
|
|
557
|
+
return { handled: true, actions: scanGreaterToken(source, pos, input.physicalLineStart) };
|
|
525
558
|
case "-":
|
|
526
559
|
return { handled: true, actions: scanDashToken(source, pos, lineStart) };
|
|
527
560
|
case "~": {
|
|
@@ -563,6 +596,15 @@ function runToken3(src, pos, end, type) {
|
|
|
563
596
|
}
|
|
564
597
|
|
|
565
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
|
+
}
|
|
566
608
|
function scanSpacingToken(src, pos) {
|
|
567
609
|
const char = src[pos];
|
|
568
610
|
if (char === `
|
|
@@ -624,7 +666,7 @@ class Lexer {
|
|
|
624
666
|
this.blockOpenerDepth = nextBlockOpenerDepth(this.blockOpenerDepth, type);
|
|
625
667
|
}
|
|
626
668
|
emitTokenAction(action) {
|
|
627
|
-
advanceByToken(this.state, action.type, action.length);
|
|
669
|
+
advanceByToken(this.state, action.type, action.length, action.value);
|
|
628
670
|
this.addToken(action.type, action.value);
|
|
629
671
|
}
|
|
630
672
|
emitTokenActions(actions) {
|
|
@@ -638,11 +680,11 @@ class Lexer {
|
|
|
638
680
|
}
|
|
639
681
|
scanToken() {
|
|
640
682
|
const char = this.current();
|
|
641
|
-
const isLineStart = this.state
|
|
683
|
+
const isLineStart = isSyntaxLineStart(this.state);
|
|
642
684
|
const src = this.state.source;
|
|
643
685
|
const spacingAction = scanSpacingToken(src, this.state.pos);
|
|
644
686
|
if (spacingAction) {
|
|
645
|
-
this.emitTokenAction(spacingAction);
|
|
687
|
+
this.emitTokenAction(limitBlockquotePrefixSpace(spacingAction, this.state.tokens.at(-1)));
|
|
646
688
|
return;
|
|
647
689
|
}
|
|
648
690
|
const punctuation = scanPunctuationToken({
|
|
@@ -650,6 +692,7 @@ class Lexer {
|
|
|
650
692
|
source: src,
|
|
651
693
|
pos: this.state.pos,
|
|
652
694
|
lineStart: isLineStart,
|
|
695
|
+
physicalLineStart: this.state.lineStart,
|
|
653
696
|
splitBlockClose: this.splitBlockClosePositions.has(this.state.pos),
|
|
654
697
|
findInvalidAnchorNameEnd: () => this.findInvalidAnchorNameEnd()
|
|
655
698
|
});
|
|
@@ -866,7 +909,7 @@ function parseBlocksUntil(ctx, closeCondition, options) {
|
|
|
866
909
|
const elements = [];
|
|
867
910
|
let consumed = 0;
|
|
868
911
|
let pos = ctx.pos;
|
|
869
|
-
const excluded = options?.excludedBlockNames;
|
|
912
|
+
const excluded = mergeExcludedBlockNames(ctx.scope.excludedBlockNames, options?.excludedBlockNames);
|
|
870
913
|
const blockRules = excluded ? getExcludedBlockRules(ctx.blockRules, excluded) : ctx.blockRules;
|
|
871
914
|
const blockScope = {
|
|
872
915
|
...ctx.scope,
|
|
@@ -908,6 +951,13 @@ function parseBlocksUntil(ctx, closeCondition, options) {
|
|
|
908
951
|
}
|
|
909
952
|
return { elements, consumed };
|
|
910
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
|
+
}
|
|
911
961
|
function getExcludedBlockRules(blockRules, excluded) {
|
|
912
962
|
let byExcluded = excludedBlockRulesCache.get(blockRules);
|
|
913
963
|
if (!byExcluded) {
|
|
@@ -944,6 +994,31 @@ function getCandidateInlineRules(inlineRules, tokenType) {
|
|
|
944
994
|
byType.set(tokenType, candidates);
|
|
945
995
|
return candidates;
|
|
946
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
|
+
|
|
947
1022
|
// packages/parser/src/parser/rules/inline/parsing/plain-text.ts
|
|
948
1023
|
var MIN_INLINE_TEXT_RUN_LENGTH = 32;
|
|
949
1024
|
var MIN_INLINE_TEXT_RUN_DOCUMENT_TOKENS = 1e5;
|
|
@@ -986,6 +1061,135 @@ function isPlainTextRunToken(ctx, pos) {
|
|
|
986
1061
|
return token5.value !== "(";
|
|
987
1062
|
}
|
|
988
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
|
+
|
|
989
1193
|
// packages/parser/src/parser/constants.ts
|
|
990
1194
|
var BLOCK_START_TOKENS = [
|
|
991
1195
|
"BLOCKQUOTE_MARKER",
|
|
@@ -1116,7 +1320,7 @@ function isParagraphBreakingBlockStart(ctx, newlinePos, lookAhead) {
|
|
|
1116
1320
|
if (!nextMeaningfulToken.lineStart && !isIndentedBlockOpener) {
|
|
1117
1321
|
return false;
|
|
1118
1322
|
}
|
|
1119
|
-
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);
|
|
1120
1324
|
}
|
|
1121
1325
|
function isOrphanCloseSpan(ctx, blockEndOpenPos) {
|
|
1122
1326
|
const token5 = ctx.tokens[blockEndOpenPos];
|
|
@@ -1226,27 +1430,45 @@ function parseInlineUntil(ctx, endType) {
|
|
|
1226
1430
|
let consumed = 0;
|
|
1227
1431
|
let pos = ctx.pos;
|
|
1228
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
|
+
}
|
|
1229
1450
|
const { inlineRules } = ctx;
|
|
1230
1451
|
const inlineCtx = {
|
|
1231
1452
|
...ctx,
|
|
1232
|
-
pos
|
|
1453
|
+
pos,
|
|
1454
|
+
scope: { ...ctx.scope, inlineEnd }
|
|
1233
1455
|
};
|
|
1234
1456
|
const canCollectLongPlainTextRuns = ctx.tokens.length >= MIN_INLINE_TEXT_RUN_DOCUMENT_TOKENS;
|
|
1235
|
-
while (pos <
|
|
1457
|
+
while (pos < inlineEnd) {
|
|
1236
1458
|
const token5 = ctx.tokens[pos];
|
|
1237
1459
|
if (!token5 || token5.type === "EOF") {
|
|
1238
1460
|
break;
|
|
1239
1461
|
}
|
|
1240
|
-
if (
|
|
1462
|
+
if (ctx.scope.blockCloseCondition) {
|
|
1241
1463
|
const checkCtx = { ...ctx, pos };
|
|
1242
1464
|
if (ctx.scope.blockCloseCondition(checkCtx)) {
|
|
1243
1465
|
break;
|
|
1244
1466
|
}
|
|
1245
1467
|
}
|
|
1246
|
-
if (!
|
|
1468
|
+
if (!multiline && token5.type === "NEWLINE") {
|
|
1247
1469
|
break;
|
|
1248
1470
|
}
|
|
1249
|
-
if (
|
|
1471
|
+
if (multiline && token5.type === "NEWLINE" && !ctx.scope.tableFormatting) {
|
|
1250
1472
|
const boundary = getParagraphNewlineBoundary(ctx, pos, nodes.length > 0);
|
|
1251
1473
|
if (boundary.shouldBreak) {
|
|
1252
1474
|
if (boundary.preservePrecedingLineBreak) {
|
|
@@ -1256,6 +1478,11 @@ function parseInlineUntil(ctx, endType) {
|
|
|
1256
1478
|
break;
|
|
1257
1479
|
}
|
|
1258
1480
|
}
|
|
1481
|
+
if (ctx.scope.tableFormatting?.suppressedClosers.has(pos)) {
|
|
1482
|
+
pos++;
|
|
1483
|
+
consumed++;
|
|
1484
|
+
continue;
|
|
1485
|
+
}
|
|
1259
1486
|
if (token5.type === endType) {
|
|
1260
1487
|
break;
|
|
1261
1488
|
}
|
|
@@ -1280,6 +1507,24 @@ function parseInlineUntil(ctx, endType) {
|
|
|
1280
1507
|
for (const rule of getCandidateInlineRules(inlineRules, token5.type)) {
|
|
1281
1508
|
const result = rule.parse(inlineCtx);
|
|
1282
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
|
+
}
|
|
1283
1528
|
nodes.push(...result.elements);
|
|
1284
1529
|
consumed += result.consumed;
|
|
1285
1530
|
pos += result.consumed;
|
|
@@ -1295,6 +1540,16 @@ function parseInlineUntil(ctx, endType) {
|
|
|
1295
1540
|
}
|
|
1296
1541
|
return { elements: nodes, consumed };
|
|
1297
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
|
+
]);
|
|
1298
1553
|
// packages/parser/src/parser/rules/block/parsing/attributes/names.ts
|
|
1299
1554
|
function consumeAttributeName(ctx, startPos, startConsumed, startName, options) {
|
|
1300
1555
|
if (startName === "_" && isAttributeWordToken(ctx.tokens[startPos])) {
|
|
@@ -1470,7 +1725,7 @@ function eofToken() {
|
|
|
1470
1725
|
}
|
|
1471
1726
|
function hasClosingMarkerBeforeNewline(ctx, markerType, markerValue) {
|
|
1472
1727
|
let pos = ctx.pos;
|
|
1473
|
-
while (pos < ctx.tokens.length) {
|
|
1728
|
+
while (pos < (ctx.scope.inlineEnd ?? ctx.tokens.length)) {
|
|
1474
1729
|
const token5 = ctx.tokens[pos];
|
|
1475
1730
|
if (!token5 || token5.type === "NEWLINE" || token5.type === "EOF") {
|
|
1476
1731
|
return false;
|
|
@@ -1484,31 +1739,6 @@ function hasClosingMarkerBeforeNewline(ctx, markerType, markerValue) {
|
|
|
1484
1739
|
}
|
|
1485
1740
|
return false;
|
|
1486
1741
|
}
|
|
1487
|
-
function hasClosingMarkerBeforeParagraphBreak(ctx, markerType, markerValue) {
|
|
1488
|
-
let pos = ctx.pos;
|
|
1489
|
-
while (pos < ctx.tokens.length) {
|
|
1490
|
-
const token5 = ctx.tokens[pos];
|
|
1491
|
-
if (!token5 || token5.type === "EOF") {
|
|
1492
|
-
return false;
|
|
1493
|
-
}
|
|
1494
|
-
if (token5.type === "NEWLINE") {
|
|
1495
|
-
let lookAhead = 1;
|
|
1496
|
-
while (ctx.tokens[pos + lookAhead]?.type === "WHITESPACE") {
|
|
1497
|
-
lookAhead++;
|
|
1498
|
-
}
|
|
1499
|
-
if (ctx.tokens[pos + lookAhead]?.type === "NEWLINE" || ctx.tokens[pos + lookAhead]?.type === "EOF" || !ctx.tokens[pos + lookAhead]) {
|
|
1500
|
-
return false;
|
|
1501
|
-
}
|
|
1502
|
-
}
|
|
1503
|
-
if (token5.type === markerType) {
|
|
1504
|
-
if (markerValue === undefined || token5.value === markerValue) {
|
|
1505
|
-
return true;
|
|
1506
|
-
}
|
|
1507
|
-
}
|
|
1508
|
-
pos++;
|
|
1509
|
-
}
|
|
1510
|
-
return false;
|
|
1511
|
-
}
|
|
1512
1742
|
// packages/parser/src/parser/rules/block/heading/open.ts
|
|
1513
1743
|
function parseHeadingOpen(ctx) {
|
|
1514
1744
|
const marker = ctx.tokens[ctx.pos];
|
|
@@ -1575,6 +1805,15 @@ var headingRule = {
|
|
|
1575
1805
|
const inlineCtx = { ...ctx, pos };
|
|
1576
1806
|
const inlineResult = parseInlineUntil(inlineCtx, "NEWLINE");
|
|
1577
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
|
+
}
|
|
1578
1817
|
consumed += inlineResult.consumed;
|
|
1579
1818
|
pos += inlineResult.consumed;
|
|
1580
1819
|
if (ctx.tokens[pos]?.type === "NEWLINE") {
|
|
@@ -2374,17 +2613,15 @@ function parseBlockquoteLine(ctx, startPos) {
|
|
|
2374
2613
|
if (ctx.tokens[pos]?.type !== "WHITESPACE") {
|
|
2375
2614
|
return { kind: "skipped", consumed: consumeLineRemainder(ctx, pos) + consumed };
|
|
2376
2615
|
}
|
|
2377
|
-
|
|
2616
|
+
pos++;
|
|
2617
|
+
consumed++;
|
|
2618
|
+
const contentStart = pos;
|
|
2619
|
+
while (pos < ctx.tokens.length && ctx.tokens[pos]?.type !== "NEWLINE" && ctx.tokens[pos]?.type !== "EOF") {
|
|
2378
2620
|
pos++;
|
|
2379
2621
|
consumed++;
|
|
2380
2622
|
}
|
|
2381
|
-
const inlineCtx = { ...ctx, pos };
|
|
2382
|
-
const inlineResult = parseInlineUntil(inlineCtx, "NEWLINE");
|
|
2383
|
-
consumed += inlineResult.consumed;
|
|
2384
|
-
pos += inlineResult.consumed;
|
|
2385
|
-
let hasLineBreak = false;
|
|
2386
2623
|
if (ctx.tokens[pos]?.type === "NEWLINE") {
|
|
2387
|
-
|
|
2624
|
+
pos++;
|
|
2388
2625
|
consumed++;
|
|
2389
2626
|
}
|
|
2390
2627
|
return {
|
|
@@ -2392,7 +2629,7 @@ function parseBlockquoteLine(ctx, startPos) {
|
|
|
2392
2629
|
line: {
|
|
2393
2630
|
depth: depth - 1,
|
|
2394
2631
|
ltype: null,
|
|
2395
|
-
value: {
|
|
2632
|
+
value: { start: contentStart, end: pos }
|
|
2396
2633
|
},
|
|
2397
2634
|
consumed
|
|
2398
2635
|
};
|
|
@@ -2411,47 +2648,43 @@ function consumeLineRemainder(ctx, startPos) {
|
|
|
2411
2648
|
}
|
|
2412
2649
|
|
|
2413
2650
|
// packages/parser/src/parser/rules/block/blockquote/build.ts
|
|
2414
|
-
|
|
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) {
|
|
2415
2661
|
const depthTrees = processDepths(null, lines);
|
|
2416
|
-
return depthTrees.map(({ list }) => buildBlockquoteElement(list));
|
|
2662
|
+
return depthTrees.map(({ list }) => buildBlockquoteElement(ctx, list)).filter((element) => element !== null);
|
|
2417
2663
|
}
|
|
2418
|
-
function buildBlockquoteElement(list) {
|
|
2664
|
+
function buildBlockquoteElement(ctx, list) {
|
|
2419
2665
|
const children = [];
|
|
2420
|
-
let
|
|
2421
|
-
function
|
|
2422
|
-
if (
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
if (currentParagraphChildren.length > 0) {
|
|
2427
|
-
children.push({
|
|
2428
|
-
element: "container",
|
|
2429
|
-
data: {
|
|
2430
|
-
type: "paragraph",
|
|
2431
|
-
attributes: {},
|
|
2432
|
-
elements: currentParagraphChildren
|
|
2433
|
-
}
|
|
2434
|
-
});
|
|
2435
|
-
}
|
|
2436
|
-
currentParagraphChildren = [];
|
|
2437
|
-
}
|
|
2666
|
+
let pending = [];
|
|
2667
|
+
function flushPending() {
|
|
2668
|
+
if (pending.length === 0)
|
|
2669
|
+
return;
|
|
2670
|
+
children.push(...parseLines(ctx, pending));
|
|
2671
|
+
pending = [];
|
|
2438
2672
|
}
|
|
2439
2673
|
for (const item of list) {
|
|
2440
2674
|
if (item.kind === "item") {
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
}
|
|
2449
|
-
} else {
|
|
2450
|
-
flushParagraph();
|
|
2451
|
-
children.push(buildBlockquoteElement(item.children));
|
|
2675
|
+
pending.push(item.value);
|
|
2676
|
+
continue;
|
|
2677
|
+
}
|
|
2678
|
+
flushPending();
|
|
2679
|
+
const nested = buildBlockquoteElement(ctx, item.children);
|
|
2680
|
+
if (nested) {
|
|
2681
|
+
children.push(nested);
|
|
2452
2682
|
}
|
|
2453
2683
|
}
|
|
2454
|
-
|
|
2684
|
+
flushPending();
|
|
2685
|
+
if (children.length === 0) {
|
|
2686
|
+
return null;
|
|
2687
|
+
}
|
|
2455
2688
|
return {
|
|
2456
2689
|
element: "container",
|
|
2457
2690
|
data: {
|
|
@@ -2461,6 +2694,31 @@ function buildBlockquoteElement(list) {
|
|
|
2461
2694
|
}
|
|
2462
2695
|
};
|
|
2463
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
|
+
};
|
|
2464
2722
|
|
|
2465
2723
|
// packages/parser/src/parser/rules/block/blockquote/lines.ts
|
|
2466
2724
|
function collectBlockquoteLines(ctx) {
|
|
@@ -2469,16 +2727,90 @@ function collectBlockquoteLines(ctx) {
|
|
|
2469
2727
|
let consumed = 0;
|
|
2470
2728
|
while (pos < ctx.tokens.length) {
|
|
2471
2729
|
const result = parseBlockquoteLine(ctx, pos);
|
|
2472
|
-
if (result.kind === "stop")
|
|
2473
|
-
|
|
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
|
+
}
|
|
2474
2738
|
pos += result.consumed;
|
|
2475
2739
|
consumed += result.consumed;
|
|
2476
2740
|
if (result.kind === "parsed") {
|
|
2477
2741
|
lines.push(result.line);
|
|
2478
2742
|
}
|
|
2479
2743
|
}
|
|
2744
|
+
blankCommentOnlyLines(ctx, lines);
|
|
2480
2745
|
return { lines, consumed };
|
|
2481
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
|
+
}
|
|
2482
2814
|
|
|
2483
2815
|
// packages/parser/src/parser/rules/block/blockquote/index.ts
|
|
2484
2816
|
var blockquoteRule = {
|
|
@@ -2497,9 +2829,9 @@ var blockquoteRule = {
|
|
|
2497
2829
|
}
|
|
2498
2830
|
return { success: false };
|
|
2499
2831
|
}
|
|
2500
|
-
const blockquotes = buildBlockquoteElements(blockquoteLines.lines);
|
|
2832
|
+
const blockquotes = buildBlockquoteElements(ctx, blockquoteLines.lines);
|
|
2501
2833
|
if (blockquotes.length === 0) {
|
|
2502
|
-
return { success:
|
|
2834
|
+
return { success: true, elements: [], consumed: blockquoteLines.consumed };
|
|
2503
2835
|
}
|
|
2504
2836
|
return {
|
|
2505
2837
|
success: true,
|
|
@@ -2594,17 +2926,8 @@ function parseDefinitionItemValue(ctx, startPos) {
|
|
|
2594
2926
|
break;
|
|
2595
2927
|
}
|
|
2596
2928
|
if (token5.type === "NEWLINE") {
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
pos++;
|
|
2600
|
-
consumed++;
|
|
2601
|
-
break;
|
|
2602
|
-
}
|
|
2603
|
-
if (nextToken?.type === "NEWLINE" || !nextToken || nextToken.type === "EOF") {
|
|
2604
|
-
pos++;
|
|
2605
|
-
consumed++;
|
|
2606
|
-
break;
|
|
2607
|
-
}
|
|
2929
|
+
consumed++;
|
|
2930
|
+
break;
|
|
2608
2931
|
}
|
|
2609
2932
|
const inlineCtx = { ...ctx, pos };
|
|
2610
2933
|
const result = parseInlineUntil(inlineCtx, "NEWLINE");
|
|
@@ -2682,14 +3005,10 @@ var definitionListRule = {
|
|
|
2682
3005
|
if (result.items.length === 0) {
|
|
2683
3006
|
return { success: false };
|
|
2684
3007
|
}
|
|
3008
|
+
const items = toDefinitionListItems(result.items.filter((item) => item.value.length > 0));
|
|
2685
3009
|
return {
|
|
2686
3010
|
success: true,
|
|
2687
|
-
elements: [
|
|
2688
|
-
{
|
|
2689
|
-
element: "definition-list",
|
|
2690
|
-
data: toDefinitionListItems(result.items)
|
|
2691
|
-
}
|
|
2692
|
-
],
|
|
3011
|
+
elements: items.length > 0 ? [{ element: "definition-list", data: items }] : [],
|
|
2693
3012
|
consumed: result.consumed
|
|
2694
3013
|
};
|
|
2695
3014
|
}
|
|
@@ -2794,20 +3113,49 @@ var paragraphRule = {
|
|
|
2794
3113
|
}
|
|
2795
3114
|
return {
|
|
2796
3115
|
success: true,
|
|
2797
|
-
elements:
|
|
2798
|
-
{
|
|
2799
|
-
element: "container",
|
|
2800
|
-
data: {
|
|
2801
|
-
type: "paragraph",
|
|
2802
|
-
attributes: {},
|
|
2803
|
-
elements
|
|
2804
|
-
}
|
|
2805
|
-
}
|
|
2806
|
-
],
|
|
3116
|
+
elements: wrapParagraphElements(elements),
|
|
2807
3117
|
consumed: result.consumed
|
|
2808
3118
|
};
|
|
2809
3119
|
}
|
|
2810
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
|
+
}
|
|
2811
3159
|
|
|
2812
3160
|
// packages/parser/src/parser/rules/block/div/close.ts
|
|
2813
3161
|
function isDivClose(ctx) {
|
|
@@ -3173,9 +3521,6 @@ function consumeCodeClose(ctx, startPos, closeNameConsumed) {
|
|
|
3173
3521
|
pos++;
|
|
3174
3522
|
consumed++;
|
|
3175
3523
|
}
|
|
3176
|
-
if (ctx.tokens[pos]?.type === "NEWLINE") {
|
|
3177
|
-
consumed++;
|
|
3178
|
-
}
|
|
3179
3524
|
return consumed;
|
|
3180
3525
|
}
|
|
3181
3526
|
|
|
@@ -3232,16 +3577,13 @@ var codeBlockRule = {
|
|
|
3232
3577
|
name: attrResult.attrs.name ?? null
|
|
3233
3578
|
};
|
|
3234
3579
|
ctx.codeBlocks.push(codeBlockData);
|
|
3235
|
-
|
|
3236
|
-
|
|
3237
|
-
|
|
3238
|
-
|
|
3239
|
-
|
|
3240
|
-
|
|
3241
|
-
|
|
3242
|
-
],
|
|
3243
|
-
consumed
|
|
3244
|
-
};
|
|
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 };
|
|
3245
3587
|
}
|
|
3246
3588
|
};
|
|
3247
3589
|
|
|
@@ -3620,7 +3962,30 @@ function parseTableCell(ctx, startPos, cellStart) {
|
|
|
3620
3962
|
consumed++;
|
|
3621
3963
|
}
|
|
3622
3964
|
const { inlineRules } = ctx;
|
|
3623
|
-
|
|
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
|
+
};
|
|
3624
3989
|
while (pos < ctx.tokens.length) {
|
|
3625
3990
|
const token5 = ctx.tokens[pos];
|
|
3626
3991
|
if (!token5 || token5.type === "NEWLINE" || token5.type === "EOF") {
|
|
@@ -3629,6 +3994,11 @@ function parseTableCell(ctx, startPos, cellStart) {
|
|
|
3629
3994
|
if (isPipeTableToken(token5.type)) {
|
|
3630
3995
|
break;
|
|
3631
3996
|
}
|
|
3997
|
+
if (ctx.scope.tableFormatting?.suppressedClosers.has(pos)) {
|
|
3998
|
+
pos++;
|
|
3999
|
+
consumed++;
|
|
4000
|
+
continue;
|
|
4001
|
+
}
|
|
3632
4002
|
if (tryConsumeUnderscoreLineBreak(ctx, pos, children)) {
|
|
3633
4003
|
pos += 3;
|
|
3634
4004
|
consumed += 3;
|
|
@@ -3688,6 +4058,21 @@ function tryConsumeUnderscoreLineBreak(ctx, pos, children) {
|
|
|
3688
4058
|
|
|
3689
4059
|
// packages/parser/src/parser/rules/block/table/pipe/row.ts
|
|
3690
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
|
+
};
|
|
3691
4076
|
const rows = [];
|
|
3692
4077
|
let pos = startPos;
|
|
3693
4078
|
let consumed = 0;
|
|
@@ -3696,7 +4081,7 @@ function parsePipeTableRows(ctx, startPos) {
|
|
|
3696
4081
|
if (!token5 || !token5.lineStart || !isPipeTableToken(token5.type)) {
|
|
3697
4082
|
break;
|
|
3698
4083
|
}
|
|
3699
|
-
const rowResult = parseTableRow(
|
|
4084
|
+
const rowResult = parseTableRow(tableCtx, pos);
|
|
3700
4085
|
rows.push(rowResult.row);
|
|
3701
4086
|
pos += rowResult.consumed;
|
|
3702
4087
|
consumed += rowResult.consumed;
|
|
@@ -5868,9 +6253,9 @@ function renderListPagesItems(module2, data, compiledTemplate, parse) {
|
|
|
5868
6253
|
continue;
|
|
5869
6254
|
const ctx = {
|
|
5870
6255
|
page,
|
|
5871
|
-
index: i + 1,
|
|
6256
|
+
index: (data.pagination?.offset ?? 0) + i + 1,
|
|
5872
6257
|
total: data.totalCount,
|
|
5873
|
-
limit: module2.limit,
|
|
6258
|
+
limit: data.pagination ? data.pagination.limit : module2.limit,
|
|
5874
6259
|
site: data.site
|
|
5875
6260
|
};
|
|
5876
6261
|
const itemAst = getModuleParseAst(parse(compiledTemplate(ctx)));
|
|
@@ -5887,12 +6272,49 @@ function renderListPagesItems(module2, data, compiledTemplate, parse) {
|
|
|
5887
6272
|
items.push(...itemAst.elements);
|
|
5888
6273
|
}
|
|
5889
6274
|
}
|
|
5890
|
-
return items;
|
|
6275
|
+
return items;
|
|
6276
|
+
}
|
|
6277
|
+
|
|
6278
|
+
// packages/parser/src/parser/rules/block/module/listpages/resolution/pager.ts
|
|
6279
|
+
function createListPagesPager(data) {
|
|
6280
|
+
const pagination = data.pagination;
|
|
6281
|
+
if (!pagination || pagination.totalPages <= 1)
|
|
6282
|
+
return [];
|
|
6283
|
+
const { currentPage, totalPages, urlPath, parameter } = pagination;
|
|
6284
|
+
const pages = new Set([1, totalPages]);
|
|
6285
|
+
for (let page = Math.max(1, currentPage - 2);page <= Math.min(totalPages, currentPage + 2); page++) {
|
|
6286
|
+
pages.add(page);
|
|
6287
|
+
}
|
|
6288
|
+
return [
|
|
6289
|
+
{
|
|
6290
|
+
element: "pager",
|
|
6291
|
+
data: {
|
|
6292
|
+
currentPage,
|
|
6293
|
+
totalPages,
|
|
6294
|
+
pages: [...pages].sort((a, b) => a - b).map((page) => ({
|
|
6295
|
+
page,
|
|
6296
|
+
href: pageUrl(urlPath, parameter, page)
|
|
6297
|
+
}))
|
|
6298
|
+
}
|
|
6299
|
+
}
|
|
6300
|
+
];
|
|
6301
|
+
}
|
|
6302
|
+
function pageUrl(urlPath, parameter, page) {
|
|
6303
|
+
const suffixStart = urlPath.search(/[?#]/);
|
|
6304
|
+
const path = suffixStart === -1 ? urlPath : urlPath.slice(0, suffixStart);
|
|
6305
|
+
const suffix = suffixStart === -1 ? "" : urlPath.slice(suffixStart);
|
|
6306
|
+
const parts = path.split("/");
|
|
6307
|
+
const result = parts.slice(0, 2);
|
|
6308
|
+
for (let index = 2;index < parts.length; index += 2) {
|
|
6309
|
+
if (parts[index] !== parameter)
|
|
6310
|
+
result.push(...parts.slice(index, index + 2));
|
|
6311
|
+
}
|
|
6312
|
+
return `${result.join("/").replace(/\/$/, "")}/${parameter}/${page}${suffix}`;
|
|
5891
6313
|
}
|
|
5892
6314
|
|
|
5893
6315
|
// packages/parser/src/parser/rules/block/module/listpages/resolution/wrapper.ts
|
|
5894
|
-
function wrapListPagesResult(module2, items, parse) {
|
|
5895
|
-
if (items.length === 0) {
|
|
6316
|
+
function wrapListPagesResult(module2, items, parse, data) {
|
|
6317
|
+
if (items.length === 0 && (!data || data.pages.length === 0)) {
|
|
5896
6318
|
return [];
|
|
5897
6319
|
}
|
|
5898
6320
|
const result = [];
|
|
@@ -5905,6 +6327,8 @@ function wrapListPagesResult(module2, items, parse) {
|
|
|
5905
6327
|
const appendAst = getModuleParseAst(parse(module2["append-line"]));
|
|
5906
6328
|
result.push(...appendAst.elements);
|
|
5907
6329
|
}
|
|
6330
|
+
if (data)
|
|
6331
|
+
result.push(...createListPagesPager(data));
|
|
5908
6332
|
if (module2.wrapper) {
|
|
5909
6333
|
return [
|
|
5910
6334
|
{
|
|
@@ -5926,7 +6350,7 @@ function isListPagesModule2(module2) {
|
|
|
5926
6350
|
}
|
|
5927
6351
|
function resolveListPages(module2, data, compiledTemplate, parse) {
|
|
5928
6352
|
const items = renderListPagesItems(module2, data, compiledTemplate, parse);
|
|
5929
|
-
return wrapListPagesResult(module2, items, parse);
|
|
6353
|
+
return wrapListPagesResult(module2, items, parse, data);
|
|
5930
6354
|
}
|
|
5931
6355
|
// packages/parser/src/parser/rules/block/module/listpages/types/external-data.ts
|
|
5932
6356
|
function definePageData(input) {
|
|
@@ -6023,10 +6447,10 @@ var URL_RESOLVABLE_FIELDS = [
|
|
|
6023
6447
|
];
|
|
6024
6448
|
|
|
6025
6449
|
// packages/parser/src/parser/rules/block/module/listpages/url-resolution/params.ts
|
|
6026
|
-
function parseUrlParams(url) {
|
|
6450
|
+
function parseUrlParams(url, hasPageName = false) {
|
|
6027
6451
|
const params = new Map;
|
|
6028
|
-
const parts = url.split("/").filter(Boolean);
|
|
6029
|
-
const pairStart = isUrlParameter(parts[0]) ? 0 : 1;
|
|
6452
|
+
const parts = url.split(/[?#]/, 1)[0].split("/").filter(Boolean);
|
|
6453
|
+
const pairStart = !hasPageName && isUrlParameter(parts[0]) ? 0 : 1;
|
|
6030
6454
|
for (let i = pairStart;i < parts.length - 1; i += 2) {
|
|
6031
6455
|
const key = parts[i];
|
|
6032
6456
|
const value = parts[i + 1];
|
|
@@ -7124,18 +7548,66 @@ function resolveListUsers(_module, data, compiledTemplate, parse) {
|
|
|
7124
7548
|
return itemAst.elements;
|
|
7125
7549
|
}
|
|
7126
7550
|
// packages/parser/src/parser/rules/block/module/resolution/data-maps.ts
|
|
7127
|
-
async function buildListPagesDataMap(dataProvider, requirements, urlPath) {
|
|
7551
|
+
async function buildListPagesDataMap(dataProvider, requirements, urlPath, paginationState = { nextUnprefixed: 1 }) {
|
|
7128
7552
|
const dataMap = new Map;
|
|
7129
|
-
const urlParams = parseUrlParams(urlPath ?? "");
|
|
7553
|
+
const urlParams = parseUrlParams(urlPath ?? "", true);
|
|
7130
7554
|
for (const req of requirements) {
|
|
7131
7555
|
const normalizedQuery = resolveAndNormalizeQuery(req, urlParams);
|
|
7132
|
-
|
|
7556
|
+
if (!urlPath || !urlPath.startsWith("/") || urlPath.startsWith("//")) {
|
|
7557
|
+
const data2 = await dataProvider.fetchListPages?.(normalizedQuery, req);
|
|
7558
|
+
if (data2)
|
|
7559
|
+
dataMap.set(req.id, data2);
|
|
7560
|
+
continue;
|
|
7561
|
+
}
|
|
7562
|
+
const ordinal = req.urlAttrPrefix ? 0 : paginationState.nextUnprefixed++;
|
|
7563
|
+
const parameter = req.urlAttrPrefix ? `${encodeURIComponent(req.urlAttrPrefix)}_p` : ordinal === 1 ? "p" : `p${ordinal}`;
|
|
7564
|
+
const perPage = Math.min(250, positiveInteger(normalizedQuery.perPage, 20));
|
|
7565
|
+
const baseOffset = positiveInteger(normalizedQuery.offset, 0);
|
|
7566
|
+
const limit = normalizedQuery.limit !== undefined && normalizedQuery.limit >= 0 ? Math.floor(normalizedQuery.limit) : undefined;
|
|
7567
|
+
const rawPage = urlParams.get(parameter) ?? "1";
|
|
7568
|
+
let currentPage = /^\d+$/.test(rawPage) ? positiveInteger(Number(rawPage), 1) : 1;
|
|
7569
|
+
currentPage = Math.min(currentPage, Math.floor((Number.MAX_SAFE_INTEGER - baseOffset) / perPage) + 1);
|
|
7570
|
+
if (limit !== undefined)
|
|
7571
|
+
currentPage = Math.min(currentPage, Math.max(1, Math.ceil(limit / perPage)));
|
|
7572
|
+
const fetchPage = () => {
|
|
7573
|
+
const relativeOffset = (currentPage - 1) * perPage;
|
|
7574
|
+
return dataProvider.fetchListPages?.({
|
|
7575
|
+
...normalizedQuery,
|
|
7576
|
+
offset: baseOffset + relativeOffset,
|
|
7577
|
+
limit: Math.min(perPage, limit === undefined ? perPage : Math.max(0, limit - relativeOffset)),
|
|
7578
|
+
perPage
|
|
7579
|
+
}, req);
|
|
7580
|
+
};
|
|
7581
|
+
let data = await fetchPage();
|
|
7133
7582
|
if (data) {
|
|
7134
|
-
|
|
7583
|
+
const count = Math.min(Math.max(0, data.totalCount - baseOffset), limit ?? Infinity);
|
|
7584
|
+
const totalPages = Math.ceil(count / perPage);
|
|
7585
|
+
const lastPage = Math.max(1, totalPages);
|
|
7586
|
+
if (currentPage > lastPage) {
|
|
7587
|
+
currentPage = lastPage;
|
|
7588
|
+
data = await fetchPage();
|
|
7589
|
+
}
|
|
7590
|
+
if (data)
|
|
7591
|
+
dataMap.set(req.id, {
|
|
7592
|
+
...data,
|
|
7593
|
+
pages: data.pages.slice(0, Math.min(perPage, Math.max(0, count - (currentPage - 1) * perPage))),
|
|
7594
|
+
pagination: {
|
|
7595
|
+
currentPage,
|
|
7596
|
+
perPage,
|
|
7597
|
+
totalPages,
|
|
7598
|
+
offset: baseOffset + (currentPage - 1) * perPage,
|
|
7599
|
+
limit,
|
|
7600
|
+
urlPath,
|
|
7601
|
+
parameter
|
|
7602
|
+
}
|
|
7603
|
+
});
|
|
7135
7604
|
}
|
|
7136
7605
|
}
|
|
7137
7606
|
return dataMap;
|
|
7138
7607
|
}
|
|
7608
|
+
function positiveInteger(value, fallback) {
|
|
7609
|
+
return value !== undefined && Number.isSafeInteger(value) && value > 0 ? value : fallback;
|
|
7610
|
+
}
|
|
7139
7611
|
async function buildListUsersDataMap(dataProvider, requirements) {
|
|
7140
7612
|
const dataMap = new Map;
|
|
7141
7613
|
for (const req of requirements) {
|
|
@@ -9124,6 +9596,8 @@ var embedBlockRule = {
|
|
|
9124
9596
|
name: "embed-block",
|
|
9125
9597
|
startTokens: ["BLOCK_OPEN"],
|
|
9126
9598
|
requiresLineStart: false,
|
|
9599
|
+
preservesPrecedingLineBreak: true,
|
|
9600
|
+
isStartPattern: (ctx, pos) => parseEmbedBlockOpen(ctx, pos) !== null,
|
|
9127
9601
|
parse(ctx) {
|
|
9128
9602
|
const openToken = currentToken(ctx);
|
|
9129
9603
|
if (openToken.type !== "BLOCK_OPEN") {
|
|
@@ -9139,38 +9613,30 @@ var embedBlockRule = {
|
|
|
9139
9613
|
pos += contentResult.consumed;
|
|
9140
9614
|
consumed += contentResult.consumed;
|
|
9141
9615
|
if (!contentResult.foundClose) {
|
|
9142
|
-
ctx.diagnostics.
|
|
9143
|
-
|
|
9144
|
-
|
|
9145
|
-
|
|
9146
|
-
|
|
9147
|
-
|
|
9616
|
+
if (!ctx.diagnostics.some((d) => d.code === "unclosed-block" && d.position === openToken.position))
|
|
9617
|
+
ctx.diagnostics.push({
|
|
9618
|
+
severity: "warning",
|
|
9619
|
+
code: "unclosed-block",
|
|
9620
|
+
message: `Missing closing tag [[/${openResult.blockName}]] for [[${openResult.blockName}]]`,
|
|
9621
|
+
position: openToken.position
|
|
9622
|
+
});
|
|
9148
9623
|
return { success: false };
|
|
9149
9624
|
}
|
|
9150
9625
|
const closeConsumed = consumeEmbedClose(ctx, pos);
|
|
9151
9626
|
pos += closeConsumed;
|
|
9152
9627
|
consumed += closeConsumed;
|
|
9153
|
-
|
|
9154
|
-
|
|
9155
|
-
|
|
9156
|
-
|
|
9157
|
-
|
|
9158
|
-
|
|
9159
|
-
|
|
9160
|
-
|
|
9161
|
-
|
|
9162
|
-
|
|
9163
|
-
|
|
9164
|
-
|
|
9165
|
-
contents: contentResult.contents.trim()
|
|
9166
|
-
}
|
|
9167
|
-
}
|
|
9168
|
-
]
|
|
9169
|
-
}
|
|
9170
|
-
}
|
|
9171
|
-
],
|
|
9172
|
-
consumed
|
|
9173
|
-
};
|
|
9628
|
+
const elements = [
|
|
9629
|
+
{ element: "embed-block", data: { contents: contentResult.contents.trim() } }
|
|
9630
|
+
];
|
|
9631
|
+
if (ctx.scope.inlineEnd === undefined && ctx.tokens[pos]?.type !== "NEWLINE" && ctx.tokens[pos]?.type !== "EOF") {
|
|
9632
|
+
const after = parseInlineUntil({ ...ctx, pos }, "PARAGRAPH_BREAK");
|
|
9633
|
+
const tail = normalizeParagraphElements(after.elements);
|
|
9634
|
+
if (tail[0]?.element === "text")
|
|
9635
|
+
tail[0].data = tail[0].data.trimStart();
|
|
9636
|
+
elements.push(...tail);
|
|
9637
|
+
consumed += after.consumed;
|
|
9638
|
+
}
|
|
9639
|
+
return { success: true, elements, consumed };
|
|
9174
9640
|
}
|
|
9175
9641
|
};
|
|
9176
9642
|
|
|
@@ -9484,11 +9950,11 @@ var iftagsRule = {
|
|
|
9484
9950
|
};
|
|
9485
9951
|
|
|
9486
9952
|
// packages/parser/src/parser/rules/block/toc/element.ts
|
|
9487
|
-
function createTocElement(align) {
|
|
9953
|
+
function createTocElement(align, title) {
|
|
9488
9954
|
return {
|
|
9489
9955
|
element: "table-of-contents",
|
|
9490
9956
|
data: {
|
|
9491
|
-
attributes: {},
|
|
9957
|
+
attributes: title === undefined ? {} : { title },
|
|
9492
9958
|
align
|
|
9493
9959
|
}
|
|
9494
9960
|
};
|
|
@@ -9531,26 +9997,17 @@ function parseTocOpen(ctx, startPos) {
|
|
|
9531
9997
|
} else {
|
|
9532
9998
|
return null;
|
|
9533
9999
|
}
|
|
9534
|
-
|
|
10000
|
+
const attributes = parseAttributes(ctx, pos);
|
|
10001
|
+
pos += attributes.consumed;
|
|
9535
10002
|
if (ctx.tokens[pos]?.type !== "BLOCK_CLOSE") {
|
|
9536
10003
|
return null;
|
|
9537
10004
|
}
|
|
9538
10005
|
return {
|
|
9539
10006
|
align,
|
|
10007
|
+
title: attributes.attrs.title,
|
|
9540
10008
|
consumed: pos + 1 - startPos
|
|
9541
10009
|
};
|
|
9542
10010
|
}
|
|
9543
|
-
function skipUntilClose(ctx, startPos) {
|
|
9544
|
-
let pos = startPos;
|
|
9545
|
-
while (pos < ctx.tokens.length) {
|
|
9546
|
-
const token5 = ctx.tokens[pos];
|
|
9547
|
-
if (!token5 || token5.type === "BLOCK_CLOSE" || token5.type === "NEWLINE" || token5.type === "EOF") {
|
|
9548
|
-
break;
|
|
9549
|
-
}
|
|
9550
|
-
pos++;
|
|
9551
|
-
}
|
|
9552
|
-
return pos;
|
|
9553
|
-
}
|
|
9554
10011
|
function isNameToken(token5) {
|
|
9555
10012
|
return token5?.type === "TEXT" || token5?.type === "IDENTIFIER";
|
|
9556
10013
|
}
|
|
@@ -9574,7 +10031,7 @@ var tocRule = {
|
|
|
9574
10031
|
}
|
|
9575
10032
|
return {
|
|
9576
10033
|
success: true,
|
|
9577
|
-
elements: [createTocElement(openResult.align)],
|
|
10034
|
+
elements: [createTocElement(openResult.align, openResult.title)],
|
|
9578
10035
|
consumed: openResult.consumed
|
|
9579
10036
|
};
|
|
9580
10037
|
}
|
|
@@ -10175,6 +10632,31 @@ var blockRules = [
|
|
|
10175
10632
|
galleryRule,
|
|
10176
10633
|
divRule
|
|
10177
10634
|
];
|
|
10635
|
+
// packages/parser/src/parser/rules/inline/formatting/close.ts
|
|
10636
|
+
function findFormattingClose(ctx, start, marker) {
|
|
10637
|
+
const table = ctx.scope.tableFormatting;
|
|
10638
|
+
const end = table?.end ?? ctx.scope.inlineEnd ?? ctx.tokens.length;
|
|
10639
|
+
for (let pos = start;pos < end; pos++) {
|
|
10640
|
+
const token5 = ctx.tokens[pos];
|
|
10641
|
+
if (!token5 || token5.type === "EOF" || ctx.scope.blockCloseCondition?.({ ...ctx, pos }))
|
|
10642
|
+
return null;
|
|
10643
|
+
if (!table && token5.type === "NEWLINE" && getParagraphNewlineBoundary(ctx, pos, true).shouldBreak)
|
|
10644
|
+
return null;
|
|
10645
|
+
if (token5.type === marker && !table?.suppressedClosers.has(pos))
|
|
10646
|
+
return pos;
|
|
10647
|
+
const protectedEnd = protectedInlineRegionEnd(ctx.tokens, pos, end);
|
|
10648
|
+
if (protectedEnd > pos)
|
|
10649
|
+
pos = protectedEnd - 1;
|
|
10650
|
+
}
|
|
10651
|
+
return null;
|
|
10652
|
+
}
|
|
10653
|
+
function consumeFormattingClose(ctx, close, contentEnd) {
|
|
10654
|
+
if (close === contentEnd)
|
|
10655
|
+
return 1;
|
|
10656
|
+
ctx.scope.tableFormatting?.suppressedClosers.add(close);
|
|
10657
|
+
return 0;
|
|
10658
|
+
}
|
|
10659
|
+
|
|
10178
10660
|
// packages/parser/src/parser/rules/inline/formatting/container.ts
|
|
10179
10661
|
function createInlineContainer(type, elements) {
|
|
10180
10662
|
return {
|
|
@@ -10186,9 +10668,10 @@ function createInlineContainer(type, elements) {
|
|
|
10186
10668
|
}
|
|
10187
10669
|
};
|
|
10188
10670
|
}
|
|
10189
|
-
function
|
|
10671
|
+
function parseDelimitedContainer(ctx, closeToken, type, options = {}) {
|
|
10190
10672
|
const startToken = currentToken(ctx);
|
|
10191
|
-
|
|
10673
|
+
const close = findFormattingClose(ctx, ctx.pos + 1, closeToken);
|
|
10674
|
+
if (close === null) {
|
|
10192
10675
|
return {
|
|
10193
10676
|
success: true,
|
|
10194
10677
|
elements: [{ element: "text", data: startToken.value }],
|
|
@@ -10196,7 +10679,7 @@ function parseSameLineDelimitedContainer(ctx, closeToken, type, options = {}) {
|
|
|
10196
10679
|
};
|
|
10197
10680
|
}
|
|
10198
10681
|
const result = parseInlineUntil({ ...ctx, pos: ctx.pos + 1 }, closeToken);
|
|
10199
|
-
const consumed = 1 + result.consumed + 1;
|
|
10682
|
+
const consumed = 1 + result.consumed + consumeFormattingClose(ctx, close, ctx.pos + 1 + result.consumed);
|
|
10200
10683
|
if (options.discardEmpty === true && result.elements.length === 0) {
|
|
10201
10684
|
return {
|
|
10202
10685
|
success: true,
|
|
@@ -10216,7 +10699,7 @@ var boldRule = {
|
|
|
10216
10699
|
name: "bold",
|
|
10217
10700
|
startTokens: ["BOLD_MARKER"],
|
|
10218
10701
|
parse(ctx) {
|
|
10219
|
-
return
|
|
10702
|
+
return parseDelimitedContainer(ctx, "BOLD_MARKER", "bold", { discardEmpty: true });
|
|
10220
10703
|
}
|
|
10221
10704
|
};
|
|
10222
10705
|
|
|
@@ -10225,102 +10708,28 @@ var italicRule = {
|
|
|
10225
10708
|
name: "italic",
|
|
10226
10709
|
startTokens: ["ITALIC_MARKER"],
|
|
10227
10710
|
parse(ctx) {
|
|
10228
|
-
return
|
|
10711
|
+
return parseDelimitedContainer(ctx, "ITALIC_MARKER", "italics");
|
|
10229
10712
|
}
|
|
10230
10713
|
};
|
|
10231
10714
|
|
|
10232
|
-
// packages/parser/src/parser/rules/inline/underline/child.ts
|
|
10233
|
-
function parseUnderlineChild(ctx, pos) {
|
|
10234
|
-
const token5 = ctx.tokens[pos];
|
|
10235
|
-
if (!token5) {
|
|
10236
|
-
return { elements: [], consumed: 0 };
|
|
10237
|
-
}
|
|
10238
|
-
if (token5.type === "NEWLINE") {
|
|
10239
|
-
return { elements: [{ element: "line-break" }], consumed: 1 };
|
|
10240
|
-
}
|
|
10241
|
-
const result = parseInlineUntil({ ...ctx, pos }, "UNDERLINE_MARKER");
|
|
10242
|
-
if (result.elements.length > 0) {
|
|
10243
|
-
return { elements: result.elements, consumed: result.consumed };
|
|
10244
|
-
}
|
|
10245
|
-
return { elements: [{ element: "text", data: token5.value }], consumed: 1 };
|
|
10246
|
-
}
|
|
10247
|
-
|
|
10248
|
-
// packages/parser/src/parser/rules/inline/underline/content.ts
|
|
10249
|
-
function parseUnderlineContent(ctx, startPos) {
|
|
10250
|
-
const children = [];
|
|
10251
|
-
let pos = startPos;
|
|
10252
|
-
let consumed = 1;
|
|
10253
|
-
while (pos < ctx.tokens.length) {
|
|
10254
|
-
const token5 = ctx.tokens[pos];
|
|
10255
|
-
if (!token5 || token5.type === "EOF")
|
|
10256
|
-
break;
|
|
10257
|
-
if (token5.type === "UNDERLINE_MARKER") {
|
|
10258
|
-
consumed++;
|
|
10259
|
-
break;
|
|
10260
|
-
}
|
|
10261
|
-
const child = parseUnderlineChild(ctx, pos);
|
|
10262
|
-
children.push(...child.elements);
|
|
10263
|
-
pos += child.consumed;
|
|
10264
|
-
consumed += child.consumed;
|
|
10265
|
-
}
|
|
10266
|
-
return { children, consumed };
|
|
10267
|
-
}
|
|
10268
|
-
|
|
10269
10715
|
// packages/parser/src/parser/rules/inline/underline/index.ts
|
|
10270
10716
|
var underlineRule = {
|
|
10271
10717
|
name: "underline",
|
|
10272
10718
|
startTokens: ["UNDERLINE_MARKER"],
|
|
10273
10719
|
parse(ctx) {
|
|
10274
|
-
|
|
10275
|
-
if (!hasClosingMarkerBeforeParagraphBreak({ ...ctx, pos: ctx.pos + 1 }, "UNDERLINE_MARKER")) {
|
|
10276
|
-
return {
|
|
10277
|
-
success: true,
|
|
10278
|
-
elements: [{ element: "text", data: startToken.value }],
|
|
10279
|
-
consumed: 1
|
|
10280
|
-
};
|
|
10281
|
-
}
|
|
10282
|
-
const { children, consumed } = parseUnderlineContent(ctx, ctx.pos + 1);
|
|
10283
|
-
if (children.length === 0) {
|
|
10284
|
-
return {
|
|
10285
|
-
success: true,
|
|
10286
|
-
elements: [],
|
|
10287
|
-
consumed
|
|
10288
|
-
};
|
|
10289
|
-
}
|
|
10290
|
-
return {
|
|
10291
|
-
success: true,
|
|
10292
|
-
elements: [createInlineContainer("underline", children)],
|
|
10293
|
-
consumed
|
|
10294
|
-
};
|
|
10720
|
+
return parseDelimitedContainer(ctx, "UNDERLINE_MARKER", "underline", { discardEmpty: true });
|
|
10295
10721
|
}
|
|
10296
10722
|
};
|
|
10297
10723
|
|
|
10298
10724
|
// packages/parser/src/parser/rules/inline/strikethrough/parse.ts
|
|
10299
10725
|
function parseStrikethroughContent(ctx) {
|
|
10300
|
-
|
|
10301
|
-
return {
|
|
10302
|
-
success: true,
|
|
10303
|
-
elements: [createInlineContainer("strikethrough", result.elements)],
|
|
10304
|
-
consumed: 1 + result.consumed + 1
|
|
10305
|
-
};
|
|
10726
|
+
return parseDelimitedContainer(ctx, "STRIKE_MARKER", "strikethrough");
|
|
10306
10727
|
}
|
|
10307
10728
|
|
|
10308
10729
|
// packages/parser/src/parser/rules/inline/strikethrough/syntax.ts
|
|
10309
10730
|
function hasValidStrikethroughClose(ctx) {
|
|
10310
|
-
|
|
10311
|
-
|
|
10312
|
-
while (pos < ctx.tokens.length) {
|
|
10313
|
-
const token5 = ctx.tokens[pos];
|
|
10314
|
-
if (!token5 || token5.type === "NEWLINE" || token5.type === "EOF") {
|
|
10315
|
-
return false;
|
|
10316
|
-
}
|
|
10317
|
-
if (token5.type === "STRIKE_MARKER") {
|
|
10318
|
-
return !prevWasWhitespace;
|
|
10319
|
-
}
|
|
10320
|
-
prevWasWhitespace = token5.type === "WHITESPACE";
|
|
10321
|
-
pos++;
|
|
10322
|
-
}
|
|
10323
|
-
return false;
|
|
10731
|
+
const close = findFormattingClose(ctx, ctx.pos + 1, "STRIKE_MARKER");
|
|
10732
|
+
return close !== null && close > ctx.pos + 1 && ctx.tokens[close - 1]?.type !== "WHITESPACE";
|
|
10324
10733
|
}
|
|
10325
10734
|
|
|
10326
10735
|
// packages/parser/src/parser/rules/inline/strikethrough/index.ts
|
|
@@ -10344,7 +10753,7 @@ var superscriptRule = {
|
|
|
10344
10753
|
name: "superscript",
|
|
10345
10754
|
startTokens: ["SUPER_MARKER"],
|
|
10346
10755
|
parse(ctx) {
|
|
10347
|
-
return
|
|
10756
|
+
return parseDelimitedContainer(ctx, "SUPER_MARKER", "superscript", {
|
|
10348
10757
|
discardEmpty: true
|
|
10349
10758
|
});
|
|
10350
10759
|
}
|
|
@@ -10355,7 +10764,7 @@ var subscriptRule = {
|
|
|
10355
10764
|
name: "subscript",
|
|
10356
10765
|
startTokens: ["SUB_MARKER"],
|
|
10357
10766
|
parse(ctx) {
|
|
10358
|
-
return
|
|
10767
|
+
return parseDelimitedContainer(ctx, "SUB_MARKER", "subscript", { discardEmpty: true });
|
|
10359
10768
|
}
|
|
10360
10769
|
};
|
|
10361
10770
|
|
|
@@ -10364,7 +10773,7 @@ var monospaceRule = {
|
|
|
10364
10773
|
name: "monospace",
|
|
10365
10774
|
startTokens: ["MONO_MARKER"],
|
|
10366
10775
|
parse(ctx) {
|
|
10367
|
-
return
|
|
10776
|
+
return parseDelimitedContainer(ctx, "MONO_CLOSE", "monospace");
|
|
10368
10777
|
}
|
|
10369
10778
|
};
|
|
10370
10779
|
|
|
@@ -10725,13 +11134,14 @@ var linkStarRule = {
|
|
|
10725
11134
|
|
|
10726
11135
|
// packages/parser/src/parser/rules/inline/color/syntax.ts
|
|
10727
11136
|
function parseColorContent(ctx) {
|
|
10728
|
-
|
|
11137
|
+
const close = findFormattingClose(ctx, ctx.pos + 1, "COLOR_MARKER");
|
|
11138
|
+
if (close === null) {
|
|
10729
11139
|
return null;
|
|
10730
11140
|
}
|
|
10731
11141
|
let pos = ctx.pos + 1;
|
|
10732
11142
|
let consumed = 1;
|
|
10733
11143
|
let colorSpec = "";
|
|
10734
|
-
while (pos < ctx.tokens.length) {
|
|
11144
|
+
while (pos < (ctx.scope.inlineEnd ?? ctx.tokens.length)) {
|
|
10735
11145
|
const token5 = ctx.tokens[pos];
|
|
10736
11146
|
if (!token5 || token5.type === "PIPE" || token5.type === "COLOR_MARKER" || token5.type === "NEWLINE" || token5.type === "EOF") {
|
|
10737
11147
|
break;
|
|
@@ -10748,14 +11158,11 @@ function parseColorContent(ctx) {
|
|
|
10748
11158
|
const contentResult = parseInlineUntil({ ...ctx, pos }, "COLOR_MARKER");
|
|
10749
11159
|
pos += contentResult.consumed;
|
|
10750
11160
|
consumed += contentResult.consumed;
|
|
10751
|
-
if (ctx.tokens[pos]?.type !== "COLOR_MARKER") {
|
|
10752
|
-
return null;
|
|
10753
|
-
}
|
|
10754
|
-
consumed++;
|
|
10755
11161
|
const color = colorSpec.trim();
|
|
10756
11162
|
if (color === "" || contentResult.elements.length === 0) {
|
|
10757
11163
|
return null;
|
|
10758
11164
|
}
|
|
11165
|
+
consumed += consumeFormattingClose(ctx, close, pos);
|
|
10759
11166
|
return {
|
|
10760
11167
|
color: hexifyColor(color),
|
|
10761
11168
|
elements: contentResult.elements,
|
|
@@ -11378,14 +11785,19 @@ function parseSpanContent(ctx, startPos, blockName) {
|
|
|
11378
11785
|
const escapedChildren = [];
|
|
11379
11786
|
const splitSpans = [];
|
|
11380
11787
|
let foundClose = false;
|
|
11788
|
+
let forcedClose = false;
|
|
11381
11789
|
let afterBlankLine = false;
|
|
11382
11790
|
let consumed = 0;
|
|
11383
11791
|
let pos = startPos;
|
|
11384
|
-
while (pos < ctx.tokens.length) {
|
|
11792
|
+
while (pos < (ctx.scope.inlineEnd ?? ctx.tokens.length)) {
|
|
11385
11793
|
const token5 = ctx.tokens[pos];
|
|
11386
11794
|
if (!token5 || token5.type === "EOF") {
|
|
11387
11795
|
break;
|
|
11388
11796
|
}
|
|
11797
|
+
if (ctx.scope.tableFormatting?.suppressedClosers.has(pos)) {
|
|
11798
|
+
forcedClose = true;
|
|
11799
|
+
break;
|
|
11800
|
+
}
|
|
11389
11801
|
const close = parseCloseSpan(ctx, pos);
|
|
11390
11802
|
if (close.success) {
|
|
11391
11803
|
pos += close.consumed;
|
|
@@ -11410,6 +11822,29 @@ function parseSpanContent(ctx, startPos, blockName) {
|
|
|
11410
11822
|
pos += parsed.consumed;
|
|
11411
11823
|
consumed += parsed.consumed;
|
|
11412
11824
|
}
|
|
11825
|
+
if (!foundClose && ctx.scope.tableFormatting && (pos === ctx.scope.inlineEnd || forcedClose)) {
|
|
11826
|
+
let depth = 0;
|
|
11827
|
+
for (let next = pos;next < ctx.scope.tableFormatting.end; next++) {
|
|
11828
|
+
const rawEnd = rawRegionEnd(ctx.tokens, next, ctx.scope.tableFormatting.end);
|
|
11829
|
+
if (rawEnd > next) {
|
|
11830
|
+
next = rawEnd - 1;
|
|
11831
|
+
continue;
|
|
11832
|
+
}
|
|
11833
|
+
if (ctx.tokens[next]?.type === "BLOCK_OPEN" && /^span_?$/i.test(ctx.tokens[next + 1]?.value ?? ""))
|
|
11834
|
+
depth++;
|
|
11835
|
+
const close = parseCloseSpan(ctx, next);
|
|
11836
|
+
if (!close.success)
|
|
11837
|
+
continue;
|
|
11838
|
+
if (depth > 0) {
|
|
11839
|
+
depth--;
|
|
11840
|
+
continue;
|
|
11841
|
+
}
|
|
11842
|
+
for (let offset = 0;offset < close.consumed; offset++)
|
|
11843
|
+
ctx.scope.tableFormatting.suppressedClosers.add(next + offset);
|
|
11844
|
+
foundClose = true;
|
|
11845
|
+
break;
|
|
11846
|
+
}
|
|
11847
|
+
}
|
|
11413
11848
|
return { children, escapedChildren, splitSpans, consumed, foundClose };
|
|
11414
11849
|
}
|
|
11415
11850
|
function parseOneSpanChild(ctx, pos, targetChildren) {
|
|
@@ -11821,135 +12256,6 @@ var footnoteRule = {
|
|
|
11821
12256
|
}
|
|
11822
12257
|
};
|
|
11823
12258
|
|
|
11824
|
-
// packages/parser/src/parser/rules/inline/image/attributes.ts
|
|
11825
|
-
function parseImageAttributes(ctx, startPos) {
|
|
11826
|
-
const result = parseAttributesRaw(ctx, startPos, false);
|
|
11827
|
-
const link = result.attrs.link ?? null;
|
|
11828
|
-
const { link: _link, ...htmlAttributes } = result.attrs;
|
|
11829
|
-
return {
|
|
11830
|
-
attributes: filterUnsafeAttributes(htmlAttributes),
|
|
11831
|
-
link,
|
|
11832
|
-
consumed: result.consumed
|
|
11833
|
-
};
|
|
11834
|
-
}
|
|
11835
|
-
|
|
11836
|
-
// packages/parser/src/parser/rules/inline/image/body.ts
|
|
11837
|
-
function parseImageSourceText(ctx, startPos) {
|
|
11838
|
-
let pos = startPos;
|
|
11839
|
-
let consumed = 0;
|
|
11840
|
-
while (ctx.tokens[pos]?.type === "WHITESPACE") {
|
|
11841
|
-
pos++;
|
|
11842
|
-
consumed++;
|
|
11843
|
-
}
|
|
11844
|
-
let sourceText = "";
|
|
11845
|
-
while (pos < ctx.tokens.length) {
|
|
11846
|
-
const token5 = ctx.tokens[pos];
|
|
11847
|
-
if (!token5 || token5.type === "WHITESPACE" || token5.type === "BLOCK_CLOSE" || token5.type === "NEWLINE" || token5.type === "EOF") {
|
|
11848
|
-
break;
|
|
11849
|
-
}
|
|
11850
|
-
sourceText += token5.value;
|
|
11851
|
-
pos++;
|
|
11852
|
-
consumed++;
|
|
11853
|
-
}
|
|
11854
|
-
return { sourceText, consumed };
|
|
11855
|
-
}
|
|
11856
|
-
|
|
11857
|
-
// packages/parser/src/parser/rules/inline/image/syntax.ts
|
|
11858
|
-
var IMAGE_BLOCK_NAMES = new Set([
|
|
11859
|
-
"image",
|
|
11860
|
-
"=image",
|
|
11861
|
-
"<image",
|
|
11862
|
-
">image",
|
|
11863
|
-
"f<image",
|
|
11864
|
-
"f>image",
|
|
11865
|
-
"f=image"
|
|
11866
|
-
]);
|
|
11867
|
-
function parseImageBlockName(ctx, startPos) {
|
|
11868
|
-
let pos = startPos;
|
|
11869
|
-
let consumed = 0;
|
|
11870
|
-
while (ctx.tokens[pos]?.type === "WHITESPACE") {
|
|
11871
|
-
pos++;
|
|
11872
|
-
consumed++;
|
|
11873
|
-
}
|
|
11874
|
-
const prefixResult = parseImagePrefix(ctx, pos);
|
|
11875
|
-
const prefix = prefixResult.prefix;
|
|
11876
|
-
pos += prefixResult.consumed;
|
|
11877
|
-
consumed += prefixResult.consumed;
|
|
11878
|
-
const nameToken = ctx.tokens[pos];
|
|
11879
|
-
if (!nameToken || nameToken.type !== "TEXT" && nameToken.type !== "IDENTIFIER") {
|
|
11880
|
-
return null;
|
|
11881
|
-
}
|
|
11882
|
-
return { name: prefix + nameToken.value.toLowerCase(), consumed: consumed + 1 };
|
|
11883
|
-
}
|
|
11884
|
-
function isImageBlockName(blockName) {
|
|
11885
|
-
return IMAGE_BLOCK_NAMES.has(blockName);
|
|
11886
|
-
}
|
|
11887
|
-
function parseImagePrefix(ctx, pos) {
|
|
11888
|
-
const token5 = ctx.tokens[pos];
|
|
11889
|
-
if (token5?.type === "EQUALS") {
|
|
11890
|
-
return { prefix: "=", consumed: 1 };
|
|
11891
|
-
}
|
|
11892
|
-
if (token5?.type === "TEXT" && token5.value === "<") {
|
|
11893
|
-
return { prefix: "<", consumed: 1 };
|
|
11894
|
-
}
|
|
11895
|
-
if ((token5?.type === "TEXT" || token5?.type === "BLOCKQUOTE_MARKER") && token5.value === ">") {
|
|
11896
|
-
return { prefix: ">", consumed: 1 };
|
|
11897
|
-
}
|
|
11898
|
-
if (token5?.type === "IDENTIFIER" && token5.value.toLowerCase() === "f") {
|
|
11899
|
-
return parseFloatPrefix(ctx, pos + 1);
|
|
11900
|
-
}
|
|
11901
|
-
return { prefix: "", consumed: 0 };
|
|
11902
|
-
}
|
|
11903
|
-
function parseFloatPrefix(ctx, pos) {
|
|
11904
|
-
const token5 = ctx.tokens[pos];
|
|
11905
|
-
if (token5?.type === "TEXT" && token5.value === "<") {
|
|
11906
|
-
return { prefix: "f<", consumed: 2 };
|
|
11907
|
-
}
|
|
11908
|
-
if ((token5?.type === "TEXT" || token5?.type === "BLOCKQUOTE_MARKER") && token5.value === ">") {
|
|
11909
|
-
return { prefix: "f>", consumed: 2 };
|
|
11910
|
-
}
|
|
11911
|
-
if (token5?.type === "EQUALS") {
|
|
11912
|
-
return { prefix: "f=", consumed: 2 };
|
|
11913
|
-
}
|
|
11914
|
-
return { prefix: "", consumed: 0 };
|
|
11915
|
-
}
|
|
11916
|
-
|
|
11917
|
-
// packages/parser/src/parser/rules/inline/image/open.ts
|
|
11918
|
-
function parseImageOpen(ctx) {
|
|
11919
|
-
if (ctx.tokens[ctx.pos]?.type !== "BLOCK_OPEN") {
|
|
11920
|
-
return null;
|
|
11921
|
-
}
|
|
11922
|
-
let pos = ctx.pos + 1;
|
|
11923
|
-
let consumed = 1;
|
|
11924
|
-
const nameResult = parseImageBlockName(ctx, pos);
|
|
11925
|
-
if (!nameResult || !isImageBlockName(nameResult.name)) {
|
|
11926
|
-
return null;
|
|
11927
|
-
}
|
|
11928
|
-
pos += nameResult.consumed;
|
|
11929
|
-
consumed += nameResult.consumed;
|
|
11930
|
-
const sourceText = parseImageSourceText(ctx, pos);
|
|
11931
|
-
pos += sourceText.consumed;
|
|
11932
|
-
consumed += sourceText.consumed;
|
|
11933
|
-
const attrs = parseImageAttributes(ctx, pos);
|
|
11934
|
-
pos += attrs.consumed;
|
|
11935
|
-
consumed += attrs.consumed;
|
|
11936
|
-
if (ctx.tokens[pos]?.type !== "BLOCK_CLOSE") {
|
|
11937
|
-
return null;
|
|
11938
|
-
}
|
|
11939
|
-
pos++;
|
|
11940
|
-
consumed++;
|
|
11941
|
-
if (!sourceText.sourceText) {
|
|
11942
|
-
return null;
|
|
11943
|
-
}
|
|
11944
|
-
return {
|
|
11945
|
-
blockName: nameResult.name,
|
|
11946
|
-
sourceText: sourceText.sourceText,
|
|
11947
|
-
link: attrs.link,
|
|
11948
|
-
attributes: attrs.attributes,
|
|
11949
|
-
consumed
|
|
11950
|
-
};
|
|
11951
|
-
}
|
|
11952
|
-
|
|
11953
12259
|
// packages/parser/src/parser/rules/inline/image/source.ts
|
|
11954
12260
|
function parseImageSource(src) {
|
|
11955
12261
|
if (src.startsWith("http://") || src.startsWith("https://") || src.startsWith("/")) {
|
|
@@ -13000,6 +13306,7 @@ var inlineRules = [
|
|
|
13000
13306
|
htmlInlineRule,
|
|
13001
13307
|
rawRule,
|
|
13002
13308
|
imageRule,
|
|
13309
|
+
embedBlockRule,
|
|
13003
13310
|
sizeRule,
|
|
13004
13311
|
footnoteRule,
|
|
13005
13312
|
spanRule,
|
|
@@ -14168,7 +14475,7 @@ async function resolveModulesWithAsyncParse(ast, dataProvider, options) {
|
|
|
14168
14475
|
registry.register(ast);
|
|
14169
14476
|
const parse2 = async (source) => registry.register(await options.parse(source));
|
|
14170
14477
|
const [listPagesData, listUsersData, tagCloudData] = await Promise.all([
|
|
14171
|
-
buildListPagesDataMap(dataProvider, options.requirements.listPages ?? [], options.urlPath),
|
|
14478
|
+
buildListPagesDataMap(dataProvider, options.requirements.listPages ?? [], options.urlPath, options.paginationState),
|
|
14172
14479
|
buildListUsersDataMap(dataProvider, options.requirements.listUsers ?? []),
|
|
14173
14480
|
buildTagCloudDataMap(dataProvider, options.requirements.tagCloud ?? [])
|
|
14174
14481
|
]);
|
|
@@ -14256,9 +14563,9 @@ async function resolveListPagesAsync(module2, data, template, parse2) {
|
|
|
14256
14563
|
continue;
|
|
14257
14564
|
const variableContext = {
|
|
14258
14565
|
page,
|
|
14259
|
-
index: i + 1,
|
|
14566
|
+
index: (data.pagination?.offset ?? 0) + i + 1,
|
|
14260
14567
|
total: data.totalCount,
|
|
14261
|
-
limit: module2.limit,
|
|
14568
|
+
limit: data.pagination ? data.pagination.limit : module2.limit,
|
|
14262
14569
|
site: data.site
|
|
14263
14570
|
};
|
|
14264
14571
|
const parsed = await parse2(template(variableContext));
|
|
@@ -14278,6 +14585,7 @@ async function resolveListPagesAsync(module2, data, template, parse2) {
|
|
|
14278
14585
|
if (module2["append-line"] && !module2.separate) {
|
|
14279
14586
|
result.push(...(await parse2(module2["append-line"])).elements);
|
|
14280
14587
|
}
|
|
14588
|
+
result.push(...createListPagesPager(data));
|
|
14281
14589
|
return module2.wrapper ? [
|
|
14282
14590
|
{
|
|
14283
14591
|
element: "container",
|
|
@@ -14378,6 +14686,9 @@ async function processWikitext(source, options) {
|
|
|
14378
14686
|
const dataProvider = createModuleDataProvider(options, callbackContext);
|
|
14379
14687
|
const parseFragment = parseSource2;
|
|
14380
14688
|
let ast = initial.ast;
|
|
14689
|
+
const paginationState = { nextUnprefixed: 1 };
|
|
14690
|
+
const requestedPath = options.page.urlPath;
|
|
14691
|
+
const urlPath = !requestedPath || /^\/(?:[?#]|$)/.test(requestedPath) ? `/${options.page.fullName}${requestedPath?.slice(1) ?? ""}` : requestedPath;
|
|
14381
14692
|
for (let pass = 0;pass < DEFAULT_MODULE_MAX_PASSES; pass++) {
|
|
14382
14693
|
const extraction = extractDataRequirements(ast);
|
|
14383
14694
|
if (pass > 0 && !hasResolvableRequirements(extraction.requirements, options.dataProvider)) {
|
|
@@ -14388,7 +14699,8 @@ async function processWikitext(source, options) {
|
|
|
14388
14699
|
compiledListPagesTemplates: extraction.compiledListPagesTemplates,
|
|
14389
14700
|
compiledListUsersTemplates: extraction.compiledListUsersTemplates,
|
|
14390
14701
|
requirements: extraction.requirements,
|
|
14391
|
-
urlPath
|
|
14702
|
+
urlPath,
|
|
14703
|
+
paginationState,
|
|
14392
14704
|
pageTags: options.page.tags
|
|
14393
14705
|
});
|
|
14394
14706
|
ast = resolved.ast;
|