@wdprlib/parser 4.1.0 → 4.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -1
- package/dist/index.cjs +476 -39
- package/dist/index.d.cts +121 -2
- package/dist/index.d.ts +121 -2
- package/dist/index.js +448 -11
- package/package.json +2 -2
- package/src/index.ts +15 -0
- package/src/parser/rules/block/gallery/index.ts +215 -0
- package/src/parser/rules/block/gallery/items.ts +62 -0
- package/src/parser/rules/block/index.ts +3 -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/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.js
CHANGED
|
@@ -4468,6 +4468,92 @@ var listUsersModuleRule = {
|
|
|
4468
4468
|
}
|
|
4469
4469
|
};
|
|
4470
4470
|
|
|
4471
|
+
// packages/parser/src/parser/rules/block/module/tagcloud/parser.ts
|
|
4472
|
+
import { CSS_LENGTH_UNITS } from "@wdprlib/ast";
|
|
4473
|
+
var FONT_SIZE_PATTERN = new RegExp(`^([0-9]+)(${CSS_LENGTH_UNITS.join("|")})$`, "i");
|
|
4474
|
+
var COLOR_PATTERN = /^[0-9]+,[0-9]+,[0-9]+$/;
|
|
4475
|
+
var POSITIVE_INT_PATTERN = /^[0-9]+$/;
|
|
4476
|
+
var ERROR_FONT_FORMAT = "Unsupported format for font size. Use a number followed by a CSS length unit such as px, em or %.";
|
|
4477
|
+
var ERROR_FONT_MISMATCH = "Format for minFontSize and maxFontSize must use the same unit.";
|
|
4478
|
+
var ERROR_COLOR_FORMAT = 'Unsupported color format. Use "RRR,GGG,BBB" for Red,Green,Blue each within 0-255 range.';
|
|
4479
|
+
function errorBlock(message) {
|
|
4480
|
+
return {
|
|
4481
|
+
element: "container",
|
|
4482
|
+
data: {
|
|
4483
|
+
type: "div",
|
|
4484
|
+
attributes: { class: "error-block" },
|
|
4485
|
+
elements: [{ element: "text", data: message }]
|
|
4486
|
+
}
|
|
4487
|
+
};
|
|
4488
|
+
}
|
|
4489
|
+
function parseLimit(value) {
|
|
4490
|
+
if (!value || !POSITIVE_INT_PATTERN.test(value))
|
|
4491
|
+
return 50;
|
|
4492
|
+
const num = Number.parseInt(value, 10);
|
|
4493
|
+
return Number.isSafeInteger(num) && num > 0 ? num : 50;
|
|
4494
|
+
}
|
|
4495
|
+
function normalizeTarget(value) {
|
|
4496
|
+
if (!value)
|
|
4497
|
+
return "/system:page-tags/tag/";
|
|
4498
|
+
let target = value;
|
|
4499
|
+
if (!target.startsWith("/"))
|
|
4500
|
+
target = `/${target}`;
|
|
4501
|
+
if (!target.endsWith("/"))
|
|
4502
|
+
target = `${target}/`;
|
|
4503
|
+
return `${target}tag/`;
|
|
4504
|
+
}
|
|
4505
|
+
function parseColor(value) {
|
|
4506
|
+
const [r = 0, g = 0, b = 0] = value.split(",").map((part) => Number.parseInt(part, 10));
|
|
4507
|
+
return [r, g, b];
|
|
4508
|
+
}
|
|
4509
|
+
var tagCloudModuleRule = {
|
|
4510
|
+
name: "module-tagcloud",
|
|
4511
|
+
acceptsNames: ["tagcloud"],
|
|
4512
|
+
hasBody: false,
|
|
4513
|
+
parse(_ctx, _pos, args) {
|
|
4514
|
+
const maxFontSize = args.maxfontsize;
|
|
4515
|
+
const minFontSize = args.minfontsize;
|
|
4516
|
+
const maxColor = args.maxcolor;
|
|
4517
|
+
const minColor = args.mincolor;
|
|
4518
|
+
let sizeSmall = 100;
|
|
4519
|
+
let sizeBig = 300;
|
|
4520
|
+
let fontSizeUnit = "%";
|
|
4521
|
+
if (maxFontSize && minFontSize) {
|
|
4522
|
+
const maxMatch = FONT_SIZE_PATTERN.exec(maxFontSize);
|
|
4523
|
+
if (!maxMatch)
|
|
4524
|
+
return errorBlock(ERROR_FONT_FORMAT);
|
|
4525
|
+
const maxUnit = maxMatch[2].toLowerCase();
|
|
4526
|
+
const minMatch = FONT_SIZE_PATTERN.exec(minFontSize);
|
|
4527
|
+
if (!minMatch || minMatch[2].toLowerCase() !== maxUnit) {
|
|
4528
|
+
return errorBlock(ERROR_FONT_MISMATCH);
|
|
4529
|
+
}
|
|
4530
|
+
sizeBig = Number.parseInt(maxMatch[1], 10);
|
|
4531
|
+
sizeSmall = Number.parseInt(minMatch[1], 10);
|
|
4532
|
+
fontSizeUnit = maxUnit;
|
|
4533
|
+
}
|
|
4534
|
+
let colorSmall = [128, 128, 192];
|
|
4535
|
+
let colorBig = [64, 64, 128];
|
|
4536
|
+
if (maxColor && minColor) {
|
|
4537
|
+
if (!COLOR_PATTERN.test(maxColor) || !COLOR_PATTERN.test(minColor)) {
|
|
4538
|
+
return errorBlock(ERROR_COLOR_FORMAT);
|
|
4539
|
+
}
|
|
4540
|
+
colorSmall = parseColor(minColor);
|
|
4541
|
+
colorBig = parseColor(maxColor);
|
|
4542
|
+
}
|
|
4543
|
+
return {
|
|
4544
|
+
module: "tag-cloud",
|
|
4545
|
+
"min-font-size": sizeSmall,
|
|
4546
|
+
"max-font-size": sizeBig,
|
|
4547
|
+
"font-size-unit": fontSizeUnit,
|
|
4548
|
+
"min-color": colorSmall,
|
|
4549
|
+
"max-color": colorBig,
|
|
4550
|
+
target: normalizeTarget(args.target),
|
|
4551
|
+
limit: parseLimit(args.limit),
|
|
4552
|
+
category: args.category || null
|
|
4553
|
+
};
|
|
4554
|
+
}
|
|
4555
|
+
};
|
|
4556
|
+
|
|
4471
4557
|
// packages/parser/src/parser/rules/block/module/mapping.ts
|
|
4472
4558
|
var MODULE_RULES = [
|
|
4473
4559
|
rateModuleRule,
|
|
@@ -4477,7 +4563,8 @@ var MODULE_RULES = [
|
|
|
4477
4563
|
joinModuleRule,
|
|
4478
4564
|
pageTreeModuleRule,
|
|
4479
4565
|
listPagesModuleRule,
|
|
4480
|
-
listUsersModuleRule
|
|
4566
|
+
listUsersModuleRule,
|
|
4567
|
+
tagCloudModuleRule
|
|
4481
4568
|
];
|
|
4482
4569
|
var moduleRuleMap = new Map;
|
|
4483
4570
|
for (const rule of MODULE_RULES) {
|
|
@@ -5558,18 +5645,130 @@ function extractListUsersModule(listUsers, state, result) {
|
|
|
5558
5645
|
result.compiledListUsersTemplates.set(id, compileListUsersTemplate(body));
|
|
5559
5646
|
}
|
|
5560
5647
|
|
|
5648
|
+
// packages/parser/src/parser/rules/block/module/tagcloud/resolve.ts
|
|
5649
|
+
function isTagCloudModule(module) {
|
|
5650
|
+
return module.module === "tag-cloud";
|
|
5651
|
+
}
|
|
5652
|
+
var NO_TAGS_MESSAGE_PREFIX = "It seems you have no tags attached to pages. To attach a tag simply click on the ";
|
|
5653
|
+
var NO_TAGS_MESSAGE_SUFFIX = " button at the bottom of any page.";
|
|
5654
|
+
function rawUrlEncode(value) {
|
|
5655
|
+
return encodeURIComponent(value).replace(/[!'()*]/g, (char) => `%${char.charCodeAt(0).toString(16).toUpperCase()}`);
|
|
5656
|
+
}
|
|
5657
|
+
function selectTags(tags, limit) {
|
|
5658
|
+
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));
|
|
5659
|
+
}
|
|
5660
|
+
function compareTags(a, b) {
|
|
5661
|
+
return a < b ? -1 : a > b ? 1 : 0;
|
|
5662
|
+
}
|
|
5663
|
+
function resolveTagCloud(module, data) {
|
|
5664
|
+
if (data.status === "category-not-found") {
|
|
5665
|
+
return [
|
|
5666
|
+
{
|
|
5667
|
+
element: "container",
|
|
5668
|
+
data: {
|
|
5669
|
+
type: "div",
|
|
5670
|
+
attributes: { class: "error-block" },
|
|
5671
|
+
elements: [{ element: "text", data: `Category "${data.category}" can not be found.` }]
|
|
5672
|
+
}
|
|
5673
|
+
}
|
|
5674
|
+
];
|
|
5675
|
+
}
|
|
5676
|
+
const tags = selectTags(data.tags, module.limit);
|
|
5677
|
+
if (tags.length === 0) {
|
|
5678
|
+
return [noTagsMessage()];
|
|
5679
|
+
}
|
|
5680
|
+
let minWeight = Number.POSITIVE_INFINITY;
|
|
5681
|
+
let maxWeight = Number.NEGATIVE_INFINITY;
|
|
5682
|
+
for (const tag of tags) {
|
|
5683
|
+
if (tag.weight < minWeight)
|
|
5684
|
+
minWeight = tag.weight;
|
|
5685
|
+
if (tag.weight > maxWeight)
|
|
5686
|
+
maxWeight = tag.weight;
|
|
5687
|
+
}
|
|
5688
|
+
const weightRange = maxWeight - minWeight;
|
|
5689
|
+
const categorySuffix = data.category !== null ? `/category/${rawUrlEncode(data.category)}` : "";
|
|
5690
|
+
const anchors = [];
|
|
5691
|
+
for (const tag of tags) {
|
|
5692
|
+
const a = weightRange === 0 ? 0 : (tag.weight - minWeight) / weightRange;
|
|
5693
|
+
const fontSize = interpolate(module["min-font-size"], module["max-font-size"], a);
|
|
5694
|
+
const [r, g, b] = [0, 1, 2].map((i) => interpolate(module["min-color"][i], module["max-color"][i], a));
|
|
5695
|
+
anchors.push({ element: "text", data: `
|
|
5696
|
+
` });
|
|
5697
|
+
anchors.push({
|
|
5698
|
+
element: "anchor",
|
|
5699
|
+
data: {
|
|
5700
|
+
target: null,
|
|
5701
|
+
attributes: {
|
|
5702
|
+
class: "tag",
|
|
5703
|
+
href: `${module.target}${rawUrlEncode(tag.tag)}${categorySuffix}`,
|
|
5704
|
+
style: `font-size: ${fontSize}${module["font-size-unit"]}; color: rgb(${r}, ${g}, ${b});`
|
|
5705
|
+
},
|
|
5706
|
+
elements: [{ element: "text", data: tag.tag }]
|
|
5707
|
+
}
|
|
5708
|
+
});
|
|
5709
|
+
}
|
|
5710
|
+
anchors.push({ element: "text", data: `
|
|
5711
|
+
` });
|
|
5712
|
+
return [
|
|
5713
|
+
{
|
|
5714
|
+
element: "container",
|
|
5715
|
+
data: {
|
|
5716
|
+
type: "div",
|
|
5717
|
+
attributes: { class: "pages-tag-cloud-box" },
|
|
5718
|
+
elements: anchors
|
|
5719
|
+
}
|
|
5720
|
+
}
|
|
5721
|
+
];
|
|
5722
|
+
}
|
|
5723
|
+
function interpolate(min, max, a) {
|
|
5724
|
+
return Math.round(min + (max - min) * a);
|
|
5725
|
+
}
|
|
5726
|
+
function noTagsMessage() {
|
|
5727
|
+
return {
|
|
5728
|
+
element: "container",
|
|
5729
|
+
data: {
|
|
5730
|
+
type: "paragraph",
|
|
5731
|
+
attributes: {},
|
|
5732
|
+
elements: [
|
|
5733
|
+
{ element: "text", data: NO_TAGS_MESSAGE_PREFIX },
|
|
5734
|
+
{
|
|
5735
|
+
element: "container",
|
|
5736
|
+
data: {
|
|
5737
|
+
type: "italics",
|
|
5738
|
+
attributes: {},
|
|
5739
|
+
elements: [{ element: "text", data: "tags" }]
|
|
5740
|
+
}
|
|
5741
|
+
},
|
|
5742
|
+
{ element: "text", data: NO_TAGS_MESSAGE_SUFFIX }
|
|
5743
|
+
]
|
|
5744
|
+
}
|
|
5745
|
+
};
|
|
5746
|
+
}
|
|
5747
|
+
|
|
5748
|
+
// packages/parser/src/parser/rules/block/module/listpages/extraction/tagcloud.ts
|
|
5749
|
+
function extractTagCloudModule(tagCloud, state, result) {
|
|
5750
|
+
const id = state.nextId++;
|
|
5751
|
+
result.requirements.tagCloud.push({
|
|
5752
|
+
id,
|
|
5753
|
+
category: tagCloud.category,
|
|
5754
|
+
limit: tagCloud.limit
|
|
5755
|
+
});
|
|
5756
|
+
}
|
|
5757
|
+
|
|
5561
5758
|
// packages/parser/src/parser/rules/block/module/listpages/extract.ts
|
|
5562
5759
|
function extractDataRequirements(ast) {
|
|
5563
5760
|
const result = {
|
|
5564
5761
|
requirements: {
|
|
5565
5762
|
listPages: [],
|
|
5566
|
-
listUsers: []
|
|
5763
|
+
listUsers: [],
|
|
5764
|
+
tagCloud: []
|
|
5567
5765
|
},
|
|
5568
5766
|
compiledListPagesTemplates: new Map,
|
|
5569
5767
|
compiledListUsersTemplates: new Map
|
|
5570
5768
|
};
|
|
5571
5769
|
const listPagesState = { nextId: 0 };
|
|
5572
5770
|
const listUsersState = { nextId: 0 };
|
|
5771
|
+
const tagCloudState = { nextId: 0 };
|
|
5573
5772
|
walkElements(ast.elements, (element) => {
|
|
5574
5773
|
if (element.element !== "module")
|
|
5575
5774
|
return;
|
|
@@ -5577,6 +5776,8 @@ function extractDataRequirements(ast) {
|
|
|
5577
5776
|
extractListPagesModule(element.data, listPagesState, result);
|
|
5578
5777
|
} else if (isListUsersModule(element.data)) {
|
|
5579
5778
|
extractListUsersModule(element.data, listUsersState, result);
|
|
5779
|
+
} else if (isTagCloudModule(element.data)) {
|
|
5780
|
+
extractTagCloudModule(element.data, tagCloudState, result);
|
|
5580
5781
|
}
|
|
5581
5782
|
});
|
|
5582
5783
|
return result;
|
|
@@ -6692,6 +6893,16 @@ async function buildListUsersDataMap(dataProvider, requirements) {
|
|
|
6692
6893
|
}
|
|
6693
6894
|
return dataMap;
|
|
6694
6895
|
}
|
|
6896
|
+
async function buildTagCloudDataMap(dataProvider, requirements) {
|
|
6897
|
+
const dataMap = new Map;
|
|
6898
|
+
for (const req of requirements) {
|
|
6899
|
+
const data = await dataProvider.fetchTagCloud?.(req);
|
|
6900
|
+
if (data) {
|
|
6901
|
+
dataMap.set(req.id, data);
|
|
6902
|
+
}
|
|
6903
|
+
}
|
|
6904
|
+
return dataMap;
|
|
6905
|
+
}
|
|
6695
6906
|
|
|
6696
6907
|
// packages/parser/src/parser/rules/block/module/resolution/contexts.ts
|
|
6697
6908
|
async function buildListPagesContext(dataProvider, requirements, compiledTemplates, parse, urlPath) {
|
|
@@ -6708,6 +6919,16 @@ async function buildListPagesContext(dataProvider, requirements, compiledTemplat
|
|
|
6708
6919
|
parse
|
|
6709
6920
|
};
|
|
6710
6921
|
}
|
|
6922
|
+
async function buildTagCloudContext(dataProvider, requirements) {
|
|
6923
|
+
if (requirements.length === 0 || !dataProvider.fetchTagCloud) {
|
|
6924
|
+
return null;
|
|
6925
|
+
}
|
|
6926
|
+
const dataMap = await buildTagCloudDataMap(dataProvider, requirements);
|
|
6927
|
+
if (dataMap.size === 0) {
|
|
6928
|
+
return null;
|
|
6929
|
+
}
|
|
6930
|
+
return { dataMap };
|
|
6931
|
+
}
|
|
6711
6932
|
async function buildListUsersContext(dataProvider, requirements, compiledTemplates, parse) {
|
|
6712
6933
|
if (requirements.length === 0 || !dataProvider.fetchListUsers) {
|
|
6713
6934
|
return null;
|
|
@@ -6764,10 +6985,27 @@ function resolveDynamicModuleElement(element, ctx, ids) {
|
|
|
6764
6985
|
ids: { ...ids, listUsersId: listUsersId + 1 }
|
|
6765
6986
|
};
|
|
6766
6987
|
}
|
|
6988
|
+
if (isTagCloudModule(element.data)) {
|
|
6989
|
+
const elements = [];
|
|
6990
|
+
const tagCloudId = ids.tagCloudId;
|
|
6991
|
+
if (ctx.tagCloud) {
|
|
6992
|
+
const moduleData = ctx.tagCloud.dataMap.get(tagCloudId);
|
|
6993
|
+
if (moduleData) {
|
|
6994
|
+
elements.push(...resolveTagCloud(element.data, moduleData));
|
|
6995
|
+
}
|
|
6996
|
+
} else if (!ctx.fetchTagCloudProvided) {
|
|
6997
|
+
elements.push(element);
|
|
6998
|
+
}
|
|
6999
|
+
return {
|
|
7000
|
+
handled: true,
|
|
7001
|
+
elements,
|
|
7002
|
+
ids: { ...ids, tagCloudId: tagCloudId + 1 }
|
|
7003
|
+
};
|
|
7004
|
+
}
|
|
6767
7005
|
return { handled: false, elements: [element], ids };
|
|
6768
7006
|
}
|
|
6769
7007
|
function countDynamicModules(elements) {
|
|
6770
|
-
const counts = { listPagesId: 0, listUsersId: 0 };
|
|
7008
|
+
const counts = { listPagesId: 0, listUsersId: 0, tagCloudId: 0 };
|
|
6771
7009
|
walkElements(elements, (element) => {
|
|
6772
7010
|
if (element.element !== "module")
|
|
6773
7011
|
return;
|
|
@@ -6775,6 +7013,8 @@ function countDynamicModules(elements) {
|
|
|
6775
7013
|
counts.listPagesId++;
|
|
6776
7014
|
} else if (isListUsersModule2(element.data)) {
|
|
6777
7015
|
counts.listUsersId++;
|
|
7016
|
+
} else if (isTagCloudModule(element.data)) {
|
|
7017
|
+
counts.tagCloudId++;
|
|
6778
7018
|
}
|
|
6779
7019
|
});
|
|
6780
7020
|
return counts;
|
|
@@ -6785,12 +7025,18 @@ function walkAndResolve(elements, ctx) {
|
|
|
6785
7025
|
const result = [];
|
|
6786
7026
|
let listPagesId = ctx.listPagesIdCounter;
|
|
6787
7027
|
let listUsersId = ctx.listUsersIdCounter;
|
|
7028
|
+
let tagCloudId = ctx.tagCloudIdCounter;
|
|
6788
7029
|
for (const element of elements) {
|
|
6789
|
-
const dynamicModule = resolveDynamicModuleElement(element, ctx, {
|
|
7030
|
+
const dynamicModule = resolveDynamicModuleElement(element, ctx, {
|
|
7031
|
+
listPagesId,
|
|
7032
|
+
listUsersId,
|
|
7033
|
+
tagCloudId
|
|
7034
|
+
});
|
|
6790
7035
|
if (dynamicModule.handled) {
|
|
6791
7036
|
result.push(...dynamicModule.elements);
|
|
6792
7037
|
listPagesId = dynamicModule.ids.listPagesId;
|
|
6793
7038
|
listUsersId = dynamicModule.ids.listUsersId;
|
|
7039
|
+
tagCloudId = dynamicModule.ids.tagCloudId;
|
|
6794
7040
|
continue;
|
|
6795
7041
|
}
|
|
6796
7042
|
if (isIfTagsElement(element)) {
|
|
@@ -6801,21 +7047,25 @@ function walkAndResolve(elements, ctx) {
|
|
|
6801
7047
|
const childResult = walkAndResolve(ifTagsData.elements, {
|
|
6802
7048
|
...ctx,
|
|
6803
7049
|
listPagesIdCounter: listPagesId,
|
|
6804
|
-
listUsersIdCounter: listUsersId
|
|
7050
|
+
listUsersIdCounter: listUsersId,
|
|
7051
|
+
tagCloudIdCounter: tagCloudId
|
|
6805
7052
|
});
|
|
6806
7053
|
result.push(...childResult.elements);
|
|
6807
7054
|
listPagesId = childResult.nextListPagesId;
|
|
6808
7055
|
listUsersId = childResult.nextListUsersId;
|
|
7056
|
+
tagCloudId = childResult.nextTagCloudId;
|
|
6809
7057
|
} else {
|
|
6810
7058
|
const counts = countDynamicModules(ifTagsData.elements);
|
|
6811
7059
|
listPagesId += counts.listPagesId;
|
|
6812
7060
|
listUsersId += counts.listUsersId;
|
|
7061
|
+
tagCloudId += counts.tagCloudId;
|
|
6813
7062
|
}
|
|
6814
7063
|
} else {
|
|
6815
7064
|
const childResult = walkAndResolve(ifTagsData.elements, {
|
|
6816
7065
|
...ctx,
|
|
6817
7066
|
listPagesIdCounter: listPagesId,
|
|
6818
|
-
listUsersIdCounter: listUsersId
|
|
7067
|
+
listUsersIdCounter: listUsersId,
|
|
7068
|
+
tagCloudIdCounter: tagCloudId
|
|
6819
7069
|
});
|
|
6820
7070
|
result.push({
|
|
6821
7071
|
element: "if-tags",
|
|
@@ -6826,28 +7076,37 @@ function walkAndResolve(elements, ctx) {
|
|
|
6826
7076
|
});
|
|
6827
7077
|
listPagesId = childResult.nextListPagesId;
|
|
6828
7078
|
listUsersId = childResult.nextListUsersId;
|
|
7079
|
+
tagCloudId = childResult.nextTagCloudId;
|
|
6829
7080
|
}
|
|
6830
7081
|
continue;
|
|
6831
7082
|
}
|
|
6832
|
-
const mapped = mapElementChildrenWithState(element, { listPagesId, listUsersId }, (children, state) => {
|
|
7083
|
+
const mapped = mapElementChildrenWithState(element, { listPagesId, listUsersId, tagCloudId }, (children, state) => {
|
|
6833
7084
|
const childResult = walkAndResolve(children, {
|
|
6834
7085
|
...ctx,
|
|
6835
7086
|
listPagesIdCounter: state.listPagesId,
|
|
6836
|
-
listUsersIdCounter: state.listUsersId
|
|
7087
|
+
listUsersIdCounter: state.listUsersId,
|
|
7088
|
+
tagCloudIdCounter: state.tagCloudId
|
|
6837
7089
|
});
|
|
6838
7090
|
return {
|
|
6839
7091
|
elements: childResult.elements,
|
|
6840
7092
|
state: {
|
|
6841
7093
|
listPagesId: childResult.nextListPagesId,
|
|
6842
|
-
listUsersId: childResult.nextListUsersId
|
|
7094
|
+
listUsersId: childResult.nextListUsersId,
|
|
7095
|
+
tagCloudId: childResult.nextTagCloudId
|
|
6843
7096
|
}
|
|
6844
7097
|
};
|
|
6845
7098
|
});
|
|
6846
7099
|
result.push(mapped.element);
|
|
6847
7100
|
listPagesId = mapped.state.listPagesId;
|
|
6848
7101
|
listUsersId = mapped.state.listUsersId;
|
|
7102
|
+
tagCloudId = mapped.state.tagCloudId;
|
|
6849
7103
|
}
|
|
6850
|
-
return {
|
|
7104
|
+
return {
|
|
7105
|
+
elements: result,
|
|
7106
|
+
nextListPagesId: listPagesId,
|
|
7107
|
+
nextListUsersId: listUsersId,
|
|
7108
|
+
nextTagCloudId: tagCloudId
|
|
7109
|
+
};
|
|
6851
7110
|
}
|
|
6852
7111
|
|
|
6853
7112
|
// packages/parser/src/parser/rules/block/module/resolution/styles.ts
|
|
@@ -6886,15 +7145,19 @@ async function resolveModules(ast, dataProvider, options) {
|
|
|
6886
7145
|
const parse = createModuleParseFunction(options, dataProvider);
|
|
6887
7146
|
const listPagesCtx = await buildListPagesContext(dataProvider, options.requirements.listPages ?? [], options.compiledListPagesTemplates, parse, options.urlPath);
|
|
6888
7147
|
const listUsersCtx = await buildListUsersContext(dataProvider, options.requirements.listUsers ?? [], options.compiledListUsersTemplates, parse);
|
|
7148
|
+
const tagCloudCtx = await buildTagCloudContext(dataProvider, options.requirements.tagCloud ?? []);
|
|
6889
7149
|
const pageTags = dataProvider.getPageTags?.() ?? null;
|
|
6890
7150
|
const resolvedElements = walkAndResolve(ast.elements, {
|
|
6891
7151
|
listPages: listPagesCtx,
|
|
6892
7152
|
listUsers: listUsersCtx,
|
|
7153
|
+
tagCloud: tagCloudCtx,
|
|
6893
7154
|
fetchListPagesProvided: dataProvider.fetchListPages !== undefined,
|
|
6894
7155
|
fetchListUsersProvided: dataProvider.fetchListUsers !== undefined,
|
|
7156
|
+
fetchTagCloudProvided: dataProvider.fetchTagCloud !== undefined,
|
|
6895
7157
|
pageTags,
|
|
6896
7158
|
listPagesIdCounter: 0,
|
|
6897
|
-
listUsersIdCounter: 0
|
|
7159
|
+
listUsersIdCounter: 0,
|
|
7160
|
+
tagCloudIdCounter: 0
|
|
6898
7161
|
});
|
|
6899
7162
|
const { elements: finalElements, styles } = collectStyles(resolvedElements.elements);
|
|
6900
7163
|
const result = {
|
|
@@ -8994,6 +9257,177 @@ var bibliographyRule = {
|
|
|
8994
9257
|
}
|
|
8995
9258
|
};
|
|
8996
9259
|
|
|
9260
|
+
// packages/parser/src/parser/rules/block/gallery/items.ts
|
|
9261
|
+
function parseGalleryItemLine(content) {
|
|
9262
|
+
const spacePos = content.indexOf(" ");
|
|
9263
|
+
let source = spacePos < 0 ? content : content.slice(0, spacePos);
|
|
9264
|
+
const attrText = spacePos < 0 ? "" : content.slice(spacePos + 1);
|
|
9265
|
+
let newWindow = false;
|
|
9266
|
+
if (source.startsWith("*")) {
|
|
9267
|
+
source = source.slice(1);
|
|
9268
|
+
newWindow = true;
|
|
9269
|
+
}
|
|
9270
|
+
const attrs = parseItemAttrs(attrText);
|
|
9271
|
+
let link = attrs.get("link") ?? null;
|
|
9272
|
+
if (link !== null && link.startsWith("*")) {
|
|
9273
|
+
newWindow = true;
|
|
9274
|
+
link = link.slice(1);
|
|
9275
|
+
}
|
|
9276
|
+
const alt = attrs.get("alt") ?? null;
|
|
9277
|
+
return { source, link, alt, newWindow };
|
|
9278
|
+
}
|
|
9279
|
+
function parseItemAttrs(text) {
|
|
9280
|
+
const attrs = new Map;
|
|
9281
|
+
const parts = text.trim().split('="');
|
|
9282
|
+
let key = parts[0]?.trim() ?? "";
|
|
9283
|
+
for (let i = 1;i < parts.length; i++) {
|
|
9284
|
+
const val = parts[i] ?? "";
|
|
9285
|
+
const quotePos = val.lastIndexOf('"');
|
|
9286
|
+
if (quotePos < 0) {
|
|
9287
|
+
attrs.set(key, "");
|
|
9288
|
+
key = val.slice(1).trim();
|
|
9289
|
+
} else {
|
|
9290
|
+
attrs.set(key, stripslashes(val.slice(0, quotePos)));
|
|
9291
|
+
key = val.slice(quotePos + 1).trim();
|
|
9292
|
+
}
|
|
9293
|
+
}
|
|
9294
|
+
return attrs;
|
|
9295
|
+
}
|
|
9296
|
+
function stripslashes(value) {
|
|
9297
|
+
return value.replace(/\\(.)/gs, "$1").replace(/\\$/, "");
|
|
9298
|
+
}
|
|
9299
|
+
|
|
9300
|
+
// packages/parser/src/parser/rules/block/gallery/index.ts
|
|
9301
|
+
var GALLERY_SIZES = ["small", "medium", "thumbnail", "square", "original"];
|
|
9302
|
+
function normalizeSize(value) {
|
|
9303
|
+
return value !== undefined && GALLERY_SIZES.includes(value) ? value : "thumbnail";
|
|
9304
|
+
}
|
|
9305
|
+
function normalizeViewer(value) {
|
|
9306
|
+
return value !== "no" && value !== "false";
|
|
9307
|
+
}
|
|
9308
|
+
function normalizeOrder(value) {
|
|
9309
|
+
switch (value) {
|
|
9310
|
+
case "name":
|
|
9311
|
+
case "name desc":
|
|
9312
|
+
case "created_at":
|
|
9313
|
+
case "created_at desc":
|
|
9314
|
+
return value;
|
|
9315
|
+
case "nameDesc":
|
|
9316
|
+
return "name desc";
|
|
9317
|
+
case "dateAdded":
|
|
9318
|
+
return "created_at";
|
|
9319
|
+
case "dateAddedDesc":
|
|
9320
|
+
return "created_at desc";
|
|
9321
|
+
case "name desc desc":
|
|
9322
|
+
return "name";
|
|
9323
|
+
case "created_at desc desc":
|
|
9324
|
+
return "created_at";
|
|
9325
|
+
default:
|
|
9326
|
+
return "name";
|
|
9327
|
+
}
|
|
9328
|
+
}
|
|
9329
|
+
function tryParseGalleryContent(ctx, pos) {
|
|
9330
|
+
const start = pos;
|
|
9331
|
+
if (ctx.tokens[pos]?.type !== "NEWLINE") {
|
|
9332
|
+
return null;
|
|
9333
|
+
}
|
|
9334
|
+
const lines = [];
|
|
9335
|
+
let p = pos + 1;
|
|
9336
|
+
for (;; ) {
|
|
9337
|
+
const colon = ctx.tokens[p];
|
|
9338
|
+
if (colon?.type !== "COLON" || !colon.lineStart) {
|
|
9339
|
+
break;
|
|
9340
|
+
}
|
|
9341
|
+
const space = ctx.tokens[p + 1];
|
|
9342
|
+
if (space?.type !== "WHITESPACE" || !space.value.startsWith(" ")) {
|
|
9343
|
+
break;
|
|
9344
|
+
}
|
|
9345
|
+
let content = "";
|
|
9346
|
+
let q = p + 1;
|
|
9347
|
+
while (q < ctx.tokens.length) {
|
|
9348
|
+
const token5 = ctx.tokens[q];
|
|
9349
|
+
if (!token5 || token5.type === "NEWLINE" || token5.type === "EOF") {
|
|
9350
|
+
break;
|
|
9351
|
+
}
|
|
9352
|
+
content += token5.value;
|
|
9353
|
+
q++;
|
|
9354
|
+
}
|
|
9355
|
+
if (content === " ") {
|
|
9356
|
+
return null;
|
|
9357
|
+
}
|
|
9358
|
+
if (ctx.tokens[q]?.type !== "NEWLINE") {
|
|
9359
|
+
return null;
|
|
9360
|
+
}
|
|
9361
|
+
lines.push(content.trim());
|
|
9362
|
+
p = q + 1;
|
|
9363
|
+
}
|
|
9364
|
+
if (lines.length === 0) {
|
|
9365
|
+
return null;
|
|
9366
|
+
}
|
|
9367
|
+
if (ctx.tokens[p]?.type !== "BLOCK_END_OPEN") {
|
|
9368
|
+
return null;
|
|
9369
|
+
}
|
|
9370
|
+
const nameResult = parseBlockName(ctx, p + 1);
|
|
9371
|
+
if (!nameResult || nameResult.name !== "gallery") {
|
|
9372
|
+
return null;
|
|
9373
|
+
}
|
|
9374
|
+
const closePos = p + 1 + nameResult.consumed;
|
|
9375
|
+
if (ctx.tokens[closePos]?.type !== "BLOCK_CLOSE") {
|
|
9376
|
+
return null;
|
|
9377
|
+
}
|
|
9378
|
+
return { lines, consumed: closePos + 1 - start };
|
|
9379
|
+
}
|
|
9380
|
+
var galleryRule = {
|
|
9381
|
+
name: "gallery",
|
|
9382
|
+
startTokens: ["BLOCK_OPEN"],
|
|
9383
|
+
requiresLineStart: true,
|
|
9384
|
+
parse(ctx) {
|
|
9385
|
+
if (ctx.tokens[ctx.pos]?.type !== "BLOCK_OPEN") {
|
|
9386
|
+
return { success: false };
|
|
9387
|
+
}
|
|
9388
|
+
let pos = ctx.pos + 1;
|
|
9389
|
+
const nameResult = parseBlockName(ctx, pos);
|
|
9390
|
+
if (!nameResult || nameResult.name !== "gallery") {
|
|
9391
|
+
return { success: false };
|
|
9392
|
+
}
|
|
9393
|
+
pos += nameResult.consumed;
|
|
9394
|
+
const attrResult = parseAttributesRaw(ctx, pos);
|
|
9395
|
+
pos += attrResult.consumed;
|
|
9396
|
+
if (ctx.tokens[pos]?.type !== "BLOCK_CLOSE") {
|
|
9397
|
+
return { success: false };
|
|
9398
|
+
}
|
|
9399
|
+
pos++;
|
|
9400
|
+
const size = normalizeSize(attrResult.attrs.size);
|
|
9401
|
+
const viewer = normalizeViewer(attrResult.attrs.viewer);
|
|
9402
|
+
const order = normalizeOrder(attrResult.attrs.order);
|
|
9403
|
+
const openConsumed = pos - ctx.pos;
|
|
9404
|
+
const content = tryParseGalleryContent(ctx, pos);
|
|
9405
|
+
if (!content) {
|
|
9406
|
+
return {
|
|
9407
|
+
success: true,
|
|
9408
|
+
elements: [
|
|
9409
|
+
{
|
|
9410
|
+
element: "gallery",
|
|
9411
|
+
data: { size, order, viewer, content: { type: "auto", files: null } }
|
|
9412
|
+
}
|
|
9413
|
+
],
|
|
9414
|
+
consumed: openConsumed
|
|
9415
|
+
};
|
|
9416
|
+
}
|
|
9417
|
+
const items = content.lines.map(parseGalleryItemLine);
|
|
9418
|
+
return {
|
|
9419
|
+
success: true,
|
|
9420
|
+
elements: [
|
|
9421
|
+
{
|
|
9422
|
+
element: "gallery",
|
|
9423
|
+
data: { size, order, viewer, content: { type: "items", items } }
|
|
9424
|
+
}
|
|
9425
|
+
],
|
|
9426
|
+
consumed: openConsumed + content.consumed
|
|
9427
|
+
};
|
|
9428
|
+
}
|
|
9429
|
+
};
|
|
9430
|
+
|
|
8997
9431
|
// packages/parser/src/parser/rules/block/index.ts
|
|
8998
9432
|
var blockRules = [
|
|
8999
9433
|
blockCommentRule,
|
|
@@ -9023,6 +9457,7 @@ var blockRules = [
|
|
|
9023
9457
|
iframeRule,
|
|
9024
9458
|
iftagsRule,
|
|
9025
9459
|
bibliographyRule,
|
|
9460
|
+
galleryRule,
|
|
9026
9461
|
divRule
|
|
9027
9462
|
];
|
|
9028
9463
|
// packages/parser/src/parser/rules/inline/formatting/container.ts
|
|
@@ -13038,6 +13473,7 @@ function parse(source, options) {
|
|
|
13038
13473
|
export {
|
|
13039
13474
|
tokenize,
|
|
13040
13475
|
text,
|
|
13476
|
+
resolveTagCloud,
|
|
13041
13477
|
resolveModules,
|
|
13042
13478
|
resolveListUsers,
|
|
13043
13479
|
resolveIncludesWithTrace,
|
|
@@ -13059,6 +13495,7 @@ export {
|
|
|
13059
13495
|
link,
|
|
13060
13496
|
lineBreak,
|
|
13061
13497
|
italics,
|
|
13498
|
+
isTagCloudModule,
|
|
13062
13499
|
isListUsersModule2 as isListUsersModule,
|
|
13063
13500
|
horizontalRule,
|
|
13064
13501
|
heading,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wdprlib/parser",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.3.0",
|
|
4
4
|
"description": "Parser for Wikidot markup",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ast",
|
|
@@ -41,6 +41,6 @@
|
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
43
|
"@braintree/sanitize-url": "^7.1.1",
|
|
44
|
-
"@wdprlib/ast": "2.
|
|
44
|
+
"@wdprlib/ast": "2.3.0"
|
|
45
45
|
}
|
|
46
46
|
}
|
package/src/index.ts
CHANGED
|
@@ -58,6 +58,12 @@ export type {
|
|
|
58
58
|
DateItem,
|
|
59
59
|
Embed,
|
|
60
60
|
TocEntry,
|
|
61
|
+
// Gallery
|
|
62
|
+
GallerySize,
|
|
63
|
+
GalleryOrder,
|
|
64
|
+
GalleryItem,
|
|
65
|
+
GalleryContent,
|
|
66
|
+
GalleryData,
|
|
61
67
|
// Diagnostics
|
|
62
68
|
Diagnostic,
|
|
63
69
|
DiagnosticSeverity,
|
|
@@ -133,6 +139,12 @@ export type {
|
|
|
133
139
|
ListUsersDataFetcher,
|
|
134
140
|
ListUsersVariableContext,
|
|
135
141
|
ListUsersCompiledTemplate,
|
|
142
|
+
// TagCloud types
|
|
143
|
+
TagCloudDataRequirement,
|
|
144
|
+
TagCloudTagData,
|
|
145
|
+
TagCloudExternalData,
|
|
146
|
+
TagCloudDataFetcher,
|
|
147
|
+
TagCloudModuleData,
|
|
136
148
|
// Normalized query types
|
|
137
149
|
NormalizedListPagesQuery,
|
|
138
150
|
NormalizedTags,
|
|
@@ -167,4 +179,7 @@ export {
|
|
|
167
179
|
compileListUsersTemplate,
|
|
168
180
|
isListUsersModule,
|
|
169
181
|
resolveListUsers,
|
|
182
|
+
// TagCloud
|
|
183
|
+
isTagCloudModule,
|
|
184
|
+
resolveTagCloud,
|
|
170
185
|
} from "./parser/rules/block/module/index";
|