@wdprlib/parser 4.3.0 → 5.0.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/README.md +26 -38
- package/dist/index.cjs +1035 -249
- package/dist/index.d.cts +203 -158
- package/dist/index.d.ts +203 -158
- package/dist/index.js +930 -139
- package/package.json +2 -2
- package/src/index.ts +13 -0
- package/src/parser/parse/context.ts +1 -0
- package/src/parser/parse/options.ts +6 -0
- package/src/parser/parse/result.ts +3 -1
- package/src/parser/preprocess/expr/index.ts +26 -0
- package/src/parser/preprocess/utils/raw-regions.ts +16 -7
- package/src/parser/rules/block/module/include/index.ts +6 -1
- package/src/parser/rules/block/module/include/resolve/index.ts +23 -3
- package/src/parser/rules/block/module/include/resolve/iterate.ts +71 -0
- package/src/parser/rules/block/module/index.ts +4 -1
- package/src/parser/rules/block/module/listpages/index.ts +2 -0
- package/src/parser/rules/block/module/listpages/resolution/items.ts +2 -2
- package/src/parser/rules/block/module/listpages/resolution/wrapper.ts +3 -3
- package/src/parser/rules/block/module/listpages/selectors.ts +64 -0
- package/src/parser/rules/block/module/listpages/types/external-data.ts +22 -0
- package/src/parser/rules/block/module/listusers/resolve.ts +2 -2
- package/src/parser/rules/block/module/resolution/document.ts +357 -0
- package/src/parser/rules/block/module/resolution/resolve-async.ts +269 -0
- package/src/parser/rules/block/module/resolution/styles.ts +134 -12
- package/src/parser/rules/block/module/resolution/walk-resolve.ts +19 -1
- package/src/parser/rules/block/module/resolve.ts +32 -13
- package/src/parser/rules/block/module/types.ts +7 -2
- package/src/parser/rules/contracts/parse-context.ts +1 -0
- package/src/pipeline/index.ts +7 -0
- package/src/pipeline/process.ts +172 -0
- package/src/pipeline/types.ts +63 -0
package/dist/index.js
CHANGED
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
listItemElements,
|
|
16
16
|
listItemSubList
|
|
17
17
|
} from "@wdprlib/ast";
|
|
18
|
-
import { createSettings, DEFAULT_SETTINGS as
|
|
18
|
+
import { createSettings, DEFAULT_SETTINGS as DEFAULT_SETTINGS3 } from "@wdprlib/ast";
|
|
19
19
|
|
|
20
20
|
// packages/parser/src/lexer/tokens.ts
|
|
21
21
|
function createToken(type, value, position, lineStart = false) {
|
|
@@ -5782,6 +5782,11 @@ function extractDataRequirements(ast) {
|
|
|
5782
5782
|
});
|
|
5783
5783
|
return result;
|
|
5784
5784
|
}
|
|
5785
|
+
// packages/parser/src/parser/rules/block/module/types.ts
|
|
5786
|
+
function getModuleParseAst(result) {
|
|
5787
|
+
return "ast" in result ? result.ast : result;
|
|
5788
|
+
}
|
|
5789
|
+
|
|
5785
5790
|
// packages/parser/src/parser/rules/block/module/listpages/resolution/items.ts
|
|
5786
5791
|
function renderListPagesItems(module, data, compiledTemplate, parse) {
|
|
5787
5792
|
const items = [];
|
|
@@ -5796,7 +5801,7 @@ function renderListPagesItems(module, data, compiledTemplate, parse) {
|
|
|
5796
5801
|
limit: module.limit,
|
|
5797
5802
|
site: data.site
|
|
5798
5803
|
};
|
|
5799
|
-
const itemAst = parse(compiledTemplate(ctx));
|
|
5804
|
+
const itemAst = getModuleParseAst(parse(compiledTemplate(ctx)));
|
|
5800
5805
|
if (module.separate) {
|
|
5801
5806
|
items.push({
|
|
5802
5807
|
element: "container",
|
|
@@ -5820,12 +5825,12 @@ function wrapListPagesResult(module, items, parse) {
|
|
|
5820
5825
|
}
|
|
5821
5826
|
const result = [];
|
|
5822
5827
|
if (module["prepend-line"] && !module.separate) {
|
|
5823
|
-
const prependAst = parse(module["prepend-line"]);
|
|
5828
|
+
const prependAst = getModuleParseAst(parse(module["prepend-line"]));
|
|
5824
5829
|
result.push(...prependAst.elements);
|
|
5825
5830
|
}
|
|
5826
5831
|
result.push(...items);
|
|
5827
5832
|
if (module["append-line"] && !module.separate) {
|
|
5828
|
-
const appendAst = parse(module["append-line"]);
|
|
5833
|
+
const appendAst = getModuleParseAst(parse(module["append-line"]));
|
|
5829
5834
|
result.push(...appendAst.elements);
|
|
5830
5835
|
}
|
|
5831
5836
|
if (module.wrapper) {
|
|
@@ -5851,6 +5856,60 @@ function resolveListPages(module, data, compiledTemplate, parse) {
|
|
|
5851
5856
|
const items = renderListPagesItems(module, data, compiledTemplate, parse);
|
|
5852
5857
|
return wrapListPagesResult(module, items, parse);
|
|
5853
5858
|
}
|
|
5859
|
+
// packages/parser/src/parser/rules/block/module/listpages/types/external-data.ts
|
|
5860
|
+
function definePageData(input) {
|
|
5861
|
+
const separator = input.fullname.indexOf(":");
|
|
5862
|
+
const category = separator === -1 ? "_default" : input.fullname.slice(0, separator);
|
|
5863
|
+
const name = separator === -1 ? input.fullname : input.fullname.slice(separator + 1);
|
|
5864
|
+
return {
|
|
5865
|
+
...input,
|
|
5866
|
+
name: input.name ?? name,
|
|
5867
|
+
category: input.category ?? category,
|
|
5868
|
+
hiddenTags: input.hiddenTags ?? [],
|
|
5869
|
+
children: input.children ?? 0,
|
|
5870
|
+
comments: input.comments ?? 0,
|
|
5871
|
+
size: input.size ?? 0,
|
|
5872
|
+
rating: input.rating ?? 0,
|
|
5873
|
+
ratingVotes: input.ratingVotes ?? 0,
|
|
5874
|
+
revisions: input.revisions ?? 0
|
|
5875
|
+
};
|
|
5876
|
+
}
|
|
5877
|
+
// packages/parser/src/parser/rules/block/module/listpages/selectors.ts
|
|
5878
|
+
function matchesListPagesSelectors(page, query, currentPage) {
|
|
5879
|
+
return matchesCategory(page.category, query.category, currentPage.category) && matchesTags(page, query.tags, currentPage);
|
|
5880
|
+
}
|
|
5881
|
+
function matchesCategory(category, selector, currentCategory) {
|
|
5882
|
+
if (!selector)
|
|
5883
|
+
return category === currentCategory;
|
|
5884
|
+
if (selector.exclude.includes(category))
|
|
5885
|
+
return false;
|
|
5886
|
+
const hasPositiveSelector = selector.all || selector.current || selector.include.length > 0;
|
|
5887
|
+
return !hasPositiveSelector || selector.all || selector.current && category === currentCategory || selector.include.includes(category);
|
|
5888
|
+
}
|
|
5889
|
+
function matchesTags(page, selector, currentPage) {
|
|
5890
|
+
if (!selector)
|
|
5891
|
+
return true;
|
|
5892
|
+
const allTags = new Set([...page.tags, ...page.hiddenTags]);
|
|
5893
|
+
if (selector.all.some((tag) => !allTags.has(tag)))
|
|
5894
|
+
return false;
|
|
5895
|
+
if (selector.any.length > 0 && !selector.any.some((tag) => allTags.has(tag)))
|
|
5896
|
+
return false;
|
|
5897
|
+
if (selector.none.some((tag) => allTags.has(tag)))
|
|
5898
|
+
return false;
|
|
5899
|
+
if (selector.special === "none")
|
|
5900
|
+
return allTags.size === 0;
|
|
5901
|
+
const currentTags = new Set(currentPage.tags.filter((tag) => !tag.startsWith("_")));
|
|
5902
|
+
if (selector.special === "same-visible") {
|
|
5903
|
+
return page.tags.some((tag) => currentTags.has(tag));
|
|
5904
|
+
}
|
|
5905
|
+
if (selector.special === "same-all") {
|
|
5906
|
+
return setsEqual(new Set(page.tags), currentTags);
|
|
5907
|
+
}
|
|
5908
|
+
return true;
|
|
5909
|
+
}
|
|
5910
|
+
function setsEqual(left, right) {
|
|
5911
|
+
return left.size === right.size && [...left].every((value) => right.has(value));
|
|
5912
|
+
}
|
|
5854
5913
|
// packages/parser/src/parser/rules/block/module/listpages/url-resolution/fields.ts
|
|
5855
5914
|
var URL_RESOLVABLE_FIELDS = [
|
|
5856
5915
|
{ attr: "offset", queryKey: "offset", type: "number" },
|
|
@@ -6280,13 +6339,20 @@ var BASE_PLACEHOLDER_OPEN = "";
|
|
|
6280
6339
|
var BASE_PLACEHOLDER_CLOSE = "";
|
|
6281
6340
|
var RAW_BLOCK_OPEN_PATTERN = /\[\[\s*(code|html)\b[^\]]*\]\]/iy;
|
|
6282
6341
|
function makeUniqueSentinels(source) {
|
|
6283
|
-
let
|
|
6284
|
-
let
|
|
6285
|
-
|
|
6286
|
-
|
|
6287
|
-
|
|
6342
|
+
let openRun = 0;
|
|
6343
|
+
let closeRun = 0;
|
|
6344
|
+
let longestOpenRun = 0;
|
|
6345
|
+
let longestCloseRun = 0;
|
|
6346
|
+
for (const char of source) {
|
|
6347
|
+
openRun = char === BASE_PLACEHOLDER_OPEN ? openRun + 1 : 0;
|
|
6348
|
+
closeRun = char === BASE_PLACEHOLDER_CLOSE ? closeRun + 1 : 0;
|
|
6349
|
+
longestOpenRun = Math.max(longestOpenRun, openRun);
|
|
6350
|
+
longestCloseRun = Math.max(longestCloseRun, closeRun);
|
|
6288
6351
|
}
|
|
6289
|
-
return {
|
|
6352
|
+
return {
|
|
6353
|
+
open: BASE_PLACEHOLDER_OPEN.repeat(longestOpenRun + 1),
|
|
6354
|
+
close: BASE_PLACEHOLDER_CLOSE.repeat(longestCloseRun + 1)
|
|
6355
|
+
};
|
|
6290
6356
|
}
|
|
6291
6357
|
function maskRawRegions(source, sentinels) {
|
|
6292
6358
|
const placeholders = [];
|
|
@@ -6744,16 +6810,31 @@ function expandIterativeWithTrace(source, fetcher, maxIterations) {
|
|
|
6744
6810
|
reachedMaxIterations: iterations.length === maxIterations && scanIncludeDirectives(current2).length > 0
|
|
6745
6811
|
};
|
|
6746
6812
|
}
|
|
6747
|
-
async function
|
|
6813
|
+
async function expandIterativeAsyncWithTrace(source, fetcher, maxIterations) {
|
|
6748
6814
|
let current2 = source;
|
|
6749
6815
|
const replacementCache = new Map;
|
|
6816
|
+
const dependencies = [];
|
|
6817
|
+
const iterations = [];
|
|
6750
6818
|
for (let i = 0;i < maxIterations; i++) {
|
|
6751
|
-
const expanded = await
|
|
6752
|
-
if (expanded === null
|
|
6819
|
+
const expanded = await expandOneIterationAsyncWithTrace(current2, fetcher, replacementCache, i);
|
|
6820
|
+
if (expanded === null)
|
|
6753
6821
|
break;
|
|
6754
|
-
|
|
6822
|
+
dependencies.push(...expanded.dependencies);
|
|
6823
|
+
iterations.push({
|
|
6824
|
+
iteration: i,
|
|
6825
|
+
directives: expanded.references,
|
|
6826
|
+
changed: expanded.source !== current2
|
|
6827
|
+
});
|
|
6828
|
+
if (expanded.source === current2)
|
|
6829
|
+
break;
|
|
6830
|
+
current2 = expanded.source;
|
|
6755
6831
|
}
|
|
6756
|
-
return
|
|
6832
|
+
return {
|
|
6833
|
+
source: current2,
|
|
6834
|
+
dependencies,
|
|
6835
|
+
iterations,
|
|
6836
|
+
reachedMaxIterations: iterations.length === maxIterations && scanIncludeDirectives(current2).length > 0
|
|
6837
|
+
};
|
|
6757
6838
|
}
|
|
6758
6839
|
function expandOneIteration(source, fetcher, replacementCache) {
|
|
6759
6840
|
if (!MAYBE_INCLUDE_PATTERN.test(source))
|
|
@@ -6791,12 +6872,13 @@ function expandOneIterationWithTrace(source, fetcher, replacementCache, iteratio
|
|
|
6791
6872
|
dependencies
|
|
6792
6873
|
};
|
|
6793
6874
|
}
|
|
6794
|
-
async function
|
|
6875
|
+
async function expandOneIterationAsyncWithTrace(source, fetcher, replacementCache, iteration) {
|
|
6795
6876
|
if (!MAYBE_INCLUDE_PATTERN.test(source))
|
|
6796
6877
|
return null;
|
|
6797
6878
|
const directives = scanIncludeDirectives(source);
|
|
6798
6879
|
if (directives.length === 0)
|
|
6799
6880
|
return null;
|
|
6881
|
+
const references = directives.map(createIncludeReference);
|
|
6800
6882
|
const replacements = await Promise.all(directives.map(({ inner }) => replaceCachedAsync(inner, fetcher, replacementCache)));
|
|
6801
6883
|
const parts = [];
|
|
6802
6884
|
let lastPos = 0;
|
|
@@ -6806,7 +6888,11 @@ async function expandOneIterationAsync(source, fetcher, replacementCache) {
|
|
|
6806
6888
|
lastPos = end;
|
|
6807
6889
|
}
|
|
6808
6890
|
parts.push(source.slice(lastPos));
|
|
6809
|
-
return
|
|
6891
|
+
return {
|
|
6892
|
+
source: parts.join(""),
|
|
6893
|
+
references,
|
|
6894
|
+
dependencies: references.map((reference) => ({ ...reference, iteration }))
|
|
6895
|
+
};
|
|
6810
6896
|
}
|
|
6811
6897
|
function replaceCached(inner, fetcher, cache) {
|
|
6812
6898
|
const cached = cache.get(inner);
|
|
@@ -6848,12 +6934,20 @@ function resolveIncludesWithTrace(source, fetcher, options) {
|
|
|
6848
6934
|
return expandIterativeWithTrace(source, cachedFetcher, maxIterations);
|
|
6849
6935
|
}
|
|
6850
6936
|
async function resolveIncludesAsync(source, fetcher, options) {
|
|
6937
|
+
return (await resolveIncludesAsyncWithTrace(source, fetcher, options)).source;
|
|
6938
|
+
}
|
|
6939
|
+
async function resolveIncludesAsyncWithTrace(source, fetcher, options) {
|
|
6851
6940
|
if (options?.settings && !options.settings.enablePageSyntax) {
|
|
6852
|
-
return
|
|
6941
|
+
return {
|
|
6942
|
+
source,
|
|
6943
|
+
dependencies: [],
|
|
6944
|
+
iterations: [],
|
|
6945
|
+
reachedMaxIterations: false
|
|
6946
|
+
};
|
|
6853
6947
|
}
|
|
6854
6948
|
const maxIterations = options?.maxIterations ?? 10;
|
|
6855
6949
|
const cachedFetcher = createCachedAsyncIncludeFetcher(fetcher, normalizePageKey);
|
|
6856
|
-
return
|
|
6950
|
+
return expandIterativeAsyncWithTrace(source, cachedFetcher, maxIterations);
|
|
6857
6951
|
}
|
|
6858
6952
|
function normalizePageKey(location) {
|
|
6859
6953
|
const site = location.site ?? "";
|
|
@@ -6867,7 +6961,7 @@ function isListUsersModule2(module) {
|
|
|
6867
6961
|
function resolveListUsers(_module, data, compiledTemplate, parse) {
|
|
6868
6962
|
const ctx = { user: data.user };
|
|
6869
6963
|
const substituted = compiledTemplate(ctx);
|
|
6870
|
-
const itemAst = parse(substituted);
|
|
6964
|
+
const itemAst = getModuleParseAst(parse(substituted));
|
|
6871
6965
|
return itemAst.elements;
|
|
6872
6966
|
}
|
|
6873
6967
|
// packages/parser/src/parser/rules/block/module/resolution/data-maps.ts
|
|
@@ -7020,6 +7114,117 @@ function countDynamicModules(elements) {
|
|
|
7020
7114
|
return counts;
|
|
7021
7115
|
}
|
|
7022
7116
|
|
|
7117
|
+
// packages/parser/src/parser/rules/block/module/resolution/styles.ts
|
|
7118
|
+
import { STYLE_ANCHOR_PREFIX, STYLE_SLOT_PREFIX } from "@wdprlib/ast";
|
|
7119
|
+
function collectStyles(elements, ignoredAnchors = new WeakSet) {
|
|
7120
|
+
const styles = [];
|
|
7121
|
+
const anchoredStyles = [];
|
|
7122
|
+
const anchors = [];
|
|
7123
|
+
const usedSlots = collectExistingStyleSlots(elements);
|
|
7124
|
+
const ctx = { nextSlotId: 0, usedSlots };
|
|
7125
|
+
const filtered = collectStylesFromElements(elements, styles, anchoredStyles, anchors, ignoredAnchors, ctx);
|
|
7126
|
+
return { elements: filtered, styles, anchoredStyles, anchors };
|
|
7127
|
+
}
|
|
7128
|
+
function mergeCollectedStyles(existing, collected, resolvedSlots = new Map, anchoredStyles = []) {
|
|
7129
|
+
const unanchoredPrevious = [...existing ?? []];
|
|
7130
|
+
for (const style of anchoredStyles)
|
|
7131
|
+
removeFirst(unanchoredPrevious, style);
|
|
7132
|
+
for (const style of collected) {
|
|
7133
|
+
if (isStyleSlotMarker(style))
|
|
7134
|
+
removeFirst(unanchoredPrevious, style);
|
|
7135
|
+
}
|
|
7136
|
+
const merged = unanchoredPrevious.filter((style) => !isStyleSlotMarker(style));
|
|
7137
|
+
for (const style of collected) {
|
|
7138
|
+
if (isStyleSlotMarker(style))
|
|
7139
|
+
appendStyleSlot(merged, style, resolvedSlots);
|
|
7140
|
+
else
|
|
7141
|
+
merged.push(style);
|
|
7142
|
+
}
|
|
7143
|
+
return merged;
|
|
7144
|
+
}
|
|
7145
|
+
function isStyleSlotMarker(style) {
|
|
7146
|
+
return style.startsWith(STYLE_SLOT_PREFIX);
|
|
7147
|
+
}
|
|
7148
|
+
function createStyleSlotMarker(slotId) {
|
|
7149
|
+
return `${STYLE_SLOT_PREFIX}${slotId}`;
|
|
7150
|
+
}
|
|
7151
|
+
function getStyleSlotId(data) {
|
|
7152
|
+
const slotId = data._styleSlot;
|
|
7153
|
+
return Number.isSafeInteger(slotId) && slotId >= 0 ? slotId : undefined;
|
|
7154
|
+
}
|
|
7155
|
+
function removeFirst(values, value) {
|
|
7156
|
+
const index = values.indexOf(value);
|
|
7157
|
+
if (index >= 0)
|
|
7158
|
+
values.splice(index, 1);
|
|
7159
|
+
}
|
|
7160
|
+
function appendStyleSlot(target, marker, resolvedSlots) {
|
|
7161
|
+
const slotId = Number(marker.slice(STYLE_SLOT_PREFIX.length));
|
|
7162
|
+
const replacement = resolvedSlots.get(slotId);
|
|
7163
|
+
if (replacement)
|
|
7164
|
+
target.push(...replacement);
|
|
7165
|
+
else
|
|
7166
|
+
target.push(marker);
|
|
7167
|
+
}
|
|
7168
|
+
function collectExistingStyleSlots(elements) {
|
|
7169
|
+
const slots = new Set;
|
|
7170
|
+
walkElements(elements, (element) => {
|
|
7171
|
+
if (element.element !== "if-tags")
|
|
7172
|
+
return;
|
|
7173
|
+
const slotId = getStyleSlotId(element.data);
|
|
7174
|
+
if (slotId !== undefined)
|
|
7175
|
+
slots.add(slotId);
|
|
7176
|
+
});
|
|
7177
|
+
return slots;
|
|
7178
|
+
}
|
|
7179
|
+
function allocateStyleSlot(ctx) {
|
|
7180
|
+
while (ctx.usedSlots.has(ctx.nextSlotId))
|
|
7181
|
+
ctx.nextSlotId++;
|
|
7182
|
+
const slotId = ctx.nextSlotId++;
|
|
7183
|
+
ctx.usedSlots.add(slotId);
|
|
7184
|
+
return slotId;
|
|
7185
|
+
}
|
|
7186
|
+
function collectStylesFromElements(elements, styles, anchoredStyles, anchors, ignoredAnchors, ctx) {
|
|
7187
|
+
const result = [];
|
|
7188
|
+
for (const element of elements) {
|
|
7189
|
+
if (element.element === "style") {
|
|
7190
|
+
const css = element.data;
|
|
7191
|
+
if (css.startsWith(STYLE_SLOT_PREFIX)) {
|
|
7192
|
+
styles.push(css);
|
|
7193
|
+
continue;
|
|
7194
|
+
}
|
|
7195
|
+
if (css.startsWith(STYLE_ANCHOR_PREFIX)) {
|
|
7196
|
+
anchors.push(element);
|
|
7197
|
+
if (ignoredAnchors.has(element)) {
|
|
7198
|
+
result.push(element);
|
|
7199
|
+
continue;
|
|
7200
|
+
}
|
|
7201
|
+
const anchoredCss = css.slice(STYLE_ANCHOR_PREFIX.length);
|
|
7202
|
+
styles.push(anchoredCss);
|
|
7203
|
+
anchoredStyles.push(anchoredCss);
|
|
7204
|
+
result.push(element);
|
|
7205
|
+
continue;
|
|
7206
|
+
}
|
|
7207
|
+
styles.push(css);
|
|
7208
|
+
const anchor = { element: "style", data: `${STYLE_ANCHOR_PREFIX}${css}` };
|
|
7209
|
+
anchors.push(anchor);
|
|
7210
|
+
result.push(anchor);
|
|
7211
|
+
continue;
|
|
7212
|
+
}
|
|
7213
|
+
if (element.element === "if-tags") {
|
|
7214
|
+
const slotId = getStyleSlotId(element.data) ?? allocateStyleSlot(ctx);
|
|
7215
|
+
styles.push(createStyleSlotMarker(slotId));
|
|
7216
|
+
const data = { ...element.data, _styleSlot: slotId };
|
|
7217
|
+
result.push({
|
|
7218
|
+
element: "if-tags",
|
|
7219
|
+
data
|
|
7220
|
+
});
|
|
7221
|
+
continue;
|
|
7222
|
+
}
|
|
7223
|
+
result.push(mapElementChildren(element, (children) => collectStylesFromElements(children, styles, anchoredStyles, anchors, ignoredAnchors, ctx)));
|
|
7224
|
+
}
|
|
7225
|
+
return result;
|
|
7226
|
+
}
|
|
7227
|
+
|
|
7023
7228
|
// packages/parser/src/parser/rules/block/module/resolution/walk-resolve.ts
|
|
7024
7229
|
function walkAndResolve(elements, ctx) {
|
|
7025
7230
|
const result = [];
|
|
@@ -7042,6 +7247,7 @@ function walkAndResolve(elements, ctx) {
|
|
|
7042
7247
|
if (isIfTagsElement(element)) {
|
|
7043
7248
|
const ifTagsData = element.data;
|
|
7044
7249
|
const resolveResult = resolveIfTags(ifTagsData, ctx.pageTags);
|
|
7250
|
+
const styleSlotId = getStyleSlotId(ifTagsData);
|
|
7045
7251
|
if (resolveResult.evaluated) {
|
|
7046
7252
|
if (resolveResult.matched) {
|
|
7047
7253
|
const childResult = walkAndResolve(ifTagsData.elements, {
|
|
@@ -7050,11 +7256,23 @@ function walkAndResolve(elements, ctx) {
|
|
|
7050
7256
|
listUsersIdCounter: listUsersId,
|
|
7051
7257
|
tagCloudIdCounter: tagCloudId
|
|
7052
7258
|
});
|
|
7053
|
-
|
|
7259
|
+
if (styleSlotId === undefined) {
|
|
7260
|
+
result.push(...childResult.elements);
|
|
7261
|
+
} else {
|
|
7262
|
+
const collected = collectStyles(childResult.elements);
|
|
7263
|
+
ctx.resolvedStyleSlots.set(styleSlotId, collected.styles);
|
|
7264
|
+
for (const anchor of collected.anchors)
|
|
7265
|
+
ctx.routedStyleAnchors.add(anchor);
|
|
7266
|
+
result.push({ element: "style", data: createStyleSlotMarker(styleSlotId) }, ...collected.elements);
|
|
7267
|
+
}
|
|
7054
7268
|
listPagesId = childResult.nextListPagesId;
|
|
7055
7269
|
listUsersId = childResult.nextListUsersId;
|
|
7056
7270
|
tagCloudId = childResult.nextTagCloudId;
|
|
7057
7271
|
} else {
|
|
7272
|
+
if (styleSlotId !== undefined) {
|
|
7273
|
+
ctx.resolvedStyleSlots.set(styleSlotId, []);
|
|
7274
|
+
result.push({ element: "style", data: createStyleSlotMarker(styleSlotId) });
|
|
7275
|
+
}
|
|
7058
7276
|
const counts = countDynamicModules(ifTagsData.elements);
|
|
7059
7277
|
listPagesId += counts.listPagesId;
|
|
7060
7278
|
listUsersId += counts.listUsersId;
|
|
@@ -7109,44 +7327,361 @@ function walkAndResolve(elements, ctx) {
|
|
|
7109
7327
|
};
|
|
7110
7328
|
}
|
|
7111
7329
|
|
|
7112
|
-
// packages/parser/src/parser/rules/block/module/resolution/
|
|
7113
|
-
import {
|
|
7114
|
-
|
|
7115
|
-
|
|
7116
|
-
|
|
7117
|
-
|
|
7118
|
-
|
|
7330
|
+
// packages/parser/src/parser/rules/block/module/resolution/document.ts
|
|
7331
|
+
import {
|
|
7332
|
+
evaluateExpression,
|
|
7333
|
+
isTruthy
|
|
7334
|
+
} from "@wdprlib/ast";
|
|
7335
|
+
|
|
7336
|
+
// packages/parser/src/parser/toc.ts
|
|
7337
|
+
class TocIndexer {
|
|
7338
|
+
index = 0;
|
|
7339
|
+
next() {
|
|
7340
|
+
return this.index++;
|
|
7341
|
+
}
|
|
7342
|
+
}
|
|
7343
|
+
function buildTocList(indexer, items) {
|
|
7344
|
+
const listItems = items.map((item) => buildTocListItem(indexer, item));
|
|
7345
|
+
return {
|
|
7346
|
+
element: "list",
|
|
7347
|
+
data: {
|
|
7348
|
+
type: "bullet",
|
|
7349
|
+
attributes: {},
|
|
7350
|
+
items: listItems
|
|
7351
|
+
}
|
|
7352
|
+
};
|
|
7353
|
+
}
|
|
7354
|
+
function buildTocListItem(indexer, item) {
|
|
7355
|
+
if (item.kind === "list") {
|
|
7356
|
+
return {
|
|
7357
|
+
"item-type": "sub-list",
|
|
7358
|
+
element: "list",
|
|
7359
|
+
data: {
|
|
7360
|
+
type: "bullet",
|
|
7361
|
+
attributes: {},
|
|
7362
|
+
items: item.children.map((child) => buildTocListItem(indexer, child))
|
|
7363
|
+
}
|
|
7364
|
+
};
|
|
7365
|
+
}
|
|
7366
|
+
const anchor = `#toc${indexer.next()}`;
|
|
7367
|
+
const linkElement = {
|
|
7368
|
+
element: "link",
|
|
7369
|
+
data: {
|
|
7370
|
+
type: "table-of-contents",
|
|
7371
|
+
link: anchor,
|
|
7372
|
+
extra: null,
|
|
7373
|
+
label: { text: item.value },
|
|
7374
|
+
target: null
|
|
7375
|
+
}
|
|
7376
|
+
};
|
|
7377
|
+
return {
|
|
7378
|
+
"item-type": "elements",
|
|
7379
|
+
attributes: {},
|
|
7380
|
+
elements: [linkElement]
|
|
7381
|
+
};
|
|
7382
|
+
}
|
|
7383
|
+
function buildTableOfContents(entries) {
|
|
7384
|
+
if (entries.length === 0) {
|
|
7385
|
+
return [];
|
|
7386
|
+
}
|
|
7387
|
+
const depthItems = entries.map((entry) => ({
|
|
7388
|
+
depth: entry.level - 1,
|
|
7389
|
+
ltype: null,
|
|
7390
|
+
value: entry.text
|
|
7391
|
+
}));
|
|
7392
|
+
const trees = processDepths(null, depthItems);
|
|
7393
|
+
const indexer = new TocIndexer;
|
|
7394
|
+
return trees.map((tree) => buildTocList(indexer, tree.list));
|
|
7395
|
+
}
|
|
7396
|
+
|
|
7397
|
+
// packages/parser/src/parser/rules/block/module/resolution/document.ts
|
|
7398
|
+
class ModuleDocumentRegistry {
|
|
7399
|
+
footnotesByElement = new WeakMap;
|
|
7400
|
+
diagnostics = [];
|
|
7401
|
+
register(result, options = {}) {
|
|
7402
|
+
const parseResult = isParseResult(result) ? result : null;
|
|
7403
|
+
const ast = parseResult ? parseResult.ast : result;
|
|
7404
|
+
const elements = options.stripLegacyImplicitFootnoteBlock ? stripTrailingDefaultFootnoteBlock(ast.elements) : ast.elements;
|
|
7405
|
+
const registeredAst = elements === ast.elements ? ast : { ...ast, elements };
|
|
7406
|
+
if (parseResult) {
|
|
7407
|
+
this.diagnostics.push(...parseResult.diagnostics);
|
|
7408
|
+
}
|
|
7409
|
+
this.registerFootnotes(registeredAst);
|
|
7410
|
+
return registeredAst;
|
|
7411
|
+
}
|
|
7412
|
+
finalize(ast, elements, pageTags, ensureFootnoteBlock = true) {
|
|
7413
|
+
const normalizedElements = normalizeFootnoteBlocks(elements, ensureFootnoteBlock);
|
|
7414
|
+
const footnotes = [];
|
|
7415
|
+
const htmlBlocks = [];
|
|
7416
|
+
const codeBlocks = [];
|
|
7417
|
+
const tocEntries = [];
|
|
7418
|
+
const collectElement = (element) => {
|
|
7419
|
+
if (element.element === "footnote") {
|
|
7420
|
+
const content = this.footnotesByElement.get(element);
|
|
7421
|
+
if (content)
|
|
7422
|
+
footnotes.push(content);
|
|
7423
|
+
} else if (element.element === "html") {
|
|
7424
|
+
htmlBlocks.push(element.data.contents);
|
|
7425
|
+
} else if (element.element === "code") {
|
|
7426
|
+
codeBlocks.push(element.data);
|
|
7427
|
+
} else if (isTocHeading(element)) {
|
|
7428
|
+
tocEntries.push({
|
|
7429
|
+
level: element.data.type.header.level,
|
|
7430
|
+
text: extractHeadingText(element.data.elements)
|
|
7431
|
+
});
|
|
7432
|
+
}
|
|
7433
|
+
};
|
|
7434
|
+
walkRenderOrder(normalizedElements, pageTags, collectElement);
|
|
7435
|
+
const result = { ...ast, elements: normalizedElements };
|
|
7436
|
+
setOptionalArray(result, "footnotes", footnotes);
|
|
7437
|
+
setOptionalArray(result, "html-blocks", htmlBlocks);
|
|
7438
|
+
setOptionalArray(result, "code-blocks", codeBlocks);
|
|
7439
|
+
setOptionalArray(result, "table-of-contents", buildTableOfContents(tocEntries));
|
|
7440
|
+
return result;
|
|
7441
|
+
}
|
|
7442
|
+
registerFootnotes(ast) {
|
|
7443
|
+
const footnoteElements = [];
|
|
7444
|
+
walkSyntaxOrder(ast.elements, (element) => {
|
|
7445
|
+
if (element.element === "footnote")
|
|
7446
|
+
footnoteElements.push(element);
|
|
7447
|
+
});
|
|
7448
|
+
for (let i = 0;i < footnoteElements.length; i++) {
|
|
7449
|
+
const content = ast.footnotes?.[i];
|
|
7450
|
+
if (content)
|
|
7451
|
+
this.footnotesByElement.set(footnoteElements[i], content);
|
|
7452
|
+
}
|
|
7453
|
+
}
|
|
7454
|
+
}
|
|
7455
|
+
function isParseResult(result) {
|
|
7456
|
+
return "ast" in result && "diagnostics" in result;
|
|
7457
|
+
}
|
|
7458
|
+
function setOptionalArray(tree, key, value) {
|
|
7459
|
+
if (value.length > 0) {
|
|
7460
|
+
tree[key] = value;
|
|
7461
|
+
} else {
|
|
7462
|
+
delete tree[key];
|
|
7463
|
+
}
|
|
7464
|
+
}
|
|
7465
|
+
function stripTrailingDefaultFootnoteBlock(elements) {
|
|
7466
|
+
const last = elements.at(-1);
|
|
7467
|
+
if (last?.element !== "footnote-block" || last.data.title !== null || last.data.hide === true) {
|
|
7468
|
+
return elements;
|
|
7469
|
+
}
|
|
7470
|
+
return elements.slice(0, -1);
|
|
7471
|
+
}
|
|
7472
|
+
function normalizeFootnoteBlocks(elements, ensureFootnoteBlock) {
|
|
7473
|
+
const state = { found: false };
|
|
7474
|
+
const normalized = mapSyntaxElements(elements, (element) => {
|
|
7475
|
+
if (element.element !== "footnote-block")
|
|
7476
|
+
return element;
|
|
7477
|
+
if (state.found)
|
|
7478
|
+
return null;
|
|
7479
|
+
state.found = true;
|
|
7480
|
+
return element;
|
|
7481
|
+
});
|
|
7482
|
+
if (!state.found && ensureFootnoteBlock) {
|
|
7483
|
+
normalized.push({
|
|
7484
|
+
element: "footnote-block",
|
|
7485
|
+
data: { title: null, hide: false }
|
|
7486
|
+
});
|
|
7487
|
+
}
|
|
7488
|
+
return normalized;
|
|
7489
|
+
}
|
|
7490
|
+
function containsSyntaxFootnoteBlock(elements) {
|
|
7491
|
+
let found = false;
|
|
7492
|
+
walkSyntaxOrder(elements, (element) => {
|
|
7493
|
+
if (element.element === "footnote-block")
|
|
7494
|
+
found = true;
|
|
7495
|
+
});
|
|
7496
|
+
return found;
|
|
7119
7497
|
}
|
|
7120
|
-
function
|
|
7498
|
+
function mapSyntaxElements(elements, transform) {
|
|
7121
7499
|
const result = [];
|
|
7500
|
+
for (const original of elements) {
|
|
7501
|
+
const element = transform(original);
|
|
7502
|
+
if (!element)
|
|
7503
|
+
continue;
|
|
7504
|
+
result.push(mapSyntaxChildren(element, (children) => mapSyntaxElements(children, transform)));
|
|
7505
|
+
}
|
|
7506
|
+
return result;
|
|
7507
|
+
}
|
|
7508
|
+
function mapSyntaxChildren(element, transform) {
|
|
7509
|
+
if (element.element === "if") {
|
|
7510
|
+
return {
|
|
7511
|
+
...element,
|
|
7512
|
+
data: {
|
|
7513
|
+
...element.data,
|
|
7514
|
+
then: transform(element.data.then),
|
|
7515
|
+
else: transform(element.data.else)
|
|
7516
|
+
}
|
|
7517
|
+
};
|
|
7518
|
+
}
|
|
7519
|
+
if (element.element === "ifexpr") {
|
|
7520
|
+
return {
|
|
7521
|
+
...element,
|
|
7522
|
+
data: {
|
|
7523
|
+
...element.data,
|
|
7524
|
+
then: transform(element.data.then),
|
|
7525
|
+
else: transform(element.data.else)
|
|
7526
|
+
}
|
|
7527
|
+
};
|
|
7528
|
+
}
|
|
7529
|
+
if (element.element === "bibliography-block") {
|
|
7530
|
+
return {
|
|
7531
|
+
...element,
|
|
7532
|
+
data: {
|
|
7533
|
+
...element.data,
|
|
7534
|
+
entries: element.data.entries.map((entry) => ({
|
|
7535
|
+
...entry,
|
|
7536
|
+
key: transform(entry.key),
|
|
7537
|
+
value: transform(entry.value)
|
|
7538
|
+
}))
|
|
7539
|
+
}
|
|
7540
|
+
};
|
|
7541
|
+
}
|
|
7542
|
+
if (element.element === "list") {
|
|
7543
|
+
return {
|
|
7544
|
+
...element,
|
|
7545
|
+
data: {
|
|
7546
|
+
...element.data,
|
|
7547
|
+
items: element.data.items.map((item) => item["item-type"] === "elements" ? { ...item, elements: transform(item.elements) } : mapSubList(item, transform))
|
|
7548
|
+
}
|
|
7549
|
+
};
|
|
7550
|
+
}
|
|
7551
|
+
if (element.element === "table") {
|
|
7552
|
+
return {
|
|
7553
|
+
...element,
|
|
7554
|
+
data: {
|
|
7555
|
+
...element.data,
|
|
7556
|
+
rows: element.data.rows.map((row) => ({
|
|
7557
|
+
...row,
|
|
7558
|
+
cells: row.cells.map((cell) => ({ ...cell, elements: transform(cell.elements) }))
|
|
7559
|
+
}))
|
|
7560
|
+
}
|
|
7561
|
+
};
|
|
7562
|
+
}
|
|
7563
|
+
if (element.element === "definition-list") {
|
|
7564
|
+
return {
|
|
7565
|
+
...element,
|
|
7566
|
+
data: element.data.map((entry) => ({
|
|
7567
|
+
...entry,
|
|
7568
|
+
key: transform(entry.key),
|
|
7569
|
+
value: transform(entry.value)
|
|
7570
|
+
}))
|
|
7571
|
+
};
|
|
7572
|
+
}
|
|
7573
|
+
if (element.element === "tab-view") {
|
|
7574
|
+
return {
|
|
7575
|
+
...element,
|
|
7576
|
+
data: element.data.map((tab) => ({ ...tab, elements: transform(tab.elements) }))
|
|
7577
|
+
};
|
|
7578
|
+
}
|
|
7579
|
+
const children = getGenericElementChildren(element);
|
|
7580
|
+
return children === null ? element : withGenericElementChildren(element, transform(children));
|
|
7581
|
+
}
|
|
7582
|
+
function mapSubList(item, transform) {
|
|
7583
|
+
const transformed = transform([listElement(item.data)])[0];
|
|
7584
|
+
return transformed?.element === "list" ? { ...item, data: transformed.data } : item;
|
|
7585
|
+
}
|
|
7586
|
+
function walkSyntaxOrder(elements, callback) {
|
|
7122
7587
|
for (const element of elements) {
|
|
7123
|
-
|
|
7124
|
-
|
|
7588
|
+
callback(element);
|
|
7589
|
+
walkAllSyntaxChildren(element, (children) => walkSyntaxOrder(children, callback));
|
|
7590
|
+
}
|
|
7591
|
+
}
|
|
7592
|
+
function walkRenderOrder(elements, pageTags, callback) {
|
|
7593
|
+
for (const element of elements) {
|
|
7594
|
+
callback(element);
|
|
7595
|
+
if (element.element === "if") {
|
|
7596
|
+
walkRenderOrder(isTruthy(element.data.condition) ? element.data.then : element.data.else, pageTags, callback);
|
|
7597
|
+
continue;
|
|
7598
|
+
}
|
|
7599
|
+
if (element.element === "ifexpr") {
|
|
7600
|
+
const evaluated = evaluateExpression(element.data.expression);
|
|
7601
|
+
if (evaluated.success) {
|
|
7602
|
+
walkRenderOrder(evaluated.value !== 0 ? element.data.then : element.data.else, pageTags, callback);
|
|
7603
|
+
}
|
|
7125
7604
|
continue;
|
|
7126
7605
|
}
|
|
7127
7606
|
if (element.element === "if-tags") {
|
|
7128
|
-
const
|
|
7129
|
-
|
|
7130
|
-
|
|
7131
|
-
|
|
7132
|
-
|
|
7133
|
-
|
|
7134
|
-
|
|
7607
|
+
const resolved = resolveIfTags(element.data, pageTags);
|
|
7608
|
+
if (!resolved.evaluated || resolved.matched) {
|
|
7609
|
+
walkRenderOrder(element.data.elements, pageTags, callback);
|
|
7610
|
+
}
|
|
7611
|
+
continue;
|
|
7612
|
+
}
|
|
7613
|
+
if (element.element === "bibliography-block") {
|
|
7614
|
+
if (!element.data.hide) {
|
|
7615
|
+
for (const entry of element.data.entries) {
|
|
7616
|
+
walkRenderOrder(entry.value, pageTags, callback);
|
|
7617
|
+
}
|
|
7618
|
+
}
|
|
7135
7619
|
continue;
|
|
7136
7620
|
}
|
|
7137
|
-
|
|
7621
|
+
walkBasicChildren(element, (children) => walkRenderOrder(children, pageTags, callback));
|
|
7138
7622
|
}
|
|
7139
|
-
|
|
7623
|
+
}
|
|
7624
|
+
function walkAllSyntaxChildren(element, callback) {
|
|
7625
|
+
if (element.element === "if" || element.element === "ifexpr") {
|
|
7626
|
+
callback(element.data.then);
|
|
7627
|
+
callback(element.data.else);
|
|
7628
|
+
return;
|
|
7629
|
+
}
|
|
7630
|
+
if (element.element === "bibliography-block") {
|
|
7631
|
+
for (const entry of element.data.entries) {
|
|
7632
|
+
callback(entry.key);
|
|
7633
|
+
callback(entry.value);
|
|
7634
|
+
}
|
|
7635
|
+
return;
|
|
7636
|
+
}
|
|
7637
|
+
walkBasicChildren(element, callback);
|
|
7638
|
+
}
|
|
7639
|
+
function walkBasicChildren(element, callback) {
|
|
7640
|
+
if (element.element === "list") {
|
|
7641
|
+
for (const item of element.data.items) {
|
|
7642
|
+
callback(item["item-type"] === "elements" ? item.elements : [listElement(item.data)]);
|
|
7643
|
+
}
|
|
7644
|
+
return;
|
|
7645
|
+
}
|
|
7646
|
+
if (element.element === "table") {
|
|
7647
|
+
for (const row of element.data.rows) {
|
|
7648
|
+
for (const cell of row.cells)
|
|
7649
|
+
callback(cell.elements);
|
|
7650
|
+
}
|
|
7651
|
+
return;
|
|
7652
|
+
}
|
|
7653
|
+
if (element.element === "definition-list") {
|
|
7654
|
+
for (const entry of element.data) {
|
|
7655
|
+
callback(entry.key);
|
|
7656
|
+
callback(entry.value);
|
|
7657
|
+
}
|
|
7658
|
+
return;
|
|
7659
|
+
}
|
|
7660
|
+
if (element.element === "tab-view") {
|
|
7661
|
+
for (const tab of element.data)
|
|
7662
|
+
callback(tab.elements);
|
|
7663
|
+
return;
|
|
7664
|
+
}
|
|
7665
|
+
const children = getGenericElementChildren(element);
|
|
7666
|
+
if (children !== null)
|
|
7667
|
+
callback(children);
|
|
7668
|
+
}
|
|
7669
|
+
function isTocHeading(element) {
|
|
7670
|
+
return element.element === "container" && typeof element.data.type === "object" && "header" in element.data.type && element.data.type.header["has-toc"];
|
|
7140
7671
|
}
|
|
7141
7672
|
|
|
7142
7673
|
// packages/parser/src/parser/rules/block/module/resolve.ts
|
|
7143
7674
|
var MODULE_SECONDARY_INCLUDE_MAX_ITERATIONS = 5;
|
|
7144
7675
|
async function resolveModules(ast, dataProvider, options) {
|
|
7145
|
-
const
|
|
7676
|
+
const registry = new ModuleDocumentRegistry;
|
|
7677
|
+
registry.register(ast);
|
|
7678
|
+
const parse = createModuleParseFunction(options, dataProvider, registry);
|
|
7146
7679
|
const listPagesCtx = await buildListPagesContext(dataProvider, options.requirements.listPages ?? [], options.compiledListPagesTemplates, parse, options.urlPath);
|
|
7147
7680
|
const listUsersCtx = await buildListUsersContext(dataProvider, options.requirements.listUsers ?? [], options.compiledListUsersTemplates, parse);
|
|
7148
7681
|
const tagCloudCtx = await buildTagCloudContext(dataProvider, options.requirements.tagCloud ?? []);
|
|
7149
7682
|
const pageTags = dataProvider.getPageTags?.() ?? null;
|
|
7683
|
+
const resolvedStyleSlots = new Map;
|
|
7684
|
+
const routedStyleAnchors = new WeakSet;
|
|
7150
7685
|
const resolvedElements = walkAndResolve(ast.elements, {
|
|
7151
7686
|
listPages: listPagesCtx,
|
|
7152
7687
|
listUsers: listUsersCtx,
|
|
@@ -7157,24 +7692,30 @@ async function resolveModules(ast, dataProvider, options) {
|
|
|
7157
7692
|
pageTags,
|
|
7158
7693
|
listPagesIdCounter: 0,
|
|
7159
7694
|
listUsersIdCounter: 0,
|
|
7160
|
-
tagCloudIdCounter: 0
|
|
7695
|
+
tagCloudIdCounter: 0,
|
|
7696
|
+
resolvedStyleSlots,
|
|
7697
|
+
routedStyleAnchors
|
|
7161
7698
|
});
|
|
7162
|
-
const {
|
|
7699
|
+
const {
|
|
7700
|
+
elements: finalElements,
|
|
7701
|
+
styles,
|
|
7702
|
+
anchoredStyles
|
|
7703
|
+
} = collectStyles(resolvedElements.elements, routedStyleAnchors);
|
|
7163
7704
|
const result = {
|
|
7164
7705
|
...ast,
|
|
7165
7706
|
elements: finalElements
|
|
7166
7707
|
};
|
|
7167
|
-
|
|
7168
|
-
|
|
7169
|
-
|
|
7170
|
-
|
|
7708
|
+
const mergedStyles = mergeCollectedStyles(ast.styles, styles, resolvedStyleSlots, anchoredStyles);
|
|
7709
|
+
if (mergedStyles.length > 0)
|
|
7710
|
+
result.styles = mergedStyles;
|
|
7711
|
+
options.onDiagnostics?.(registry.diagnostics);
|
|
7712
|
+
return registry.finalize(result, finalElements, pageTags, containsSyntaxFootnoteBlock(ast.elements));
|
|
7171
7713
|
}
|
|
7172
|
-
function createModuleParseFunction(options, dataProvider) {
|
|
7714
|
+
function createModuleParseFunction(options, dataProvider, registry) {
|
|
7173
7715
|
const transform = createModuleSourceTransform(options, dataProvider);
|
|
7174
|
-
|
|
7175
|
-
|
|
7176
|
-
}
|
|
7177
|
-
return (source) => options.parse(transform(source));
|
|
7716
|
+
return (source) => registry.register(options.parse(transform ? transform(source) : source), {
|
|
7717
|
+
stripLegacyImplicitFootnoteBlock: true
|
|
7718
|
+
});
|
|
7178
7719
|
}
|
|
7179
7720
|
function createModuleSourceTransform(options, dataProvider) {
|
|
7180
7721
|
if (options.transformModuleSource) {
|
|
@@ -12309,6 +12850,7 @@ function createParseContext(tokens, options = {}) {
|
|
|
12309
12850
|
version: options.version ?? "wikidot",
|
|
12310
12851
|
trackPositions: options.trackPositions ?? true,
|
|
12311
12852
|
settings: options.settings ?? DEFAULT_SETTINGS,
|
|
12853
|
+
appendImplicitFootnoteBlock: options.appendImplicitFootnoteBlock ?? true,
|
|
12312
12854
|
footnotes: [],
|
|
12313
12855
|
tocEntries: [],
|
|
12314
12856
|
codeBlocks: [],
|
|
@@ -12826,67 +13368,6 @@ function suppressAtLevel(elements) {
|
|
|
12826
13368
|
function suppressDivAdjacentParagraphs(elements) {
|
|
12827
13369
|
return suppressAtLevel(elements);
|
|
12828
13370
|
}
|
|
12829
|
-
// packages/parser/src/parser/toc.ts
|
|
12830
|
-
class TocIndexer {
|
|
12831
|
-
index = 0;
|
|
12832
|
-
next() {
|
|
12833
|
-
return this.index++;
|
|
12834
|
-
}
|
|
12835
|
-
}
|
|
12836
|
-
function buildTocList(indexer, items) {
|
|
12837
|
-
const listItems = items.map((item) => buildTocListItem(indexer, item));
|
|
12838
|
-
return {
|
|
12839
|
-
element: "list",
|
|
12840
|
-
data: {
|
|
12841
|
-
type: "bullet",
|
|
12842
|
-
attributes: {},
|
|
12843
|
-
items: listItems
|
|
12844
|
-
}
|
|
12845
|
-
};
|
|
12846
|
-
}
|
|
12847
|
-
function buildTocListItem(indexer, item) {
|
|
12848
|
-
if (item.kind === "list") {
|
|
12849
|
-
return {
|
|
12850
|
-
"item-type": "sub-list",
|
|
12851
|
-
element: "list",
|
|
12852
|
-
data: {
|
|
12853
|
-
type: "bullet",
|
|
12854
|
-
attributes: {},
|
|
12855
|
-
items: item.children.map((child) => buildTocListItem(indexer, child))
|
|
12856
|
-
}
|
|
12857
|
-
};
|
|
12858
|
-
}
|
|
12859
|
-
const anchor = `#toc${indexer.next()}`;
|
|
12860
|
-
const linkElement = {
|
|
12861
|
-
element: "link",
|
|
12862
|
-
data: {
|
|
12863
|
-
type: "table-of-contents",
|
|
12864
|
-
link: anchor,
|
|
12865
|
-
extra: null,
|
|
12866
|
-
label: { text: item.value },
|
|
12867
|
-
target: null
|
|
12868
|
-
}
|
|
12869
|
-
};
|
|
12870
|
-
return {
|
|
12871
|
-
"item-type": "elements",
|
|
12872
|
-
attributes: {},
|
|
12873
|
-
elements: [linkElement]
|
|
12874
|
-
};
|
|
12875
|
-
}
|
|
12876
|
-
function buildTableOfContents(entries) {
|
|
12877
|
-
if (entries.length === 0) {
|
|
12878
|
-
return [];
|
|
12879
|
-
}
|
|
12880
|
-
const depthItems = entries.map((entry) => ({
|
|
12881
|
-
depth: entry.level - 1,
|
|
12882
|
-
ltype: null,
|
|
12883
|
-
value: entry.text
|
|
12884
|
-
}));
|
|
12885
|
-
const trees = processDepths(null, depthItems);
|
|
12886
|
-
const indexer = new TocIndexer;
|
|
12887
|
-
return trees.map((tree) => buildTocList(indexer, tree.list));
|
|
12888
|
-
}
|
|
12889
|
-
|
|
12890
13371
|
// packages/parser/src/parser/parse/footnotes.ts
|
|
12891
13372
|
function containsFootnoteBlock(elements) {
|
|
12892
13373
|
let found = false;
|
|
@@ -12900,7 +13381,9 @@ function containsFootnoteBlock(elements) {
|
|
|
12900
13381
|
// packages/parser/src/parser/parse/result.ts
|
|
12901
13382
|
function finalizeParseResult(ctx, children) {
|
|
12902
13383
|
const cleanedChildren = postprocessChildren(children);
|
|
12903
|
-
appendImplicitFootnoteBlock
|
|
13384
|
+
if (ctx.appendImplicitFootnoteBlock) {
|
|
13385
|
+
appendImplicitFootnoteBlock(cleanedChildren);
|
|
13386
|
+
}
|
|
12904
13387
|
return {
|
|
12905
13388
|
ast: buildSyntaxTree(ctx, cleanedChildren),
|
|
12906
13389
|
diagnostics: ctx.diagnostics
|
|
@@ -13272,30 +13755,6 @@ function preprocess(text) {
|
|
|
13272
13755
|
return result;
|
|
13273
13756
|
}
|
|
13274
13757
|
|
|
13275
|
-
// packages/parser/src/parser/preprocess/expr/evaluate.ts
|
|
13276
|
-
import { evaluateExpression, formatExprValue, isTruthy } from "@wdprlib/ast";
|
|
13277
|
-
function evaluateDirective(kind, match) {
|
|
13278
|
-
if (kind === "expr") {
|
|
13279
|
-
const result2 = evaluateExpression(match.head);
|
|
13280
|
-
if (result2.success)
|
|
13281
|
-
return formatExprValue(result2.value);
|
|
13282
|
-
if (result2.error === "empty expression")
|
|
13283
|
-
return "";
|
|
13284
|
-
return "ERROR";
|
|
13285
|
-
}
|
|
13286
|
-
if (kind === "if") {
|
|
13287
|
-
if (!match.hasPipe)
|
|
13288
|
-
return "";
|
|
13289
|
-
return isTruthy(match.head) ? match.thenText : match.elseText;
|
|
13290
|
-
}
|
|
13291
|
-
if (!match.hasPipe)
|
|
13292
|
-
return "";
|
|
13293
|
-
const result = evaluateExpression(match.head);
|
|
13294
|
-
if (!result.success)
|
|
13295
|
-
return "ERROR";
|
|
13296
|
-
return result.value !== 0 && !Number.isNaN(result.value) ? match.thenText : match.elseText;
|
|
13297
|
-
}
|
|
13298
|
-
|
|
13299
13758
|
// packages/parser/src/parser/preprocess/expr/chars.ts
|
|
13300
13759
|
function isWhitespace(ch) {
|
|
13301
13760
|
return ch === " " || ch === "\t" || ch === `
|
|
@@ -13324,6 +13783,30 @@ function matchDirectiveKind(source, i) {
|
|
|
13324
13783
|
return null;
|
|
13325
13784
|
}
|
|
13326
13785
|
|
|
13786
|
+
// packages/parser/src/parser/preprocess/expr/evaluate.ts
|
|
13787
|
+
import { evaluateExpression as evaluateExpression2, formatExprValue, isTruthy as isTruthy2 } from "@wdprlib/ast";
|
|
13788
|
+
function evaluateDirective(kind, match) {
|
|
13789
|
+
if (kind === "expr") {
|
|
13790
|
+
const result2 = evaluateExpression2(match.head);
|
|
13791
|
+
if (result2.success)
|
|
13792
|
+
return formatExprValue(result2.value);
|
|
13793
|
+
if (result2.error === "empty expression")
|
|
13794
|
+
return "";
|
|
13795
|
+
return "ERROR";
|
|
13796
|
+
}
|
|
13797
|
+
if (kind === "if") {
|
|
13798
|
+
if (!match.hasPipe)
|
|
13799
|
+
return "";
|
|
13800
|
+
return isTruthy2(match.head) ? match.thenText : match.elseText;
|
|
13801
|
+
}
|
|
13802
|
+
if (!match.hasPipe)
|
|
13803
|
+
return "";
|
|
13804
|
+
const result = evaluateExpression2(match.head);
|
|
13805
|
+
if (!result.success)
|
|
13806
|
+
return "ERROR";
|
|
13807
|
+
return result.value !== 0 && !Number.isNaN(result.value) ? match.thenText : match.elseText;
|
|
13808
|
+
}
|
|
13809
|
+
|
|
13327
13810
|
// packages/parser/src/parser/preprocess/expr/parse.ts
|
|
13328
13811
|
function tryParseInnermostDirective(source, start, kind) {
|
|
13329
13812
|
const keywordLen = kind === "ifexpr" ? 6 : kind === "expr" ? 4 : 2;
|
|
@@ -13425,11 +13908,14 @@ function expandInnermost(source) {
|
|
|
13425
13908
|
}
|
|
13426
13909
|
|
|
13427
13910
|
// packages/parser/src/parser/preprocess/expr/index.ts
|
|
13911
|
+
var MAX_EXPR_NESTING = 64;
|
|
13428
13912
|
function preprocessExpr(source) {
|
|
13429
13913
|
if (!source.includes("[[#"))
|
|
13430
13914
|
return source;
|
|
13431
13915
|
const sentinels = makeUniqueSentinels(source);
|
|
13432
13916
|
const { masked, placeholders } = maskRawRegions(source, sentinels);
|
|
13917
|
+
if (exceedsExprNestingLimit(masked))
|
|
13918
|
+
return source;
|
|
13433
13919
|
const reduced = reduceExpr(masked);
|
|
13434
13920
|
return restorePlaceholders(reduced, placeholders, sentinels);
|
|
13435
13921
|
}
|
|
@@ -13444,6 +13930,26 @@ function reduceExpr(source) {
|
|
|
13444
13930
|
}
|
|
13445
13931
|
return current2;
|
|
13446
13932
|
}
|
|
13933
|
+
function exceedsExprNestingLimit(source) {
|
|
13934
|
+
const expressionStack = [];
|
|
13935
|
+
let expressionDepth = 0;
|
|
13936
|
+
for (let i = 0;i < source.length; i++) {
|
|
13937
|
+
if (source.startsWith("[[", i)) {
|
|
13938
|
+
const isExpression = matchDirectiveKind(source, i) !== null;
|
|
13939
|
+
expressionStack.push(isExpression);
|
|
13940
|
+
if (isExpression && ++expressionDepth > MAX_EXPR_NESTING)
|
|
13941
|
+
return true;
|
|
13942
|
+
i++;
|
|
13943
|
+
continue;
|
|
13944
|
+
}
|
|
13945
|
+
if (source.startsWith("]]", i)) {
|
|
13946
|
+
if (expressionStack.pop())
|
|
13947
|
+
expressionDepth--;
|
|
13948
|
+
i++;
|
|
13949
|
+
}
|
|
13950
|
+
}
|
|
13951
|
+
return false;
|
|
13952
|
+
}
|
|
13447
13953
|
|
|
13448
13954
|
// packages/parser/src/parser/parse/source.ts
|
|
13449
13955
|
function prepareSourceForParse(source, options) {
|
|
@@ -13470,6 +13976,287 @@ function parse(source, options) {
|
|
|
13470
13976
|
});
|
|
13471
13977
|
return new Parser(tokens, options).parse();
|
|
13472
13978
|
}
|
|
13979
|
+
// packages/parser/src/pipeline/process.ts
|
|
13980
|
+
import {
|
|
13981
|
+
DEFAULT_SETTINGS as DEFAULT_SETTINGS2
|
|
13982
|
+
} from "@wdprlib/ast";
|
|
13983
|
+
|
|
13984
|
+
// packages/parser/src/parser/rules/block/module/resolution/resolve-async.ts
|
|
13985
|
+
async function resolveModulesWithAsyncParse(ast, dataProvider, options) {
|
|
13986
|
+
const registry = new ModuleDocumentRegistry;
|
|
13987
|
+
registry.register(ast);
|
|
13988
|
+
const parse2 = async (source) => registry.register(await options.parse(source));
|
|
13989
|
+
const [listPagesData, listUsersData, tagCloudData] = await Promise.all([
|
|
13990
|
+
buildListPagesDataMap(dataProvider, options.requirements.listPages ?? [], options.urlPath),
|
|
13991
|
+
buildListUsersDataMap(dataProvider, options.requirements.listUsers ?? []),
|
|
13992
|
+
buildTagCloudDataMap(dataProvider, options.requirements.tagCloud ?? [])
|
|
13993
|
+
]);
|
|
13994
|
+
const context = {
|
|
13995
|
+
dataProvider,
|
|
13996
|
+
listPagesData,
|
|
13997
|
+
listUsersData,
|
|
13998
|
+
tagCloudData,
|
|
13999
|
+
options,
|
|
14000
|
+
parse: parse2
|
|
14001
|
+
};
|
|
14002
|
+
const state = { listPagesId: 0, listUsersId: 0, tagCloudId: 0 };
|
|
14003
|
+
const resolvedElements = await resolveElements(ast.elements, context, state);
|
|
14004
|
+
const { elements, styles, anchoredStyles } = collectStyles(resolvedElements);
|
|
14005
|
+
const intermediate = { ...ast, elements };
|
|
14006
|
+
const mergedStyles = mergeCollectedStyles(ast.styles, styles, new Map, anchoredStyles);
|
|
14007
|
+
if (mergedStyles.length > 0)
|
|
14008
|
+
intermediate.styles = mergedStyles;
|
|
14009
|
+
else
|
|
14010
|
+
delete intermediate.styles;
|
|
14011
|
+
return {
|
|
14012
|
+
ast: registry.finalize(intermediate, elements, options.pageTags),
|
|
14013
|
+
diagnostics: registry.diagnostics
|
|
14014
|
+
};
|
|
14015
|
+
}
|
|
14016
|
+
async function resolveElements(elements, context, state) {
|
|
14017
|
+
const result = [];
|
|
14018
|
+
for (const element of elements) {
|
|
14019
|
+
if (element.element === "module") {
|
|
14020
|
+
const resolved = await resolveModuleElement(element, context, state);
|
|
14021
|
+
if (resolved !== null) {
|
|
14022
|
+
result.push(...resolved);
|
|
14023
|
+
continue;
|
|
14024
|
+
}
|
|
14025
|
+
}
|
|
14026
|
+
if (element.element === "if-tags") {
|
|
14027
|
+
const resolution = resolveIfTags(element.data, context.options.pageTags);
|
|
14028
|
+
if (resolution.matched) {
|
|
14029
|
+
result.push(...await resolveElements(element.data.elements, context, state));
|
|
14030
|
+
}
|
|
14031
|
+
continue;
|
|
14032
|
+
}
|
|
14033
|
+
result.push(await resolveElementChildren(element, context, state));
|
|
14034
|
+
}
|
|
14035
|
+
return result;
|
|
14036
|
+
}
|
|
14037
|
+
async function resolveModuleElement(element, context, state) {
|
|
14038
|
+
if (isListPagesModule2(element.data)) {
|
|
14039
|
+
const id = state.listPagesId++;
|
|
14040
|
+
const data = context.listPagesData.get(id);
|
|
14041
|
+
const template = context.options.compiledListPagesTemplates.get(id);
|
|
14042
|
+
if (data && template)
|
|
14043
|
+
return resolveListPagesAsync(element.data, data, template, context.parse);
|
|
14044
|
+
return context.dataProvider.fetchListPages ? [] : [element];
|
|
14045
|
+
}
|
|
14046
|
+
if (isListUsersModule2(element.data)) {
|
|
14047
|
+
const id = state.listUsersId++;
|
|
14048
|
+
const data = context.listUsersData.get(id);
|
|
14049
|
+
const template = context.options.compiledListUsersTemplates?.get(id);
|
|
14050
|
+
if (data && template) {
|
|
14051
|
+
const variableContext = { user: data.user };
|
|
14052
|
+
return (await context.parse(template(variableContext))).elements;
|
|
14053
|
+
}
|
|
14054
|
+
return context.dataProvider.fetchListUsers ? [] : [element];
|
|
14055
|
+
}
|
|
14056
|
+
if (isTagCloudModule(element.data)) {
|
|
14057
|
+
const id = state.tagCloudId++;
|
|
14058
|
+
const data = context.tagCloudData.get(id);
|
|
14059
|
+
if (data)
|
|
14060
|
+
return resolveTagCloud(element.data, data);
|
|
14061
|
+
return context.dataProvider.fetchTagCloud ? [] : [element];
|
|
14062
|
+
}
|
|
14063
|
+
return null;
|
|
14064
|
+
}
|
|
14065
|
+
async function resolveListPagesAsync(module, data, template, parse2) {
|
|
14066
|
+
if (data.pages.length === 0)
|
|
14067
|
+
return [];
|
|
14068
|
+
const result = [];
|
|
14069
|
+
if (module["prepend-line"] && !module.separate) {
|
|
14070
|
+
result.push(...(await parse2(module["prepend-line"])).elements);
|
|
14071
|
+
}
|
|
14072
|
+
for (let i = 0;i < data.pages.length; i++) {
|
|
14073
|
+
const page = data.pages[i];
|
|
14074
|
+
if (!page)
|
|
14075
|
+
continue;
|
|
14076
|
+
const variableContext = {
|
|
14077
|
+
page,
|
|
14078
|
+
index: i + 1,
|
|
14079
|
+
total: data.totalCount,
|
|
14080
|
+
limit: module.limit,
|
|
14081
|
+
site: data.site
|
|
14082
|
+
};
|
|
14083
|
+
const parsed = await parse2(template(variableContext));
|
|
14084
|
+
if (module.separate) {
|
|
14085
|
+
result.push({
|
|
14086
|
+
element: "container",
|
|
14087
|
+
data: {
|
|
14088
|
+
type: "div",
|
|
14089
|
+
attributes: { class: "list-pages-item" },
|
|
14090
|
+
elements: parsed.elements
|
|
14091
|
+
}
|
|
14092
|
+
});
|
|
14093
|
+
} else {
|
|
14094
|
+
result.push(...parsed.elements);
|
|
14095
|
+
}
|
|
14096
|
+
}
|
|
14097
|
+
if (module["append-line"] && !module.separate) {
|
|
14098
|
+
result.push(...(await parse2(module["append-line"])).elements);
|
|
14099
|
+
}
|
|
14100
|
+
return module.wrapper ? [
|
|
14101
|
+
{
|
|
14102
|
+
element: "container",
|
|
14103
|
+
data: {
|
|
14104
|
+
type: "div",
|
|
14105
|
+
attributes: { class: "list-pages-box" },
|
|
14106
|
+
elements: result
|
|
14107
|
+
}
|
|
14108
|
+
}
|
|
14109
|
+
] : result;
|
|
14110
|
+
}
|
|
14111
|
+
async function resolveElementChildren(element, context, state) {
|
|
14112
|
+
if (element.element === "list") {
|
|
14113
|
+
const items = [];
|
|
14114
|
+
for (const item of element.data.items) {
|
|
14115
|
+
if (item["item-type"] === "elements") {
|
|
14116
|
+
items.push({ ...item, elements: await resolveElements(item.elements, context, state) });
|
|
14117
|
+
} else {
|
|
14118
|
+
const resolved = (await resolveElements([listElement(item.data)], context, state))[0];
|
|
14119
|
+
items.push(resolved?.element === "list" ? { ...item, data: resolved.data } : item);
|
|
14120
|
+
}
|
|
14121
|
+
}
|
|
14122
|
+
return { ...element, data: { ...element.data, items } };
|
|
14123
|
+
}
|
|
14124
|
+
if (element.element === "table") {
|
|
14125
|
+
const rows = [];
|
|
14126
|
+
for (const row of element.data.rows) {
|
|
14127
|
+
const cells = [];
|
|
14128
|
+
for (const cell of row.cells) {
|
|
14129
|
+
cells.push({ ...cell, elements: await resolveElements(cell.elements, context, state) });
|
|
14130
|
+
}
|
|
14131
|
+
rows.push({ ...row, cells });
|
|
14132
|
+
}
|
|
14133
|
+
return { ...element, data: { ...element.data, rows } };
|
|
14134
|
+
}
|
|
14135
|
+
if (element.element === "definition-list") {
|
|
14136
|
+
const entries = [];
|
|
14137
|
+
for (const entry of element.data) {
|
|
14138
|
+
entries.push({
|
|
14139
|
+
...entry,
|
|
14140
|
+
key: await resolveElements(entry.key, context, state),
|
|
14141
|
+
value: await resolveElements(entry.value, context, state)
|
|
14142
|
+
});
|
|
14143
|
+
}
|
|
14144
|
+
return { ...element, data: entries };
|
|
14145
|
+
}
|
|
14146
|
+
if (element.element === "tab-view") {
|
|
14147
|
+
const tabs = [];
|
|
14148
|
+
for (const tab of element.data) {
|
|
14149
|
+
tabs.push({ ...tab, elements: await resolveElements(tab.elements, context, state) });
|
|
14150
|
+
}
|
|
14151
|
+
return { ...element, data: tabs };
|
|
14152
|
+
}
|
|
14153
|
+
const children = getGenericElementChildren(element);
|
|
14154
|
+
return children === null ? element : withGenericElementChildren(element, await resolveElements(children, context, state));
|
|
14155
|
+
}
|
|
14156
|
+
|
|
14157
|
+
// packages/parser/src/pipeline/process.ts
|
|
14158
|
+
var DEFAULT_MODULE_MAX_PASSES = 5;
|
|
14159
|
+
var PIPELINE_DIAGNOSTIC_POSITION = {
|
|
14160
|
+
start: { line: 1, column: 1, offset: 0 },
|
|
14161
|
+
end: { line: 1, column: 1, offset: 0 }
|
|
14162
|
+
};
|
|
14163
|
+
async function processWikitext(source, options) {
|
|
14164
|
+
const settings = options.settings ?? DEFAULT_SETTINGS2;
|
|
14165
|
+
const callbackContext = {
|
|
14166
|
+
page: options.page,
|
|
14167
|
+
settings
|
|
14168
|
+
};
|
|
14169
|
+
const dependencies = [];
|
|
14170
|
+
const diagnostics = [];
|
|
14171
|
+
const fetchInclude = createRequestIncludeFetcher(options.dataProvider?.fetchInclude ? (pageRef) => options.dataProvider.fetchInclude(pageRef, callbackContext) : undefined);
|
|
14172
|
+
const resolveSource = async (input) => {
|
|
14173
|
+
if (!fetchInclude)
|
|
14174
|
+
return input;
|
|
14175
|
+
const resolution = await resolveIncludesAsyncWithTrace(input, fetchInclude, {
|
|
14176
|
+
maxIterations: options.includeMaxIterations,
|
|
14177
|
+
settings
|
|
14178
|
+
});
|
|
14179
|
+
dependencies.push(...resolution.dependencies);
|
|
14180
|
+
if (resolution.reachedMaxIterations) {
|
|
14181
|
+
diagnostics.push(createLimitDiagnostic("include-resolution-limit", `Include expansion stopped after ${options.includeMaxIterations ?? 10} iterations.`));
|
|
14182
|
+
}
|
|
14183
|
+
return resolution.source;
|
|
14184
|
+
};
|
|
14185
|
+
const expandedSource = await resolveSource(source);
|
|
14186
|
+
const initial = parse(expandedSource, {
|
|
14187
|
+
settings,
|
|
14188
|
+
pageTags: options.page.tags,
|
|
14189
|
+
appendImplicitFootnoteBlock: false
|
|
14190
|
+
});
|
|
14191
|
+
diagnostics.push(...initial.diagnostics);
|
|
14192
|
+
const dataProvider = createModuleDataProvider(options, callbackContext);
|
|
14193
|
+
const parseFragment = async (fragmentSource) => parse(await resolveSource(fragmentSource), {
|
|
14194
|
+
settings,
|
|
14195
|
+
pageTags: options.page.tags,
|
|
14196
|
+
appendImplicitFootnoteBlock: false
|
|
14197
|
+
});
|
|
14198
|
+
let ast = initial.ast;
|
|
14199
|
+
for (let pass = 0;pass < DEFAULT_MODULE_MAX_PASSES; pass++) {
|
|
14200
|
+
const extraction = extractDataRequirements(ast);
|
|
14201
|
+
if (pass > 0 && !hasResolvableRequirements(extraction.requirements, options.dataProvider)) {
|
|
14202
|
+
break;
|
|
14203
|
+
}
|
|
14204
|
+
const resolved = await resolveModulesWithAsyncParse(ast, dataProvider, {
|
|
14205
|
+
parse: parseFragment,
|
|
14206
|
+
compiledListPagesTemplates: extraction.compiledListPagesTemplates,
|
|
14207
|
+
compiledListUsersTemplates: extraction.compiledListUsersTemplates,
|
|
14208
|
+
requirements: extraction.requirements,
|
|
14209
|
+
urlPath: options.page.urlPath,
|
|
14210
|
+
pageTags: options.page.tags
|
|
14211
|
+
});
|
|
14212
|
+
ast = resolved.ast;
|
|
14213
|
+
diagnostics.push(...resolved.diagnostics);
|
|
14214
|
+
}
|
|
14215
|
+
if (hasResolvableRequirements(extractDataRequirements(ast).requirements, options.dataProvider)) {
|
|
14216
|
+
diagnostics.push(createLimitDiagnostic("module-resolution-limit", `Module resolution stopped after ${DEFAULT_MODULE_MAX_PASSES} passes.`));
|
|
14217
|
+
}
|
|
14218
|
+
return {
|
|
14219
|
+
ast,
|
|
14220
|
+
page: options.page,
|
|
14221
|
+
settings,
|
|
14222
|
+
diagnostics,
|
|
14223
|
+
dependencies
|
|
14224
|
+
};
|
|
14225
|
+
}
|
|
14226
|
+
function hasResolvableRequirements(requirements, provider) {
|
|
14227
|
+
return Boolean(provider?.fetchListPages && requirements.listPages.length > 0 || provider?.fetchListUsers && requirements.listUsers.length > 0 || provider?.fetchTagCloud && requirements.tagCloud.length > 0);
|
|
14228
|
+
}
|
|
14229
|
+
function createLimitDiagnostic(code, message) {
|
|
14230
|
+
return {
|
|
14231
|
+
severity: "warning",
|
|
14232
|
+
code,
|
|
14233
|
+
message,
|
|
14234
|
+
position: PIPELINE_DIAGNOSTIC_POSITION
|
|
14235
|
+
};
|
|
14236
|
+
}
|
|
14237
|
+
function createModuleDataProvider(options, context) {
|
|
14238
|
+
const provider = options.dataProvider;
|
|
14239
|
+
return {
|
|
14240
|
+
fetchListPages: provider?.fetchListPages ? (query, requirement) => provider.fetchListPages(query, requirement, context) : undefined,
|
|
14241
|
+
fetchListUsers: provider?.fetchListUsers ? (requirement) => provider.fetchListUsers(requirement, context) : undefined,
|
|
14242
|
+
fetchTagCloud: provider?.fetchTagCloud ? (requirement) => provider.fetchTagCloud(requirement, context) : undefined,
|
|
14243
|
+
getPageTags: () => options.page.tags
|
|
14244
|
+
};
|
|
14245
|
+
}
|
|
14246
|
+
function createRequestIncludeFetcher(fetcher) {
|
|
14247
|
+
if (!fetcher)
|
|
14248
|
+
return;
|
|
14249
|
+
const cache = new Map;
|
|
14250
|
+
return (pageRef) => {
|
|
14251
|
+
const key = `${pageRef.site ?? ""}:${pageRef.page.toLowerCase()}`;
|
|
14252
|
+
const cached = cache.get(key);
|
|
14253
|
+
if (cached)
|
|
14254
|
+
return cached;
|
|
14255
|
+
const result = fetcher(pageRef).catch(() => null);
|
|
14256
|
+
cache.set(key, result);
|
|
14257
|
+
return result;
|
|
14258
|
+
};
|
|
14259
|
+
}
|
|
13473
14260
|
export {
|
|
13474
14261
|
tokenize,
|
|
13475
14262
|
text,
|
|
@@ -13477,8 +14264,10 @@ export {
|
|
|
13477
14264
|
resolveModules,
|
|
13478
14265
|
resolveListUsers,
|
|
13479
14266
|
resolveIncludesWithTrace,
|
|
14267
|
+
resolveIncludesAsyncWithTrace,
|
|
13480
14268
|
resolveIncludesAsync,
|
|
13481
14269
|
resolveIncludes,
|
|
14270
|
+
processWikitext,
|
|
13482
14271
|
preprocessIftags,
|
|
13483
14272
|
parseTags,
|
|
13484
14273
|
parseParent,
|
|
@@ -13489,6 +14278,7 @@ export {
|
|
|
13489
14278
|
parse,
|
|
13490
14279
|
paragraph,
|
|
13491
14280
|
normalizeQuery,
|
|
14281
|
+
matchesListPagesSelectors,
|
|
13492
14282
|
listItemSubList,
|
|
13493
14283
|
listItemElements,
|
|
13494
14284
|
list,
|
|
@@ -13502,6 +14292,7 @@ export {
|
|
|
13502
14292
|
extractListUsersVariables,
|
|
13503
14293
|
extractIncludeReferences,
|
|
13504
14294
|
extractDataRequirements,
|
|
14295
|
+
definePageData,
|
|
13505
14296
|
createToken,
|
|
13506
14297
|
createSettings,
|
|
13507
14298
|
createPosition,
|
|
@@ -13513,5 +14304,5 @@ export {
|
|
|
13513
14304
|
STYLE_SLOT_PREFIX2 as STYLE_SLOT_PREFIX,
|
|
13514
14305
|
Parser,
|
|
13515
14306
|
Lexer,
|
|
13516
|
-
|
|
14307
|
+
DEFAULT_SETTINGS3 as DEFAULT_SETTINGS
|
|
13517
14308
|
};
|