@wdprlib/parser 5.0.0 → 5.1.2

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 CHANGED
@@ -31,7 +31,7 @@ var __export = (target, all) => {
31
31
  var exports_src = {};
32
32
  __export(exports_src, {
33
33
  tokenize: () => tokenize,
34
- text: () => import_ast8.text,
34
+ text: () => import_ast9.text,
35
35
  resolveTagCloud: () => resolveTagCloud,
36
36
  resolveModules: () => resolveModules,
37
37
  resolveListUsers: () => resolveListUsers,
@@ -48,39 +48,39 @@ __export(exports_src, {
48
48
  parseDateSelector: () => parseDateSelector,
49
49
  parseCategory: () => parseCategory,
50
50
  parse: () => parse,
51
- paragraph: () => import_ast8.paragraph,
51
+ paragraph: () => import_ast9.paragraph,
52
52
  normalizeQuery: () => normalizeQuery,
53
53
  matchesListPagesSelectors: () => matchesListPagesSelectors,
54
- listItemSubList: () => import_ast8.listItemSubList,
55
- listItemElements: () => import_ast8.listItemElements,
56
- list: () => import_ast8.list,
57
- link: () => import_ast8.link,
58
- lineBreak: () => import_ast8.lineBreak,
59
- italics: () => import_ast8.italics,
54
+ listItemSubList: () => import_ast9.listItemSubList,
55
+ listItemElements: () => import_ast9.listItemElements,
56
+ list: () => import_ast9.list,
57
+ link: () => import_ast9.link,
58
+ lineBreak: () => import_ast9.lineBreak,
59
+ italics: () => import_ast9.italics,
60
60
  isTagCloudModule: () => isTagCloudModule,
61
61
  isListUsersModule: () => isListUsersModule2,
62
- horizontalRule: () => import_ast8.horizontalRule,
63
- heading: () => import_ast8.heading,
62
+ horizontalRule: () => import_ast9.horizontalRule,
63
+ heading: () => import_ast9.heading,
64
64
  extractListUsersVariables: () => extractListUsersVariables,
65
65
  extractIncludeReferences: () => extractIncludeReferences,
66
66
  extractDataRequirements: () => extractDataRequirements,
67
67
  definePageData: () => definePageData,
68
68
  createToken: () => createToken,
69
- createSettings: () => import_ast9.createSettings,
70
- createPosition: () => import_ast8.createPosition,
71
- createPoint: () => import_ast8.createPoint,
72
- container: () => import_ast8.container,
69
+ createSettings: () => import_ast10.createSettings,
70
+ createPosition: () => import_ast9.createPosition,
71
+ createPoint: () => import_ast9.createPoint,
72
+ container: () => import_ast9.container,
73
73
  compileTemplate: () => compileTemplate,
74
74
  compileListUsersTemplate: () => compileListUsersTemplate,
75
- bold: () => import_ast8.bold,
75
+ bold: () => import_ast9.bold,
76
76
  STYLE_SLOT_PREFIX: () => import_ast4.STYLE_SLOT_PREFIX,
77
77
  Parser: () => Parser,
78
78
  Lexer: () => Lexer,
79
- DEFAULT_SETTINGS: () => import_ast9.DEFAULT_SETTINGS
79
+ DEFAULT_SETTINGS: () => import_ast10.DEFAULT_SETTINGS
80
80
  });
81
81
  module.exports = __toCommonJS(exports_src);
82
- var import_ast8 = require("@wdprlib/ast");
83
82
  var import_ast9 = require("@wdprlib/ast");
83
+ var import_ast10 = require("@wdprlib/ast");
84
84
 
85
85
  // packages/parser/src/lexer/tokens.ts
86
86
  function createToken(type, value, position, lineStart = false) {
@@ -1447,7 +1447,7 @@ function parseNextBlock(ctx, skipWhitespace2, isAtEnd2) {
1447
1447
  }
1448
1448
 
1449
1449
  // packages/parser/src/parser/parse/context.ts
1450
- var import_ast5 = require("@wdprlib/ast");
1450
+ var import_ast6 = require("@wdprlib/ast");
1451
1451
 
1452
1452
  // packages/parser/src/parser/rules/tokens.ts
1453
1453
  function currentToken(ctx) {
@@ -6655,13 +6655,40 @@ function scanIncludeDirectives(source) {
6655
6655
  `, start);
6656
6656
  let depth = 0;
6657
6657
  let linkDepth = 0;
6658
+ const nestedQuotes = [];
6659
+ const nestedQuoteAllowed = [];
6658
6660
  let i = start;
6659
6661
  let closeEnd = -1;
6660
6662
  while (i < source.length) {
6661
6663
  const ch = source.charCodeAt(i);
6662
6664
  const next = source.charCodeAt(i + 1);
6663
6665
  const nextNext = source.charCodeAt(i + 2);
6664
- if (ch === OPEN_BRACKET && next === OPEN_BRACKET && nextNext === OPEN_BRACKET) {
6666
+ if (ch === 10 || ch === 13) {
6667
+ linkDepth = 0;
6668
+ if (depth > 1) {
6669
+ depth = 1;
6670
+ nestedQuotes.length = 0;
6671
+ nestedQuoteAllowed.length = 0;
6672
+ }
6673
+ i++;
6674
+ continue;
6675
+ }
6676
+ const nestedQuote = nestedQuotes.at(-1);
6677
+ if (nestedQuote !== undefined && nestedQuote !== null) {
6678
+ if (ch === 92) {
6679
+ i += 2;
6680
+ } else {
6681
+ if (ch === nestedQuote) {
6682
+ nestedQuotes[nestedQuotes.length - 1] = null;
6683
+ nestedQuoteAllowed[nestedQuoteAllowed.length - 1] = false;
6684
+ }
6685
+ i++;
6686
+ }
6687
+ } else if (nestedQuote === null && nestedQuoteAllowed.at(-1) === true && (ch === 34 || ch === 39)) {
6688
+ nestedQuotes[nestedQuotes.length - 1] = ch;
6689
+ nestedQuoteAllowed[nestedQuoteAllowed.length - 1] = false;
6690
+ i++;
6691
+ } else if (ch === OPEN_BRACKET && next === OPEN_BRACKET && nextNext === OPEN_BRACKET) {
6665
6692
  linkDepth++;
6666
6693
  i += 3;
6667
6694
  } else if (linkDepth > 0 && ch === CLOSE_BRACKET && next === CLOSE_BRACKET && nextNext === CLOSE_BRACKET) {
@@ -6670,10 +6697,26 @@ function scanIncludeDirectives(source) {
6670
6697
  } else if (linkDepth > 0) {
6671
6698
  i++;
6672
6699
  } else if (ch === OPEN_BRACKET && next === OPEN_BRACKET) {
6700
+ if (nestedQuoteAllowed.length > 0) {
6701
+ nestedQuoteAllowed[nestedQuoteAllowed.length - 1] = false;
6702
+ }
6703
+ if (depth > 0) {
6704
+ nestedQuotes.push(null);
6705
+ nestedQuoteAllowed.push(false);
6706
+ }
6673
6707
  depth++;
6674
6708
  i += 2;
6709
+ } else if (ch === CLOSE_BRACKET && next !== CLOSE_BRACKET && depth > 1) {
6710
+ depth--;
6711
+ nestedQuotes.pop();
6712
+ nestedQuoteAllowed.pop();
6713
+ i++;
6675
6714
  } else if (ch === CLOSE_BRACKET && next === CLOSE_BRACKET) {
6676
6715
  const closeStart = i;
6716
+ if (depth > 1) {
6717
+ nestedQuotes.pop();
6718
+ nestedQuoteAllowed.pop();
6719
+ }
6677
6720
  depth--;
6678
6721
  i += 2;
6679
6722
  if (depth <= 0) {
@@ -6690,6 +6733,13 @@ function scanIncludeDirectives(source) {
6690
6733
  }
6691
6734
  }
6692
6735
  } else {
6736
+ if (nestedQuoteAllowed.length > 0) {
6737
+ if (ch === 61) {
6738
+ nestedQuoteAllowed[nestedQuoteAllowed.length - 1] = true;
6739
+ } else if (ch !== 32 && ch !== 9) {
6740
+ nestedQuoteAllowed[nestedQuoteAllowed.length - 1] = false;
6741
+ }
6742
+ }
6693
6743
  i++;
6694
6744
  }
6695
6745
  }
@@ -6875,13 +6925,13 @@ function expandIterativeWithTrace(source, fetcher, maxIterations) {
6875
6925
  reachedMaxIterations: iterations.length === maxIterations && scanIncludeDirectives(current2).length > 0
6876
6926
  };
6877
6927
  }
6878
- async function expandIterativeAsyncWithTrace(source, fetcher, maxIterations) {
6928
+ async function expandIterativeAsyncWithTrace(source, fetcher, maxIterations, shouldDefer) {
6879
6929
  let current2 = source;
6880
6930
  const replacementCache = new Map;
6881
6931
  const dependencies = [];
6882
6932
  const iterations = [];
6883
6933
  for (let i = 0;i < maxIterations; i++) {
6884
- const expanded = await expandOneIterationAsyncWithTrace(current2, fetcher, replacementCache, i);
6934
+ const expanded = await expandOneIterationAsyncWithTrace(current2, fetcher, replacementCache, i, shouldDefer);
6885
6935
  if (expanded === null)
6886
6936
  break;
6887
6937
  dependencies.push(...expanded.dependencies);
@@ -6898,7 +6948,7 @@ async function expandIterativeAsyncWithTrace(source, fetcher, maxIterations) {
6898
6948
  source: current2,
6899
6949
  dependencies,
6900
6950
  iterations,
6901
- reachedMaxIterations: iterations.length === maxIterations && scanIncludeDirectives(current2).length > 0
6951
+ reachedMaxIterations: iterations.length === maxIterations && hasResolvableDirectives(current2, shouldDefer)
6902
6952
  };
6903
6953
  }
6904
6954
  function expandOneIteration(source, fetcher, replacementCache) {
@@ -6937,14 +6987,15 @@ function expandOneIterationWithTrace(source, fetcher, replacementCache, iteratio
6937
6987
  dependencies
6938
6988
  };
6939
6989
  }
6940
- async function expandOneIterationAsyncWithTrace(source, fetcher, replacementCache, iteration) {
6990
+ async function expandOneIterationAsyncWithTrace(source, fetcher, replacementCache, iteration, shouldDefer) {
6941
6991
  if (!MAYBE_INCLUDE_PATTERN.test(source))
6942
6992
  return null;
6943
6993
  const directives = scanIncludeDirectives(source);
6944
6994
  if (directives.length === 0)
6945
6995
  return null;
6946
6996
  const references = directives.map(createIncludeReference);
6947
- const replacements = await Promise.all(directives.map(({ inner }) => replaceCachedAsync(inner, fetcher, replacementCache)));
6997
+ const deferred = references.map((reference) => shouldDefer?.(reference) ?? false);
6998
+ const replacements = await Promise.all(directives.map((directive, index) => deferred[index] ? Promise.resolve(source.slice(directive.start, directive.end)) : replaceCachedAsync(directive.inner, fetcher, replacementCache)));
6948
6999
  const parts = [];
6949
7000
  let lastPos = 0;
6950
7001
  for (let i = 0;i < directives.length; i++) {
@@ -6956,9 +7007,15 @@ async function expandOneIterationAsyncWithTrace(source, fetcher, replacementCach
6956
7007
  return {
6957
7008
  source: parts.join(""),
6958
7009
  references,
6959
- dependencies: references.map((reference) => ({ ...reference, iteration }))
7010
+ dependencies: references.filter((_, index) => !deferred[index]).map((reference) => ({ ...reference, iteration }))
6960
7011
  };
6961
7012
  }
7013
+ function hasResolvableDirectives(source, shouldDefer) {
7014
+ const directives = scanIncludeDirectives(source);
7015
+ if (!shouldDefer)
7016
+ return directives.length > 0;
7017
+ return directives.some((directive) => !shouldDefer(createIncludeReference(directive)));
7018
+ }
6962
7019
  function replaceCached(inner, fetcher, cache) {
6963
7020
  const cached = cache.get(inner);
6964
7021
  if (cached !== undefined)
@@ -7014,6 +7071,19 @@ async function resolveIncludesAsyncWithTrace(source, fetcher, options) {
7014
7071
  const cachedFetcher = createCachedAsyncIncludeFetcher(fetcher, normalizePageKey);
7015
7072
  return expandIterativeAsyncWithTrace(source, cachedFetcher, maxIterations);
7016
7073
  }
7074
+ async function resolveIncludesAsyncWithTraceSelective(source, fetcher, shouldDefer, options) {
7075
+ if (options?.settings && !options.settings.enablePageSyntax) {
7076
+ return {
7077
+ source,
7078
+ dependencies: [],
7079
+ iterations: [],
7080
+ reachedMaxIterations: false
7081
+ };
7082
+ }
7083
+ const maxIterations = options?.maxIterations ?? 10;
7084
+ const cachedFetcher = createCachedAsyncIncludeFetcher(fetcher, normalizePageKey);
7085
+ return expandIterativeAsyncWithTrace(source, cachedFetcher, maxIterations, shouldDefer);
7086
+ }
7017
7087
  function normalizePageKey(location) {
7018
7088
  const site = location.site ?? "";
7019
7089
  const page = location.page.toLowerCase();
@@ -8481,6 +8551,9 @@ var tabviewRule = {
8481
8551
  }
8482
8552
  };
8483
8553
 
8554
+ // packages/parser/src/parser/rules/block/include/index.ts
8555
+ var import_ast5 = require("@wdprlib/ast");
8556
+
8484
8557
  // packages/parser/src/parser/rules/block/include/arguments.ts
8485
8558
  function collectIncludeArguments(ctx, startPos) {
8486
8559
  const argumentTokens = [];
@@ -8596,6 +8669,7 @@ var includeRule = {
8596
8669
  }
8597
8670
  pos++;
8598
8671
  consumed++;
8672
+ const directiveEnd = pos;
8599
8673
  if (ctx.tokens[pos]?.type === "NEWLINE") {
8600
8674
  pos++;
8601
8675
  consumed++;
@@ -8603,6 +8677,20 @@ var includeRule = {
8603
8677
  if (!args.target) {
8604
8678
  return { success: false };
8605
8679
  }
8680
+ const location = parsePageRef(args.target);
8681
+ if (ctx.deferInclude?.(location)) {
8682
+ const source = ctx.tokens.slice(ctx.pos, directiveEnd).map((token5) => token5.value).join("");
8683
+ const elements = [];
8684
+ const lines = source.split(`
8685
+ `);
8686
+ for (let index = 0;index < lines.length; index++) {
8687
+ if (index > 0)
8688
+ elements.push(import_ast5.lineBreak());
8689
+ if (lines[index] !== "")
8690
+ elements.push(import_ast5.text(lines[index]));
8691
+ }
8692
+ return { success: true, elements: [import_ast5.paragraph(elements)], consumed };
8693
+ }
8606
8694
  return {
8607
8695
  success: true,
8608
8696
  elements: [
@@ -8611,7 +8699,7 @@ var includeRule = {
8611
8699
  data: {
8612
8700
  "paragraph-safe": false,
8613
8701
  variables: parseVariables(args.argumentTokens),
8614
- location: parsePageRef(args.target),
8702
+ location,
8615
8703
  elements: []
8616
8704
  }
8617
8705
  }
@@ -9879,9 +9967,9 @@ function parseGalleryItemLine(content) {
9879
9967
  const alt = attrs.get("alt") ?? null;
9880
9968
  return { source, link, alt, newWindow };
9881
9969
  }
9882
- function parseItemAttrs(text) {
9970
+ function parseItemAttrs(text2) {
9883
9971
  const attrs = new Map;
9884
- const parts = text.trim().split('="');
9972
+ const parts = text2.trim().split('="');
9885
9973
  let key = parts[0]?.trim() ?? "";
9886
9974
  for (let i = 1;i < parts.length; i++) {
9887
9975
  const val = parts[i] ?? "";
@@ -11943,11 +12031,11 @@ var guillemetRule = {
11943
12031
  startTokens: ["LEFT_DOUBLE_ANGLE", "RIGHT_DOUBLE_ANGLE"],
11944
12032
  parse(ctx) {
11945
12033
  const token5 = ctx.tokens[ctx.pos];
11946
- const text = guillemetText(token5?.type);
11947
- if (text) {
12034
+ const text2 = guillemetText(token5?.type);
12035
+ if (text2) {
11948
12036
  return {
11949
12037
  success: true,
11950
- elements: [{ element: "text", data: text }],
12038
+ elements: [{ element: "text", data: text2 }],
11951
12039
  consumed: 1
11952
12040
  };
11953
12041
  }
@@ -12905,14 +12993,15 @@ var inlineRules = [
12905
12993
  textRule
12906
12994
  ];
12907
12995
  // packages/parser/src/parser/parse/context.ts
12908
- function createParseContext(tokens, options = {}) {
12996
+ function createParseContext(tokens, options = {}, deferInclude) {
12909
12997
  return {
12910
12998
  tokens,
12911
12999
  pos: 0,
12912
13000
  version: options.version ?? "wikidot",
12913
13001
  trackPositions: options.trackPositions ?? true,
12914
- settings: options.settings ?? import_ast5.DEFAULT_SETTINGS,
13002
+ settings: options.settings ?? import_ast6.DEFAULT_SETTINGS,
12915
13003
  appendImplicitFootnoteBlock: options.appendImplicitFootnoteBlock ?? true,
13004
+ deferInclude,
12916
13005
  footnotes: [],
12917
13006
  tocEntries: [],
12918
13007
  codeBlocks: [],
@@ -13489,39 +13578,41 @@ class Parser {
13489
13578
  this.ctx = createParseContext(tokens, options);
13490
13579
  }
13491
13580
  parse() {
13492
- const children = [];
13493
- while (!this.isAtEnd()) {
13494
- const blocks = this.parseBlock();
13495
- children.push(...blocks);
13496
- }
13497
- return finalizeParseResult(this.ctx, children);
13581
+ return parseContext(this.ctx);
13498
13582
  }
13499
- isAtEnd() {
13500
- return this.ctx.pos >= this.ctx.tokens.length || this.currentToken().type === "EOF";
13501
- }
13502
- currentToken() {
13503
- return this.ctx.tokens[this.ctx.pos] ?? this.eofToken();
13504
- }
13505
- eofToken() {
13506
- return {
13507
- type: "EOF",
13508
- value: "",
13509
- position: {
13510
- start: { line: 0, column: 0, offset: 0 },
13511
- end: { line: 0, column: 0, offset: 0 }
13512
- },
13513
- lineStart: false
13514
- };
13515
- }
13516
- skipWhitespace() {
13517
- while (this.currentToken().type === "WHITESPACE") {
13518
- this.ctx.pos++;
13519
- }
13583
+ }
13584
+ function parseTokensWithIncludeDeferral(tokens, options, deferInclude) {
13585
+ return parseContext(createParseContext(tokens, options, deferInclude));
13586
+ }
13587
+ function parseContext(ctx) {
13588
+ const children = [];
13589
+ while (!isAtEnd3(ctx)) {
13590
+ children.push(...parseBlock(ctx));
13520
13591
  }
13521
- parseBlock() {
13522
- return parseNextBlock(this.ctx, () => this.skipWhitespace(), () => this.isAtEnd());
13592
+ return finalizeParseResult(ctx, children);
13593
+ }
13594
+ function isAtEnd3(ctx) {
13595
+ return ctx.pos >= ctx.tokens.length || currentToken2(ctx).type === "EOF";
13596
+ }
13597
+ function currentToken2(ctx) {
13598
+ return ctx.tokens[ctx.pos] ?? {
13599
+ type: "EOF",
13600
+ value: "",
13601
+ position: {
13602
+ start: { line: 0, column: 0, offset: 0 },
13603
+ end: { line: 0, column: 0, offset: 0 }
13604
+ },
13605
+ lineStart: false
13606
+ };
13607
+ }
13608
+ function skipWhitespace4(ctx) {
13609
+ while (currentToken2(ctx).type === "WHITESPACE") {
13610
+ ctx.pos++;
13523
13611
  }
13524
13612
  }
13613
+ function parseBlock(ctx) {
13614
+ return parseNextBlock(ctx, () => skipWhitespace4(ctx), () => isAtEnd3(ctx));
13615
+ }
13525
13616
 
13526
13617
  // packages/parser/src/parser/parse/plain-non-ascii.ts
13527
13618
  var LARGE_PLAIN_TEXT_MIN_LENGTH = 1e5;
@@ -13529,8 +13620,8 @@ function parsePlainNonAsciiDocument(source) {
13529
13620
  if (!isPlainNonAsciiDocument(source)) {
13530
13621
  return null;
13531
13622
  }
13532
- const text = trimNewlineEdges(source);
13533
- const elements = text === "" ? [] : buildPlainParagraphs(text);
13623
+ const text2 = trimNewlineEdges(source);
13624
+ const elements = text2 === "" ? [] : buildPlainParagraphs(text2);
13534
13625
  elements.push({
13535
13626
  element: "footnote-block",
13536
13627
  data: { title: null, hide: false }
@@ -13550,8 +13641,8 @@ function parseLargePlainTextDocument(source) {
13550
13641
  if (source.length < LARGE_PLAIN_TEXT_MIN_LENGTH || hasWikitextSyntaxCandidate(source)) {
13551
13642
  return null;
13552
13643
  }
13553
- const text = trimNewlineEdges(source);
13554
- const elements = text === "" ? [] : buildPlainParagraphs(text);
13644
+ const text2 = trimNewlineEdges(source);
13645
+ const elements = text2 === "" ? [] : buildPlainParagraphs(text2);
13555
13646
  elements.push({
13556
13647
  element: "footnote-block",
13557
13648
  data: { title: null, hide: false }
@@ -13616,10 +13707,10 @@ function trimNewlineEdges(source) {
13616
13707
  end--;
13617
13708
  return start === 0 && end === source.length ? source : source.slice(start, end);
13618
13709
  }
13619
- function buildPlainParagraphs(text) {
13620
- const paragraphs = text.indexOf(`
13710
+ function buildPlainParagraphs(text2) {
13711
+ const paragraphs = text2.indexOf(`
13621
13712
 
13622
- `) === -1 ? [text] : text.split(/\n{2,}/).filter((part) => part !== "");
13713
+ `) === -1 ? [text2] : text2.split(/\n{2,}/).filter((part) => part !== "");
13623
13714
  return paragraphs.map((paragraphText) => ({
13624
13715
  element: "container",
13625
13716
  data: {
@@ -13629,8 +13720,8 @@ function buildPlainParagraphs(text) {
13629
13720
  }
13630
13721
  }));
13631
13722
  }
13632
- function buildPlainParagraphElements(text) {
13633
- const lines = text.split(`
13723
+ function buildPlainParagraphElements(text2) {
13724
+ const lines = text2.split(`
13634
13725
  `);
13635
13726
  const elements = Array.from({ length: lines.length * 2 - 1 });
13636
13727
  let out = 0;
@@ -13644,32 +13735,32 @@ function buildPlainParagraphElements(text) {
13644
13735
  }
13645
13736
 
13646
13737
  // packages/parser/src/parser/preprocess/whitespace/detection.ts
13647
- function needsWhitespaceSubstitution(text) {
13648
- if (text.length === 0)
13738
+ function needsWhitespaceSubstitution(text2) {
13739
+ if (text2.length === 0)
13649
13740
  return false;
13650
- if (text[0] === `
13651
- ` || text[0] === " " || text[text.length - 1] === `
13741
+ if (text2[0] === `
13742
+ ` || text2[0] === " " || text2[text2.length - 1] === `
13652
13743
  `) {
13653
13744
  return true;
13654
13745
  }
13655
- return text.indexOf("\r") !== -1 || text.indexOf("\t") !== -1 || text.indexOf("\x00") !== -1 || text.indexOf(" ") !== -1 || text.indexOf(" ") !== -1 || text.indexOf("\\\n") !== -1 || text.indexOf(`
13746
+ return text2.indexOf("\r") !== -1 || text2.indexOf("\t") !== -1 || text2.indexOf("\x00") !== -1 || text2.indexOf(" ") !== -1 || text2.indexOf(" ") !== -1 || text2.indexOf("\\\n") !== -1 || text2.indexOf(`
13656
13747
 
13657
13748
 
13658
- `) !== -1 || text.indexOf(`
13749
+ `) !== -1 || text2.indexOf(`
13659
13750
  `) !== -1;
13660
13751
  }
13661
- function mayContainWhitespaceOnlyLine(text) {
13662
- const first = text[0];
13752
+ function mayContainWhitespaceOnlyLine(text2) {
13753
+ const first = text2[0];
13663
13754
  if (first === " " || first === "\t" || first === `
13664
13755
  ` || first === " " || first === " ") {
13665
13756
  return true;
13666
13757
  }
13667
- return text.indexOf(`
13668
- `) !== -1 || text.indexOf(`
13758
+ return text2.indexOf(`
13759
+ `) !== -1 || text2.indexOf(`
13669
13760
 
13670
- `) !== -1 || text.indexOf(`
13671
- `) !== -1 || text.indexOf(`
13672
-  `) !== -1 || text.indexOf(`
13761
+ `) !== -1 || text2.indexOf(`
13762
+ `) !== -1 || text2.indexOf(`
13763
+  `) !== -1 || text2.indexOf(`
13673
13764
   `) !== -1;
13674
13765
  }
13675
13766
 
@@ -13682,18 +13773,18 @@ var TABS = /\t/g;
13682
13773
  var NULL_CHARS = new RegExp(String.fromCharCode(0), "g");
13683
13774
 
13684
13775
  // packages/parser/src/parser/preprocess/whitespace/leading-spaces.ts
13685
- function replaceLeadingSpaces(text) {
13686
- return text.replace(LEADING_NONSTANDARD_WHITESPACE, (match) => {
13776
+ function replaceLeadingSpaces(text2) {
13777
+ return text2.replace(LEADING_NONSTANDARD_WHITESPACE, (match) => {
13687
13778
  return " ".repeat(match.length);
13688
13779
  });
13689
13780
  }
13690
13781
 
13691
13782
  // packages/parser/src/parser/preprocess/whitespace/index.ts
13692
- function substitute(text) {
13693
- if (!needsWhitespaceSubstitution(text)) {
13694
- return text;
13783
+ function substitute(text2) {
13784
+ if (!needsWhitespaceSubstitution(text2)) {
13785
+ return text2;
13695
13786
  }
13696
- let result = text;
13787
+ let result = text2;
13697
13788
  if (result.indexOf("\r") !== -1) {
13698
13789
  result = result.replace(DOS_MAC_NEWLINES, `
13699
13790
  `);
@@ -13723,21 +13814,21 @@ function substitute(text) {
13723
13814
  }
13724
13815
  return result;
13725
13816
  }
13726
- function trimLeadingNewlines(text) {
13817
+ function trimLeadingNewlines(text2) {
13727
13818
  let index = 0;
13728
- while (text[index] === `
13819
+ while (text2[index] === `
13729
13820
  `) {
13730
13821
  index++;
13731
13822
  }
13732
- return index === 0 ? text : text.slice(index);
13823
+ return index === 0 ? text2 : text2.slice(index);
13733
13824
  }
13734
- function trimTrailingNewlines(text) {
13735
- let end = text.length;
13736
- while (end > 0 && text[end - 1] === `
13825
+ function trimTrailingNewlines(text2) {
13826
+ let end = text2.length;
13827
+ while (end > 0 && text2[end - 1] === `
13737
13828
  `) {
13738
13829
  end--;
13739
13830
  }
13740
- return end === text.length ? text : text.slice(0, end);
13831
+ return end === text2.length ? text2 : text2.slice(0, end);
13741
13832
  }
13742
13833
 
13743
13834
  // packages/parser/src/parser/preprocess/typography.ts
@@ -13747,50 +13838,50 @@ var LEFT_DOUBLE_QUOTE = "“";
13747
13838
  var RIGHT_DOUBLE_QUOTE = "”";
13748
13839
  var LOW_DOUBLE_QUOTE = "„";
13749
13840
  var ELLIPSIS = "…";
13750
- function replaceExactEllipsisPattern(text, pattern) {
13841
+ function replaceExactEllipsisPattern(text2, pattern) {
13751
13842
  let searchFrom = 0;
13752
13843
  let result = "";
13753
13844
  let lastCopied = 0;
13754
13845
  const patternLength = pattern.length;
13755
- while (searchFrom < text.length) {
13756
- const index = text.indexOf(pattern, searchFrom);
13846
+ while (searchFrom < text2.length) {
13847
+ const index = text2.indexOf(pattern, searchFrom);
13757
13848
  if (index === -1)
13758
13849
  break;
13759
- const prev = index > 0 ? text[index - 1] : "";
13760
- const next = index + patternLength < text.length ? text[index + patternLength] : "";
13850
+ const prev = index > 0 ? text2[index - 1] : "";
13851
+ const next = index + patternLength < text2.length ? text2[index + patternLength] : "";
13761
13852
  if (prev !== "." && next !== ".") {
13762
- result += text.slice(lastCopied, index) + ELLIPSIS;
13853
+ result += text2.slice(lastCopied, index) + ELLIPSIS;
13763
13854
  lastCopied = index + patternLength;
13764
13855
  searchFrom = lastCopied;
13765
13856
  } else {
13766
13857
  searchFrom = index + 1;
13767
13858
  }
13768
13859
  }
13769
- return lastCopied === 0 ? text : result + text.slice(lastCopied);
13860
+ return lastCopied === 0 ? text2 : result + text2.slice(lastCopied);
13770
13861
  }
13771
- function replaceDelimitedTypography(text, opener, closer, leftQuote, rightQuote) {
13862
+ function replaceDelimitedTypography(text2, opener, closer, leftQuote, rightQuote) {
13772
13863
  let searchFrom = 0;
13773
13864
  let result = "";
13774
13865
  let lastCopied = 0;
13775
- while (searchFrom < text.length) {
13776
- const openIndex = text.indexOf(opener, searchFrom);
13866
+ while (searchFrom < text2.length) {
13867
+ const openIndex = text2.indexOf(opener, searchFrom);
13777
13868
  if (openIndex === -1)
13778
13869
  break;
13779
13870
  const contentStart = openIndex + opener.length;
13780
- const closeIndex = text.indexOf(closer, contentStart);
13871
+ const closeIndex = text2.indexOf(closer, contentStart);
13781
13872
  if (closeIndex === -1)
13782
13873
  break;
13783
- result += text.slice(lastCopied, openIndex);
13874
+ result += text2.slice(lastCopied, openIndex);
13784
13875
  result += leftQuote;
13785
- result += text.slice(contentStart, closeIndex);
13876
+ result += text2.slice(contentStart, closeIndex);
13786
13877
  result += rightQuote;
13787
13878
  lastCopied = closeIndex + closer.length;
13788
13879
  searchFrom = lastCopied;
13789
13880
  }
13790
- return lastCopied === 0 ? text : result + text.slice(lastCopied);
13881
+ return lastCopied === 0 ? text2 : result + text2.slice(lastCopied);
13791
13882
  }
13792
- function substitute2(text) {
13793
- let result = text;
13883
+ function substitute2(text2) {
13884
+ let result = text2;
13794
13885
  if (result.includes("``") && result.includes("''")) {
13795
13886
  result = replaceDelimitedTypography(result, "``", "''", LEFT_DOUBLE_QUOTE, RIGHT_DOUBLE_QUOTE);
13796
13887
  }
@@ -13810,8 +13901,8 @@ function substitute2(text) {
13810
13901
  }
13811
13902
 
13812
13903
  // packages/parser/src/parser/preprocess/index.ts
13813
- function preprocess(text) {
13814
- let result = text;
13904
+ function preprocess(text2) {
13905
+ let result = text2;
13815
13906
  result = substitute(result);
13816
13907
  result = substitute2(result);
13817
13908
  return result;
@@ -13846,12 +13937,12 @@ function matchDirectiveKind(source, i) {
13846
13937
  }
13847
13938
 
13848
13939
  // packages/parser/src/parser/preprocess/expr/evaluate.ts
13849
- var import_ast6 = require("@wdprlib/ast");
13940
+ var import_ast7 = require("@wdprlib/ast");
13850
13941
  function evaluateDirective(kind, match) {
13851
13942
  if (kind === "expr") {
13852
- const result2 = import_ast6.evaluateExpression(match.head);
13943
+ const result2 = import_ast7.evaluateExpression(match.head);
13853
13944
  if (result2.success)
13854
- return import_ast6.formatExprValue(result2.value);
13945
+ return import_ast7.formatExprValue(result2.value);
13855
13946
  if (result2.error === "empty expression")
13856
13947
  return "";
13857
13948
  return "ERROR";
@@ -13859,11 +13950,11 @@ function evaluateDirective(kind, match) {
13859
13950
  if (kind === "if") {
13860
13951
  if (!match.hasPipe)
13861
13952
  return "";
13862
- return import_ast6.isTruthy(match.head) ? match.thenText : match.elseText;
13953
+ return import_ast7.isTruthy(match.head) ? match.thenText : match.elseText;
13863
13954
  }
13864
13955
  if (!match.hasPipe)
13865
13956
  return "";
13866
- const result = import_ast6.evaluateExpression(match.head);
13957
+ const result = import_ast7.evaluateExpression(match.head);
13867
13958
  if (!result.success)
13868
13959
  return "ERROR";
13869
13960
  return result.value !== 0 && !Number.isNaN(result.value) ? match.thenText : match.elseText;
@@ -14023,6 +14114,12 @@ function prepareSourceForParse(source, options) {
14023
14114
  // packages/parser/src/parser/parse/index.ts
14024
14115
  var COMPACT_TEXT_RUN_SOURCE_LENGTH = 1e5;
14025
14116
  function parse(source, options) {
14117
+ return parseSource(source, options);
14118
+ }
14119
+ function parseWithIncludeDeferral(source, options, deferInclude) {
14120
+ return parseSource(source, options, deferInclude);
14121
+ }
14122
+ function parseSource(source, options, deferInclude) {
14026
14123
  const plainResult = parsePlainNonAsciiDocument(source);
14027
14124
  if (plainResult) {
14028
14125
  return plainResult;
@@ -14036,10 +14133,10 @@ function parse(source, options) {
14036
14133
  trackPositions: options?.trackPositions,
14037
14134
  compactTextRuns: preprocessed.length >= COMPACT_TEXT_RUN_SOURCE_LENGTH
14038
14135
  });
14039
- return new Parser(tokens, options).parse();
14136
+ return deferInclude ? parseTokensWithIncludeDeferral(tokens, options ?? {}, deferInclude) : new Parser(tokens, options).parse();
14040
14137
  }
14041
14138
  // packages/parser/src/pipeline/process.ts
14042
- var import_ast7 = require("@wdprlib/ast");
14139
+ var import_ast8 = require("@wdprlib/ast");
14043
14140
 
14044
14141
  // packages/parser/src/parser/rules/block/module/resolution/resolve-async.ts
14045
14142
  async function resolveModulesWithAsyncParse(ast, dataProvider, options) {
@@ -14221,7 +14318,7 @@ var PIPELINE_DIAGNOSTIC_POSITION = {
14221
14318
  end: { line: 1, column: 1, offset: 0 }
14222
14319
  };
14223
14320
  async function processWikitext(source, options) {
14224
- const settings = options.settings ?? import_ast7.DEFAULT_SETTINGS;
14321
+ const settings = options.settings ?? import_ast8.DEFAULT_SETTINGS;
14225
14322
  const callbackContext = {
14226
14323
  page: options.page,
14227
14324
  settings
@@ -14230,31 +14327,32 @@ async function processWikitext(source, options) {
14230
14327
  const diagnostics = [];
14231
14328
  const fetchInclude = createRequestIncludeFetcher(options.dataProvider?.fetchInclude ? (pageRef) => options.dataProvider.fetchInclude(pageRef, callbackContext) : undefined);
14232
14329
  const resolveSource = async (input) => {
14233
- if (!fetchInclude)
14234
- return input;
14235
- const resolution = await resolveIncludesAsyncWithTrace(input, fetchInclude, {
14236
- maxIterations: options.includeMaxIterations,
14237
- settings
14238
- });
14239
- dependencies.push(...resolution.dependencies);
14240
- if (resolution.reachedMaxIterations) {
14241
- diagnostics.push(createLimitDiagnostic("include-resolution-limit", `Include expansion stopped after ${options.includeMaxIterations ?? 10} iterations.`));
14330
+ let expanded = input;
14331
+ if (fetchInclude) {
14332
+ const resolution = await resolveIncludesAsyncWithTraceSelective(input, fetchInclude, (reference) => isCurrentPageInclude(reference.location, options.page), {
14333
+ maxIterations: options.includeMaxIterations,
14334
+ settings
14335
+ });
14336
+ dependencies.push(...resolution.dependencies);
14337
+ if (resolution.reachedMaxIterations) {
14338
+ diagnostics.push(createLimitDiagnostic("include-resolution-limit", `Include expansion stopped after ${options.includeMaxIterations ?? 10} iterations.`));
14339
+ }
14340
+ expanded = resolution.source;
14242
14341
  }
14243
- return resolution.source;
14342
+ return expanded;
14244
14343
  };
14245
- const expandedSource = await resolveSource(source);
14246
- const initial = parse(expandedSource, {
14247
- settings,
14248
- pageTags: options.page.tags,
14249
- appendImplicitFootnoteBlock: false
14250
- });
14344
+ const parseSource2 = async (input) => {
14345
+ const expanded = await resolveSource(input);
14346
+ return parseWithIncludeDeferral(expanded, {
14347
+ settings,
14348
+ pageTags: options.page.tags,
14349
+ appendImplicitFootnoteBlock: false
14350
+ }, (location) => isCurrentPageInclude(location, options.page));
14351
+ };
14352
+ const initial = await parseSource2(source);
14251
14353
  diagnostics.push(...initial.diagnostics);
14252
14354
  const dataProvider = createModuleDataProvider(options, callbackContext);
14253
- const parseFragment = async (fragmentSource) => parse(await resolveSource(fragmentSource), {
14254
- settings,
14255
- pageTags: options.page.tags,
14256
- appendImplicitFootnoteBlock: false
14257
- });
14355
+ const parseFragment = parseSource2;
14258
14356
  let ast = initial.ast;
14259
14357
  for (let pass = 0;pass < DEFAULT_MODULE_MAX_PASSES; pass++) {
14260
14358
  const extraction = extractDataRequirements(ast);
@@ -14283,6 +14381,14 @@ async function processWikitext(source, options) {
14283
14381
  dependencies
14284
14382
  };
14285
14383
  }
14384
+ function isCurrentPageInclude(location, page) {
14385
+ if (location.site !== null) {
14386
+ if (!page.site || location.site.toLowerCase() !== page.site.toLowerCase())
14387
+ return false;
14388
+ }
14389
+ const target = location.page.toLowerCase();
14390
+ return target === page.fullName.toLowerCase() || target === page.unixName?.toLowerCase();
14391
+ }
14286
14392
  function hasResolvableRequirements(requirements, provider) {
14287
14393
  return Boolean(provider?.fetchListPages && requirements.listPages.length > 0 || provider?.fetchListUsers && requirements.listUsers.length > 0 || provider?.fetchTagCloud && requirements.tagCloud.length > 0);
14288
14394
  }