@wdprlib/parser 5.4.0 → 6.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/dist/index.cjs +420 -127
- package/dist/index.d.cts +93 -8
- package/dist/index.d.ts +93 -8
- package/dist/index.js +380 -84
- package/package.json +2 -2
- package/src/build-info.generated.ts +2 -2
- package/src/index.ts +3 -0
- package/src/parser/rules/block/module/index.ts +3 -2
- package/src/parser/rules/block/module/listpages/extraction/listpages.ts +5 -0
- package/src/parser/rules/block/module/listpages/extraction/query.ts +1 -0
- package/src/parser/rules/block/module/listpages/extraction/template.ts +16 -0
- package/src/parser/rules/block/module/listpages/extraction/variables.ts +1 -0
- package/src/parser/rules/block/module/listpages/index.ts +1 -0
- package/src/parser/rules/block/module/listpages/normalization/order-parent.ts +9 -1
- package/src/parser/rules/block/module/listpages/normalize.ts +1 -0
- package/src/parser/rules/block/module/listpages/parser.ts +1 -0
- package/src/parser/rules/block/module/listpages/resolve.ts +4 -2
- package/src/parser/rules/block/module/listpages/template/excerpt.ts +63 -0
- package/src/parser/rules/block/module/listpages/template/format/content.ts +0 -32
- package/src/parser/rules/block/module/listpages/template/format/index.ts +1 -1
- package/src/parser/rules/block/module/listpages/template/getters/index.ts +14 -0
- package/src/parser/rules/block/module/listpages/template/getters/parameterized.ts +3 -1
- package/src/parser/rules/block/module/listpages/template/getters/registered.ts +52 -0
- package/src/parser/rules/block/module/listpages/template/getters/simple.ts +15 -5
- package/src/parser/rules/block/module/listpages/template/literal.ts +6 -0
- package/src/parser/rules/block/module/listpages/template/syntax.ts +10 -1
- package/src/parser/rules/block/module/listpages/types/data-requirements.ts +6 -0
- package/src/parser/rules/block/module/listpages/types/external-data.ts +36 -2
- package/src/parser/rules/block/module/listpages/types/normalized-query.ts +14 -4
- package/src/parser/rules/block/module/listpages/types/query.ts +2 -0
- package/src/parser/rules/block/module/listpages/types/variables.ts +5 -0
- package/src/parser/rules/block/module/listpages/url-resolution/fields.ts +2 -0
- package/src/parser/rules/block/module/listusers/resolve.ts +2 -1
- package/src/parser/rules/block/module/mapping.ts +2 -1
- package/src/parser/rules/block/module/rate/index.ts +16 -19
- package/src/parser/rules/block/module/rate/resolve.ts +108 -0
- package/src/parser/rules/block/module/rate/types.ts +6 -16
- package/src/parser/rules/block/module/resolution/resolve-async.ts +2 -1
- package/src/parser/rules/block/module/resolve.ts +10 -8
- package/src/parser/rules/block/module/types-common.ts +4 -0
- package/src/parser/rules/inline/parsing/inline-content.ts +10 -1
- package/src/parser/rules/inline/size/content.ts +31 -4
- package/src/pipeline/process.ts +13 -0
- package/src/pipeline/types.ts +19 -0
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// packages/parser/src/build-info.generated.ts
|
|
2
2
|
var buildInfo = Object.freeze({
|
|
3
|
-
version: "
|
|
4
|
-
sha: "
|
|
3
|
+
version: "6.0.0",
|
|
4
|
+
sha: "705ff97e22abd7bfb49d7f8f30087e6f09654c91",
|
|
5
5
|
dirty: false
|
|
6
6
|
});
|
|
7
7
|
|
|
@@ -2627,7 +2627,8 @@ function parseInlineUntil(ctx, endType) {
|
|
|
2627
2627
|
let pos = ctx.pos;
|
|
2628
2628
|
let consumedEmptyRaw = false;
|
|
2629
2629
|
const paragraphMode = endType === "PARAGRAPH_BREAK";
|
|
2630
|
-
const
|
|
2630
|
+
const preserveNewlines = endType === "EOF";
|
|
2631
|
+
const multiline = paragraphMode || preserveNewlines || FORMATTING_CLOSE_TOKENS.has(endType);
|
|
2631
2632
|
let inlineEnd = ctx.scope.inlineEnd ?? ctx.tokens.length;
|
|
2632
2633
|
if (!multiline) {
|
|
2633
2634
|
for (let end = ctx.pos;end < inlineEnd; end++) {
|
|
@@ -2665,6 +2666,12 @@ function parseInlineUntil(ctx, endType) {
|
|
|
2665
2666
|
if (!multiline && token5.type === "NEWLINE") {
|
|
2666
2667
|
break;
|
|
2667
2668
|
}
|
|
2669
|
+
if (preserveNewlines && token5.type === "NEWLINE") {
|
|
2670
|
+
nodes.push({ element: "text", data: token5.value });
|
|
2671
|
+
pos++;
|
|
2672
|
+
consumed++;
|
|
2673
|
+
continue;
|
|
2674
|
+
}
|
|
2668
2675
|
if (multiline && token5.type === "NEWLINE" && !ctx.scope.tableFormatting) {
|
|
2669
2676
|
const boundary = getParagraphNewlineBoundary(ctx, pos, nodes.length > 0);
|
|
2670
2677
|
if (boundary.shouldBreak) {
|
|
@@ -5697,8 +5704,18 @@ var rateModuleRule = {
|
|
|
5697
5704
|
name: "module-rate",
|
|
5698
5705
|
acceptsNames: ["rate"],
|
|
5699
5706
|
hasBody: false,
|
|
5700
|
-
parse() {
|
|
5701
|
-
return { module: "rate" };
|
|
5707
|
+
parse(_ctx, _pos, args) {
|
|
5708
|
+
return { module: "rate", ref: Object.keys(args).length === 0 ? { kind: "main" } : null };
|
|
5709
|
+
}
|
|
5710
|
+
};
|
|
5711
|
+
var customRateModuleRule = {
|
|
5712
|
+
name: "module-custom-rate",
|
|
5713
|
+
acceptsNames: ["customrate"],
|
|
5714
|
+
hasBody: false,
|
|
5715
|
+
parse(_ctx, _pos, args) {
|
|
5716
|
+
const key = args.key;
|
|
5717
|
+
const valid = key !== undefined && key !== "" && Object.keys(args).every((name) => name === "key");
|
|
5718
|
+
return { module: "custom-rate", ref: valid ? { kind: "custom", axisKey: key } : null };
|
|
5702
5719
|
}
|
|
5703
5720
|
};
|
|
5704
5721
|
|
|
@@ -5833,6 +5850,7 @@ var listPagesModuleRule = {
|
|
|
5833
5850
|
"created-at": createdAt,
|
|
5834
5851
|
"updated-at": updatedAt,
|
|
5835
5852
|
rating,
|
|
5853
|
+
"rating-axis": args["rating-axis"],
|
|
5836
5854
|
votes,
|
|
5837
5855
|
name,
|
|
5838
5856
|
fullname,
|
|
@@ -5976,6 +5994,7 @@ var tagCloudModuleRule = {
|
|
|
5976
5994
|
// packages/parser/src/parser/rules/block/module/mapping.ts
|
|
5977
5995
|
var MODULE_RULES = [
|
|
5978
5996
|
rateModuleRule,
|
|
5997
|
+
customRateModuleRule,
|
|
5979
5998
|
cssModuleRule,
|
|
5980
5999
|
backlinksModuleRule,
|
|
5981
6000
|
categoriesModuleRule,
|
|
@@ -6546,22 +6565,6 @@ function getDayOfYear(date) {
|
|
|
6546
6565
|
function splitContentSections(content) {
|
|
6547
6566
|
return content.split(/^={4,}$/m).map((section) => section.trim());
|
|
6548
6567
|
}
|
|
6549
|
-
function getSummary(page) {
|
|
6550
|
-
if (page.content) {
|
|
6551
|
-
const sections = splitContentSections(page.content);
|
|
6552
|
-
if (sections.length > 1) {
|
|
6553
|
-
return sections[0]?.trim() ?? "";
|
|
6554
|
-
}
|
|
6555
|
-
}
|
|
6556
|
-
return getFirstParagraph(page.content);
|
|
6557
|
-
}
|
|
6558
|
-
function getFirstParagraph(content) {
|
|
6559
|
-
if (!content)
|
|
6560
|
-
return "";
|
|
6561
|
-
const stripped = content.replace(/^(\+{1,6}) (.*)/gm, "").replace(/^\[\[toc(\s[^\]]+)?\]\]/gim, "").replace(/^\[\[\/?div(\s[^\]]+)?\]\]/gim, "").replace(/^\[\[\/?module(\s[^\]]+)?\]\]/gim, "").trim();
|
|
6562
|
-
const paragraphs = stripped.split(/\n{2,}/);
|
|
6563
|
-
return paragraphs[0]?.trim() ?? "";
|
|
6564
|
-
}
|
|
6565
6568
|
// packages/parser/src/parser/rules/block/module/listpages/template/format/tags.ts
|
|
6566
6569
|
function formatTagsLinked(tags, prefix) {
|
|
6567
6570
|
if (tags.length === 0)
|
|
@@ -6574,6 +6577,16 @@ function formatUserLinked(user) {
|
|
|
6574
6577
|
return "Anonymous";
|
|
6575
6578
|
return `[[*user ${user.name}]]`;
|
|
6576
6579
|
}
|
|
6580
|
+
// packages/parser/src/parser/rules/block/module/listpages/template/getters/parameterized.ts
|
|
6581
|
+
import { excerptText } from "@wdprlib/ast";
|
|
6582
|
+
|
|
6583
|
+
// packages/parser/src/parser/rules/block/module/listpages/template/literal.ts
|
|
6584
|
+
function literalWikitext(value) {
|
|
6585
|
+
if (value === "")
|
|
6586
|
+
return "";
|
|
6587
|
+
return `@<${Array.from(value, (char) => `&#${char.codePointAt(0)};`).join("")}>@`;
|
|
6588
|
+
}
|
|
6589
|
+
|
|
6577
6590
|
// packages/parser/src/parser/rules/block/module/listpages/template/getters/parameterized.ts
|
|
6578
6591
|
function createBraceParamGetter(name, param) {
|
|
6579
6592
|
switch (name) {
|
|
@@ -6602,7 +6615,7 @@ function createParenParamGetter(name, param) {
|
|
|
6602
6615
|
if (name !== "preview")
|
|
6603
6616
|
return null;
|
|
6604
6617
|
const len = Number(param);
|
|
6605
|
-
return (ctx) => (ctx.page.
|
|
6618
|
+
return (ctx) => literalWikitext(excerptText(ctx.page.readableText ?? "", { maxLength: len }));
|
|
6606
6619
|
}
|
|
6607
6620
|
function createFormattedGetter(name, format) {
|
|
6608
6621
|
switch (name) {
|
|
@@ -6629,6 +6642,7 @@ function createTagsLinkedGetter(name, format) {
|
|
|
6629
6642
|
}
|
|
6630
6643
|
|
|
6631
6644
|
// packages/parser/src/parser/rules/block/module/listpages/template/getters/simple.ts
|
|
6645
|
+
import { countCharacters, excerptText as excerptText2 } from "@wdprlib/ast";
|
|
6632
6646
|
var DEFAULT_PREVIEW_LENGTH = 200;
|
|
6633
6647
|
var SIMPLE_GETTERS = {
|
|
6634
6648
|
created_at: (ctx) => formatDate(ctx.page.createdAt),
|
|
@@ -6658,14 +6672,14 @@ var SIMPLE_GETTERS = {
|
|
|
6658
6672
|
parent_title: (ctx) => ctx.page.parentTitle ?? "",
|
|
6659
6673
|
parent_title_linked: (ctx) => ctx.page.parentFullname ? `[[[${ctx.page.parentFullname} | ${ctx.page.parentTitle}]]]` : "",
|
|
6660
6674
|
content: (ctx) => ctx.page.content ?? "",
|
|
6661
|
-
preview: (ctx) => (ctx.page.
|
|
6662
|
-
summary: (ctx) =>
|
|
6663
|
-
first_paragraph: (ctx) =>
|
|
6675
|
+
preview: (ctx) => literalWikitext(excerptText2(ctx.page.readableText ?? "", { maxLength: DEFAULT_PREVIEW_LENGTH })),
|
|
6676
|
+
summary: (ctx) => literalWikitext(ctx.page.firstParagraph ?? ""),
|
|
6677
|
+
first_paragraph: (ctx) => literalWikitext(ctx.page.firstParagraph ?? ""),
|
|
6664
6678
|
tags: (ctx) => ctx.page.tags.join(" "),
|
|
6665
6679
|
_tags: (ctx) => ctx.page.hiddenTags.join(" "),
|
|
6666
6680
|
children: (ctx) => String(ctx.page.children),
|
|
6667
6681
|
comments: (ctx) => String(ctx.page.comments),
|
|
6668
|
-
size: (ctx) => String(ctx.page.size),
|
|
6682
|
+
size: (ctx) => ctx.page.readableText !== undefined ? String(countCharacters(ctx.page.readableText)) : ctx.page.size !== undefined ? String(ctx.page.size) : "",
|
|
6669
6683
|
rating: (ctx) => String(ctx.page.rating),
|
|
6670
6684
|
rating_votes: (ctx) => String(ctx.page.ratingVotes),
|
|
6671
6685
|
rating_percent: (ctx) => String(ctx.page.ratingPercent ?? 0),
|
|
@@ -6679,11 +6693,136 @@ var SIMPLE_GETTERS = {
|
|
|
6679
6693
|
site_domain: (ctx) => ctx.site.domain
|
|
6680
6694
|
};
|
|
6681
6695
|
|
|
6696
|
+
// packages/parser/src/parser/rules/block/module/listpages/template/getters/registered.ts
|
|
6697
|
+
function createRegisteredGetter(name, key, format) {
|
|
6698
|
+
if (name === "metadata")
|
|
6699
|
+
return (ctx) => {
|
|
6700
|
+
const metadata = ctx.page.metadata;
|
|
6701
|
+
const entry = metadata && Object.hasOwn(metadata, key) ? metadata[key] : null;
|
|
6702
|
+
if (!entry)
|
|
6703
|
+
return "";
|
|
6704
|
+
let value;
|
|
6705
|
+
switch (entry.type) {
|
|
6706
|
+
case "text":
|
|
6707
|
+
value = entry.value;
|
|
6708
|
+
break;
|
|
6709
|
+
case "number":
|
|
6710
|
+
value = String(entry.value);
|
|
6711
|
+
break;
|
|
6712
|
+
case "date":
|
|
6713
|
+
value = formatDate(entry.value, format);
|
|
6714
|
+
break;
|
|
6715
|
+
case "user":
|
|
6716
|
+
value = format === "id" ? String(entry.value.id) : format === "unix" ? entry.value.unixName : entry.value.name;
|
|
6717
|
+
break;
|
|
6718
|
+
}
|
|
6719
|
+
return literalWikitext(value);
|
|
6720
|
+
};
|
|
6721
|
+
if (name === "customrate" || name === "customrate_votes" || name === "customrate_percent")
|
|
6722
|
+
return (ctx) => {
|
|
6723
|
+
const ratings = ctx.page.customRates;
|
|
6724
|
+
const entry = ratings && Object.hasOwn(ratings, key) ? ratings[key] : null;
|
|
6725
|
+
if (!entry)
|
|
6726
|
+
return "";
|
|
6727
|
+
return String(name === "customrate" ? entry.points : name === "customrate_votes" ? entry.votes : entry.percent);
|
|
6728
|
+
};
|
|
6729
|
+
return null;
|
|
6730
|
+
}
|
|
6731
|
+
|
|
6732
|
+
// packages/parser/src/parser/rules/block/module/listpages/template/getters/index.ts
|
|
6733
|
+
import { compileTextExcerpt } from "@wdprlib/ast";
|
|
6734
|
+
|
|
6735
|
+
// packages/parser/src/parser/rules/block/module/listpages/template/excerpt.ts
|
|
6736
|
+
function findExcerptEnd(template, contentStart) {
|
|
6737
|
+
let quote;
|
|
6738
|
+
for (let cursor = contentStart + "excerpt{".length;cursor < template.length; cursor++) {
|
|
6739
|
+
const char = template[cursor];
|
|
6740
|
+
if (quote) {
|
|
6741
|
+
if (char === "\\")
|
|
6742
|
+
cursor++;
|
|
6743
|
+
else if (char === quote)
|
|
6744
|
+
quote = undefined;
|
|
6745
|
+
} else if (char === '"' || char === "'") {
|
|
6746
|
+
quote = char;
|
|
6747
|
+
} else if (char === "}") {
|
|
6748
|
+
return template.startsWith("%%", cursor + 1) ? cursor + 1 : -1;
|
|
6749
|
+
}
|
|
6750
|
+
}
|
|
6751
|
+
return -1;
|
|
6752
|
+
}
|
|
6753
|
+
function parseExcerptOptions(input) {
|
|
6754
|
+
if (input.length > 8192)
|
|
6755
|
+
return null;
|
|
6756
|
+
const attributes = new Map;
|
|
6757
|
+
let cursor = 0;
|
|
6758
|
+
while (cursor < input.length) {
|
|
6759
|
+
while (cursor < input.length && /\s/.test(input[cursor]))
|
|
6760
|
+
cursor++;
|
|
6761
|
+
if (cursor === input.length)
|
|
6762
|
+
break;
|
|
6763
|
+
const start = cursor;
|
|
6764
|
+
while (cursor < input.length && /[a-z]/.test(input[cursor]))
|
|
6765
|
+
cursor++;
|
|
6766
|
+
const name = input.slice(start, cursor);
|
|
6767
|
+
if (!["pattern", "flags", "group", "match", "max"].includes(name) || attributes.has(name))
|
|
6768
|
+
return null;
|
|
6769
|
+
while (cursor < input.length && /\s/.test(input[cursor]))
|
|
6770
|
+
cursor++;
|
|
6771
|
+
if (input[cursor++] !== "=")
|
|
6772
|
+
return null;
|
|
6773
|
+
while (cursor < input.length && /\s/.test(input[cursor]))
|
|
6774
|
+
cursor++;
|
|
6775
|
+
const quote = input[cursor++];
|
|
6776
|
+
if (quote !== '"' && quote !== "'")
|
|
6777
|
+
return null;
|
|
6778
|
+
let value = "";
|
|
6779
|
+
while (cursor < input.length && input[cursor] !== quote) {
|
|
6780
|
+
if (input[cursor] === "\\" && (input[cursor + 1] === quote || input[cursor + 1] === "\\")) {
|
|
6781
|
+
value += input[cursor + 1] === quote ? quote : "\\\\";
|
|
6782
|
+
cursor += 2;
|
|
6783
|
+
} else
|
|
6784
|
+
value += input[cursor++];
|
|
6785
|
+
}
|
|
6786
|
+
if (input[cursor++] !== quote)
|
|
6787
|
+
return null;
|
|
6788
|
+
if (cursor < input.length && !/\s/.test(input[cursor]))
|
|
6789
|
+
return null;
|
|
6790
|
+
attributes.set(name, value);
|
|
6791
|
+
}
|
|
6792
|
+
const pattern = attributes.get("pattern");
|
|
6793
|
+
if (pattern === undefined)
|
|
6794
|
+
return null;
|
|
6795
|
+
const group = attributes.get("group");
|
|
6796
|
+
const match = attributes.get("match");
|
|
6797
|
+
const max = attributes.get("max");
|
|
6798
|
+
if (match !== undefined && !/^\d+$/.test(match) || max !== undefined && !/^\d+$/.test(max))
|
|
6799
|
+
return null;
|
|
6800
|
+
return {
|
|
6801
|
+
pattern,
|
|
6802
|
+
flags: attributes.get("flags"),
|
|
6803
|
+
group: group === undefined ? undefined : /^\d+$/.test(group) ? Number(group) : group,
|
|
6804
|
+
match: match === undefined ? undefined : Number(match),
|
|
6805
|
+
maxLength: max === undefined ? undefined : Number(max)
|
|
6806
|
+
};
|
|
6807
|
+
}
|
|
6808
|
+
|
|
6682
6809
|
// packages/parser/src/parser/rules/block/module/listpages/template/getters/index.ts
|
|
6683
6810
|
function createVariableGetter(name, braceParam, parenParam, format) {
|
|
6811
|
+
if (name === "excerpt") {
|
|
6812
|
+
const options = braceParam === undefined ? null : parseExcerptOptions(braceParam);
|
|
6813
|
+
if (!options || parenParam !== undefined || format !== undefined)
|
|
6814
|
+
return () => "";
|
|
6815
|
+
const extract = compileTextExcerpt(options);
|
|
6816
|
+
return (ctx) => literalWikitext(extract(ctx.page.readableText ?? ""));
|
|
6817
|
+
}
|
|
6818
|
+
const registeredGetter = braceParam !== undefined ? createRegisteredGetter(name, braceParam, format) : null;
|
|
6819
|
+
if (registeredGetter)
|
|
6820
|
+
return registeredGetter;
|
|
6684
6821
|
const braceGetter = braceParam !== undefined ? createBraceParamGetter(name, braceParam) : null;
|
|
6685
6822
|
if (braceGetter)
|
|
6686
6823
|
return braceGetter;
|
|
6824
|
+
if (braceParam !== undefined)
|
|
6825
|
+
return () => "";
|
|
6687
6826
|
const parenGetter = parenParam !== undefined ? createParenParamGetter(name, parenParam) : null;
|
|
6688
6827
|
if (parenGetter)
|
|
6689
6828
|
return parenGetter;
|
|
@@ -6705,7 +6844,7 @@ function scanTemplateVariables(template) {
|
|
|
6705
6844
|
if (start === -1)
|
|
6706
6845
|
break;
|
|
6707
6846
|
const contentStart = start + 2;
|
|
6708
|
-
const end = template.indexOf("%%", contentStart);
|
|
6847
|
+
const end = template.slice(contentStart, contentStart + 8).toLowerCase() === "excerpt{" ? findExcerptEnd(template, contentStart) : template.indexOf("%%", contentStart);
|
|
6709
6848
|
if (end === -1)
|
|
6710
6849
|
break;
|
|
6711
6850
|
const parsed = parseTemplateVariableContent(template.slice(contentStart, end));
|
|
@@ -6728,6 +6867,11 @@ function parseTemplateVariableContent(content) {
|
|
|
6728
6867
|
if (cursor === 0)
|
|
6729
6868
|
return null;
|
|
6730
6869
|
const name = content.slice(0, cursor);
|
|
6870
|
+
if (name.toLowerCase() === "excerpt" && content[cursor] === "{") {
|
|
6871
|
+
if (!content.endsWith("}"))
|
|
6872
|
+
return null;
|
|
6873
|
+
return { name, braceParam: content.slice(cursor + 1, -1) };
|
|
6874
|
+
}
|
|
6731
6875
|
let braceParam;
|
|
6732
6876
|
let parenParam;
|
|
6733
6877
|
let format;
|
|
@@ -6807,6 +6951,7 @@ function buildQuery(module) {
|
|
|
6807
6951
|
updatedAt: module["updated-at"],
|
|
6808
6952
|
createdBy: module["created-by"],
|
|
6809
6953
|
rating: module.rating,
|
|
6954
|
+
ratingAxis: module["rating-axis"],
|
|
6810
6955
|
votes: module.votes,
|
|
6811
6956
|
name: module.name,
|
|
6812
6957
|
fullname: module.fullname,
|
|
@@ -6861,6 +7006,7 @@ var KNOWN_VARIABLES = new Set([
|
|
|
6861
7006
|
"parent_title_linked",
|
|
6862
7007
|
"content",
|
|
6863
7008
|
"preview",
|
|
7009
|
+
"excerpt",
|
|
6864
7010
|
"summary",
|
|
6865
7011
|
"first_paragraph",
|
|
6866
7012
|
"tags",
|
|
@@ -6898,12 +7044,24 @@ function extractVariablesFromTemplate(template) {
|
|
|
6898
7044
|
const contentIndices = new Set;
|
|
6899
7045
|
const previewLengths = new Set;
|
|
6900
7046
|
const formFields = new Set;
|
|
7047
|
+
const metadataKeys = new Set;
|
|
7048
|
+
const customRateKeys = new Set;
|
|
6901
7049
|
let tagsLinkPrefix;
|
|
6902
7050
|
let hiddenTagsLinkPrefix;
|
|
6903
7051
|
for (const match of scanTemplateVariables(template)) {
|
|
6904
7052
|
const varName = match.name.toLowerCase();
|
|
6905
7053
|
if (match.braceParam !== undefined) {
|
|
6906
7054
|
switch (varName) {
|
|
7055
|
+
case "metadata":
|
|
7056
|
+
metadataKeys.add(match.braceParam);
|
|
7057
|
+
variables.add("metadata");
|
|
7058
|
+
continue;
|
|
7059
|
+
case "customrate":
|
|
7060
|
+
case "customrate_votes":
|
|
7061
|
+
case "customrate_percent":
|
|
7062
|
+
customRateKeys.add(match.braceParam);
|
|
7063
|
+
variables.add(varName);
|
|
7064
|
+
continue;
|
|
6907
7065
|
case "content":
|
|
6908
7066
|
contentIndices.add(Number(match.braceParam));
|
|
6909
7067
|
variables.add("content_n");
|
|
@@ -6953,6 +7111,8 @@ function extractVariablesFromTemplate(template) {
|
|
|
6953
7111
|
contentIndices: Array.from(contentIndices).sort((a, b) => a - b),
|
|
6954
7112
|
previewLengths: Array.from(previewLengths).sort((a, b) => a - b),
|
|
6955
7113
|
formFields: Array.from(formFields).sort(),
|
|
7114
|
+
metadataKeys: [...metadataKeys].sort(),
|
|
7115
|
+
customRateKeys: [...customRateKeys].sort(),
|
|
6956
7116
|
tagsLinkPrefix,
|
|
6957
7117
|
hiddenTagsLinkPrefix
|
|
6958
7118
|
};
|
|
@@ -6974,6 +7134,9 @@ function extractListPagesModule(listPages, state, result) {
|
|
|
6974
7134
|
contentSectionIndices: extraction.contentIndices,
|
|
6975
7135
|
previewLengths: extraction.previewLengths,
|
|
6976
7136
|
formFields: extraction.formFields,
|
|
7137
|
+
metadataKeys: extraction.metadataKeys,
|
|
7138
|
+
customRateKeys: extraction.customRateKeys,
|
|
7139
|
+
needsReadableText: extraction.variables.some((name) => ["preview", "preview_n", "summary", "first_paragraph", "excerpt"].includes(name)),
|
|
6977
7140
|
tagsLinkPrefix: extraction.tagsLinkPrefix,
|
|
6978
7141
|
hiddenTagsLinkPrefix: extraction.hiddenTagsLinkPrefix,
|
|
6979
7142
|
urlAttrPrefix: listPages["url-attr-prefix"],
|
|
@@ -7306,13 +7469,101 @@ function wrapListPagesResult(module, items, parse, data) {
|
|
|
7306
7469
|
return result;
|
|
7307
7470
|
}
|
|
7308
7471
|
|
|
7472
|
+
// packages/parser/src/parser/rules/block/module/rate/resolve.ts
|
|
7473
|
+
function refKey(ref) {
|
|
7474
|
+
return ref.kind === "main" ? "main" : `custom:${ref.axisKey}`;
|
|
7475
|
+
}
|
|
7476
|
+
async function resolveRatings(ast, fetchRatings) {
|
|
7477
|
+
const refs = new Map;
|
|
7478
|
+
mapDocument(ast, (element) => {
|
|
7479
|
+
if (isRating(element) && element.data.ref)
|
|
7480
|
+
refs.set(refKey(element.data.ref), element.data.ref);
|
|
7481
|
+
return element;
|
|
7482
|
+
});
|
|
7483
|
+
const states = new Map;
|
|
7484
|
+
if (fetchRatings && refs.size > 0) {
|
|
7485
|
+
for (const state of await fetchRatings([...refs.values()])) {
|
|
7486
|
+
const key = refKey(state.ref);
|
|
7487
|
+
if (refs.has(key))
|
|
7488
|
+
states.set(key, state);
|
|
7489
|
+
}
|
|
7490
|
+
}
|
|
7491
|
+
return mapDocument(ast, (element) => {
|
|
7492
|
+
if (!isRating(element))
|
|
7493
|
+
return element;
|
|
7494
|
+
const { state: _previous, ...data } = element.data;
|
|
7495
|
+
const state = data.ref ? states.get(refKey(data.ref)) : undefined;
|
|
7496
|
+
return { ...element, data: state ? { ...data, state } : data };
|
|
7497
|
+
});
|
|
7498
|
+
}
|
|
7499
|
+
function suppressModuleRatings(result) {
|
|
7500
|
+
const ast = mapDocument(getModuleParseAst(result), (element) => isRating(element) ? null : element);
|
|
7501
|
+
return "ast" in result ? { ...result, ast } : ast;
|
|
7502
|
+
}
|
|
7503
|
+
function isRating(element) {
|
|
7504
|
+
return element.element === "module" && (element.data.module === "rate" || element.data.module === "custom-rate");
|
|
7505
|
+
}
|
|
7506
|
+
function mapDocument(ast, transform) {
|
|
7507
|
+
const map = (elements) => elements.flatMap((original) => {
|
|
7508
|
+
const element = transform(original);
|
|
7509
|
+
if (!element)
|
|
7510
|
+
return [];
|
|
7511
|
+
if (element.element === "if") {
|
|
7512
|
+
return [
|
|
7513
|
+
{
|
|
7514
|
+
...element,
|
|
7515
|
+
data: {
|
|
7516
|
+
...element.data,
|
|
7517
|
+
then: map(element.data.then),
|
|
7518
|
+
else: map(element.data.else)
|
|
7519
|
+
}
|
|
7520
|
+
}
|
|
7521
|
+
];
|
|
7522
|
+
}
|
|
7523
|
+
if (element.element === "ifexpr") {
|
|
7524
|
+
return [
|
|
7525
|
+
{
|
|
7526
|
+
...element,
|
|
7527
|
+
data: {
|
|
7528
|
+
...element.data,
|
|
7529
|
+
then: map(element.data.then),
|
|
7530
|
+
else: map(element.data.else)
|
|
7531
|
+
}
|
|
7532
|
+
}
|
|
7533
|
+
];
|
|
7534
|
+
}
|
|
7535
|
+
if (element.element === "bibliography-block") {
|
|
7536
|
+
return [
|
|
7537
|
+
{
|
|
7538
|
+
...element,
|
|
7539
|
+
data: {
|
|
7540
|
+
...element.data,
|
|
7541
|
+
entries: element.data.entries.map((entry) => ({
|
|
7542
|
+
...entry,
|
|
7543
|
+
key: map(entry.key),
|
|
7544
|
+
value: map(entry.value)
|
|
7545
|
+
}))
|
|
7546
|
+
}
|
|
7547
|
+
}
|
|
7548
|
+
];
|
|
7549
|
+
}
|
|
7550
|
+
return [mapElementChildren(element, map)];
|
|
7551
|
+
});
|
|
7552
|
+
return {
|
|
7553
|
+
...ast,
|
|
7554
|
+
elements: map(ast.elements),
|
|
7555
|
+
...ast.footnotes ? { footnotes: ast.footnotes.map(map) } : {}
|
|
7556
|
+
};
|
|
7557
|
+
}
|
|
7558
|
+
|
|
7309
7559
|
// packages/parser/src/parser/rules/block/module/listpages/resolve.ts
|
|
7310
7560
|
function isListPagesModule2(module) {
|
|
7311
7561
|
return module.module === "list-pages";
|
|
7312
7562
|
}
|
|
7313
7563
|
function resolveListPages(module, data, compiledTemplate, parse) {
|
|
7314
|
-
const
|
|
7315
|
-
|
|
7564
|
+
const parseFragment = (source) => suppressModuleRatings(parse(source));
|
|
7565
|
+
const items = renderListPagesItems(module, data, compiledTemplate, parseFragment);
|
|
7566
|
+
return wrapListPagesResult(module, items, parseFragment, data);
|
|
7316
7567
|
}
|
|
7317
7568
|
// packages/parser/src/parser/rules/block/module/listpages/types/external-data.ts
|
|
7318
7569
|
function definePageData(input) {
|
|
@@ -7326,7 +7577,6 @@ function definePageData(input) {
|
|
|
7326
7577
|
hiddenTags: input.hiddenTags ?? [],
|
|
7327
7578
|
children: input.children ?? 0,
|
|
7328
7579
|
comments: input.comments ?? 0,
|
|
7329
|
-
size: input.size ?? 0,
|
|
7330
7580
|
rating: input.rating ?? 0,
|
|
7331
7581
|
ratingVotes: input.ratingVotes ?? 0,
|
|
7332
7582
|
revisions: input.revisions ?? 0
|
|
@@ -7404,6 +7654,7 @@ var URL_RESOLVABLE_FIELDS = [
|
|
|
7404
7654
|
aliases: ["createdby", "created_by"]
|
|
7405
7655
|
},
|
|
7406
7656
|
{ attr: "rating", queryKey: "rating", type: "string" },
|
|
7657
|
+
{ attr: "rating-axis", queryKey: "ratingAxis", type: "string" },
|
|
7407
7658
|
{ attr: "votes", queryKey: "votes", type: "string" },
|
|
7408
7659
|
{ attr: "reverse", queryKey: "reverse", type: "boolean" }
|
|
7409
7660
|
];
|
|
@@ -7505,6 +7756,7 @@ var ORDER_FIELD_MAP = {
|
|
|
7505
7756
|
votes: "votes",
|
|
7506
7757
|
revisions: "revisions",
|
|
7507
7758
|
comments: "comments",
|
|
7759
|
+
commented_at: "commented_at",
|
|
7508
7760
|
pagelength: "size",
|
|
7509
7761
|
size: "size",
|
|
7510
7762
|
random: "random",
|
|
@@ -7512,6 +7764,13 @@ var ORDER_FIELD_MAP = {
|
|
|
7512
7764
|
updated_at: "updated_at"
|
|
7513
7765
|
};
|
|
7514
7766
|
function parseOrder(value) {
|
|
7767
|
+
const metadata = /^metadata\{([^}]*)\}(?:\s+(asc|desc))?$/i.exec(value.trim());
|
|
7768
|
+
if (metadata)
|
|
7769
|
+
return {
|
|
7770
|
+
field: "metadata",
|
|
7771
|
+
key: metadata[1],
|
|
7772
|
+
direction: metadata[2]?.toLowerCase() === "asc" ? "asc" : "desc"
|
|
7773
|
+
};
|
|
7515
7774
|
const defaultOrder = { field: "created_at", direction: "desc" };
|
|
7516
7775
|
const trimmed = value.trim().toLowerCase();
|
|
7517
7776
|
if (!trimmed)
|
|
@@ -7631,6 +7890,8 @@ function normalizeQuery(query) {
|
|
|
7631
7890
|
result.linkTo = query.linkTo;
|
|
7632
7891
|
if (query.createdBy)
|
|
7633
7892
|
result.createdBy = query.createdBy;
|
|
7893
|
+
if (query.ratingAxis !== undefined)
|
|
7894
|
+
result.ratingAxis = query.ratingAxis;
|
|
7634
7895
|
if (query.name)
|
|
7635
7896
|
result.name = query.name;
|
|
7636
7897
|
if (query.fullname)
|
|
@@ -8538,7 +8799,7 @@ function isListUsersModule2(module) {
|
|
|
8538
8799
|
function resolveListUsers(_module, data, compiledTemplate, parse) {
|
|
8539
8800
|
const ctx = { user: data.user };
|
|
8540
8801
|
const substituted = compiledTemplate(ctx);
|
|
8541
|
-
const itemAst = getModuleParseAst(parse(substituted));
|
|
8802
|
+
const itemAst = getModuleParseAst(suppressModuleRatings(parse(substituted)));
|
|
8542
8803
|
return itemAst.elements;
|
|
8543
8804
|
}
|
|
8544
8805
|
// packages/parser/src/parser/rules/block/module/resolution/data-maps.ts
|
|
@@ -9334,11 +9595,11 @@ async function resolveModules(ast, dataProvider, options) {
|
|
|
9334
9595
|
if (mergedStyles.length > 0)
|
|
9335
9596
|
result.styles = mergedStyles;
|
|
9336
9597
|
options.onDiagnostics?.(registry.diagnostics);
|
|
9337
|
-
return registry.finalize(result, finalElements, pageTags, containsSyntaxFootnoteBlock(ast.elements));
|
|
9598
|
+
return resolveRatings(registry.finalize(result, finalElements, pageTags, containsSyntaxFootnoteBlock(ast.elements)), dataProvider.fetchRatings);
|
|
9338
9599
|
}
|
|
9339
9600
|
function createModuleParseFunction(options, dataProvider, registry) {
|
|
9340
9601
|
const transform = createModuleSourceTransform(options, dataProvider);
|
|
9341
|
-
return (source) => registry.register(options.parse(transform ? transform(source) : source), {
|
|
9602
|
+
return (source) => registry.register(suppressModuleRatings(options.parse(transform ? transform(source) : source)), {
|
|
9342
9603
|
stripLegacyImplicitFootnoteBlock: true
|
|
9343
9604
|
});
|
|
9344
9605
|
}
|
|
@@ -12811,55 +13072,6 @@ var dateRule = {
|
|
|
12811
13072
|
}
|
|
12812
13073
|
};
|
|
12813
13074
|
|
|
12814
|
-
// packages/parser/src/parser/rules/inline/size/content.ts
|
|
12815
|
-
function parseSizeContent(ctx, startPos) {
|
|
12816
|
-
const children = [];
|
|
12817
|
-
let pos = startPos;
|
|
12818
|
-
let consumed = 0;
|
|
12819
|
-
while (pos < ctx.tokens.length) {
|
|
12820
|
-
const token5 = ctx.tokens[pos];
|
|
12821
|
-
if (!token5 || token5.type === "EOF") {
|
|
12822
|
-
break;
|
|
12823
|
-
}
|
|
12824
|
-
const closeResult = tryConsumeSizeClose(ctx, pos);
|
|
12825
|
-
if (closeResult) {
|
|
12826
|
-
return {
|
|
12827
|
-
children,
|
|
12828
|
-
consumed: consumed + closeResult.consumed,
|
|
12829
|
-
foundClose: true
|
|
12830
|
-
};
|
|
12831
|
-
}
|
|
12832
|
-
const inlineCtx = { ...ctx, pos };
|
|
12833
|
-
const inlineResult = parseInlineUntil(inlineCtx, "BLOCK_END_OPEN");
|
|
12834
|
-
if (inlineResult.elements.length > 0) {
|
|
12835
|
-
for (const element of inlineResult.elements)
|
|
12836
|
-
children.push(element);
|
|
12837
|
-
pos += inlineResult.consumed;
|
|
12838
|
-
consumed += inlineResult.consumed;
|
|
12839
|
-
} else {
|
|
12840
|
-
children.push({ element: "text", data: token5.value });
|
|
12841
|
-
pos++;
|
|
12842
|
-
consumed++;
|
|
12843
|
-
}
|
|
12844
|
-
}
|
|
12845
|
-
return { children, consumed, foundClose: false };
|
|
12846
|
-
}
|
|
12847
|
-
function tryConsumeSizeClose(ctx, pos) {
|
|
12848
|
-
if (ctx.tokens[pos]?.type !== "BLOCK_END_OPEN") {
|
|
12849
|
-
return null;
|
|
12850
|
-
}
|
|
12851
|
-
const closeNameResult = parseBlockName(ctx, pos + 1);
|
|
12852
|
-
if (!closeNameResult || closeNameResult.name !== "size") {
|
|
12853
|
-
return null;
|
|
12854
|
-
}
|
|
12855
|
-
let closePos = pos + 1 + closeNameResult.consumed;
|
|
12856
|
-
let consumed = 1 + closeNameResult.consumed;
|
|
12857
|
-
if (ctx.tokens[closePos]?.type === "BLOCK_CLOSE") {
|
|
12858
|
-
consumed++;
|
|
12859
|
-
}
|
|
12860
|
-
return { consumed };
|
|
12861
|
-
}
|
|
12862
|
-
|
|
12863
13075
|
// packages/parser/src/parser/rules/inline/size/value.ts
|
|
12864
13076
|
var VALID_SIZE_UNITS = ["px", "em", "rem", "ex", "%", "cm", "mm", "in", "pc"];
|
|
12865
13077
|
var VALID_SIZE_KEYWORDS = [
|
|
@@ -12929,6 +13141,81 @@ function parseSizeOpen(ctx) {
|
|
|
12929
13141
|
return { size: sizeResult.size, bodyStart: pos, consumed };
|
|
12930
13142
|
}
|
|
12931
13143
|
|
|
13144
|
+
// packages/parser/src/parser/rules/inline/size/content.ts
|
|
13145
|
+
function parseSizeContent(ctx, startPos) {
|
|
13146
|
+
const children = [];
|
|
13147
|
+
let pos = startPos;
|
|
13148
|
+
let consumed = 0;
|
|
13149
|
+
const inlineEnd = findSizeClose(ctx, startPos);
|
|
13150
|
+
while (pos < (ctx.scope.inlineEnd ?? ctx.tokens.length)) {
|
|
13151
|
+
const token5 = ctx.tokens[pos];
|
|
13152
|
+
if (!token5 || token5.type === "EOF") {
|
|
13153
|
+
break;
|
|
13154
|
+
}
|
|
13155
|
+
const closeResult = tryConsumeSizeClose(ctx, pos);
|
|
13156
|
+
if (closeResult) {
|
|
13157
|
+
return {
|
|
13158
|
+
children,
|
|
13159
|
+
consumed: consumed + closeResult.consumed,
|
|
13160
|
+
foundClose: true
|
|
13161
|
+
};
|
|
13162
|
+
}
|
|
13163
|
+
const inlineCtx = { ...ctx, pos, scope: { ...ctx.scope, inlineEnd } };
|
|
13164
|
+
const inlineResult = parseInlineUntil(inlineCtx, "EOF");
|
|
13165
|
+
if (inlineResult.consumed > 0) {
|
|
13166
|
+
for (const element of inlineResult.elements)
|
|
13167
|
+
children.push(element);
|
|
13168
|
+
pos += inlineResult.consumed;
|
|
13169
|
+
consumed += inlineResult.consumed;
|
|
13170
|
+
} else {
|
|
13171
|
+
children.push({ element: "text", data: token5.value });
|
|
13172
|
+
pos++;
|
|
13173
|
+
consumed++;
|
|
13174
|
+
}
|
|
13175
|
+
}
|
|
13176
|
+
return { children, consumed, foundClose: false };
|
|
13177
|
+
}
|
|
13178
|
+
function findSizeClose(ctx, startPos) {
|
|
13179
|
+
const end = ctx.scope.inlineEnd ?? ctx.tokens.length;
|
|
13180
|
+
let depth = 0;
|
|
13181
|
+
for (let pos = startPos;pos < end; pos++) {
|
|
13182
|
+
const protectedEnd = protectedInlineRegionEnd(ctx.tokens, pos, end);
|
|
13183
|
+
if (protectedEnd > pos) {
|
|
13184
|
+
pos = protectedEnd - 1;
|
|
13185
|
+
continue;
|
|
13186
|
+
}
|
|
13187
|
+
const open = ctx.tokens[pos]?.type === "BLOCK_OPEN" ? parseSizeOpen({ ...ctx, pos }) : null;
|
|
13188
|
+
if (open) {
|
|
13189
|
+
depth++;
|
|
13190
|
+
pos = open.bodyStart - 1;
|
|
13191
|
+
continue;
|
|
13192
|
+
}
|
|
13193
|
+
const close = tryConsumeSizeClose(ctx, pos);
|
|
13194
|
+
if (!close)
|
|
13195
|
+
continue;
|
|
13196
|
+
if (depth === 0)
|
|
13197
|
+
return pos;
|
|
13198
|
+
depth--;
|
|
13199
|
+
pos += close.consumed - 1;
|
|
13200
|
+
}
|
|
13201
|
+
return end;
|
|
13202
|
+
}
|
|
13203
|
+
function tryConsumeSizeClose(ctx, pos) {
|
|
13204
|
+
if (ctx.tokens[pos]?.type !== "BLOCK_END_OPEN") {
|
|
13205
|
+
return null;
|
|
13206
|
+
}
|
|
13207
|
+
const closeNameResult = parseBlockName(ctx, pos + 1);
|
|
13208
|
+
if (!closeNameResult || closeNameResult.name !== "size") {
|
|
13209
|
+
return null;
|
|
13210
|
+
}
|
|
13211
|
+
let closePos = pos + 1 + closeNameResult.consumed;
|
|
13212
|
+
let consumed = 1 + closeNameResult.consumed;
|
|
13213
|
+
if (ctx.tokens[closePos]?.type === "BLOCK_CLOSE") {
|
|
13214
|
+
consumed++;
|
|
13215
|
+
}
|
|
13216
|
+
return { consumed };
|
|
13217
|
+
}
|
|
13218
|
+
|
|
12932
13219
|
// packages/parser/src/parser/rules/inline/size/index.ts
|
|
12933
13220
|
var sizeRule = {
|
|
12934
13221
|
name: "size",
|
|
@@ -15341,14 +15628,17 @@ function parseSource(source, options, deferInclude) {
|
|
|
15341
15628
|
}
|
|
15342
15629
|
// packages/parser/src/pipeline/process.ts
|
|
15343
15630
|
import {
|
|
15344
|
-
DEFAULT_SETTINGS as DEFAULT_SETTINGS2
|
|
15631
|
+
DEFAULT_SETTINGS as DEFAULT_SETTINGS2,
|
|
15632
|
+
extractReadableText,
|
|
15633
|
+
extractFirstParagraph,
|
|
15634
|
+
countCharacters as countCharacters2
|
|
15345
15635
|
} from "@wdprlib/ast";
|
|
15346
15636
|
|
|
15347
15637
|
// packages/parser/src/parser/rules/block/module/resolution/resolve-async.ts
|
|
15348
15638
|
async function resolveModulesWithAsyncParse(ast, dataProvider, options) {
|
|
15349
15639
|
const registry = new ModuleDocumentRegistry;
|
|
15350
15640
|
registry.register(ast);
|
|
15351
|
-
const parse2 = async (source) => registry.register(await options.parse(source));
|
|
15641
|
+
const parse2 = async (source) => registry.register(suppressModuleRatings(await options.parse(source)));
|
|
15352
15642
|
const [listPagesData, listUsersData, tagCloudData] = await Promise.all([
|
|
15353
15643
|
buildListPagesDataMap(dataProvider, options.requirements.listPages ?? [], options.urlPath, options.paginationState),
|
|
15354
15644
|
buildListUsersDataMap(dataProvider, options.requirements.listUsers ?? []),
|
|
@@ -15584,8 +15874,13 @@ async function processWikitext(source, options) {
|
|
|
15584
15874
|
if (hasResolvableRequirements(extractDataRequirements(ast).requirements, options.dataProvider)) {
|
|
15585
15875
|
diagnostics.push(createLimitDiagnostic("module-resolution-limit", `Module resolution stopped after ${DEFAULT_MODULE_MAX_PASSES} passes.`));
|
|
15586
15876
|
}
|
|
15877
|
+
ast = await resolveRatings(ast, dataProvider.fetchRatings);
|
|
15878
|
+
const readableText = extractReadableText(ast, options.readableText);
|
|
15587
15879
|
return {
|
|
15588
15880
|
ast,
|
|
15881
|
+
readableText,
|
|
15882
|
+
firstParagraph: extractFirstParagraph(ast, options.readableText),
|
|
15883
|
+
characterCount: countCharacters2(readableText),
|
|
15589
15884
|
page: options.page,
|
|
15590
15885
|
settings,
|
|
15591
15886
|
diagnostics,
|
|
@@ -15614,6 +15909,7 @@ function createLimitDiagnostic(code, message) {
|
|
|
15614
15909
|
function createModuleDataProvider(options, context) {
|
|
15615
15910
|
const provider = options.dataProvider;
|
|
15616
15911
|
return {
|
|
15912
|
+
fetchRatings: provider?.fetchRatings ? (refs) => provider.fetchRatings(refs, context) : undefined,
|
|
15617
15913
|
fetchListPages: provider?.fetchListPages ? (query, requirement) => provider.fetchListPages(query, requirement, context) : undefined,
|
|
15618
15914
|
fetchListUsers: provider?.fetchListUsers ? (requirement) => provider.fetchListUsers(requirement, context) : undefined,
|
|
15619
15915
|
fetchTagCloud: provider?.fetchTagCloud ? (requirement) => provider.fetchTagCloud(requirement, context) : undefined,
|