@wdprlib/parser 3.1.2 → 3.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/dist/index.cjs +295 -118
- package/dist/index.js +272 -95
- package/package.json +5 -3
- package/src/index.ts +163 -0
- package/src/lexer/index.ts +20 -0
- package/src/lexer/lexer.ts +687 -0
- package/src/lexer/tokens.ts +141 -0
- package/src/parser/constants.ts +173 -0
- package/src/parser/depth.ts +251 -0
- package/src/parser/index.ts +18 -0
- package/src/parser/parse.ts +315 -0
- package/src/parser/postprocess/divAdjacentParagraph.ts +76 -0
- package/src/parser/postprocess/index.ts +15 -0
- package/src/parser/postprocess/spanStrip.ts +697 -0
- package/src/parser/preprocess/expr.ts +265 -0
- package/src/parser/preprocess/index.ts +38 -0
- package/src/parser/preprocess/typography.ts +67 -0
- package/src/parser/preprocess/utils.ts +250 -0
- package/src/parser/preprocess/whitespace.ts +111 -0
- package/src/parser/rules/block/align.ts +282 -0
- package/src/parser/rules/block/bibliography.ts +359 -0
- package/src/parser/rules/block/block-list.ts +689 -0
- package/src/parser/rules/block/blockquote.ts +238 -0
- package/src/parser/rules/block/center.ts +87 -0
- package/src/parser/rules/block/clear-float.ts +75 -0
- package/src/parser/rules/block/code.ts +187 -0
- package/src/parser/rules/block/collapsible.ts +337 -0
- package/src/parser/rules/block/comment.ts +73 -0
- package/src/parser/rules/block/content-separator.ts +79 -0
- package/src/parser/rules/block/definition-list.ts +270 -0
- package/src/parser/rules/block/div.ts +400 -0
- package/src/parser/rules/block/embed-block.ts +153 -0
- package/src/parser/rules/block/footnoteblock.ts +200 -0
- package/src/parser/rules/block/heading.ts +142 -0
- package/src/parser/rules/block/horizontal-rule.ts +61 -0
- package/src/parser/rules/block/html.ts +222 -0
- package/src/parser/rules/block/iframe.ts +239 -0
- package/src/parser/rules/block/iftags.ts +150 -0
- package/src/parser/rules/block/include.ts +179 -0
- package/src/parser/rules/block/index.ts +127 -0
- package/src/parser/rules/block/list.ts +244 -0
- package/src/parser/rules/block/math.ts +183 -0
- package/src/parser/rules/block/module/backlinks/index.ts +31 -0
- package/src/parser/rules/block/module/backlinks/types.ts +21 -0
- package/src/parser/rules/block/module/categories/index.ts +34 -0
- package/src/parser/rules/block/module/categories/types.ts +21 -0
- package/src/parser/rules/block/module/css/index.ts +37 -0
- package/src/parser/rules/block/module/iftags/condition.ts +109 -0
- package/src/parser/rules/block/module/iftags/index.ts +26 -0
- package/src/parser/rules/block/module/iftags/preprocess.ts +140 -0
- package/src/parser/rules/block/module/iftags/resolve.ts +73 -0
- package/src/parser/rules/block/module/iftags/types.ts +63 -0
- package/src/parser/rules/block/module/include/index.ts +20 -0
- package/src/parser/rules/block/module/include/resolve.ts +556 -0
- package/src/parser/rules/block/module/index.ts +122 -0
- package/src/parser/rules/block/module/join/index.ts +34 -0
- package/src/parser/rules/block/module/join/types.ts +23 -0
- package/src/parser/rules/block/module/listpages/compiler.ts +453 -0
- package/src/parser/rules/block/module/listpages/extract.ts +410 -0
- package/src/parser/rules/block/module/listpages/index.ts +83 -0
- package/src/parser/rules/block/module/listpages/normalize.ts +390 -0
- package/src/parser/rules/block/module/listpages/parser.ts +106 -0
- package/src/parser/rules/block/module/listpages/resolve.ts +130 -0
- package/src/parser/rules/block/module/listpages/types.ts +513 -0
- package/src/parser/rules/block/module/listpages/url-resolver.ts +186 -0
- package/src/parser/rules/block/module/listusers/compiler.ts +77 -0
- package/src/parser/rules/block/module/listusers/extract.ts +45 -0
- package/src/parser/rules/block/module/listusers/index.ts +36 -0
- package/src/parser/rules/block/module/listusers/parser.ts +54 -0
- package/src/parser/rules/block/module/listusers/resolve.ts +58 -0
- package/src/parser/rules/block/module/listusers/types.ts +93 -0
- package/src/parser/rules/block/module/mapping.ts +61 -0
- package/src/parser/rules/block/module/page-tree/index.ts +38 -0
- package/src/parser/rules/block/module/page-tree/types.ts +29 -0
- package/src/parser/rules/block/module/rate/index.ts +28 -0
- package/src/parser/rules/block/module/rate/types.ts +19 -0
- package/src/parser/rules/block/module/resolve.ts +411 -0
- package/src/parser/rules/block/module/types-common.ts +59 -0
- package/src/parser/rules/block/module/types.ts +61 -0
- package/src/parser/rules/block/module/utils.ts +43 -0
- package/src/parser/rules/block/module/walk.ts +380 -0
- package/src/parser/rules/block/module.ts +164 -0
- package/src/parser/rules/block/orphan-li.ts +177 -0
- package/src/parser/rules/block/paragraph.ts +157 -0
- package/src/parser/rules/block/table-block.ts +726 -0
- package/src/parser/rules/block/table.ts +441 -0
- package/src/parser/rules/block/tabview.ts +331 -0
- package/src/parser/rules/block/toc.ts +129 -0
- package/src/parser/rules/block/utils.ts +615 -0
- package/src/parser/rules/index.ts +49 -0
- package/src/parser/rules/inline/anchor-name.ts +154 -0
- package/src/parser/rules/inline/anchor.ts +327 -0
- package/src/parser/rules/inline/bibcite.ts +153 -0
- package/src/parser/rules/inline/bold.ts +86 -0
- package/src/parser/rules/inline/color.ts +140 -0
- package/src/parser/rules/inline/comment.ts +90 -0
- package/src/parser/rules/inline/equation-ref.ts +115 -0
- package/src/parser/rules/inline/expr.ts +526 -0
- package/src/parser/rules/inline/footnote.ts +223 -0
- package/src/parser/rules/inline/guillemet.ts +64 -0
- package/src/parser/rules/inline/html.ts +132 -0
- package/src/parser/rules/inline/image.ts +328 -0
- package/src/parser/rules/inline/index.ts +150 -0
- package/src/parser/rules/inline/italic.ts +74 -0
- package/src/parser/rules/inline/line-break.ts +326 -0
- package/src/parser/rules/inline/link-anchor.ts +147 -0
- package/src/parser/rules/inline/link-single.ts +164 -0
- package/src/parser/rules/inline/link-star.ts +134 -0
- package/src/parser/rules/inline/link-triple.ts +267 -0
- package/src/parser/rules/inline/math-inline.ts +126 -0
- package/src/parser/rules/inline/monospace.ts +78 -0
- package/src/parser/rules/inline/raw.ts +262 -0
- package/src/parser/rules/inline/size.ts +244 -0
- package/src/parser/rules/inline/span.ts +424 -0
- package/src/parser/rules/inline/strikethrough.ts +115 -0
- package/src/parser/rules/inline/subscript.ts +84 -0
- package/src/parser/rules/inline/superscript.ts +84 -0
- package/src/parser/rules/inline/text.ts +84 -0
- package/src/parser/rules/inline/underline.ts +127 -0
- package/src/parser/rules/inline/user.ts +147 -0
- package/src/parser/rules/inline/utils.ts +344 -0
- package/src/parser/rules/types.ts +252 -0
- package/src/parser/rules/utils.ts +155 -0
- package/src/parser/toc.ts +130 -0
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* Template compiler for the ListUsers module.
|
|
4
|
+
*
|
|
5
|
+
* Compiles ListUsers template strings (e.g., `"%%title%% (%%name%%)"`) into
|
|
6
|
+
* executable functions for efficient rendering. The compilation approach is
|
|
7
|
+
* identical to the ListPages compiler: the template is split into static
|
|
8
|
+
* string segments and dynamic getter functions.
|
|
9
|
+
*
|
|
10
|
+
* Only three variables are supported: `%%number%%`, `%%title%%`, and `%%name%%`.
|
|
11
|
+
*
|
|
12
|
+
* @module
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import type { ListUsersCompiledTemplate, ListUsersVariableContext } from "./types";
|
|
16
|
+
|
|
17
|
+
/** Regex for matching `%%variable%%` patterns in the template. */
|
|
18
|
+
const VARIABLE_REGEX = /%%([a-z_]+)%%/gi;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Compile a ListUsers template string into an executable function.
|
|
22
|
+
*
|
|
23
|
+
* The template is split into alternating static strings and dynamic getter
|
|
24
|
+
* functions. The returned function concatenates these parts for each call.
|
|
25
|
+
*
|
|
26
|
+
* @param template - The template string containing `%%variable%%` placeholders
|
|
27
|
+
* @returns A compiled function that accepts a `ListUsersVariableContext` and returns rendered text
|
|
28
|
+
*/
|
|
29
|
+
export function compileListUsersTemplate(template: string): ListUsersCompiledTemplate {
|
|
30
|
+
const parts: (string | ((ctx: ListUsersVariableContext) => string))[] = [];
|
|
31
|
+
let lastIndex = 0;
|
|
32
|
+
|
|
33
|
+
for (const match of template.matchAll(VARIABLE_REGEX)) {
|
|
34
|
+
if (match.index !== undefined && match.index > lastIndex) {
|
|
35
|
+
parts.push(template.slice(lastIndex, match.index));
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const [, varName] = match;
|
|
39
|
+
if (!varName) continue;
|
|
40
|
+
const getter = createVariableGetter(varName.toLowerCase());
|
|
41
|
+
parts.push(getter);
|
|
42
|
+
|
|
43
|
+
lastIndex = match.index !== undefined ? match.index + match[0].length : lastIndex;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (lastIndex < template.length) {
|
|
47
|
+
parts.push(template.slice(lastIndex));
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return (ctx: ListUsersVariableContext): string => {
|
|
51
|
+
let result = "";
|
|
52
|
+
for (const part of parts) {
|
|
53
|
+
result += typeof part === "string" ? part : part(ctx);
|
|
54
|
+
}
|
|
55
|
+
return result;
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Create a getter function for a specific ListUsers variable.
|
|
61
|
+
*
|
|
62
|
+
* @param name - Lowercase variable name
|
|
63
|
+
* @returns A function that extracts the variable's value from a ListUsersVariableContext.
|
|
64
|
+
* Unknown names return a function that always returns an empty string.
|
|
65
|
+
*/
|
|
66
|
+
function createVariableGetter(name: string): (ctx: ListUsersVariableContext) => string {
|
|
67
|
+
switch (name) {
|
|
68
|
+
case "number":
|
|
69
|
+
return (ctx) => String(ctx.user.number);
|
|
70
|
+
case "title":
|
|
71
|
+
return (ctx) => ctx.user.title;
|
|
72
|
+
case "name":
|
|
73
|
+
return (ctx) => ctx.user.name;
|
|
74
|
+
default:
|
|
75
|
+
return () => "";
|
|
76
|
+
}
|
|
77
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* Data requirement extraction for the ListUsers module.
|
|
4
|
+
*
|
|
5
|
+
* Analyzes a ListUsers template string to determine which variables
|
|
6
|
+
* (`%%number%%`, `%%title%%`, `%%name%%`) are referenced. This tells the
|
|
7
|
+
* external application which user data fields need to be provided.
|
|
8
|
+
*
|
|
9
|
+
* @module
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import type { ListUsersVariable } from "./types";
|
|
13
|
+
import { compileListUsersTemplate } from "./compiler";
|
|
14
|
+
|
|
15
|
+
/** Regex for matching `%%variable%%` patterns in ListUsers templates. */
|
|
16
|
+
const VARIABLE_REGEX = /%%([a-z_]+)%%/gi;
|
|
17
|
+
|
|
18
|
+
/** The complete list of recognized ListUsers template variables. */
|
|
19
|
+
const KNOWN_VARIABLES: ListUsersVariable[] = ["number", "title", "name"];
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Extract the set of template variables referenced in a ListUsers template string.
|
|
23
|
+
*
|
|
24
|
+
* Scans for `%%variable%%` patterns and returns only those that match known
|
|
25
|
+
* ListUsers variables. Unknown variables are silently ignored.
|
|
26
|
+
*
|
|
27
|
+
* @param template - The template string from the module body
|
|
28
|
+
* @returns Deduplicated array of referenced variable names
|
|
29
|
+
*/
|
|
30
|
+
export function extractListUsersVariables(template: string): ListUsersVariable[] {
|
|
31
|
+
const variables = new Set<ListUsersVariable>();
|
|
32
|
+
|
|
33
|
+
for (const match of template.matchAll(VARIABLE_REGEX)) {
|
|
34
|
+
const [, varName] = match;
|
|
35
|
+
if (!varName) continue;
|
|
36
|
+
const normalized = varName.toLowerCase();
|
|
37
|
+
if (KNOWN_VARIABLES.includes(normalized as ListUsersVariable)) {
|
|
38
|
+
variables.add(normalized as ListUsersVariable);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return Array.from(variables);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export { compileListUsersTemplate };
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* ListUsers module for Wikidot's `[[module ListUsers users="."]]` block.
|
|
4
|
+
*
|
|
5
|
+
* Displays information about site members using a template with
|
|
6
|
+
* `%%number%%`, `%%title%%`, and `%%name%%` variables. Currently only
|
|
7
|
+
* `users="."` (the logged-in user) is supported.
|
|
8
|
+
*
|
|
9
|
+
* Follows the same three-phase lifecycle as ListPages: parse, extract, resolve.
|
|
10
|
+
*
|
|
11
|
+
* @module
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
// Parser
|
|
15
|
+
export { listUsersModuleRule } from "./parser";
|
|
16
|
+
|
|
17
|
+
// Types
|
|
18
|
+
export type {
|
|
19
|
+
ListUsersVariable,
|
|
20
|
+
ListUsersUserData,
|
|
21
|
+
ListUsersDataRequirement,
|
|
22
|
+
ListUsersExternalData,
|
|
23
|
+
ListUsersDataFetcher,
|
|
24
|
+
ListUsersVariableContext,
|
|
25
|
+
ListUsersCompiledTemplate,
|
|
26
|
+
} from "./types";
|
|
27
|
+
|
|
28
|
+
// Extraction
|
|
29
|
+
export { extractListUsersVariables } from "./extract";
|
|
30
|
+
|
|
31
|
+
// Compiler
|
|
32
|
+
export { compileListUsersTemplate } from "./compiler";
|
|
33
|
+
|
|
34
|
+
// Resolution
|
|
35
|
+
export type { ListUsersModuleData } from "./resolve";
|
|
36
|
+
export { isListUsersModule, resolveListUsers } from "./resolve";
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* Parser rule for the Wikidot `[[module ListUsers ...]]` block.
|
|
4
|
+
*
|
|
5
|
+
* Parses the module's attributes into a `list-users` Module AST node.
|
|
6
|
+
* Currently only `users="."` (logged-in user) is supported; other values
|
|
7
|
+
* produce an error block element.
|
|
8
|
+
*
|
|
9
|
+
* @module
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import type { Element, Module } from "@wdprlib/ast";
|
|
13
|
+
import type { ModuleRule } from "../types";
|
|
14
|
+
|
|
15
|
+
/** Error message displayed when an unsupported `users` value is provided. */
|
|
16
|
+
const ERROR_MESSAGE = 'Currently only users="." is implemented.';
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Module rule for `[[module ListUsers ...]]`.
|
|
20
|
+
*
|
|
21
|
+
* ListUsers displays information about site members. The `users` attribute
|
|
22
|
+
* controls which users are listed. Currently only `"."` (the logged-in user)
|
|
23
|
+
* is implemented. Any other value produces an error block.
|
|
24
|
+
*
|
|
25
|
+
* The template body uses `%%number%%`, `%%title%%`, and `%%name%%` variables.
|
|
26
|
+
*/
|
|
27
|
+
export const listUsersModuleRule: ModuleRule = {
|
|
28
|
+
name: "module-listusers",
|
|
29
|
+
acceptsNames: ["listusers"],
|
|
30
|
+
hasBody: true,
|
|
31
|
+
|
|
32
|
+
parse(_ctx, _pos, args, body): Module | Element {
|
|
33
|
+
const { users, ...rest } = args;
|
|
34
|
+
const usersValue = users ?? ".";
|
|
35
|
+
|
|
36
|
+
if (usersValue !== ".") {
|
|
37
|
+
return {
|
|
38
|
+
element: "container",
|
|
39
|
+
data: {
|
|
40
|
+
type: "div",
|
|
41
|
+
attributes: { class: "error-block" },
|
|
42
|
+
elements: [{ element: "text", data: ERROR_MESSAGE }],
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return {
|
|
48
|
+
module: "list-users",
|
|
49
|
+
users: usersValue,
|
|
50
|
+
body,
|
|
51
|
+
attributes: rest,
|
|
52
|
+
};
|
|
53
|
+
},
|
|
54
|
+
};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* ListUsers module resolution.
|
|
4
|
+
*
|
|
5
|
+
* After the application has fetched user data based on the extracted requirements,
|
|
6
|
+
* this module substitutes that data into the pre-compiled template and re-parses
|
|
7
|
+
* the resulting wikitext to produce final AST elements.
|
|
8
|
+
*
|
|
9
|
+
* @module
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import type { Element, Module } from "@wdprlib/ast";
|
|
13
|
+
import type {
|
|
14
|
+
ListUsersExternalData,
|
|
15
|
+
ListUsersCompiledTemplate,
|
|
16
|
+
ListUsersVariableContext,
|
|
17
|
+
} from "./types";
|
|
18
|
+
import type { ParseFunction } from "../types";
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Narrowed type for the list-users variant of the Module discriminated union.
|
|
22
|
+
*/
|
|
23
|
+
export type ListUsersModuleData = Extract<Module, { module: "list-users" }>;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Type guard to check if a Module is a list-users module.
|
|
27
|
+
*
|
|
28
|
+
* @param module - A Module discriminated union value
|
|
29
|
+
* @returns true if the module is a list-users module
|
|
30
|
+
*/
|
|
31
|
+
export function isListUsersModule(module: Module): module is ListUsersModuleData {
|
|
32
|
+
return module.module === "list-users";
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Resolve a single ListUsers module by substituting fetched user data into
|
|
37
|
+
* the pre-compiled template and re-parsing the result as wikitext.
|
|
38
|
+
*
|
|
39
|
+
* Currently ListUsers only renders the logged-in user (no iteration over
|
|
40
|
+
* multiple users), so the template is executed exactly once.
|
|
41
|
+
*
|
|
42
|
+
* @param _module - The list-users module data from the AST (unused, reserved for future use)
|
|
43
|
+
* @param data - External user data fetched by the application
|
|
44
|
+
* @param compiledTemplate - Pre-compiled template function from the extraction phase
|
|
45
|
+
* @param parse - Parser function for re-parsing the substituted template as wikitext
|
|
46
|
+
* @returns Array of AST elements produced by parsing the rendered template
|
|
47
|
+
*/
|
|
48
|
+
export function resolveListUsers(
|
|
49
|
+
_module: ListUsersModuleData,
|
|
50
|
+
data: ListUsersExternalData,
|
|
51
|
+
compiledTemplate: ListUsersCompiledTemplate,
|
|
52
|
+
parse: ParseFunction,
|
|
53
|
+
): Element[] {
|
|
54
|
+
const ctx: ListUsersVariableContext = { user: data.user };
|
|
55
|
+
const substituted = compiledTemplate(ctx);
|
|
56
|
+
const itemAst = parse(substituted);
|
|
57
|
+
return itemAst.elements;
|
|
58
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* Type definitions for the ListUsers module.
|
|
4
|
+
*
|
|
5
|
+
* The `[[module ListUsers users="."]]` block displays information about site
|
|
6
|
+
* members. Currently, only `users="."` (the logged-in user) is supported.
|
|
7
|
+
* The template body can reference three variables: `%%number%%`, `%%title%%`,
|
|
8
|
+
* and `%%name%%`.
|
|
9
|
+
*
|
|
10
|
+
* @module
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Supported template variables for ListUsers.
|
|
15
|
+
*
|
|
16
|
+
* - `number` - The user's numeric ID
|
|
17
|
+
* - `title` - The user's display title/nickname
|
|
18
|
+
* - `name` - The user's account name
|
|
19
|
+
*/
|
|
20
|
+
export type ListUsersVariable = "number" | "title" | "name";
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* User data that must be provided by the external data source.
|
|
24
|
+
*
|
|
25
|
+
* Each field corresponds to a template variable of the same name.
|
|
26
|
+
*/
|
|
27
|
+
export interface ListUsersUserData {
|
|
28
|
+
/** The user's numeric ID, rendered by `%%number%%` */
|
|
29
|
+
number: number;
|
|
30
|
+
/** The user's display title, rendered by `%%title%%` */
|
|
31
|
+
title: string;
|
|
32
|
+
/** The user's account name, rendered by `%%name%%` */
|
|
33
|
+
name: string;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Data requirement for a single ListUsers module instance.
|
|
38
|
+
*
|
|
39
|
+
* Produced by the extraction phase and consumed by the application to
|
|
40
|
+
* determine what data to fetch.
|
|
41
|
+
*/
|
|
42
|
+
export interface ListUsersDataRequirement {
|
|
43
|
+
/** Unique identifier for this module instance (sequential, 0-based) */
|
|
44
|
+
id: number;
|
|
45
|
+
/** The `users` attribute value (currently only `"."` is supported) */
|
|
46
|
+
users: string;
|
|
47
|
+
/** Template variables that need data from the external source */
|
|
48
|
+
neededVariables: ListUsersVariable[];
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* External data provided by the application for a single ListUsers module.
|
|
53
|
+
*
|
|
54
|
+
* Currently ListUsers only returns information about the logged-in user.
|
|
55
|
+
* Return null/undefined from the fetcher to indicate no user is logged in.
|
|
56
|
+
*/
|
|
57
|
+
export interface ListUsersExternalData {
|
|
58
|
+
/** Data for the logged-in user */
|
|
59
|
+
user: ListUsersUserData;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Callback to fetch user data for a ListUsers module.
|
|
64
|
+
*
|
|
65
|
+
* Called during the resolution phase for each ListUsers module in the AST.
|
|
66
|
+
* Return null/undefined to skip the module (outputs nothing, e.g., when
|
|
67
|
+
* no user is logged in).
|
|
68
|
+
*
|
|
69
|
+
* @param requirement - The data requirement describing what data is needed
|
|
70
|
+
* @returns User data, null/undefined to skip, or a Promise of the same
|
|
71
|
+
*/
|
|
72
|
+
export type ListUsersDataFetcher = (
|
|
73
|
+
requirement: ListUsersDataRequirement,
|
|
74
|
+
) => ListUsersExternalData | null | undefined | Promise<ListUsersExternalData | null | undefined>;
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Context passed to a compiled ListUsers template function during rendering.
|
|
78
|
+
*/
|
|
79
|
+
export interface ListUsersVariableContext {
|
|
80
|
+
/** The user whose data is being rendered */
|
|
81
|
+
user: ListUsersUserData;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* A compiled ListUsers template function.
|
|
86
|
+
*
|
|
87
|
+
* Accepts a variable context and returns the rendered wikitext string
|
|
88
|
+
* with all `%%variable%%` placeholders substituted.
|
|
89
|
+
*
|
|
90
|
+
* @param ctx - The variable context containing user data
|
|
91
|
+
* @returns Rendered wikitext string
|
|
92
|
+
*/
|
|
93
|
+
export type ListUsersCompiledTemplate = (ctx: ListUsersVariableContext) => string;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* Module rule registry and name-based lookup.
|
|
4
|
+
*
|
|
5
|
+
* This module maintains the complete list of supported Wikidot module rules
|
|
6
|
+
* and provides a case-insensitive lookup by module name. When the parser
|
|
7
|
+
* encounters `[[module XYZ ...]]`, it uses `getModuleRuleByName("xyz")` to
|
|
8
|
+
* find the corresponding rule handler.
|
|
9
|
+
*
|
|
10
|
+
* @module
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import type { ModuleRule } from "./types";
|
|
14
|
+
import { rateModuleRule } from "./rate/index";
|
|
15
|
+
import { cssModuleRule } from "./css/index";
|
|
16
|
+
import { backlinksModuleRule } from "./backlinks/index";
|
|
17
|
+
import { categoriesModuleRule } from "./categories/index";
|
|
18
|
+
import { joinModuleRule } from "./join/index";
|
|
19
|
+
import { pageTreeModuleRule } from "./page-tree/index";
|
|
20
|
+
import { listPagesModuleRule } from "./listpages/parser";
|
|
21
|
+
import { listUsersModuleRule } from "./listusers/parser";
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Complete list of all registered module rules.
|
|
25
|
+
*
|
|
26
|
+
* Each rule handles one or more Wikidot module names. The order does not
|
|
27
|
+
* affect lookup behavior since the lookup map is built from `acceptsNames`.
|
|
28
|
+
*/
|
|
29
|
+
export const MODULE_RULES: ModuleRule[] = [
|
|
30
|
+
rateModuleRule,
|
|
31
|
+
cssModuleRule,
|
|
32
|
+
backlinksModuleRule,
|
|
33
|
+
categoriesModuleRule,
|
|
34
|
+
joinModuleRule,
|
|
35
|
+
pageTreeModuleRule,
|
|
36
|
+
listPagesModuleRule,
|
|
37
|
+
listUsersModuleRule,
|
|
38
|
+
];
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Internal lookup map from lowercase module name to its rule handler.
|
|
42
|
+
* Built once at module load time from the `acceptsNames` arrays.
|
|
43
|
+
*/
|
|
44
|
+
const moduleRuleMap: Map<string, ModuleRule> = new Map();
|
|
45
|
+
|
|
46
|
+
// Build the map
|
|
47
|
+
for (const rule of MODULE_RULES) {
|
|
48
|
+
for (const name of rule.acceptsNames) {
|
|
49
|
+
moduleRuleMap.set(name.toLowerCase(), rule);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Look up a module rule by its Wikidot module name (case-insensitive).
|
|
55
|
+
*
|
|
56
|
+
* @param name - The module name from `[[module Name ...]]` syntax
|
|
57
|
+
* @returns The matching module rule, or undefined if no rule handles this name
|
|
58
|
+
*/
|
|
59
|
+
export function getModuleRuleByName(name: string): ModuleRule | undefined {
|
|
60
|
+
return moduleRuleMap.get(name.toLowerCase());
|
|
61
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* Parser rule for the Wikidot `[[module PageTree]]` block.
|
|
4
|
+
*
|
|
5
|
+
* Renders a hierarchical tree of pages based on parent-child relationships.
|
|
6
|
+
* Accepts optional `root`, `show-root`, and `depth` attributes.
|
|
7
|
+
*
|
|
8
|
+
* @module
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import type { ModuleRule } from "../types";
|
|
12
|
+
import { parseInt32 } from "../utils";
|
|
13
|
+
import type { PageTreeModuleData } from "./types";
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Module rule for `[[module PageTree]]`.
|
|
17
|
+
*
|
|
18
|
+
* Parses `root`, `show-root`, and `depth` attributes. The `show-root`
|
|
19
|
+
* attribute intentionally uses strict comparison with `"true"` (not
|
|
20
|
+
* `parseBool`) because Wikidot only accepts `"true"` for this attribute,
|
|
21
|
+
* not `"yes"`.
|
|
22
|
+
*/
|
|
23
|
+
export const pageTreeModuleRule: ModuleRule = {
|
|
24
|
+
name: "module-page-tree",
|
|
25
|
+
acceptsNames: ["pagetree"],
|
|
26
|
+
hasBody: false,
|
|
27
|
+
|
|
28
|
+
parse(_ctx, _pos, args): PageTreeModuleData {
|
|
29
|
+
// Note: Wikidot only accepts "true" for showRoot, not "yes"
|
|
30
|
+
const showRootValue = args["show-root"] ?? args.showroot;
|
|
31
|
+
return {
|
|
32
|
+
module: "page-tree",
|
|
33
|
+
root: args.root ?? null,
|
|
34
|
+
"show-root": showRootValue === "true",
|
|
35
|
+
depth: parseInt32(args.depth) ?? null,
|
|
36
|
+
};
|
|
37
|
+
},
|
|
38
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* Type definitions for the PageTree module.
|
|
4
|
+
*
|
|
5
|
+
* The `[[module PageTree]]` block renders a hierarchical tree view of pages
|
|
6
|
+
* based on parent-child relationships. It starts from a specified root page
|
|
7
|
+
* (or the current page) and displays descendants up to a configurable depth.
|
|
8
|
+
*
|
|
9
|
+
* @module
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* AST data for a `[[module PageTree]]` element.
|
|
14
|
+
*
|
|
15
|
+
* The rendering application should build a tree of pages starting from the
|
|
16
|
+
* root and display them as a nested list.
|
|
17
|
+
*/
|
|
18
|
+
export interface PageTreeModuleData {
|
|
19
|
+
module: "page-tree";
|
|
20
|
+
/** Root page to start the tree from, or null for the current page */
|
|
21
|
+
root: string | null;
|
|
22
|
+
/**
|
|
23
|
+
* Whether to display the root page itself in the tree.
|
|
24
|
+
* Note: Wikidot only accepts the string `"true"` for this attribute, not `"yes"`.
|
|
25
|
+
*/
|
|
26
|
+
"show-root": boolean;
|
|
27
|
+
/** Maximum depth of the tree, or null for unlimited depth */
|
|
28
|
+
depth: number | null;
|
|
29
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* Parser rule for the Wikidot `[[module Rate]]` block.
|
|
4
|
+
*
|
|
5
|
+
* Renders a page rating widget. This is a simple module with no attributes
|
|
6
|
+
* and no body content.
|
|
7
|
+
*
|
|
8
|
+
* @module
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import type { ModuleRule } from "../types";
|
|
12
|
+
import type { RateModuleData } from "./types";
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Module rule for `[[module Rate]]`.
|
|
16
|
+
*
|
|
17
|
+
* Simply produces a `{ module: "rate" }` AST node. The rendering application
|
|
18
|
+
* is responsible for displaying upvote/downvote buttons and the current rating.
|
|
19
|
+
*/
|
|
20
|
+
export const rateModuleRule: ModuleRule = {
|
|
21
|
+
name: "module-rate",
|
|
22
|
+
acceptsNames: ["rate"],
|
|
23
|
+
hasBody: false,
|
|
24
|
+
|
|
25
|
+
parse(): RateModuleData {
|
|
26
|
+
return { module: "rate" };
|
|
27
|
+
},
|
|
28
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* Type definitions for the Rate module.
|
|
4
|
+
*
|
|
5
|
+
* The `[[module Rate]]` block renders a page rating widget (upvote/downvote buttons).
|
|
6
|
+
* It takes no attributes and has no body.
|
|
7
|
+
*
|
|
8
|
+
* @module
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* AST data for a `[[module Rate]]` element.
|
|
13
|
+
*
|
|
14
|
+
* This module has no configurable properties. The rendering application
|
|
15
|
+
* is responsible for displaying the appropriate rating widget.
|
|
16
|
+
*/
|
|
17
|
+
export interface RateModuleData {
|
|
18
|
+
module: "rate";
|
|
19
|
+
}
|