@wdprlib/parser 4.0.0 → 4.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -1
- package/dist/index.cjs +345 -64
- package/dist/index.d.cts +121 -2
- package/dist/index.d.ts +121 -2
- package/dist/index.js +317 -36
- package/package.json +2 -2
- package/src/index.ts +9 -0
- package/src/parser/rules/block/module/index.ts +10 -0
- package/src/parser/rules/block/module/listpages/extract.ts +9 -0
- package/src/parser/rules/block/module/listpages/extraction/tagcloud.ts +25 -0
- package/src/parser/rules/block/module/listpages/types/data-requirements.ts +2 -0
- package/src/parser/rules/block/module/listpages/url-resolution/fields.ts +4 -4
- package/src/parser/rules/block/module/listpages/url-resolution/params.ts +12 -1
- package/src/parser/rules/block/module/listpages/url-resolution/resolve.ts +10 -1
- package/src/parser/rules/block/module/listpages/url-resolution/value.ts +13 -4
- package/src/parser/rules/block/module/mapping.ts +2 -0
- package/src/parser/rules/block/module/resolution/contexts.ts +29 -1
- package/src/parser/rules/block/module/resolution/data-maps.ts +17 -0
- package/src/parser/rules/block/module/resolution/dynamic-modules.ts +29 -2
- package/src/parser/rules/block/module/resolution/walk-resolve.ts +28 -4
- package/src/parser/rules/block/module/resolve.ts +11 -1
- package/src/parser/rules/block/module/tagcloud/index.ts +15 -0
- package/src/parser/rules/block/module/tagcloud/parser.ts +127 -0
- package/src/parser/rules/block/module/tagcloud/resolve.ts +173 -0
- package/src/parser/rules/block/module/tagcloud/types.ts +85 -0
- package/src/parser/rules/block/module/types-common.ts +15 -0
package/dist/index.cjs
CHANGED
|
@@ -31,7 +31,8 @@ var __export = (target, all) => {
|
|
|
31
31
|
var exports_src = {};
|
|
32
32
|
__export(exports_src, {
|
|
33
33
|
tokenize: () => tokenize,
|
|
34
|
-
text: () =>
|
|
34
|
+
text: () => import_ast6.text,
|
|
35
|
+
resolveTagCloud: () => resolveTagCloud,
|
|
35
36
|
resolveModules: () => resolveModules,
|
|
36
37
|
resolveListUsers: () => resolveListUsers,
|
|
37
38
|
resolveIncludesWithTrace: () => resolveIncludesWithTrace,
|
|
@@ -45,36 +46,37 @@ __export(exports_src, {
|
|
|
45
46
|
parseDateSelector: () => parseDateSelector,
|
|
46
47
|
parseCategory: () => parseCategory,
|
|
47
48
|
parse: () => parse,
|
|
48
|
-
paragraph: () =>
|
|
49
|
+
paragraph: () => import_ast6.paragraph,
|
|
49
50
|
normalizeQuery: () => normalizeQuery,
|
|
50
|
-
listItemSubList: () =>
|
|
51
|
-
listItemElements: () =>
|
|
52
|
-
list: () =>
|
|
53
|
-
link: () =>
|
|
54
|
-
lineBreak: () =>
|
|
55
|
-
italics: () =>
|
|
51
|
+
listItemSubList: () => import_ast6.listItemSubList,
|
|
52
|
+
listItemElements: () => import_ast6.listItemElements,
|
|
53
|
+
list: () => import_ast6.list,
|
|
54
|
+
link: () => import_ast6.link,
|
|
55
|
+
lineBreak: () => import_ast6.lineBreak,
|
|
56
|
+
italics: () => import_ast6.italics,
|
|
57
|
+
isTagCloudModule: () => isTagCloudModule,
|
|
56
58
|
isListUsersModule: () => isListUsersModule2,
|
|
57
|
-
horizontalRule: () =>
|
|
58
|
-
heading: () =>
|
|
59
|
+
horizontalRule: () => import_ast6.horizontalRule,
|
|
60
|
+
heading: () => import_ast6.heading,
|
|
59
61
|
extractListUsersVariables: () => extractListUsersVariables,
|
|
60
62
|
extractIncludeReferences: () => extractIncludeReferences,
|
|
61
63
|
extractDataRequirements: () => extractDataRequirements,
|
|
62
64
|
createToken: () => createToken,
|
|
63
|
-
createSettings: () =>
|
|
64
|
-
createPosition: () =>
|
|
65
|
-
createPoint: () =>
|
|
66
|
-
container: () =>
|
|
65
|
+
createSettings: () => import_ast7.createSettings,
|
|
66
|
+
createPosition: () => import_ast6.createPosition,
|
|
67
|
+
createPoint: () => import_ast6.createPoint,
|
|
68
|
+
container: () => import_ast6.container,
|
|
67
69
|
compileTemplate: () => compileTemplate,
|
|
68
70
|
compileListUsersTemplate: () => compileListUsersTemplate,
|
|
69
|
-
bold: () =>
|
|
70
|
-
STYLE_SLOT_PREFIX: () =>
|
|
71
|
+
bold: () => import_ast6.bold,
|
|
72
|
+
STYLE_SLOT_PREFIX: () => import_ast3.STYLE_SLOT_PREFIX,
|
|
71
73
|
Parser: () => Parser,
|
|
72
74
|
Lexer: () => Lexer,
|
|
73
|
-
DEFAULT_SETTINGS: () =>
|
|
75
|
+
DEFAULT_SETTINGS: () => import_ast7.DEFAULT_SETTINGS
|
|
74
76
|
});
|
|
75
77
|
module.exports = __toCommonJS(exports_src);
|
|
76
|
-
var import_ast5 = require("@wdprlib/ast");
|
|
77
78
|
var import_ast6 = require("@wdprlib/ast");
|
|
79
|
+
var import_ast7 = require("@wdprlib/ast");
|
|
78
80
|
|
|
79
81
|
// packages/parser/src/lexer/tokens.ts
|
|
80
82
|
function createToken(type, value, position, lineStart = false) {
|
|
@@ -1441,7 +1443,7 @@ function parseNextBlock(ctx, skipWhitespace2, isAtEnd2) {
|
|
|
1441
1443
|
}
|
|
1442
1444
|
|
|
1443
1445
|
// packages/parser/src/parser/parse/context.ts
|
|
1444
|
-
var
|
|
1446
|
+
var import_ast4 = require("@wdprlib/ast");
|
|
1445
1447
|
|
|
1446
1448
|
// packages/parser/src/parser/rules/tokens.ts
|
|
1447
1449
|
function currentToken(ctx) {
|
|
@@ -4527,6 +4529,92 @@ var listUsersModuleRule = {
|
|
|
4527
4529
|
}
|
|
4528
4530
|
};
|
|
4529
4531
|
|
|
4532
|
+
// packages/parser/src/parser/rules/block/module/tagcloud/parser.ts
|
|
4533
|
+
var import_ast = require("@wdprlib/ast");
|
|
4534
|
+
var FONT_SIZE_PATTERN = new RegExp(`^([0-9]+)(${import_ast.CSS_LENGTH_UNITS.join("|")})$`, "i");
|
|
4535
|
+
var COLOR_PATTERN = /^[0-9]+,[0-9]+,[0-9]+$/;
|
|
4536
|
+
var POSITIVE_INT_PATTERN = /^[0-9]+$/;
|
|
4537
|
+
var ERROR_FONT_FORMAT = "Unsupported format for font size. Use a number followed by a CSS length unit such as px, em or %.";
|
|
4538
|
+
var ERROR_FONT_MISMATCH = "Format for minFontSize and maxFontSize must use the same unit.";
|
|
4539
|
+
var ERROR_COLOR_FORMAT = 'Unsupported color format. Use "RRR,GGG,BBB" for Red,Green,Blue each within 0-255 range.';
|
|
4540
|
+
function errorBlock(message) {
|
|
4541
|
+
return {
|
|
4542
|
+
element: "container",
|
|
4543
|
+
data: {
|
|
4544
|
+
type: "div",
|
|
4545
|
+
attributes: { class: "error-block" },
|
|
4546
|
+
elements: [{ element: "text", data: message }]
|
|
4547
|
+
}
|
|
4548
|
+
};
|
|
4549
|
+
}
|
|
4550
|
+
function parseLimit(value) {
|
|
4551
|
+
if (!value || !POSITIVE_INT_PATTERN.test(value))
|
|
4552
|
+
return 50;
|
|
4553
|
+
const num = Number.parseInt(value, 10);
|
|
4554
|
+
return Number.isSafeInteger(num) && num > 0 ? num : 50;
|
|
4555
|
+
}
|
|
4556
|
+
function normalizeTarget(value) {
|
|
4557
|
+
if (!value)
|
|
4558
|
+
return "/system:page-tags/tag/";
|
|
4559
|
+
let target = value;
|
|
4560
|
+
if (!target.startsWith("/"))
|
|
4561
|
+
target = `/${target}`;
|
|
4562
|
+
if (!target.endsWith("/"))
|
|
4563
|
+
target = `${target}/`;
|
|
4564
|
+
return `${target}tag/`;
|
|
4565
|
+
}
|
|
4566
|
+
function parseColor(value) {
|
|
4567
|
+
const [r = 0, g = 0, b = 0] = value.split(",").map((part) => Number.parseInt(part, 10));
|
|
4568
|
+
return [r, g, b];
|
|
4569
|
+
}
|
|
4570
|
+
var tagCloudModuleRule = {
|
|
4571
|
+
name: "module-tagcloud",
|
|
4572
|
+
acceptsNames: ["tagcloud"],
|
|
4573
|
+
hasBody: false,
|
|
4574
|
+
parse(_ctx, _pos, args) {
|
|
4575
|
+
const maxFontSize = args.maxfontsize;
|
|
4576
|
+
const minFontSize = args.minfontsize;
|
|
4577
|
+
const maxColor = args.maxcolor;
|
|
4578
|
+
const minColor = args.mincolor;
|
|
4579
|
+
let sizeSmall = 100;
|
|
4580
|
+
let sizeBig = 300;
|
|
4581
|
+
let fontSizeUnit = "%";
|
|
4582
|
+
if (maxFontSize && minFontSize) {
|
|
4583
|
+
const maxMatch = FONT_SIZE_PATTERN.exec(maxFontSize);
|
|
4584
|
+
if (!maxMatch)
|
|
4585
|
+
return errorBlock(ERROR_FONT_FORMAT);
|
|
4586
|
+
const maxUnit = maxMatch[2].toLowerCase();
|
|
4587
|
+
const minMatch = FONT_SIZE_PATTERN.exec(minFontSize);
|
|
4588
|
+
if (!minMatch || minMatch[2].toLowerCase() !== maxUnit) {
|
|
4589
|
+
return errorBlock(ERROR_FONT_MISMATCH);
|
|
4590
|
+
}
|
|
4591
|
+
sizeBig = Number.parseInt(maxMatch[1], 10);
|
|
4592
|
+
sizeSmall = Number.parseInt(minMatch[1], 10);
|
|
4593
|
+
fontSizeUnit = maxUnit;
|
|
4594
|
+
}
|
|
4595
|
+
let colorSmall = [128, 128, 192];
|
|
4596
|
+
let colorBig = [64, 64, 128];
|
|
4597
|
+
if (maxColor && minColor) {
|
|
4598
|
+
if (!COLOR_PATTERN.test(maxColor) || !COLOR_PATTERN.test(minColor)) {
|
|
4599
|
+
return errorBlock(ERROR_COLOR_FORMAT);
|
|
4600
|
+
}
|
|
4601
|
+
colorSmall = parseColor(minColor);
|
|
4602
|
+
colorBig = parseColor(maxColor);
|
|
4603
|
+
}
|
|
4604
|
+
return {
|
|
4605
|
+
module: "tag-cloud",
|
|
4606
|
+
"min-font-size": sizeSmall,
|
|
4607
|
+
"max-font-size": sizeBig,
|
|
4608
|
+
"font-size-unit": fontSizeUnit,
|
|
4609
|
+
"min-color": colorSmall,
|
|
4610
|
+
"max-color": colorBig,
|
|
4611
|
+
target: normalizeTarget(args.target),
|
|
4612
|
+
limit: parseLimit(args.limit),
|
|
4613
|
+
category: args.category || null
|
|
4614
|
+
};
|
|
4615
|
+
}
|
|
4616
|
+
};
|
|
4617
|
+
|
|
4530
4618
|
// packages/parser/src/parser/rules/block/module/mapping.ts
|
|
4531
4619
|
var MODULE_RULES = [
|
|
4532
4620
|
rateModuleRule,
|
|
@@ -4536,7 +4624,8 @@ var MODULE_RULES = [
|
|
|
4536
4624
|
joinModuleRule,
|
|
4537
4625
|
pageTreeModuleRule,
|
|
4538
4626
|
listPagesModuleRule,
|
|
4539
|
-
listUsersModuleRule
|
|
4627
|
+
listUsersModuleRule,
|
|
4628
|
+
tagCloudModuleRule
|
|
4540
4629
|
];
|
|
4541
4630
|
var moduleRuleMap = new Map;
|
|
4542
4631
|
for (const rule of MODULE_RULES) {
|
|
@@ -5617,18 +5706,130 @@ function extractListUsersModule(listUsers, state, result) {
|
|
|
5617
5706
|
result.compiledListUsersTemplates.set(id, compileListUsersTemplate(body));
|
|
5618
5707
|
}
|
|
5619
5708
|
|
|
5709
|
+
// packages/parser/src/parser/rules/block/module/tagcloud/resolve.ts
|
|
5710
|
+
function isTagCloudModule(module2) {
|
|
5711
|
+
return module2.module === "tag-cloud";
|
|
5712
|
+
}
|
|
5713
|
+
var NO_TAGS_MESSAGE_PREFIX = "It seems you have no tags attached to pages. To attach a tag simply click on the ";
|
|
5714
|
+
var NO_TAGS_MESSAGE_SUFFIX = " button at the bottom of any page.";
|
|
5715
|
+
function rawUrlEncode(value) {
|
|
5716
|
+
return encodeURIComponent(value).replace(/[!'()*]/g, (char) => `%${char.charCodeAt(0).toString(16).toUpperCase()}`);
|
|
5717
|
+
}
|
|
5718
|
+
function selectTags(tags, limit) {
|
|
5719
|
+
return tags.toSorted((a, b) => b.weight - a.weight || compareTags(a.tag, b.tag)).slice(0, limit).toSorted((a, b) => compareTags(a.tag, b.tag));
|
|
5720
|
+
}
|
|
5721
|
+
function compareTags(a, b) {
|
|
5722
|
+
return a < b ? -1 : a > b ? 1 : 0;
|
|
5723
|
+
}
|
|
5724
|
+
function resolveTagCloud(module2, data) {
|
|
5725
|
+
if (data.status === "category-not-found") {
|
|
5726
|
+
return [
|
|
5727
|
+
{
|
|
5728
|
+
element: "container",
|
|
5729
|
+
data: {
|
|
5730
|
+
type: "div",
|
|
5731
|
+
attributes: { class: "error-block" },
|
|
5732
|
+
elements: [{ element: "text", data: `Category "${data.category}" can not be found.` }]
|
|
5733
|
+
}
|
|
5734
|
+
}
|
|
5735
|
+
];
|
|
5736
|
+
}
|
|
5737
|
+
const tags = selectTags(data.tags, module2.limit);
|
|
5738
|
+
if (tags.length === 0) {
|
|
5739
|
+
return [noTagsMessage()];
|
|
5740
|
+
}
|
|
5741
|
+
let minWeight = Number.POSITIVE_INFINITY;
|
|
5742
|
+
let maxWeight = Number.NEGATIVE_INFINITY;
|
|
5743
|
+
for (const tag of tags) {
|
|
5744
|
+
if (tag.weight < minWeight)
|
|
5745
|
+
minWeight = tag.weight;
|
|
5746
|
+
if (tag.weight > maxWeight)
|
|
5747
|
+
maxWeight = tag.weight;
|
|
5748
|
+
}
|
|
5749
|
+
const weightRange = maxWeight - minWeight;
|
|
5750
|
+
const categorySuffix = data.category !== null ? `/category/${rawUrlEncode(data.category)}` : "";
|
|
5751
|
+
const anchors = [];
|
|
5752
|
+
for (const tag of tags) {
|
|
5753
|
+
const a = weightRange === 0 ? 0 : (tag.weight - minWeight) / weightRange;
|
|
5754
|
+
const fontSize = interpolate(module2["min-font-size"], module2["max-font-size"], a);
|
|
5755
|
+
const [r, g, b] = [0, 1, 2].map((i) => interpolate(module2["min-color"][i], module2["max-color"][i], a));
|
|
5756
|
+
anchors.push({ element: "text", data: `
|
|
5757
|
+
` });
|
|
5758
|
+
anchors.push({
|
|
5759
|
+
element: "anchor",
|
|
5760
|
+
data: {
|
|
5761
|
+
target: null,
|
|
5762
|
+
attributes: {
|
|
5763
|
+
class: "tag",
|
|
5764
|
+
href: `${module2.target}${rawUrlEncode(tag.tag)}${categorySuffix}`,
|
|
5765
|
+
style: `font-size: ${fontSize}${module2["font-size-unit"]}; color: rgb(${r}, ${g}, ${b});`
|
|
5766
|
+
},
|
|
5767
|
+
elements: [{ element: "text", data: tag.tag }]
|
|
5768
|
+
}
|
|
5769
|
+
});
|
|
5770
|
+
}
|
|
5771
|
+
anchors.push({ element: "text", data: `
|
|
5772
|
+
` });
|
|
5773
|
+
return [
|
|
5774
|
+
{
|
|
5775
|
+
element: "container",
|
|
5776
|
+
data: {
|
|
5777
|
+
type: "div",
|
|
5778
|
+
attributes: { class: "pages-tag-cloud-box" },
|
|
5779
|
+
elements: anchors
|
|
5780
|
+
}
|
|
5781
|
+
}
|
|
5782
|
+
];
|
|
5783
|
+
}
|
|
5784
|
+
function interpolate(min, max, a) {
|
|
5785
|
+
return Math.round(min + (max - min) * a);
|
|
5786
|
+
}
|
|
5787
|
+
function noTagsMessage() {
|
|
5788
|
+
return {
|
|
5789
|
+
element: "container",
|
|
5790
|
+
data: {
|
|
5791
|
+
type: "paragraph",
|
|
5792
|
+
attributes: {},
|
|
5793
|
+
elements: [
|
|
5794
|
+
{ element: "text", data: NO_TAGS_MESSAGE_PREFIX },
|
|
5795
|
+
{
|
|
5796
|
+
element: "container",
|
|
5797
|
+
data: {
|
|
5798
|
+
type: "italics",
|
|
5799
|
+
attributes: {},
|
|
5800
|
+
elements: [{ element: "text", data: "tags" }]
|
|
5801
|
+
}
|
|
5802
|
+
},
|
|
5803
|
+
{ element: "text", data: NO_TAGS_MESSAGE_SUFFIX }
|
|
5804
|
+
]
|
|
5805
|
+
}
|
|
5806
|
+
};
|
|
5807
|
+
}
|
|
5808
|
+
|
|
5809
|
+
// packages/parser/src/parser/rules/block/module/listpages/extraction/tagcloud.ts
|
|
5810
|
+
function extractTagCloudModule(tagCloud, state, result) {
|
|
5811
|
+
const id = state.nextId++;
|
|
5812
|
+
result.requirements.tagCloud.push({
|
|
5813
|
+
id,
|
|
5814
|
+
category: tagCloud.category,
|
|
5815
|
+
limit: tagCloud.limit
|
|
5816
|
+
});
|
|
5817
|
+
}
|
|
5818
|
+
|
|
5620
5819
|
// packages/parser/src/parser/rules/block/module/listpages/extract.ts
|
|
5621
5820
|
function extractDataRequirements(ast) {
|
|
5622
5821
|
const result = {
|
|
5623
5822
|
requirements: {
|
|
5624
5823
|
listPages: [],
|
|
5625
|
-
listUsers: []
|
|
5824
|
+
listUsers: [],
|
|
5825
|
+
tagCloud: []
|
|
5626
5826
|
},
|
|
5627
5827
|
compiledListPagesTemplates: new Map,
|
|
5628
5828
|
compiledListUsersTemplates: new Map
|
|
5629
5829
|
};
|
|
5630
5830
|
const listPagesState = { nextId: 0 };
|
|
5631
5831
|
const listUsersState = { nextId: 0 };
|
|
5832
|
+
const tagCloudState = { nextId: 0 };
|
|
5632
5833
|
walkElements(ast.elements, (element) => {
|
|
5633
5834
|
if (element.element !== "module")
|
|
5634
5835
|
return;
|
|
@@ -5636,6 +5837,8 @@ function extractDataRequirements(ast) {
|
|
|
5636
5837
|
extractListPagesModule(element.data, listPagesState, result);
|
|
5637
5838
|
} else if (isListUsersModule(element.data)) {
|
|
5638
5839
|
extractListUsersModule(element.data, listUsersState, result);
|
|
5840
|
+
} else if (isTagCloudModule(element.data)) {
|
|
5841
|
+
extractTagCloudModule(element.data, tagCloudState, result);
|
|
5639
5842
|
}
|
|
5640
5843
|
});
|
|
5641
5844
|
return result;
|
|
@@ -5709,11 +5912,32 @@ function resolveListPages(module2, data, compiledTemplate, parse) {
|
|
|
5709
5912
|
const items = renderListPagesItems(module2, data, compiledTemplate, parse);
|
|
5710
5913
|
return wrapListPagesResult(module2, items, parse);
|
|
5711
5914
|
}
|
|
5915
|
+
// packages/parser/src/parser/rules/block/module/listpages/url-resolution/fields.ts
|
|
5916
|
+
var URL_RESOLVABLE_FIELDS = [
|
|
5917
|
+
{ attr: "offset", queryKey: "offset", type: "number" },
|
|
5918
|
+
{ attr: "limit", queryKey: "limit", type: "number" },
|
|
5919
|
+
{ attr: "per-page", queryKey: "perPage", type: "number" },
|
|
5920
|
+
{ attr: "order", queryKey: "order", type: "string" },
|
|
5921
|
+
{ attr: "tags", queryKey: "tags", type: "string", urlAttrs: ["tag"] },
|
|
5922
|
+
{ attr: "category", queryKey: "category", type: "string" },
|
|
5923
|
+
{ attr: "parent", queryKey: "parent", type: "string" },
|
|
5924
|
+
{ attr: "range", queryKey: "range", type: "string" },
|
|
5925
|
+
{ attr: "name", queryKey: "name", type: "string" },
|
|
5926
|
+
{ attr: "fullname", queryKey: "fullname", type: "string" },
|
|
5927
|
+
{ attr: "created-at", queryKey: "createdAt", type: "string" },
|
|
5928
|
+
{ attr: "updated-at", queryKey: "updatedAt", type: "string" },
|
|
5929
|
+
{ attr: "created-by", queryKey: "createdBy", type: "string" },
|
|
5930
|
+
{ attr: "rating", queryKey: "rating", type: "string" },
|
|
5931
|
+
{ attr: "votes", queryKey: "votes", type: "string" },
|
|
5932
|
+
{ attr: "reverse", queryKey: "reverse", type: "boolean" }
|
|
5933
|
+
];
|
|
5934
|
+
|
|
5712
5935
|
// packages/parser/src/parser/rules/block/module/listpages/url-resolution/params.ts
|
|
5713
5936
|
function parseUrlParams(url) {
|
|
5714
5937
|
const params = new Map;
|
|
5715
5938
|
const parts = url.split("/").filter(Boolean);
|
|
5716
|
-
|
|
5939
|
+
const pairStart = isUrlParameter(parts[0]) ? 0 : 1;
|
|
5940
|
+
for (let i = pairStart;i < parts.length - 1; i += 2) {
|
|
5717
5941
|
const key = parts[i];
|
|
5718
5942
|
const value = parts[i + 1];
|
|
5719
5943
|
if (key && value) {
|
|
@@ -5722,6 +5946,10 @@ function parseUrlParams(url) {
|
|
|
5722
5946
|
}
|
|
5723
5947
|
return params;
|
|
5724
5948
|
}
|
|
5949
|
+
var URL_PARAMETER_NAMES = new Set(URL_RESOLVABLE_FIELDS.flatMap((field) => [field.attr, ...field.urlAttrs ?? []]));
|
|
5950
|
+
function isUrlParameter(param) {
|
|
5951
|
+
return param !== undefined && URL_PARAMETER_NAMES.has(param);
|
|
5952
|
+
}
|
|
5725
5953
|
// packages/parser/src/parser/rules/block/module/listpages/normalization/tags-category.ts
|
|
5726
5954
|
var TOKEN_SEPARATOR = /[,;\s]+/;
|
|
5727
5955
|
function parseTags(value) {
|
|
@@ -5977,26 +6205,6 @@ function normalizeQuery(query) {
|
|
|
5977
6205
|
return result;
|
|
5978
6206
|
}
|
|
5979
6207
|
|
|
5980
|
-
// packages/parser/src/parser/rules/block/module/listpages/url-resolution/fields.ts
|
|
5981
|
-
var URL_RESOLVABLE_FIELDS = [
|
|
5982
|
-
{ attr: "offset", queryKey: "offset", type: "number" },
|
|
5983
|
-
{ attr: "limit", queryKey: "limit", type: "number" },
|
|
5984
|
-
{ attr: "per-page", queryKey: "perPage", type: "number" },
|
|
5985
|
-
{ attr: "order", queryKey: "order", type: "string" },
|
|
5986
|
-
{ attr: "tags", queryKey: "tags", type: "string" },
|
|
5987
|
-
{ attr: "category", queryKey: "category", type: "string" },
|
|
5988
|
-
{ attr: "parent", queryKey: "parent", type: "string" },
|
|
5989
|
-
{ attr: "range", queryKey: "range", type: "string" },
|
|
5990
|
-
{ attr: "name", queryKey: "name", type: "string" },
|
|
5991
|
-
{ attr: "fullname", queryKey: "fullname", type: "string" },
|
|
5992
|
-
{ attr: "created-at", queryKey: "createdAt", type: "string" },
|
|
5993
|
-
{ attr: "updated-at", queryKey: "updatedAt", type: "string" },
|
|
5994
|
-
{ attr: "created-by", queryKey: "createdBy", type: "string" },
|
|
5995
|
-
{ attr: "rating", queryKey: "rating", type: "string" },
|
|
5996
|
-
{ attr: "votes", queryKey: "votes", type: "string" },
|
|
5997
|
-
{ attr: "reverse", queryKey: "reverse", type: "boolean" }
|
|
5998
|
-
];
|
|
5999
|
-
|
|
6000
6208
|
// packages/parser/src/parser/rules/block/module/listpages/url-resolution/query.ts
|
|
6001
6209
|
function assignResolvedUrlField(query, field, value) {
|
|
6002
6210
|
switch (field.type) {
|
|
@@ -6017,15 +6225,23 @@ function assignResolvedUrlField(query, field, value) {
|
|
|
6017
6225
|
}
|
|
6018
6226
|
|
|
6019
6227
|
// packages/parser/src/parser/rules/block/module/listpages/url-resolution/value.ts
|
|
6020
|
-
function resolveUrlValue(rawValue,
|
|
6228
|
+
function resolveUrlValue(rawValue, paramNames, urlParams, prefix) {
|
|
6021
6229
|
if (!rawValue)
|
|
6022
6230
|
return;
|
|
6023
6231
|
if (!rawValue.startsWith("@URL")) {
|
|
6024
6232
|
return rawValue;
|
|
6025
6233
|
}
|
|
6026
6234
|
const defaultValue = rawValue.includes("|") ? rawValue.split("|")[1] : undefined;
|
|
6027
|
-
const
|
|
6028
|
-
|
|
6235
|
+
for (const paramName of toParamNames(paramNames)) {
|
|
6236
|
+
const actualParamName = prefix ? `${prefix}_${paramName}` : paramName;
|
|
6237
|
+
const value = urlParams.get(actualParamName);
|
|
6238
|
+
if (value !== undefined)
|
|
6239
|
+
return value;
|
|
6240
|
+
}
|
|
6241
|
+
return defaultValue;
|
|
6242
|
+
}
|
|
6243
|
+
function toParamNames(paramNames) {
|
|
6244
|
+
return typeof paramNames === "string" ? [paramNames] : paramNames;
|
|
6029
6245
|
}
|
|
6030
6246
|
|
|
6031
6247
|
// packages/parser/src/parser/rules/block/module/listpages/url-resolution/resolve.ts
|
|
@@ -6036,13 +6252,16 @@ function resolveQuery(requirement, urlParams) {
|
|
|
6036
6252
|
const rawValue = rawAttributes[field.attr];
|
|
6037
6253
|
if (!rawValue)
|
|
6038
6254
|
continue;
|
|
6039
|
-
const resolvedValue = resolveUrlValue(rawValue, field
|
|
6255
|
+
const resolvedValue = resolveUrlValue(rawValue, getUrlParamNames(field), urlParams, urlAttrPrefix);
|
|
6040
6256
|
if (resolvedValue === undefined)
|
|
6041
6257
|
continue;
|
|
6042
6258
|
assignResolvedUrlField(resolved, field, resolvedValue);
|
|
6043
6259
|
}
|
|
6044
6260
|
return resolved;
|
|
6045
6261
|
}
|
|
6262
|
+
function getUrlParamNames(field) {
|
|
6263
|
+
return field.urlAttrs ? [field.attr, ...field.urlAttrs] : [field.attr];
|
|
6264
|
+
}
|
|
6046
6265
|
function resolveAndNormalizeQuery(requirement, urlParams) {
|
|
6047
6266
|
const resolved = resolveQuery(requirement, urlParams);
|
|
6048
6267
|
return normalizeQuery(resolved);
|
|
@@ -6735,6 +6954,16 @@ async function buildListUsersDataMap(dataProvider, requirements) {
|
|
|
6735
6954
|
}
|
|
6736
6955
|
return dataMap;
|
|
6737
6956
|
}
|
|
6957
|
+
async function buildTagCloudDataMap(dataProvider, requirements) {
|
|
6958
|
+
const dataMap = new Map;
|
|
6959
|
+
for (const req of requirements) {
|
|
6960
|
+
const data = await dataProvider.fetchTagCloud?.(req);
|
|
6961
|
+
if (data) {
|
|
6962
|
+
dataMap.set(req.id, data);
|
|
6963
|
+
}
|
|
6964
|
+
}
|
|
6965
|
+
return dataMap;
|
|
6966
|
+
}
|
|
6738
6967
|
|
|
6739
6968
|
// packages/parser/src/parser/rules/block/module/resolution/contexts.ts
|
|
6740
6969
|
async function buildListPagesContext(dataProvider, requirements, compiledTemplates, parse, urlPath) {
|
|
@@ -6751,6 +6980,16 @@ async function buildListPagesContext(dataProvider, requirements, compiledTemplat
|
|
|
6751
6980
|
parse
|
|
6752
6981
|
};
|
|
6753
6982
|
}
|
|
6983
|
+
async function buildTagCloudContext(dataProvider, requirements) {
|
|
6984
|
+
if (requirements.length === 0 || !dataProvider.fetchTagCloud) {
|
|
6985
|
+
return null;
|
|
6986
|
+
}
|
|
6987
|
+
const dataMap = await buildTagCloudDataMap(dataProvider, requirements);
|
|
6988
|
+
if (dataMap.size === 0) {
|
|
6989
|
+
return null;
|
|
6990
|
+
}
|
|
6991
|
+
return { dataMap };
|
|
6992
|
+
}
|
|
6754
6993
|
async function buildListUsersContext(dataProvider, requirements, compiledTemplates, parse) {
|
|
6755
6994
|
if (requirements.length === 0 || !dataProvider.fetchListUsers) {
|
|
6756
6995
|
return null;
|
|
@@ -6807,10 +7046,27 @@ function resolveDynamicModuleElement(element, ctx, ids) {
|
|
|
6807
7046
|
ids: { ...ids, listUsersId: listUsersId + 1 }
|
|
6808
7047
|
};
|
|
6809
7048
|
}
|
|
7049
|
+
if (isTagCloudModule(element.data)) {
|
|
7050
|
+
const elements = [];
|
|
7051
|
+
const tagCloudId = ids.tagCloudId;
|
|
7052
|
+
if (ctx.tagCloud) {
|
|
7053
|
+
const moduleData = ctx.tagCloud.dataMap.get(tagCloudId);
|
|
7054
|
+
if (moduleData) {
|
|
7055
|
+
elements.push(...resolveTagCloud(element.data, moduleData));
|
|
7056
|
+
}
|
|
7057
|
+
} else if (!ctx.fetchTagCloudProvided) {
|
|
7058
|
+
elements.push(element);
|
|
7059
|
+
}
|
|
7060
|
+
return {
|
|
7061
|
+
handled: true,
|
|
7062
|
+
elements,
|
|
7063
|
+
ids: { ...ids, tagCloudId: tagCloudId + 1 }
|
|
7064
|
+
};
|
|
7065
|
+
}
|
|
6810
7066
|
return { handled: false, elements: [element], ids };
|
|
6811
7067
|
}
|
|
6812
7068
|
function countDynamicModules(elements) {
|
|
6813
|
-
const counts = { listPagesId: 0, listUsersId: 0 };
|
|
7069
|
+
const counts = { listPagesId: 0, listUsersId: 0, tagCloudId: 0 };
|
|
6814
7070
|
walkElements(elements, (element) => {
|
|
6815
7071
|
if (element.element !== "module")
|
|
6816
7072
|
return;
|
|
@@ -6818,6 +7074,8 @@ function countDynamicModules(elements) {
|
|
|
6818
7074
|
counts.listPagesId++;
|
|
6819
7075
|
} else if (isListUsersModule2(element.data)) {
|
|
6820
7076
|
counts.listUsersId++;
|
|
7077
|
+
} else if (isTagCloudModule(element.data)) {
|
|
7078
|
+
counts.tagCloudId++;
|
|
6821
7079
|
}
|
|
6822
7080
|
});
|
|
6823
7081
|
return counts;
|
|
@@ -6828,12 +7086,18 @@ function walkAndResolve(elements, ctx) {
|
|
|
6828
7086
|
const result = [];
|
|
6829
7087
|
let listPagesId = ctx.listPagesIdCounter;
|
|
6830
7088
|
let listUsersId = ctx.listUsersIdCounter;
|
|
7089
|
+
let tagCloudId = ctx.tagCloudIdCounter;
|
|
6831
7090
|
for (const element of elements) {
|
|
6832
|
-
const dynamicModule = resolveDynamicModuleElement(element, ctx, {
|
|
7091
|
+
const dynamicModule = resolveDynamicModuleElement(element, ctx, {
|
|
7092
|
+
listPagesId,
|
|
7093
|
+
listUsersId,
|
|
7094
|
+
tagCloudId
|
|
7095
|
+
});
|
|
6833
7096
|
if (dynamicModule.handled) {
|
|
6834
7097
|
result.push(...dynamicModule.elements);
|
|
6835
7098
|
listPagesId = dynamicModule.ids.listPagesId;
|
|
6836
7099
|
listUsersId = dynamicModule.ids.listUsersId;
|
|
7100
|
+
tagCloudId = dynamicModule.ids.tagCloudId;
|
|
6837
7101
|
continue;
|
|
6838
7102
|
}
|
|
6839
7103
|
if (isIfTagsElement(element)) {
|
|
@@ -6844,21 +7108,25 @@ function walkAndResolve(elements, ctx) {
|
|
|
6844
7108
|
const childResult = walkAndResolve(ifTagsData.elements, {
|
|
6845
7109
|
...ctx,
|
|
6846
7110
|
listPagesIdCounter: listPagesId,
|
|
6847
|
-
listUsersIdCounter: listUsersId
|
|
7111
|
+
listUsersIdCounter: listUsersId,
|
|
7112
|
+
tagCloudIdCounter: tagCloudId
|
|
6848
7113
|
});
|
|
6849
7114
|
result.push(...childResult.elements);
|
|
6850
7115
|
listPagesId = childResult.nextListPagesId;
|
|
6851
7116
|
listUsersId = childResult.nextListUsersId;
|
|
7117
|
+
tagCloudId = childResult.nextTagCloudId;
|
|
6852
7118
|
} else {
|
|
6853
7119
|
const counts = countDynamicModules(ifTagsData.elements);
|
|
6854
7120
|
listPagesId += counts.listPagesId;
|
|
6855
7121
|
listUsersId += counts.listUsersId;
|
|
7122
|
+
tagCloudId += counts.tagCloudId;
|
|
6856
7123
|
}
|
|
6857
7124
|
} else {
|
|
6858
7125
|
const childResult = walkAndResolve(ifTagsData.elements, {
|
|
6859
7126
|
...ctx,
|
|
6860
7127
|
listPagesIdCounter: listPagesId,
|
|
6861
|
-
listUsersIdCounter: listUsersId
|
|
7128
|
+
listUsersIdCounter: listUsersId,
|
|
7129
|
+
tagCloudIdCounter: tagCloudId
|
|
6862
7130
|
});
|
|
6863
7131
|
result.push({
|
|
6864
7132
|
element: "if-tags",
|
|
@@ -6869,32 +7137,41 @@ function walkAndResolve(elements, ctx) {
|
|
|
6869
7137
|
});
|
|
6870
7138
|
listPagesId = childResult.nextListPagesId;
|
|
6871
7139
|
listUsersId = childResult.nextListUsersId;
|
|
7140
|
+
tagCloudId = childResult.nextTagCloudId;
|
|
6872
7141
|
}
|
|
6873
7142
|
continue;
|
|
6874
7143
|
}
|
|
6875
|
-
const mapped = mapElementChildrenWithState(element, { listPagesId, listUsersId }, (children, state) => {
|
|
7144
|
+
const mapped = mapElementChildrenWithState(element, { listPagesId, listUsersId, tagCloudId }, (children, state) => {
|
|
6876
7145
|
const childResult = walkAndResolve(children, {
|
|
6877
7146
|
...ctx,
|
|
6878
7147
|
listPagesIdCounter: state.listPagesId,
|
|
6879
|
-
listUsersIdCounter: state.listUsersId
|
|
7148
|
+
listUsersIdCounter: state.listUsersId,
|
|
7149
|
+
tagCloudIdCounter: state.tagCloudId
|
|
6880
7150
|
});
|
|
6881
7151
|
return {
|
|
6882
7152
|
elements: childResult.elements,
|
|
6883
7153
|
state: {
|
|
6884
7154
|
listPagesId: childResult.nextListPagesId,
|
|
6885
|
-
listUsersId: childResult.nextListUsersId
|
|
7155
|
+
listUsersId: childResult.nextListUsersId,
|
|
7156
|
+
tagCloudId: childResult.nextTagCloudId
|
|
6886
7157
|
}
|
|
6887
7158
|
};
|
|
6888
7159
|
});
|
|
6889
7160
|
result.push(mapped.element);
|
|
6890
7161
|
listPagesId = mapped.state.listPagesId;
|
|
6891
7162
|
listUsersId = mapped.state.listUsersId;
|
|
7163
|
+
tagCloudId = mapped.state.tagCloudId;
|
|
6892
7164
|
}
|
|
6893
|
-
return {
|
|
7165
|
+
return {
|
|
7166
|
+
elements: result,
|
|
7167
|
+
nextListPagesId: listPagesId,
|
|
7168
|
+
nextListUsersId: listUsersId,
|
|
7169
|
+
nextTagCloudId: tagCloudId
|
|
7170
|
+
};
|
|
6894
7171
|
}
|
|
6895
7172
|
|
|
6896
7173
|
// packages/parser/src/parser/rules/block/module/resolution/styles.ts
|
|
6897
|
-
var
|
|
7174
|
+
var import_ast2 = require("@wdprlib/ast");
|
|
6898
7175
|
function collectStyles(elements) {
|
|
6899
7176
|
const styles = [];
|
|
6900
7177
|
const ctx = { nextSlotId: 0 };
|
|
@@ -6910,7 +7187,7 @@ function collectStylesFromElements(elements, styles, ctx) {
|
|
|
6910
7187
|
}
|
|
6911
7188
|
if (element.element === "if-tags") {
|
|
6912
7189
|
const slotId = ctx.nextSlotId++;
|
|
6913
|
-
styles.push(`${
|
|
7190
|
+
styles.push(`${import_ast2.STYLE_SLOT_PREFIX}${slotId}`);
|
|
6914
7191
|
const data = { ...element.data, _styleSlot: slotId };
|
|
6915
7192
|
result.push({
|
|
6916
7193
|
element: "if-tags",
|
|
@@ -6929,15 +7206,19 @@ async function resolveModules(ast, dataProvider, options) {
|
|
|
6929
7206
|
const parse = createModuleParseFunction(options, dataProvider);
|
|
6930
7207
|
const listPagesCtx = await buildListPagesContext(dataProvider, options.requirements.listPages ?? [], options.compiledListPagesTemplates, parse, options.urlPath);
|
|
6931
7208
|
const listUsersCtx = await buildListUsersContext(dataProvider, options.requirements.listUsers ?? [], options.compiledListUsersTemplates, parse);
|
|
7209
|
+
const tagCloudCtx = await buildTagCloudContext(dataProvider, options.requirements.tagCloud ?? []);
|
|
6932
7210
|
const pageTags = dataProvider.getPageTags?.() ?? null;
|
|
6933
7211
|
const resolvedElements = walkAndResolve(ast.elements, {
|
|
6934
7212
|
listPages: listPagesCtx,
|
|
6935
7213
|
listUsers: listUsersCtx,
|
|
7214
|
+
tagCloud: tagCloudCtx,
|
|
6936
7215
|
fetchListPagesProvided: dataProvider.fetchListPages !== undefined,
|
|
6937
7216
|
fetchListUsersProvided: dataProvider.fetchListUsers !== undefined,
|
|
7217
|
+
fetchTagCloudProvided: dataProvider.fetchTagCloud !== undefined,
|
|
6938
7218
|
pageTags,
|
|
6939
7219
|
listPagesIdCounter: 0,
|
|
6940
|
-
listUsersIdCounter: 0
|
|
7220
|
+
listUsersIdCounter: 0,
|
|
7221
|
+
tagCloudIdCounter: 0
|
|
6941
7222
|
});
|
|
6942
7223
|
const { elements: finalElements, styles } = collectStyles(resolvedElements.elements);
|
|
6943
7224
|
const result = {
|
|
@@ -6969,7 +7250,7 @@ function createModuleSourceTransform(options, dataProvider) {
|
|
|
6969
7250
|
}
|
|
6970
7251
|
|
|
6971
7252
|
// packages/parser/src/parser/rules/block/module/index.ts
|
|
6972
|
-
var
|
|
7253
|
+
var import_ast3 = require("@wdprlib/ast");
|
|
6973
7254
|
|
|
6974
7255
|
// packages/parser/src/parser/rules/block/footnoteblock/attributes.ts
|
|
6975
7256
|
function parseFootnoteBlockAttributes(ctx, startPos) {
|
|
@@ -11916,7 +12197,7 @@ function createParseContext(tokens, options = {}) {
|
|
|
11916
12197
|
pos: 0,
|
|
11917
12198
|
version: options.version ?? "wikidot",
|
|
11918
12199
|
trackPositions: options.trackPositions ?? true,
|
|
11919
|
-
settings: options.settings ??
|
|
12200
|
+
settings: options.settings ?? import_ast4.DEFAULT_SETTINGS,
|
|
11920
12201
|
footnotes: [],
|
|
11921
12202
|
tocEntries: [],
|
|
11922
12203
|
codeBlocks: [],
|
|
@@ -12881,12 +13162,12 @@ function preprocess(text) {
|
|
|
12881
13162
|
}
|
|
12882
13163
|
|
|
12883
13164
|
// packages/parser/src/parser/preprocess/expr/evaluate.ts
|
|
12884
|
-
var
|
|
13165
|
+
var import_ast5 = require("@wdprlib/ast");
|
|
12885
13166
|
function evaluateDirective(kind, match) {
|
|
12886
13167
|
if (kind === "expr") {
|
|
12887
|
-
const result2 =
|
|
13168
|
+
const result2 = import_ast5.evaluateExpression(match.head);
|
|
12888
13169
|
if (result2.success)
|
|
12889
|
-
return
|
|
13170
|
+
return import_ast5.formatExprValue(result2.value);
|
|
12890
13171
|
if (result2.error === "empty expression")
|
|
12891
13172
|
return "";
|
|
12892
13173
|
return "ERROR";
|
|
@@ -12894,11 +13175,11 @@ function evaluateDirective(kind, match) {
|
|
|
12894
13175
|
if (kind === "if") {
|
|
12895
13176
|
if (!match.hasPipe)
|
|
12896
13177
|
return "";
|
|
12897
|
-
return
|
|
13178
|
+
return import_ast5.isTruthy(match.head) ? match.thenText : match.elseText;
|
|
12898
13179
|
}
|
|
12899
13180
|
if (!match.hasPipe)
|
|
12900
13181
|
return "";
|
|
12901
|
-
const result =
|
|
13182
|
+
const result = import_ast5.evaluateExpression(match.head);
|
|
12902
13183
|
if (!result.success)
|
|
12903
13184
|
return "ERROR";
|
|
12904
13185
|
return result.value !== 0 && !Number.isNaN(result.value) ? match.thenText : match.elseText;
|