wikiparser-node 1.43.0 → 1.44.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 (43) hide show
  1. package/README.md +10 -7
  2. package/bundle/bundle-es8.min.js +40 -31
  3. package/bundle/bundle-lsp.min.js +35 -26
  4. package/bundle/bundle.min.js +22 -22
  5. package/config/default.json +31 -0
  6. package/config/moegirl.json +39 -1
  7. package/dist/base.d.mts +4 -4
  8. package/dist/base.d.ts +4 -4
  9. package/dist/base.js +1 -0
  10. package/dist/base.mjs +1 -0
  11. package/dist/bin/config.js +6 -5
  12. package/dist/index.js +8 -5
  13. package/dist/lib/document.d.ts +17 -14
  14. package/dist/lib/lintConfig.js +4 -1
  15. package/dist/lib/title.d.ts +4 -1
  16. package/dist/lib/title.js +5 -1
  17. package/dist/mixin/attributesParent.js +1 -1
  18. package/dist/parser/converter.js +1 -1
  19. package/dist/render/extension.js +30 -24
  20. package/dist/render/magicWords.js +1 -1
  21. package/dist/render/math.js +31 -0
  22. package/dist/render/syntaxhighlight.js +3 -0
  23. package/dist/src/attributes.d.ts +1 -0
  24. package/dist/src/attributes.js +27 -3
  25. package/dist/src/converterFlags.js +10 -5
  26. package/dist/src/converterRule.js +2 -2
  27. package/dist/src/imageParameter.d.ts +4 -3
  28. package/dist/src/imageParameter.js +15 -7
  29. package/dist/src/link/file.d.ts +5 -4
  30. package/dist/src/link/file.js +12 -9
  31. package/dist/src/nowiki/index.d.ts +1 -0
  32. package/dist/src/nowiki/index.js +40 -28
  33. package/dist/src/tagPair/ext.d.ts +1 -0
  34. package/dist/src/tagPair/ext.js +36 -3
  35. package/dist/src/transclude.js +1 -1
  36. package/dist/util/search.js +24 -6
  37. package/dist/util/string.js +7 -1
  38. package/extensions/dist/base.js +1 -1
  39. package/extensions/dist/codejar.js +1 -1
  40. package/i18n/en.json +7 -0
  41. package/i18n/zh-hans.json +7 -0
  42. package/i18n/zh-hant.json +7 -0
  43. package/package.json +19 -12
@@ -144,6 +144,10 @@
144
144
  "105": "API talk",
145
145
  "106": "Skin",
146
146
  "107": "Skin talk",
147
+ "114": "Creation",
148
+ "115": "Creation talk",
149
+ "116": "Document",
150
+ "117": "Document talk",
147
151
  "118": "Draft",
148
152
  "119": "Draft talk",
149
153
  "126": "MOS",
@@ -375,9 +379,36 @@
375
379
  "skins": 106,
376
380
  "skin talk": 107,
377
381
  "skins talk": 107,
382
+ "creation": 114,
383
+ "创作": 114,
384
+ "萌创": 114,
385
+ "創作": 114,
386
+ "萌創": 114,
387
+ "萌娘创作": 114,
388
+ "萌娘創作": 114,
389
+ "creation talk": 115,
390
+ "萌娘创作 talk": 115,
391
+ "创作 talk": 115,
392
+ "萌创 talk": 115,
393
+ "萌娘創作 talk": 115,
394
+ "創作 talk": 115,
395
+ "萌創 talk": 115,
396
+ "萌娘创作讨论": 115,
397
+ "萌娘創作討論": 115,
398
+ "document": 116,
399
+ "library": 116,
400
+ "文档": 116,
401
+ "文檔": 116,
402
+ "document talk": 117,
403
+ "library talk": 117,
404
+ "文档 talk": 117,
405
+ "文檔 talk": 117,
406
+ "文档讨论": 117,
407
+ "文檔討論": 117,
378
408
  "draft": 118,
379
409
  "草稿": 118,
380
410
  "draft talk": 119,
411
+ "草稿 talk": 119,
381
412
  "草稿讨论": 119,
382
413
  "草稿討論": 119,
383
414
  "mos": 126,
@@ -110,6 +110,12 @@
110
110
  "13": "Help talk",
111
111
  "14": "Category",
112
112
  "15": "Category talk",
113
+ "114": "Creation",
114
+ "115": "Creation talk",
115
+ "116": "Document",
116
+ "117": "Document talk",
117
+ "118": "Draft",
118
+ "119": "Draft talk",
113
119
  "274": "Widget",
114
120
  "275": "Widget talk",
115
121
  "710": "TimedText",
@@ -138,6 +144,12 @@
138
144
  "help talk": 13,
