@wdprlib/parser 4.3.0 → 4.4.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.
@@ -0,0 +1,105 @@
1
+ import { DEFAULT_SETTINGS, type PageRef, type WikitextPageContext } from "@wdprlib/ast";
2
+ import { parse } from "../parser";
3
+ import { extractDataRequirements } from "../parser/rules/block/module/listpages/extract";
4
+ import {
5
+ resolveIncludesAsyncWithTrace,
6
+ type AsyncIncludeFetcher,
7
+ type IncludeDependency,
8
+ } from "../parser/rules/block/module/include";
9
+ import type { DataProvider } from "../parser/rules/block/module/types-common";
10
+ import { resolveModulesWithAsyncParse } from "../parser/rules/block/module/resolution/resolve-async";
11
+ import type {
12
+ ProcessedWikitextDocument,
13
+ ProcessWikitextCallbackContext,
14
+ ProcessWikitextOptions,
15
+ } from "./types";
16
+
17
+ export async function processWikitext<TPage extends WikitextPageContext>(
18
+ source: string,
19
+ options: ProcessWikitextOptions<TPage>,
20
+ ): Promise<ProcessedWikitextDocument<TPage>> {
21
+ const settings = options.settings ?? DEFAULT_SETTINGS;
22
+ const callbackContext: ProcessWikitextCallbackContext<TPage> = {
23
+ page: options.page,
24
+ settings,
25
+ };
26
+ const dependencies: IncludeDependency[] = [];
27
+ const fetchInclude = createRequestIncludeFetcher(
28
+ options.dataProvider?.fetchInclude
29
+ ? (pageRef) => options.dataProvider!.fetchInclude!(pageRef, callbackContext)
30
+ : undefined,
31
+ );
32
+ const resolveSource = async (input: string): Promise<string> => {
33
+ if (!fetchInclude) return input;
34
+ const resolution = await resolveIncludesAsyncWithTrace(input, fetchInclude, {
35
+ maxIterations: options.includeMaxIterations,
36
+ settings,
37
+ });
38
+ dependencies.push(...resolution.dependencies);
39
+ return resolution.source;
40
+ };
41
+
42
+ const expandedSource = await resolveSource(source);
43
+ const initial = parse(expandedSource, {
44
+ settings,
45
+ pageTags: options.page.tags,
46
+ appendImplicitFootnoteBlock: false,
47
+ });
48
+ const extraction = extractDataRequirements(initial.ast);
49
+ const dataProvider = createModuleDataProvider(options, callbackContext);
50
+ const resolved = await resolveModulesWithAsyncParse(initial.ast, dataProvider, {
51
+ parse: async (fragmentSource) =>
52
+ parse(await resolveSource(fragmentSource), {
53
+ settings,
54
+ pageTags: options.page.tags,
55
+ appendImplicitFootnoteBlock: false,
56
+ }),
57
+ compiledListPagesTemplates: extraction.compiledListPagesTemplates,
58
+ compiledListUsersTemplates: extraction.compiledListUsersTemplates,
59
+ requirements: extraction.requirements,
60
+ urlPath: options.page.urlPath,
61
+ pageTags: options.page.tags,
62
+ });
63
+
64
+ return {
65
+ ast: resolved.ast,
66
+ page: options.page,
67
+ settings,
68
+ diagnostics: [...initial.diagnostics, ...resolved.diagnostics],
69
+ dependencies,
70
+ };
71
+ }
72
+
73
+ function createModuleDataProvider<TPage extends WikitextPageContext>(
74
+ options: ProcessWikitextOptions<TPage>,
75
+ context: ProcessWikitextCallbackContext<TPage>,
76
+ ): DataProvider {
77
+ const provider = options.dataProvider;
78
+ return {
79
+ fetchListPages: provider?.fetchListPages
80
+ ? (query, requirement) => provider.fetchListPages!(query, requirement, context)
81
+ : undefined,
82
+ fetchListUsers: provider?.fetchListUsers
83
+ ? (requirement) => provider.fetchListUsers!(requirement, context)
84
+ : undefined,
85
+ fetchTagCloud: provider?.fetchTagCloud
86
+ ? (requirement) => provider.fetchTagCloud!(requirement, context)
87
+ : undefined,
88
+ getPageTags: () => options.page.tags,
89
+ };
90
+ }
91
+
92
+ function createRequestIncludeFetcher(
93
+ fetcher: AsyncIncludeFetcher | undefined,
94
+ ): AsyncIncludeFetcher | undefined {
95
+ if (!fetcher) return undefined;
96
+ const cache = new Map<string, Promise<string | null>>();
97
+ return (pageRef: PageRef): Promise<string | null> => {
98
+ const key = `${pageRef.site ?? ""}:${pageRef.page.toLowerCase()}`;
99
+ const cached = cache.get(key);
100
+ if (cached) return cached;
101
+ const result = fetcher(pageRef).catch(() => null);
102
+ cache.set(key, result);
103
+ return result;
104
+ };
105
+ }
@@ -0,0 +1,63 @@
1
+ import type {
2
+ Diagnostic,
3
+ PageRef,
4
+ SyntaxTree,
5
+ WikitextPageContext,
6
+ WikitextSettings,
7
+ } from "@wdprlib/ast";
8
+ import type { IncludeDependency } from "../parser/rules/block/module/include";
9
+ import type {
10
+ ListPagesDataRequirement,
11
+ ListPagesExternalData,
12
+ NormalizedListPagesQuery,
13
+ } from "../parser/rules/block/module/listpages/types";
14
+ import type {
15
+ ListUsersDataRequirement,
16
+ ListUsersExternalData,
17
+ } from "../parser/rules/block/module/listusers/types";
18
+ import type {
19
+ TagCloudDataRequirement,
20
+ TagCloudExternalData,
21
+ } from "../parser/rules/block/module/tagcloud/types";
22
+
23
+ export interface ProcessWikitextCallbackContext<TPage extends WikitextPageContext> {
24
+ page: TPage;
25
+ settings: WikitextSettings;
26
+ }
27
+
28
+ export interface ProcessWikitextDataProvider<TPage extends WikitextPageContext> {
29
+ fetchInclude?: (
30
+ pageRef: PageRef,
31
+ context: ProcessWikitextCallbackContext<TPage>,
32
+ ) => Promise<string | null>;
33
+ fetchListPages?: (
34
+ query: NormalizedListPagesQuery,
35
+ requirement: ListPagesDataRequirement,
36
+ context: ProcessWikitextCallbackContext<TPage>,
37
+ ) => Promise<ListPagesExternalData | null | undefined>;
38
+ fetchListUsers?: (
39
+ requirement: ListUsersDataRequirement,
40
+ context: ProcessWikitextCallbackContext<TPage>,
41
+ ) => Promise<ListUsersExternalData | null | undefined>;
42
+ fetchTagCloud?: (
43
+ requirement: TagCloudDataRequirement,
44
+ context: ProcessWikitextCallbackContext<TPage>,
45
+ ) => Promise<TagCloudExternalData | null | undefined>;
46
+ }
47
+
48
+ export interface ProcessWikitextOptions<TPage extends WikitextPageContext> {
49
+ page: TPage;
50
+ settings?: WikitextSettings;
51
+ dataProvider?: ProcessWikitextDataProvider<TPage>;
52
+ includeMaxIterations?: number;
53
+ }
54
+
55
+ export interface ProcessedWikitextDocument<
56
+ TPage extends WikitextPageContext = WikitextPageContext,
57
+ > {
58
+ ast: SyntaxTree;
59
+ page: TPage;
60
+ settings: WikitextSettings;
61
+ diagnostics: Diagnostic[];
62
+ dependencies: IncludeDependency[];
63
+ }