@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.
Files changed (124) hide show
  1. package/dist/index.cjs +295 -118
  2. package/dist/index.js +272 -95
  3. package/package.json +5 -3
  4. package/src/index.ts +163 -0
  5. package/src/lexer/index.ts +20 -0
  6. package/src/lexer/lexer.ts +687 -0
  7. package/src/lexer/tokens.ts +141 -0
  8. package/src/parser/constants.ts +173 -0
  9. package/src/parser/depth.ts +251 -0
  10. package/src/parser/index.ts +18 -0
  11. package/src/parser/parse.ts +315 -0
  12. package/src/parser/postprocess/divAdjacentParagraph.ts +76 -0
  13. package/src/parser/postprocess/index.ts +15 -0
  14. package/src/parser/postprocess/spanStrip.ts +697 -0
  15. package/src/parser/preprocess/expr.ts +265 -0
  16. package/src/parser/preprocess/index.ts +38 -0
  17. package/src/parser/preprocess/typography.ts +67 -0
  18. package/src/parser/preprocess/utils.ts +250 -0
  19. package/src/parser/preprocess/whitespace.ts +111 -0
  20. package/src/parser/rules/block/align.ts +282 -0
  21. package/src/parser/rules/block/bibliography.ts +359 -0
  22. package/src/parser/rules/block/block-list.ts +689 -0
  23. package/src/parser/rules/block/blockquote.ts +238 -0
  24. package/src/parser/rules/block/center.ts +87 -0
  25. package/src/parser/rules/block/clear-float.ts +75 -0
  26. package/src/parser/rules/block/code.ts +187 -0
  27. package/src/parser/rules/block/collapsible.ts +337 -0
  28. package/src/parser/rules/block/comment.ts +73 -0
  29. package/src/parser/rules/block/content-separator.ts +79 -0
  30. package/src/parser/rules/block/definition-list.ts +270 -0
  31. package/src/parser/rules/block/div.ts +400 -0
  32. package/src/parser/rules/block/embed-block.ts +153 -0
  33. package/src/parser/rules/block/footnoteblock.ts +200 -0
  34. package/src/parser/rules/block/heading.ts +142 -0
  35. package/src/parser/rules/block/horizontal-rule.ts +61 -0
  36. package/src/parser/rules/block/html.ts +222 -0
  37. package/src/parser/rules/block/iframe.ts +239 -0
  38. package/src/parser/rules/block/iftags.ts +150 -0
  39. package/src/parser/rules/block/include.ts +179 -0
  40. package/src/parser/rules/block/index.ts +127 -0
  41. package/src/parser/rules/block/list.ts +244 -0
  42. package/src/parser/rules/block/math.ts +183 -0
  43. package/src/parser/rules/block/module/backlinks/index.ts +31 -0
  44. package/src/parser/rules/block/module/backlinks/types.ts +21 -0
  45. package/src/parser/rules/block/module/categories/index.ts +34 -0
  46. package/src/parser/rules/block/module/categories/types.ts +21 -0
  47. package/src/parser/rules/block/module/css/index.ts +37 -0
  48. package/src/parser/rules/block/module/iftags/condition.ts +109 -0
  49. package/src/parser/rules/block/module/iftags/index.ts +26 -0
  50. package/src/parser/rules/block/module/iftags/preprocess.ts +140 -0
  51. package/src/parser/rules/block/module/iftags/resolve.ts +73 -0
  52. package/src/parser/rules/block/module/iftags/types.ts +63 -0
  53. package/src/parser/rules/block/module/include/index.ts +20 -0
  54. package/src/parser/rules/block/module/include/resolve.ts +556 -0
  55. package/src/parser/rules/block/module/index.ts +122 -0
  56. package/src/parser/rules/block/module/join/index.ts +34 -0
  57. package/src/parser/rules/block/module/join/types.ts +23 -0
  58. package/src/parser/rules/block/module/listpages/compiler.ts +453 -0
  59. package/src/parser/rules/block/module/listpages/extract.ts +410 -0
  60. package/src/parser/rules/block/module/listpages/index.ts +83 -0
  61. package/src/parser/rules/block/module/listpages/normalize.ts +390 -0
  62. package/src/parser/rules/block/module/listpages/parser.ts +106 -0
  63. package/src/parser/rules/block/module/listpages/resolve.ts +130 -0
  64. package/src/parser/rules/block/module/listpages/types.ts +513 -0
  65. package/src/parser/rules/block/module/listpages/url-resolver.ts +186 -0
  66. package/src/parser/rules/block/module/listusers/compiler.ts +77 -0
  67. package/src/parser/rules/block/module/listusers/extract.ts +45 -0
  68. package/src/parser/rules/block/module/listusers/index.ts +36 -0
  69. package/src/parser/rules/block/module/listusers/parser.ts +54 -0
  70. package/src/parser/rules/block/module/listusers/resolve.ts +58 -0
  71. package/src/parser/rules/block/module/listusers/types.ts +93 -0
  72. package/src/parser/rules/block/module/mapping.ts +61 -0
  73. package/src/parser/rules/block/module/page-tree/index.ts +38 -0
  74. package/src/parser/rules/block/module/page-tree/types.ts +29 -0
  75. package/src/parser/rules/block/module/rate/index.ts +28 -0
  76. package/src/parser/rules/block/module/rate/types.ts +19 -0
  77. package/src/parser/rules/block/module/resolve.ts +411 -0
  78. package/src/parser/rules/block/module/types-common.ts +59 -0
  79. package/src/parser/rules/block/module/types.ts +61 -0
  80. package/src/parser/rules/block/module/utils.ts +43 -0
  81. package/src/parser/rules/block/module/walk.ts +380 -0
  82. package/src/parser/rules/block/module.ts +164 -0
  83. package/src/parser/rules/block/orphan-li.ts +177 -0
  84. package/src/parser/rules/block/paragraph.ts +157 -0
  85. package/src/parser/rules/block/table-block.ts +726 -0
  86. package/src/parser/rules/block/table.ts +441 -0
  87. package/src/parser/rules/block/tabview.ts +331 -0
  88. package/src/parser/rules/block/toc.ts +129 -0
  89. package/src/parser/rules/block/utils.ts +615 -0
  90. package/src/parser/rules/index.ts +49 -0
  91. package/src/parser/rules/inline/anchor-name.ts +154 -0
  92. package/src/parser/rules/inline/anchor.ts +327 -0
  93. package/src/parser/rules/inline/bibcite.ts +153 -0
  94. package/src/parser/rules/inline/bold.ts +86 -0
  95. package/src/parser/rules/inline/color.ts +140 -0
  96. package/src/parser/rules/inline/comment.ts +90 -0
  97. package/src/parser/rules/inline/equation-ref.ts +115 -0
  98. package/src/parser/rules/inline/expr.ts +526 -0
  99. package/src/parser/rules/inline/footnote.ts +223 -0
  100. package/src/parser/rules/inline/guillemet.ts +64 -0
  101. package/src/parser/rules/inline/html.ts +132 -0
  102. package/src/parser/rules/inline/image.ts +328 -0
  103. package/src/parser/rules/inline/index.ts +150 -0
  104. package/src/parser/rules/inline/italic.ts +74 -0
  105. package/src/parser/rules/inline/line-break.ts +326 -0
  106. package/src/parser/rules/inline/link-anchor.ts +147 -0
  107. package/src/parser/rules/inline/link-single.ts +164 -0
  108. package/src/parser/rules/inline/link-star.ts +134 -0
  109. package/src/parser/rules/inline/link-triple.ts +267 -0
  110. package/src/parser/rules/inline/math-inline.ts +126 -0
  111. package/src/parser/rules/inline/monospace.ts +78 -0
  112. package/src/parser/rules/inline/raw.ts +262 -0
  113. package/src/parser/rules/inline/size.ts +244 -0
  114. package/src/parser/rules/inline/span.ts +424 -0
  115. package/src/parser/rules/inline/strikethrough.ts +115 -0
  116. package/src/parser/rules/inline/subscript.ts +84 -0
  117. package/src/parser/rules/inline/superscript.ts +84 -0
  118. package/src/parser/rules/inline/text.ts +84 -0
  119. package/src/parser/rules/inline/underline.ts +127 -0
  120. package/src/parser/rules/inline/user.ts +147 -0
  121. package/src/parser/rules/inline/utils.ts +344 -0
  122. package/src/parser/rules/types.ts +252 -0
  123. package/src/parser/rules/utils.ts +155 -0
  124. 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
+ }