139
145
  "category": 14,
140
146
  "category talk": 15,
147
+ "creation": 114,
148
+ "creation talk": 115,
149
+ "document": 116,
150
+ "document talk": 117,
151
+ "draft": 118,
152
+ "draft talk": 119,
141
153
  "widget": 274,
142
154
  "widget talk": 275,
143
155
  "timedtext": 710,
@@ -146,6 +158,14 @@
146
158
  "module talk": 829,
147
159
  "media": -2,
148
160
  "special": -1,
161
+ "创作": 114,
162
+ "萌创": 114,
163
+ "文档": 116,
164
+ "萌娘创作 talk": 115,
165
+ "创作 talk": 115,
166
+ "萌创 talk": 115,
167
+ "文档 talk": 117,
168
+ "草稿 talk": 119,
149
169
  "媒体": -2,
150
170
  "媒体文件": -2,
151
171
  "媒体档案": -2,
@@ -291,7 +311,25 @@
291
311
  "模組討論": 829,
292
312
  "模组对话": 829,
293
313
  "模组讨论": 829,
294
- "モジュール・トーク": 829
314
+ "モジュール・トーク": 829,
315
+ "創作": 114,
316
+ "萌創": 114,
317
+ "文檔": 116,
318
+ "萌娘創作 talk": 115,
319
+ "創作 talk": 115,
320
+ "萌創 talk": 115,
321
+ "文檔 talk": 117,
322
+ "library": 116,
323
+ "library talk": 117,
324
+ "萌娘创作": 114,
325
+ "萌娘创作讨论": 115,
326
+ "文档讨论": 117,
327
+ "草稿": 118,
328
+ "草稿讨论": 119,
329
+ "萌娘創作": 114,
330
+ "萌娘創作討論": 115,
331
+ "文檔討論": 117,
332
+ "草稿討論": 119
295
333
  },
296
334
  "functionHook": [
297
335
  "ns",
package/dist/base.d.mts CHANGED
@@ -4,14 +4,14 @@ export interface Config {
4
4
  readonly html: [string[], string[], string[]];
5
5
  readonly namespaces: Record<string, string>;
6
6
  readonly nsid: Record<string, number>;
7
- readonly variable: string[];
8
- readonly functionHook: string[];
9
7
  readonly parserFunction: [Record<string, string>, Record<string, string>, string[], string[]];
10
8
  readonly doubleUnderscore: [string[], string[], Record<string, string>, Record<string, string>];
11
9
  readonly protocol: string;
12
10
  readonly img: Record<string, string>;
13
11
  readonly redirection: string[];
14
- readonly variants: string[];
12
+ variable: string[];
13
+ functionHook: string[];
14
+ variants: string[];
15
15
  articlePath?: string;
16
16
  readonly conversionTable?: [string, string][];
17
17
  readonly redirects?: [string, string][];
@@ -48,7 +48,7 @@ export declare const stages: {
48
48
  'list-range': number;
49
49
  };
50
50
  export type Stage = keyof typeof stages;
51
- export declare const rules: readonly ["arg-in-ext", "blank-alt", "bold-header", "format-leakage", "fostered-content", "h1", "illegal-attr", "insecure-style", "invalid-gallery", "invalid-imagemap", "invalid-invoke", "invalid-isbn", "invalid-json", "invalid-url", "lonely-apos", "lonely-bracket", "lonely-http", "nested-link", "no-arg", "no-duplicate", "no-ignored", "obsolete-attr", "obsolete-tag", "parsing-order", "pipe-like", "required-attr", "syntax-like", "table-layout", "tag-like", "unbalanced-header", "unclosed-comment", "unclosed-quote", "unclosed-table", "unescaped", "unknown-page", "unmatched-tag", "unterminated-url", "url-encoding", "var-anchor", "void-ext", "invalid-css", "invalid-math"];
51
+ export declare const rules: readonly ["arg-in-ext", "blank-alt", "bold-header", "format-leakage", "fostered-content", "h1", "illegal-attr", "insecure-style", "invalid-gallery", "invalid-imagemap", "invalid-invoke", "invalid-isbn", "invalid-json", "invalid-ref", "invalid-url", "lonely-apos", "lonely-bracket", "lonely-http", "nested-link", "no-arg", "no-duplicate", "no-ignored", "obsolete-attr", "obsolete-tag", "parsing-order", "pipe-like", "required-attr", "syntax-like", "table-layout", "tag-like", "unbalanced-header", "unclosed-comment", "unclosed-quote", "unclosed-table", "unescaped", "unknown-page", "unmatched-tag", "unterminated-url", "url-encoding", "var-anchor", "void-ext", "invalid-css", "invalid-math"];
52
52
  export declare namespace LintError {
53
53
  type Severity = 'error' | 'warning';
54
54
  type Rule = typeof rules[number];
package/dist/base.d.ts CHANGED
@@ -4,14 +4,14 @@ export interface Config {
4
4
  readonly html: [string[], string[], string[]];
5
5
  readonly namespaces: Record<string, string>;
6
6
  readonly nsid: Record<string, number>;
7
- readonly variable: string[];
8
- readonly functionHook: string[];
9
7
  readonly parserFunction: [Record<string, string>, Record<string, string>, string[], string[]];
10
8
  readonly doubleUnderscore: [string[], string[], Record<string, string>, Record<string, string>];
11
9
  readonly protocol: string;
12
10
  readonly img: Record<string, string>;
13
11
  readonly redirection: string[];
14
- readonly variants: string[];
12
+ variable: string[];
13
+ functionHook: string[];
14
+ variants: string[];
15
15
  articlePath?: string;
16
16
  readonly conversionTable?: [string, string][];
17
17
  readonly redirects?: [string, string][];
@@ -48,7 +48,7 @@ export declare const stages: {
48
48
  'list-range': number;
49
49
  };
50
50
  export type Stage = keyof typeof stages;
51
- export declare const rules: readonly ["arg-in-ext", "blank-alt", "bold-header", "format-leakage", "fostered-content", "h1", "illegal-attr", "insecure-style", "invalid-gallery", "invalid-imagemap", "invalid-invoke", "invalid-isbn", "invalid-json", "invalid-url", "lonely-apos", "lonely-bracket", "lonely-http", "nested-link", "no-arg", "no-duplicate", "no-ignored", "obsolete-attr", "obsolete-tag", "parsing-order", "pipe-like", "required-attr", "syntax-like", "table-layout", "tag-like", "unbalanced-header", "unclosed-comment", "unclosed-quote", "unclosed-table", "unescaped", "unknown-page", "unmatched-tag", "unterminated-url", "url-encoding", "var-anchor", "void-ext", "invalid-css", "invalid-math"];
51
+ export declare const rules: readonly ["arg-in-ext", "blank-alt", "bold-header", "format-leakage", "fostered-content", "h1", "illegal-attr", "insecure-style", "invalid-gallery", "invalid-imagemap", "invalid-invoke", "invalid-isbn", "invalid-json", "invalid-ref", "invalid-url", "lonely-apos", "lonely-bracket", "lonely-http", "nested-link", "no-arg", "no-duplicate", "no-ignored", "obsolete-attr", "obsolete-tag", "parsing-order", "pipe-like", "required-attr", "syntax-like", "table-layout", "tag-like", "unbalanced-header", "unclosed-comment", "unclosed-quote", "unclosed-table", "unescaped", "unknown-page", "unmatched-tag", "unterminated-url", "url-encoding", "var-anchor", "void-ext", "invalid-css", "invalid-math"];
52
52
  export declare namespace LintError {
53
53
  type Severity = 'error' | 'warning';
54
54
  type Rule = typeof rules[number];
package/dist/base.js CHANGED
@@ -48,6 +48,7 @@ exports.rules = (() => {
48
48
  'invalid-invoke',
49
49
  'invalid-isbn',
50
50
  'invalid-json',
51
+ 'invalid-ref',
51
52
  'invalid-url',
52
53
  'lonely-apos',
53
54
  'lonely-bracket',
package/dist/base.mjs CHANGED
@@ -45,6 +45,7 @@ const rules = /* @__PURE__ */ (() => {
45
45
  "invalid-invoke",
46
46
  "invalid-isbn",
47
47
  "invalid-json",
48
+ "invalid-ref",
48
49
  "invalid-url",
49
50
  "lonely-apos",
50
51
  "lonely-bracket",
@@ -10,6 +10,7 @@ const child_process_1 = require("child_process");
10
10
  const strict_1 = __importDefault(require("assert/strict"));
11
11
  const cm_util_1 = require("@bhsd/cm-util");
12
12
  const diff_1 = require("../util/diff");
13
+ const string_1 = require("../util/string");
13
14
  /**
14
15
  * Converts an array to an object.
15
16
  * @param config parser configuration
@@ -40,7 +41,7 @@ const filterGadget = (id) => {
40
41
  const n = Number(id);
41
42
  return n < 2300 || n > 2303; // Gadget, Gadget talk, Gadget definition, Gadget definition talk
42
43
  };
43
- const pkg = "wikiparser-node", version = "1.43.0";
44
+ const pkg = "wikiparser-node", version = "1.44.0";
44
45
  /**
45
46
  * Get the parser configuration for a Wikimedia Foundation project.
46
47
  * @param site site nickname
@@ -108,7 +109,7 @@ exports.default = async (site, url, user, force, internal) => {
108
109
  siprop: `general|magicwords|namespaces|namespacealiases${mwConfig.functionHooks ? '' : '|functionhooks'}`,
109
110
  format: 'json',
110
111
  formatversion: '2',
111
- }, { general: { articlepath, server, variants, langconversion }, magicwords, namespaces, namespacealiases, functionhooks, } = (await (await fetch(`${url}/api.php?${new URLSearchParams(params).toString()}`, headers)).json()).query, ns = Object.entries(namespaces).filter(([id]) => filterGadget(id))
112
+ }, { general: { articlepath, server, variants, langconversion }, magicwords, namespaces, namespacealiases, functionhooks, } = (await (await fetch(`${url}/api.php?${String(new URLSearchParams(params))}`, headers)).json()).query, ns = Object.entries(namespaces).filter(([id]) => filterGadget(id))
112
113
  .flatMap(([id, { name, canonical = '' }]) => [
113
114
  [id, name],
114
115
  ...name === canonical ? [] : [[id, canonical]],
@@ -130,11 +131,11 @@ exports.default = async (site, url, user, force, internal) => {
130
131
  parserFunction[2] = getAliases(magicwords, new Set(['msg', 'raw']));
131
132
  parserFunction[3] = getAliases(magicwords, new Set(['subst', 'safesubst']));
132
133
  if (!mwConfig.functionHooks) {
133
- Object.assign(config, { functionHook: [...functionhooks.map(s => s.toLowerCase()), 'msgnw'] });
134
+ config.functionHook = [...(0, string_1.toLowerCase)(functionhooks), 'msgnw'];
134
135
  }
135
136
  if (!mwConfig.variableIDs) {
136
- const { variables } = (await (await fetch(`${url}/api.php?${new URLSearchParams({ ...params, siprop: 'variables' }).toString()}`, headers)).json()).query;
137
- Object.assign(config, { variable: [...new Set([...variables, '='])] });
137
+ const { variables } = (await (await fetch(`${url}/api.php?${String(new URLSearchParams({ ...params, siprop: 'variables' }))}`, headers)).json()).query;
138
+ config.variable = [...new Set([...variables, '='])];
138
139
  }
139
140
  if ('#choose' in parserFunction[0]) {
140
141
  delete parserFunction[0]['choose'];
package/dist/index.js CHANGED
@@ -3,6 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  /* eslint n/exports-style: 0 */
6
+ const cm_util_1 = require("@bhsd/cm-util");
6
7
  const base_1 = require("./base");
7
8
  const debug_1 = require("./util/debug");
8
9
  const constants_1 = require("./util/constants");
@@ -145,7 +146,8 @@ const Parser = {
145
146
  return this.getConfig();
146
147
  }
147
148
  /* NOT FOR BROWSER ONLY END */
148
- const parserConfig = config ?? this.config, { doubleUnderscore, ext, parserFunction, variable,
149
+ const parserConfig = config ?? this.config;
150
+ const { doubleUnderscore, ext, parserFunction, variable, variants,
149
151
  /* NOT FOR BROWSER */
150
152
  conversionTable, redirects, } = parserConfig;
151
153
  for (let i = 0; i < 2; i++) {
@@ -157,6 +159,7 @@ const Parser = {
157
159
  variable.push('translationlanguage');
158
160
  parserFunction[1]['TRANSLATIONLANGUAGE'] = 'translationlanguage';
159
161
  }
162
+ parserConfig.variants = (0, cm_util_1.getBCP47Variants)(variants);
160
163
  /* NOT FOR BROWSER */
161
164
  if (conversionTable) {
162
165
  this.conversionTable = new Map(conversionTable);
@@ -176,19 +179,19 @@ const Parser = {
176
179
  && (this.i18n[msg] ?? msg).replace('$1', this.msg(arg));
177
180
  },
178
181
  /** @implements */
179
- normalizeTitle(title, defaultNs = 0, include, config = Parser.getConfig(), opt) {
182
+ normalizeTitle(title, defaultNs = 0, include, config = Parser.getConfig(), opt, accum = []) {
180
183
  let titleObj;
181
184
  if (opt?.halfParsed) {
182
- titleObj = new title_1.Title(title, defaultNs, config, opt);
185
+ titleObj = new title_1.Title(title, defaultNs, config, opt, accum);
183
186
  }
184
187
  else {
185
188
  const { Token } = require('./src/index');
186
189
  titleObj = debug_1.Shadow.run(() => {
187
- const root = new Token(title, config);
190
+ const root = new Token(title, config, accum);
188
191
  root.type = 'root';
189
192
  root.pageName = opt?.page;
190
193
  root.parseOnce(0, include).parseOnce();
191
- const t = new title_1.Title(root.firstChild.toString(), defaultNs, config, opt);
194
+ const t = new title_1.Title(root.firstChild.toString(), defaultNs, config, opt, accum);
192
195
  root.build();
193
196
  const keys = [
194
197
  'main',
@@ -10,23 +10,26 @@ export interface TexvcLocation {
10
10
  line: number;
11
11
  column: number;
12
12
  }
13
+ export type TexvcReport = {
14
+ status: '+';
15
+ output: string;
16
+ } | {
17
+ status: 'C';
18
+ } | {
19
+ status: 'F' | 'S';
20
+ error: {
21
+ message: string;
22
+ location: {
23
+ start: TexvcLocation;
24
+ end: TexvcLocation;
25
+ };
26
+ };
27
+ };
13
28
  declare interface Texvcjs {
14
29
  check(input: string, options?: {
30
+ usemathrm?: boolean;
15
31
  usemhchem?: boolean;
16
- }): {
17
- status: '+';
18
- } | {
19
- status: 'C';
20
- } | {
21
- status: 'F' | 'S';
22
- error: {
23
- message: string;
24
- location: {
25
- start: TexvcLocation;
26
- end: TexvcLocation;
27
- };
28
- };
29
- };
32
+ }): TexvcReport;
30
33
  }
31
34
  export declare const loadTexvcjs: () => Texvcjs | null;
32
35
  export declare const loadJsonLSP: () => JSONLanguageService | null;
@@ -82,6 +82,7 @@ const defaultLintRuleConfig = {
82
82
  duplicate: 1,
83
83
  },
84
84
  ],
85
+ 'invalid-ref': [2],
85
86
  'invalid-url': [1],
86
87
  'lonely-apos': [
87
88
  1,
@@ -237,9 +238,11 @@ const defaultLintRuleConfig = {
237
238
  'void-ext': [
238
239
  2,
239
240
  {
240
- // img: 2,
241
+ // dynamicpagelist: 2,
241
242
  // languages: 2,
243
+ // rss: 2,
242
244
  // section: 2,
245
+ // templatedata: 2,
243
246
  // templatestyles: 2,
244
247
  },
245
248
  ],
@@ -1,10 +1,12 @@
1
1
  import type { Config } from '../base';
2
+ import type { Token } from '../internal';
2
3
  export interface TitleOptions {
3
4
  temporary?: boolean | undefined;
4
5
  decode?: boolean | undefined;
5
6
  selfLink?: boolean | undefined;
6
7
  halfParsed?: boolean | undefined;
7
8
  page?: string | undefined;
9
+ nowiki?: boolean;
8
10
  }
9
11
  /**
10
12
  * title object of a MediaWiki page
@@ -55,8 +57,9 @@ export declare class Title {
55
57
  * @param opt.decode 是否需要解码
56
58
  * @param opt.selfLink 是否允许selfLink
57
59
  * @param opt.page 当前页面标题
60
+ * @param opt.nowiki 是否剥离nowiki标签
58
61
  */
59
- constructor(title: string, defaultNs: number, config: Config, { temporary, decode, selfLink, page }?: TitleOptions);
62
+ constructor(title: string, defaultNs: number, config: Config, { temporary, decode, selfLink, page, nowiki }?: TitleOptions, accum?: Token[]);
60
63
  /**
61
64
  * Check if the title is a redirect and get the redirect target
62
65
  *
package/dist/lib/title.js CHANGED
@@ -123,9 +123,13 @@ class Title {
123
123
  * @param opt.decode 是否需要解码
124
124
  * @param opt.selfLink 是否允许selfLink
125
125
  * @param opt.page 当前页面标题
126
+ * @param opt.nowiki 是否剥离nowiki标签
126
127
  */
127
- constructor(title, defaultNs, config, { temporary, decode, selfLink, page } = {}) {
128
+ constructor(title, defaultNs, config, { temporary, decode, selfLink, page, nowiki } = {}, accum = []) {
128
129
  this.page = page;
130
+ if (nowiki) {
131
+ title = title.replace(/\0(\d+)e\x7F/gu, (_, p1) => accum[p1].innerText ?? '');
132
+ }
129
133
  const trimmed = title.trim(), subpage = trimmed.startsWith('../');
130
134
  if (decode && title.includes('%')) {
131
135
  try {
@@ -39,7 +39,7 @@ const attributesParent = (i = 0) => (constructor) => {
39
39
  return this.childNodes[i];
40
40
  }
41
41
  hasAttr(key) {
42
- LSP: return this.#getAttributesChild().hasAttr(key);
42
+ return this.#getAttributesChild().hasAttr(key);
43
43
  }
44
44
  getAttr(key) {
45
45
  return this.#getAttributesChild().getAttr(key);
@@ -14,7 +14,7 @@ const constants_1 = require("../util/constants");
14
14
  const parseConverter = (text, config, accum) => {
15
15
  // eslint-disable-next-line @typescript-eslint/no-unused-expressions
16
16
  /;(?=(?:[^;]*?=>)?\s*zh\s*:|(?:\s|\0\d+[cn]\x7F)*$)/u;
17
- config.regexConverter ??= new RegExp(String.raw `;(?=(?:[^;]*?=>)?\s*(?:${config.variants.join('|')})\s*:|(?:\s|\0\d+[cn]\x7F)*$)`, 'iu');
17
+ config.regexConverter ??= new RegExp(String.raw `;(?=(?:[^;]*?=>)?\s*(?:${config.variants.join('|')})\s*:|(?:\s|\0\d+[cn]\x7F)*$)`, 'u');
18
18
  const regex1 = /-\{/gu, regex2 = /-\{|\}-/gu, stack = [];
19
19
  let regex = regex1, mt = regex.exec(text);
20
20
  while (mt) {
@@ -1,9 +1,15 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.renderExt = void 0;
6
+ exports.renderExt = exports.packedModes = void 0;
4
7
  const constants_1 = require("../util/constants");
5
8
  const string_1 = require("../util/string");
6
9
  const sharable_1 = require("../util/sharable");
10
+ const index_1 = __importDefault(require("../index"));
11
+ exports.packedModes = new Set(['packed', 'packed-hover', 'packed-overlay']);
12
+ const galleryModes = new Set([...exports.packedModes, 'nolines', 'slideshow']);
7
13
  /** @ignore */
8
14
  const getCiteNoteId = (i, refName) => `cite_note${refName ? `-${(0, string_1.sanitizeAttr)(refName, true)}` : ''}-${i}`, getCiteRefId = (i, count, refName) => `cite_ref-${refName ? `${(0, string_1.sanitizeAttr)(refName, true)}_${i}-${count - 1}` : i}`, updateRef = (ref, content, dir) => {
9
15
  if (!ref.content) {
@@ -41,14 +47,12 @@ const renderExt = (token, opt) => {
41
47
  .trim()}${padding}</div>`;
42
48
  }
43
49
  case 'gallery': {
44
- const caption = firstChild.getAttrToken('caption'), perrow = parseInt(firstChild.getAttr('perrow') || ''), { classList } = firstChild, mode = firstChild.getAttr('mode')?.toLowerCase(), nolines = mode === 'nolines', padding = nolines ? 9 : 43;
45
- classList.add('gallery');
46
- if (nolines) {
47
- classList.add('mw-gallery-nolines');
48
- }
49
- else if (!mode || mode === 'traditional') {
50
- classList.add('mw-gallery-traditional');
50
+ const caption = firstChild.getAttrToken('caption'), perrow = parseInt(firstChild.getAttr('perrow') || ''), { classList } = firstChild, mode = firstChild.getAttr('mode')?.toLowerCase(), padding = mode === 'nolines' ? 9 : 43;
51
+ if (mode === 'slideshow' && firstChild.hasAttr('showthumbnails')) {
52
+ firstChild.setAttr('data-showthumbnails', '1');
51
53
  }
54
+ classList.add('gallery');
55
+ classList.add(`mw-gallery-${galleryModes.has(mode) ? mode : 'traditional'}`);
52
56
  if (perrow > 0) {
53
57
  firstChild.setAttr('style', `max-width: ${(lastChild.widths + padding) * perrow}px;${firstChild.getAttr('style') || ''}`);
54
58
  }
@@ -121,7 +125,7 @@ const renderExt = (token, opt) => {
121
125
  * 是否添加id属性
122
126
  * @param i 行号
123
127
  */
124
- g = (i) => begin && `<span id="${begin}${i}">`;
128
+ g = (i) => begin && `<span id="${(0, string_1.sanitizeId)(begin)}${i}">`;
125
129
  let mt = re.exec(html), i = 1, lastIndex = 0, output = g(i) + f(1) + (lineReplace?.replaceAll('$1', String(start)) ?? '');
126
130
  while (mt) {
127
131
  if (mt[0] === '\n') {
@@ -160,33 +164,28 @@ const renderExt = (token, opt) => {
160
164
  if (!refs) {
161
165
  return '';
162
166
  }
163
- const follow = firstChild.getAttr('follow') || '';
164
- if (/^\d+$/u.test(follow)) {
165
- return '';
167
+ const linted = firstChild.lintRef() || token.lintRef();
168
+ if (linted) {
169
+ return `<span class="error mw-ext-cite-error">Cite error: ${(0, string_1.sanitize)(index_1.default.msg(linted))}</span>`;
166
170
  }
167
171
  let refName = firstChild.getAttr('name') || '';
168
172
  if (!/\D/u.test(refName)) {
169
173
  refName = '';
170
174
  }
171
- else if (refName && follow) {
172
- return '';
173
- }
174
175
  let dir = firstChild.getAttr('dir')?.toLowerCase();
175
176
  if (dir !== 'ltr' && dir !== 'rtl') {
176
177
  dir = undefined;
177
178
  }
178
179
  const text = token.innerText?.trim(), references = token.closest('ext#references');
179
180
  if (references) {
180
- const { referencesGroup } = refs.get(references.getAttr('group') || '');
181
- if (refName && text) {
182
- const ref = referencesGroup.find(({ name: n }) => n === refName);
183
- if (ref) {
184
- updateRef(ref, lastChild, dir);
185
- }
181
+ const ref = refs.get(references.getAttr('group') || '').referencesGroup
182
+ .find(({ name: n }) => n === refName);
183
+ if (ref) {
184
+ updateRef(ref, lastChild, dir);
186
185
  }
187
186
  return '';
188
187
  }
189
- else if (!refName && !text || text && /<references\b[^>]*>/iu.test(text)) {
188
+ else if (text && /<references\b[^>]*>/iu.test(text)) {
190
189
  return '';
191
190
  }
192
191
  else if (text && /<ref\b[^>]*>/iu.test(text)) {
@@ -202,7 +201,7 @@ const renderExt = (token, opt) => {
202
201
  if (!refs.has(group)) {
203
202
  refs.set(group, { referencesGroup: [], follows: [] });
204
203
  }
205
- const { referencesGroup, follows } = refs.get(group);
204
+ const { referencesGroup, follows } = refs.get(group), follow = firstChild.getAttr('follow') || '';
206
205
  if (follow) {
207
206
  const ref = referencesGroup.find(({ name: n }) => n === follow);
208
207
  if (ref) {
@@ -260,7 +259,7 @@ const renderExt = (token, opt) => {
260
259
  if (referencesGroup.length === 0 && follows.length === 0) {
261
260
  return '';
262
261
  }
263
- let ol = `<ol class="references"${group && ` data-mw-group="${group}"`}>`;
262
+ let ol = `<ol class="references"${group && ` data-mw-group="${(0, string_1.sanitizeId)(group)}"`}>`;
264
263
  for (const { content } of follows) {
265
264
  ol += `\n<p><span class="reference-text">${content.toHtmlInternal()}</span>\n</p>`;
266
265
  }
@@ -276,6 +275,13 @@ const renderExt = (token, opt) => {
276
275
  ? ol
277
276
  : `<div class="mw-references-wrap${referencesGroup.length > 10 ? ' mw-references-columns' : ''}">${ol}</div>`;
278
277
  }
278
+ case 'math':
279
+ case 'chem':
280
+ case 'ce': {
281
+ const { texToSvg } = require('./math');
282
+ const id = firstChild.getAttr('id');
283
+ return `<span class="mwe-math-element mwe-math-element-${firstChild.getAttr('display') === 'block' ? 'block' : 'inline'}"${id ? ` id="${(0, string_1.sanitizeId)(id)}"` : ''}>${texToSvg?.(lastChild.texvcCheck()) ?? ''}</span>`;
284
+ }
279
285
  default:
280
286
  return '';
281
287
  }
@@ -665,7 +665,7 @@ const expandMagicWord = (name, args, page = '', config = index_1.default.getConf
665
665
  if (height) {
666
666
  query.set('height', height);
667
667
  }
668
- return localurl(config, [redirect, query.toString()]);
668
+ return localurl(config, [redirect, String(query)]);
669
669
  }
670
670
  default:
671
671
  throw new RangeError(`Unsupported magic word: ${name}`);
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.texToSvg = void 0;
4
+ const string_1 = require("../util/string");
5
+ const document_1 = require("../lib/document");
6
+ exports.texToSvg = (() => {
7
+ const texvcjs = (0, document_1.loadTexvcjs)();
8
+ if (!texvcjs) {
9
+ return undefined;
10
+ }
11
+ try {
12
+ const katex = require('katex');
13
+ require('katex/contrib/mhchem');
14
+ return ([result, , tex]) => {
15
+ if (result.status === '+') {
16
+ tex = result.output;
17
+ try {
18
+ return (0, string_1.newline)(katex.renderToString(tex, {
19
+ throwOnError: false,
20
+ macros: { '\\mbox': String.raw `\text{#1}` },
21
+ }));
22
+ }
23
+ catch { }
24
+ }
25
+ return `<strong class="error texerror">Failed to parse: ${tex.replaceAll(/\s/gu, ' ')}</strong>`;
26
+ };
27
+ }
28
+ catch {
29
+ return undefined;
30
+ }
31
+ })();
@@ -397,6 +397,9 @@ const loadLanguage = (lang) => {
397
397
  const { default: registerWiki } = require('prism-wiki');
398
398
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
399
399
  registerWiki(exports.Prism, index_1.default);
400
+ (0, exports.loadLanguage)('json');
401
+ (0, exports.loadLanguage)('latex');
402
+ (0, exports.loadLanguage)('lilypond');
400
403
  return lang;
401
404
  }
402
405
  catch { }
@@ -1,3 +1,4 @@
1
+ import { BoundingRect } from '../lib/rect';
1
2
  import { Token } from './index';
2
3
  import { AtomToken } from './atom';
3
4
  import { AttributeToken } from './attribute';
@@ -270,9 +270,24 @@ let AttributesToken = (() => {
270
270
  return parentNode?.type === 'html' && parentNode.closing && this.text().trim() !== '';
271
271
  }
272
272
  /** @private */
273
+ lintRef(rect, severity) {
274
+ LINT: {
275
+ const followAttr = this.getAttrToken('follow'), follow = followAttr?.getValue(), name = this.getAttr('name'), rule = 'invalid-ref';
276
+ if (follow && !/\D/u.test(follow)) {
277
+ const msg = 'int-name';
278
+ return rect ? (0, lint_1.generateForChild)(followAttr, rect, rule, msg, severity) : msg;
279
+ }
280
+ else if (follow && (this.hasAttr('details') || name && /\D/u.test(name))) {
281
+ const msg = 'ref-follow';
282
+ return rect ? (0, lint_1.generateForSelf)(this, rect, rule, msg, severity) : msg;
283
+ }
284
+ return '';
285
+ }
286
+ }
287
+ /** @private */
273
288
  lint(start = this.getAbsoluteIndex(), re) {
274
289
  LINT: {
275
- const errors = super.lint(start, re), { parentNode, childNodes, type, name: tag } = this, attrs = new Map(), duplicated = new Set(), rect = new rect_1.BoundingRect(this, start), rules = ['no-ignored', 'required-attr', 'no-duplicate'], { lintConfig } = index_1.default, { computeEditInfo, fix } = lintConfig, s = ['closingTag', 'invalidAttributes', 'nonWordAttributes']
290
+ const errors = super.lint(start, re), { parentNode, childNodes, type, name: tag } = this, attrs = new Map(), duplicated = new Set(), rect = new rect_1.BoundingRect(this, start), rules = ['no-ignored', 'required-attr', 'invalid-ref', 'no-duplicate'], { lintConfig } = index_1.default, { computeEditInfo, fix } = lintConfig, s = ['closingTag', 'invalidAttributes', 'nonWordAttributes']
276
291
  .map(k => lintConfig.getSeverity(rules[0], k));
277
292
  if (s[0] && this.#lint()) {
278
293
  const e = (0, lint_1.generateForSelf)(this, rect, rules[0], 'attributes-of-closing-tag', s[0]);
@@ -318,12 +333,21 @@ let AttributesToken = (() => {
318
333
  }
319
334
  }
320
335
  }
321
- const severity = lintConfig.getSeverity(rules[2], 'attribute');
336
+ if (tag === 'ref') {
337
+ const severity = lintConfig.getSeverity(rules[2]);
338
+ if (severity) {
339
+ const e = this.lintRef(rect, severity);
340
+ if (e) {
341
+ errors.push(e);
342
+ }
343
+ }
344
+ }
345
+ const severity = lintConfig.getSeverity(rules[3], 'attribute');
322
346
  if (severity && duplicated.size > 0) {
323
347
  for (const key of duplicated) {
324
348
  const pairs = attrs.get(key).map(attr => [attr, attr.getValue()]);
325
349
  Array.prototype.push.apply(errors, pairs.map(([attr, value], i) => {
326
- const e = (0, lint_1.generateForChild)(attr, rect, rules[2], index_1.default.msg('duplicate-attribute', key), severity);
350
+ const e = (0, lint_1.generateForChild)(attr, rect, rules[3], index_1.default.msg('duplicate-attribute', key), severity);
327
351
  if (computeEditInfo || fix) {
328
352
  const remove = (0, lint_1.fixByRemove)(e);
329
353
  if (!value || pairs.slice(0, i).some(([, v]) => v === value)) {