wikiparser-node 1.35.2 → 1.37.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.
@@ -39,46 +39,7 @@ const filterGadget = (id) => {
39
39
  const n = Number(id);
40
40
  return n < 2300 || n > 2303; // Gadget, Gadget talk, Gadget definition, Gadget definition talk
41
41
  };
42
- /**
43
- * Execute the data script.
44
- * @param obj MediaWiki module implementation
45
- */
46
- const execute = (obj) => {
47
- Object.entries(obj.files).find(([k]) => k.endsWith('.data.js'))[1]();
48
- };
49
- const mw = {
50
- loader: {
51
- done: false,
52
- /** @ignore */
53
- impl(callback) {
54
- execute(callback()[1]);
55
- },
56
- /** @ignore */
57
- implement(name, callback) {
58
- if (typeof callback === 'object') {
59
- execute(callback);
60
- }
61
- else if (!this.done) {
62
- callback();
63
- }
64
- if (name.startsWith('ext.CodeMirror.data')) {
65
- this.done = true;
66
- }
67
- },
68
- /** @ignore */
69
- state() {
70
- //
71
- },
72
- },
73
- config: {
74
- /** @ignore */
75
- set({ extCodeMirrorConfig }) {
76
- mwConfig = extCodeMirrorConfig;
77
- },
78
- },
79
- };
80
- const pkg = "wikiparser-node", version = "1.35.2";
81
- let mwConfig;
42
+ const pkg = "wikiparser-node", version = "1.37.0";
82
43
  /**
83
44
  * Get the parser configuration for a Wikimedia Foundation project.
84
45
  * @param site site nickname
@@ -122,15 +83,28 @@ exports.default = async (site, url, user, force, internal) => {
122
83
  siprop: 'general|magicwords|functionhooks|namespaces|namespacealiases',
123
84
  format: 'json',
124
85
  formatversion: '2',
125
- }, { general: { articlepath, variants, langconversion }, magicwords, namespaces, namespacealiases, functionhooks, } = (await (await fetch(`${url}/api.php?${new URLSearchParams(params).toString()}`, headers)).json()).query;
126
- try {
127
- eval(m); // eslint-disable-line no-eval
86
+ }, { general: { articlepath, variants, langconversion }, magicwords, namespaces, namespacealiases, functionhooks, } = (await (await fetch(`${url}/api.php?${new URLSearchParams(params).toString()}`, headers)).json()).query, tempFile = path_1.default.join(__dirname, 'mw.js');
87
+ fs_1.default.writeFileSync(tempFile, m);
88
+ const { stdout, stderr } = (0, child_process_1.spawnSync)(process.execPath, [
89
+ '-r',
90
+ './env.js',
91
+ process.allowedNodeEnvironmentFlags.has('--permission')
92
+ ? '--permission'
93
+ : '--experimental-permission',
94
+ `--allow-fs-read=${__dirname}`,
95
+ '--disable-warning=ExperimentalWarning',
96
+ tempFile,
97
+ ], { cwd: __dirname, encoding: 'utf8' });
98
+ fs_1.default.unlinkSync(tempFile);
99
+ if (stderr) {
100
+ console.error(stderr);
101
+ throw new Error('Failed to execute the fetched MediaWiki module!', { cause: m });
128
102
  }
129
- catch (e) {
130
- console.log(m);
131
- throw e;
103
+ let mwConfig;
104
+ try {
105
+ mwConfig = JSON.parse(stdout);
132
106
  }
133
- if (!mwConfig) {
107
+ catch {
134
108
  throw new RangeError('Extension:CodeMirror is not installed!');
135
109
  }
136
110
  const ns = Object.entries(namespaces).filter(([id]) => filterGadget(id))
@@ -138,7 +112,7 @@ exports.default = async (site, url, user, force, internal) => {
138
112
  [id, name],
139
113
  ...name === canonical ? [] : [[id, canonical]],
140
114
  ]), config = {
141
- ...(0, cm_util_1.getParserConfig)(require(path_1.default.join(dir, 'minimum')), mwConfig),
115
+ ...(0, cm_util_1.getParserConfig)(require(path_1.default.join(dir, 'minimum.json')), mwConfig),
142
116
  ...(0, cm_util_1.getKeywords)(magicwords),
143
117
  variants: langconversion ? (0, cm_util_1.getVariants)(variants) : [],
144
118
  namespaces: Object.fromEntries(ns),
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ /**
4
+ * Execute the data script.
5
+ * @param obj MediaWiki module implementation
6
+ */
7
+ const execute = (obj) => {
8
+ Object.entries(obj.files).find(([k]) => k.endsWith('.data.js'))[1]();
9
+ };
10
+ Object.assign(globalThis, {
11
+ mw: {
12
+ loader: {
13
+ done: false,
14
+ /** @ignore */
15
+ impl(callback) {
16
+ execute(callback()[1]);
17
+ },
18
+ /** @ignore */
19
+ implement(name, callback) {
20
+ if (typeof callback === 'object') {
21
+ execute(callback);
22
+ }
23
+ else if (!this.done) {
24
+ callback();
25
+ }
26
+ if (name.startsWith('ext.CodeMirror.data')) {
27
+ this.done = true;
28
+ }
29
+ },
30
+ /** @ignore */
31
+ state() {
32
+ //
33
+ },
34
+ },
35
+ config: {
36
+ /** @ignore */
37
+ set({ extCodeMirrorConfig }) {
38
+ console.log(JSON.stringify(extCodeMirrorConfig));
39
+ },
40
+ },
41
+ },
42
+ });
package/dist/index.js CHANGED
@@ -10,7 +10,7 @@ const string_1 = require("./util/string");
10
10
  const lintConfig_1 = require("./lib/lintConfig");
11
11
  const title_1 = require("./lib/title");
12
12
  /* NOT FOR BROWSER */
13
- const util_1 = __importDefault(require("util"));
13
+ const nodejs_1 = require("@bhsd/nodejs");
14
14
  const redirectMap_1 = require("./lib/redirectMap");
15
15
  /* NOT FOR BROWSER END */
16
16
  /* NOT FOR BROWSER ONLY */
@@ -20,12 +20,24 @@ const common_1 = require("@bhsd/common");
20
20
  const diff_1 = require("./util/diff");
21
21
  /* NOT FOR BROWSER ONLY */
22
22
  const re = new RegExp(String.raw `^https?:\/\/([^./]+)\.(${common_1.wmf})\.org`, 'iu');
23
+ /**
24
+ * require一个JSON文件
25
+ * @param file 文件名
26
+ * @throws {RangeError} 仅支持JSON文件
27
+ */
28
+ const jsonRequire = (file) => {
29
+ const fullPath = require.resolve(file);
30
+ if (fullPath.endsWith('.json')) {
31
+ return require(fullPath);
32
+ }
33
+ throw new RangeError('Only JSON files are supported!');
34
+ };
23
35
  /**
24
36
  * 从根路径require
25
37
  * @param file 文件名
26
38
  * @param dir 子路径
27
39
  */
28
- const rootRequire = (file, dir) => require(path_1.default.isAbsolute(file)
40
+ const rootRequire = (file, dir) => jsonRequire(path_1.default.isAbsolute(file)
29
41
  ? /* c8 ignore next */ file
30
42
  : path_1.default.join('..', file.includes('/') ? '' : dir, file));
31
43
  /* NOT FOR BROWSER ONLY END */
@@ -116,7 +128,7 @@ const Parser = {
116
128
  if (!path_1.default.isAbsolute(this.config)) {
117
129
  for (const p of this.configPaths) {
118
130
  try {
119
- this.config = require(path_1.default.resolve(process.cwd(), p, this.config));
131
+ this.config = jsonRequire(path_1.default.resolve(process.cwd(), p, this.config));
120
132
  break;
121
133
  }
122
134
  catch { }
@@ -333,7 +345,6 @@ const Parser = {
333
345
  },
334
346
  /** @implements */
335
347
  callParserFunction(name, arg, ...args) {
336
- const { expandMagicWord } = require('./render/magicWords');
337
348
  if (typeof arg === 'string') {
338
349
  args.unshift(arg);
339
350
  }
@@ -349,9 +360,9 @@ const Parser = {
349
360
  args.push(`${key}=${value}`);
350
361
  }
351
362
  }
352
- const { parserFunction } = this.getConfig(), [lcName, canonicalName] = (0, debug_1.getCanonicalName)(name, parserFunction);
363
+ const { parserFunction } = this.getConfig(), [lcName, canonicalName] = (0, debug_1.getCanonicalName)(name, parserFunction), custom = constants_1.functionHooks.has(lcName);
353
364
  let result;
354
- if (constants_1.functionHooks.has(lcName)) {
365
+ if (custom) {
355
366
  if (!canonicalName) {
356
367
  const [insensitive, sensitive] = parserFunction, entry = Object.entries(sensitive).find(([, v]) => v === lcName)
357
368
  || Object.entries(insensitive).find(([, v]) => v === lcName);
@@ -366,11 +377,12 @@ const Parser = {
366
377
  && constants_1.functionHooks.get(lcName)(firstChild);
367
378
  }
368
379
  else {
380
+ const { expandMagicWord } = require('./render/magicWords');
369
381
  result = expandMagicWord(lcName, args);
370
382
  }
371
383
  /* c8 ignore next 3 */
372
384
  if (result === false) {
373
- throw new RangeError(`Unable to resolve parser function: ${name}`);
385
+ throw new RangeError(`Unable to resolve ${custom ? 'custom' : 'built-in'} parser function: ${name}`);
374
386
  }
375
387
  return result;
376
388
  },
@@ -378,8 +390,7 @@ const Parser = {
378
390
  warn(msg, ...args) {
379
391
  /* c8 ignore start */
380
392
  if (this.warning) {
381
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
382
- console.warn(util_1.default.styleText?.('yellow', msg) ?? msg, ...args);
393
+ console.warn((0, nodejs_1.yellow)(msg), ...args);
383
394
  }
384
395
  /* c8 ignore stop */
385
396
  },
@@ -387,8 +398,7 @@ const Parser = {
387
398
  debug(msg, ...args) {
388
399
  /* c8 ignore start */
389
400
  if (this.debugging) {
390
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
391
- console.debug(util_1.default.styleText?.('blue', msg) ?? msg, ...args);
401
+ console.debug((0, nodejs_1.blue)(msg), ...args);
392
402
  }
393
403
  /* c8 ignore stop */
394
404
  },
@@ -438,8 +448,15 @@ const Parser = {
438
448
  if (!main) {
439
449
  throw new RangeError(`找不到对应时间戳的错误记录:${date}`);
440
450
  }
441
- const file = path_1.default.join(dir, main), wikitext = fs_1.default.readFileSync(file, 'utf8');
442
- const { stage, include, config, page } = require(`${file}.json`), { Token } = require('./src/index');
451
+ const { Token } = require('./src/index');
452
+ const file = path_1.default.join(dir, main), wikitext = fs_1.default.readFileSync(file, 'utf8'), { stage = constants_1.MAX_STAGE, include, config, page } = (() => {
453
+ try {
454
+ return require(`${file}.json`);
455
+ }
456
+ catch {
457
+ return {};
458
+ }
459
+ })();
443
460
  debug_1.Shadow.run(() => {
444
461
  const halfParsed = stage < constants_1.MAX_STAGE, token = new Token(halfParsed ? wikitext : (0, string_1.tidy)(wikitext), config);
445
462
  token.type = 'root';
@@ -452,8 +469,8 @@ const Parser = {
452
469
  token.parse(undefined, include);
453
470
  }
454
471
  fs_1.default.unlinkSync(file);
455
- fs_1.default.unlinkSync(`${file}.err`);
456
- fs_1.default.unlinkSync(`${file}.json`);
472
+ fs_1.default.rmSync(`${file}.err`, { force: true });
473
+ fs_1.default.rmSync(`${file}.json`, { force: true });
457
474
  }, this);
458
475
  },
459
476
  /* c8 ignore stop */
@@ -29,11 +29,10 @@ declare interface Texvcjs {
29
29
  };
30
30
  }
31
31
  export declare const loadTexvcjs: () => Texvcjs | null;
32
- export declare const jsonTags: string[];
33
32
  export declare const loadJsonLSP: () => JSONLanguageService | null;
34
33
  export declare const loadCssLSP: () => CSSLanguageService | null;
35
34
  export declare const loadHtmlData: () => IHTMLDataProvider | null;
36
- export declare const loadStylelint: () => Promise<PublicApi | null>;
35
+ export declare const loadStylelint: () => PublicApi | null;
37
36
  /** embedded document */
38
37
  declare class EmbeddedDocument implements TextDocument {
39
38
  #private;
@@ -3,11 +3,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.EmbeddedCSSDocument = exports.EmbeddedJSONDocument = exports.loadStylelint = exports.loadHtmlData = exports.loadCssLSP = exports.loadJsonLSP = exports.jsonTags = exports.loadTexvcjs = void 0;
6
+ exports.EmbeddedCSSDocument = exports.EmbeddedJSONDocument = exports.loadStylelint = exports.loadHtmlData = exports.loadCssLSP = exports.loadJsonLSP = exports.loadTexvcjs = void 0;
7
7
  const path_1 = __importDefault(require("path"));
8
8
  const common_1 = require("@bhsd/common");
9
- /* NOT FOR BROWSER */
10
9
  const constants_1 = require("../util/constants");
10
+ /* NOT FOR BROWSER */
11
+ const constants_2 = require("../util/constants");
11
12
  let texcvjs;
12
13
  const loadTexvcjs = () => {
13
14
  NPM: {
@@ -24,7 +25,6 @@ const loadTexvcjs = () => {
24
25
  }
25
26
  };
26
27
  exports.loadTexvcjs = loadTexvcjs;
27
- exports.jsonTags = ['templatedata', 'mapframe', 'maplink'];
28
28
  let jsonLSP;
29
29
  const loadJsonLSP = () => {
30
30
  if (jsonLSP === undefined) {
@@ -40,10 +40,10 @@ const loadJsonLSP = () => {
40
40
  });
41
41
  const dir = path_1.default.join('..', '..', 'data', 'ext');
42
42
  jsonLSP.configure({
43
- schemas: exports.jsonTags.map((tag) => {
44
- const uri = path_1.default.join(dir, tag);
43
+ schemas: constants_1.jsonTags.map((tag) => {
44
+ const uri = path_1.default.join(dir, `${tag}.json`);
45
45
  try {
46
- const schema = require(tag === 'maplink' ? path_1.default.join(dir, 'mapframe') : uri);
46
+ const schema = require(tag === 'maplink' ? path_1.default.join(dir, 'mapframe.json') : uri);
47
47
  return {
48
48
  uri,
49
49
  fileMatch: [tag],
@@ -98,15 +98,15 @@ exports.loadHtmlData = loadHtmlData;
98
98
  let stylelint;
99
99
  const loadStylelint = () => {
100
100
  NPM: {
101
- stylelint ??= (async () => {
101
+ if (stylelint === undefined) {
102
102
  try {
103
- return (await import('stylelint')).default;
103
+ stylelint = require('stylelint');
104
104
  }
105
105
  catch /* c8 ignore start */ {
106
- return null;
106
+ stylelint = null;
107
107
  }
108
108
  /* c8 ignore stop */
109
- })();
109
+ }
110
110
  return stylelint;
111
111
  }
112
112
  };
@@ -183,4 +183,4 @@ class EmbeddedCSSDocument extends EmbeddedDocument {
183
183
  }
184
184
  }
185
185
  exports.EmbeddedCSSDocument = EmbeddedCSSDocument;
186
- constants_1.classes['EmbeddedDocument'] = __filename;
186
+ constants_2.classes['EmbeddedDocument'] = __filename;
@@ -239,14 +239,12 @@ const defaultLintRuleConfig = {
239
239
  ],
240
240
  'invalid-math': 2,
241
241
  };
242
- Object.freeze(defaultLintRuleConfig);
243
242
  const defaultLintConfig = {
244
243
  configurationComment: 'lint',
245
244
  ignoreDisables: false,
246
245
  fix: true,
247
246
  computeEditInfo: true,
248
247
  };
249
- Object.freeze(defaultLintConfig);
250
248
  /**
251
249
  * 验证错误级别是否符合规范
252
250
  * @param severity 错误级别
package/dist/lib/lsp.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import Parser from '../index';
2
+ import { Token } from '../src/index';
2
3
  import type { Range, Position, ColorInformation, ColorPresentation, FoldingRange, DocumentLink, Location, WorkspaceEdit, Diagnostic as DiagnosticBase, TextEdit, Hover, SignatureHelp, InlayHint, CodeAction, DocumentSymbol } from 'vscode-languageserver-types';
3
4
  import type { Config, LanguageService as LanguageServiceBase, CompletionItem, SignatureData } from '../base';
4
5
  import type { AttributeToken } from '../internal';
package/dist/lib/lsp.js CHANGED
@@ -22,6 +22,7 @@ const child_process_1 = require("child_process");
22
22
  const crypto_1 = require("crypto");
23
23
  const stylelint_util_1 = require("@bhsd/stylelint-util");
24
24
  const search_1 = __importDefault(require("../util/search"));
25
+ const constants_2 = require("../util/constants");
25
26
  const document_1 = require("./document");
26
27
  exports.tasks = new WeakMap();
27
28
  const refTags = new Set(['ref']), referencesTags = new Set(['ref', 'references']), nameAttrs = new Set(['name', 'follow']), groupAttrs = new Set(['group']), renameTypes = new Set([
@@ -286,7 +287,7 @@ const partialParse = async (wikitext, watch, include, config = index_1.default.g
286
287
  };
287
288
  /* NOT FOR BROWSER ONLY */
288
289
  /** @see https://www.npmjs.com/package/stylelint-config-recommended */
289
- const cssRules = { 'block-no-empty': null }, sources = { 'invalid-css': 'css', 'invalid-math': 'texvc' }, jsonSelector = document_1.jsonTags.map(s => `ext#${s}`).join(), scores = new Map();
290
+ const cssRules = { 'block-no-empty': null }, sources = { 'invalid-css': 'css', 'invalid-math': 'texvc' }, jsonSelector = constants_2.jsonTags.map(s => `ext#${s}`).join(), scores = new Map();
290
291
  let colors;
291
292
  /**
292
293
  * Correct the position of an error.
@@ -379,15 +380,15 @@ class LanguageService {
379
380
  exports.tasks.set(uri, this);
380
381
  /* NOT FOR BROWSER ONLY */
381
382
  const dataDir = path_1.default.join('..', '..', 'data'), extDir = path_1.default.join(dataDir, 'ext');
382
- this.#lilypondData = require(path_1.default.join(extDir, 'score'));
383
- this.#mathData = require(path_1.default.join(extDir, 'math'));
383
+ this.#lilypondData = require(path_1.default.join(extDir, 'score.json'));
384
+ this.#mathData = require(path_1.default.join(extDir, 'math.json'));
384
385
  /* NOT FOR BROWSER ONLY END */
385
386
  Object.defineProperties(this, {
386
387
  config: { enumerable: false },
387
388
  data: {
388
389
  enumerable: false,
389
390
  /* NOT FOR BROWSER ONLY */
390
- value: require(path_1.default.join(dataDir, 'signatures')),
391
+ value: require(path_1.default.join(dataDir, 'signatures.json')),
391
392
  },
392
393
  });
393
394
  }
@@ -498,15 +499,15 @@ class LanguageService {
498
499
  async provideDocumentColors(rgba, text, hsl = true) {
499
500
  const root = await this.#queue(text);
500
501
  /* NOT FOR BROWSER ONLY */
501
- colors ??= (async () => {
502
+ if (colors === undefined) {
502
503
  try {
503
- return new RegExp(String.raw `\b${Object.keys((await import('color-name')).default).join('|')}\b`, 'giu');
504
+ const { default: colorName } = require('color-name');
505
+ colors = new RegExp(String.raw `\b${Object.keys(colorName).join('|')}\b`, 'giu');
504
506
  }
505
507
  catch {
506
- return false;
508
+ colors = false;
507
509
  }
508
- })();
509
- const re = await colors;
510
+ }
510
511
  /* NOT FOR BROWSER ONLY END */
511
512
  return root.querySelectorAll('attr-value,parameter-value,arg-default').reverse().flatMap(token => {
512
513
  const { type, childNodes,
@@ -522,13 +523,13 @@ class LanguageService {
522
523
  /* NOT FOR BROWSER ONLY END */
523
524
  }
524
525
  /* NOT FOR BROWSER ONLY */
525
- const isStyle = re && type === 'attr-value' && parentNode.name === 'style';
526
+ const isStyle = colors && type === 'attr-value' && parentNode.name === 'style';
526
527
  /* NOT FOR BROWSER ONLY END */
527
528
  return childNodes.filter((child) => child.type === 'text').reverse().flatMap(child => {
528
529
  const { data } = child, parts = (0, common_1.splitColors)(data, hsl).filter(([, , , isColor]) => isColor);
529
530
  /* NOT FOR BROWSER ONLY */
530
531
  if (isStyle) {
531
- parts.push(...[...data.matchAll(re)].map(({ index, 0: s }) => [s, index, index + s.length, true]));
532
+ parts.push(...[...data.matchAll(colors)].map(({ index, 0: s }) => [s, index, index + s.length, true]));
532
533
  }
533
534
  /* NOT FOR BROWSER ONLY END */
534
535
  if (parts.length === 0) {
@@ -771,7 +772,7 @@ class LanguageService {
771
772
  },
772
773
  }));
773
774
  }
774
- else if (type === 'ext-inner' && document_1.jsonTags.includes(cur.name)) {
775
+ else if (type === 'ext-inner' && constants_2.jsonTags.includes(cur.name)) {
775
776
  const jsonLSP = (0, document_1.loadJsonLSP)();
776
777
  if (!jsonLSP) {
777
778
  return undefined;
@@ -831,7 +832,7 @@ class LanguageService {
831
832
  const root = await this.#queue(text), { lintConfig } = index_1.default, needFix = lintConfig.fix;
832
833
  lintConfig.fix = false;
833
834
  /* NOT FOR BROWSER ONLY */
834
- const stylelint = await (0, document_1.loadStylelint)(), jsonLSP = (0, document_1.loadJsonLSP)();
835
+ const stylelint = (0, document_1.loadStylelint)(), jsonLSP = (0, document_1.loadJsonLSP)();
835
836
  let s;
836
837
  NPM: if (jsonLSP) {
837
838
  s = lintConfig.rules['invalid-json'];
@@ -1323,7 +1324,7 @@ class LanguageService {
1323
1324
  const textDoc = new document_1.EmbeddedCSSDocument(root, offsetNode);
1324
1325
  return (0, document_1.loadCssLSP)().doHover(textDoc, position, textDoc.styleSheet) ?? undefined;
1325
1326
  }
1326
- else if (type === 'ext-inner' && document_1.jsonTags.includes(name)) {
1327
+ else if (type === 'ext-inner' && constants_2.jsonTags.includes(name)) {
1327
1328
  const jsonLSP = (0, document_1.loadJsonLSP)();
1328
1329
  if (!jsonLSP) {
1329
1330
  return undefined;
@@ -1443,8 +1444,12 @@ class LanguageService {
1443
1444
  return hints;
1444
1445
  }
1445
1446
  /** @private */
1447
+ querySelectorAll(selector) {
1448
+ return this.#done.querySelectorAll(selector);
1449
+ }
1450
+ /** @private */
1446
1451
  findStyleTokens() {
1447
- return this.#done.querySelectorAll(cssSelector).filter(({ lastChild }) => isAttr(lastChild));
1452
+ return this.querySelectorAll(cssSelector).filter(({ lastChild }) => isAttr(lastChild));
1448
1453
  }
1449
1454
  /**
1450
1455
  * Provide refactoring actions
@@ -1586,7 +1591,7 @@ class LanguageService {
1586
1591
  async setTargetWikipedia(wiki, user) {
1587
1592
  const [site, host] = index_1.default.getWMFSite(wiki);
1588
1593
  try {
1589
- const config = require(path_1.default.join('..', '..', 'config', site));
1594
+ const config = require(path_1.default.join('..', '..', 'config', `${site}.json`));
1590
1595
  this.config = index_1.default.getConfig(config);
1591
1596
  }
1592
1597
  catch {
@@ -1,4 +1,4 @@
1
- import type { LintError, AstNode as AstNodeBase, TokenTypes } from '../base';
1
+ import type { AstNode as AstNodeBase, TokenTypes, LintError } from '../base';
2
2
  import type { NodeLike } from '../mixin/nodeLike';
3
3
  import type { AstText, Token } from '../internal';
4
4
  export type AstNodes = AstText | Token;
package/dist/lib/node.js CHANGED
@@ -327,11 +327,14 @@ let AstNode = (() => {
327
327
  this.verifyChild(j, 1);
328
328
  /* NOT FOR BROWSER END */
329
329
  return (0, lint_1.cache)(this.#rIndex[j], () => {
330
- const { childNodes } = this, n = j + (j < 0 ? childNodes.length : 0);
330
+ const { childNodes } = this, parentAIndex = this.#aIndex?.[0] === debug_1.Shadow.rev && this.#aIndex[1], n = j + (j < 0 ? childNodes.length : 0);
331
331
  let acc = this.getAttribute('padding');
332
332
  for (let i = 0; i < n; i++) {
333
333
  if (index_1.default.viewOnly) {
334
334
  this.#rIndex[i] = [debug_1.Shadow.rev, acc];
335
+ if (parentAIndex !== false) {
336
+ childNodes[i].#aIndex = [debug_1.Shadow.rev, parentAIndex + acc];
337
+ }
335
338
  }
336
339
  acc += childNodes[i].toString().length + this.getGaps(i);
337
340
  }
package/dist/lib/title.js CHANGED
@@ -300,10 +300,10 @@ class Title {
300
300
  if (!valid || ns !== 6 || interwiki) {
301
301
  throw new Error('Title.getFileUrl method is only for files!');
302
302
  }
303
- const { expandMagicWord } = require('../render/magicWords');
304
303
  if (height) {
305
304
  width ||= 1e4;
306
305
  }
306
+ const { expandMagicWord } = require('../render/magicWords');
307
307
  return expandMagicWord('filepath', [main, `${width || ''}${height ? `x${height}` : ''}`]);
308
308
  }
309
309
  /** @private */
@@ -138,22 +138,26 @@ let ConverterFlagsToken = (() => {
138
138
  return new Set(this.#flags.filter(flag => variants.has(flag)));
139
139
  }
140
140
  /** @private */
141
- isInvalidFlag(flag, variant, unknown, valid) {
141
+ isInvalidFlag(flag, variant, unknown) {
142
142
  /* PRINT ONLY */
143
143
  PRINT: if (typeof flag === 'object') {
144
+ const variants = new Set(this.getAttribute('config').variants);
144
145
  flag = flag.text().trim();
145
- variant = this.getVariantFlags();
146
+ variant = this.#flags.some(f => variants.has(f)) ? variants : new Set();
146
147
  unknown = this.getUnknownFlags();
147
- valid = new Set(this.#flags.filter(f => definedFlags.has(f)));
148
148
  }
149
149
  /* PRINT ONLY END */
150
- return Boolean(flag) && !variant.has(flag) && !unknown.has(flag) && (variant.size > 0 || !valid.has(flag));
150
+ return Boolean(flag)
151
+ && !variant.has(flag)
152
+ && !unknown.has(flag)
153
+ && (variant.size > 0 || !definedFlags.has(flag));
151
154
  }
152
155
  /** @private */
153
156
  lint(start = this.getAbsoluteIndex(), re) {
154
157
  LINT: {
155
- const variantFlags = this.getVariantFlags(), unknownFlags = this.getUnknownFlags(), validFlags = new Set(this.#flags.filter(flag => definedFlags.has(flag))), emptyFlagCount = this.#flags.filter(flag => !flag).length, knownFlagCount = this.#flags.length - unknownFlags.size - emptyFlagCount, { lintConfig } = index_1.default, { computeEditInfo, fix } = lintConfig, errors = super.lint(start, re);
156
- if (variantFlags.size === knownFlagCount || validFlags.size === knownFlagCount) {
158
+ const variantFlags = this.getVariantFlags(), unknownFlags = this.getUnknownFlags(), emptyFlagCount = this.#flags.filter(flag => !flag).length, knownFlagCount = this.#flags.length - unknownFlags.size - emptyFlagCount, { lintConfig } = index_1.default, { computeEditInfo, fix } = lintConfig, errors = super.lint(start, re);
159
+ if (variantFlags.size === knownFlagCount
160
+ || this.#flags.filter(flag => definedFlags.has(flag)).length === knownFlagCount) {
157
161
  return errors;
158
162
  }
159
163
  const rule = 'no-ignored', s = lintConfig.getSeverity(rule, 'conversionFlag');
@@ -161,7 +165,7 @@ let ConverterFlagsToken = (() => {
161
165
  const rect = new rect_1.BoundingRect(this, start);
162
166
  for (let i = 0; i < this.length; i++) {
163
167
  const child = this.childNodes[i], flag = child.text().trim();
164
- if (this.isInvalidFlag(flag, variantFlags, unknownFlags, validFlags)) {
168
+ if (this.isInvalidFlag(flag, variantFlags, unknownFlags)) {
165
169
  const e = (0, lint_1.generateForChild)(child, rect, rule, 'invalid-conversion-flag', s);
166
170
  if (computeEditInfo || fix) {
167
171
  if (variantFlags.size === 0 && definedFlags.has(flag.toUpperCase())) {
@@ -1,7 +1,7 @@
1
1
  import Parser from '../index';
2
2
  import { AstElement } from '../lib/element';
3
3
  import { AstText } from '../lib/text';
4
- import type { LintError, TokenTypes } from '../base';
4
+ import type { TokenTypes, LintError } from '../base';
5
5
  import type { Title, TitleOptions } from '../lib/title';
6
6
  import type { AstNodes, IncludeToken, HtmlToken, ExtToken, CommentToken } from '../internal';
7
7
  import { Ranges } from '../lib/ranges';
@@ -1,5 +1,5 @@
1
1
  import { NowikiBaseToken } from './base';
2
- import type { LintError, Config } from '../../base';
2
+ import type { Config, LintError } from '../../base';
3
3
  import type { Token } from '../../internal';
4
4
  /**
5
5
  * invisible HTML comment
@@ -5,12 +5,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.NowikiToken = void 0;
7
7
  const common_1 = require("@bhsd/common");
8
+ const constants_1 = require("../../util/constants");
8
9
  const lint_1 = require("../../util/lint");
9
10
  const rect_1 = require("../../lib/rect");
10
11
  const index_1 = __importDefault(require("../../index"));
11
12
  const base_1 = require("./base");
12
13
  /* NOT FOR BROWSER ONLY */
13
- const constants_1 = require("../../util/constants");
14
+ const constants_2 = require("../../util/constants");
14
15
  const document_1 = require("../../lib/document");
15
16
  /** @ignore */
16
17
  const updateLocation = ({ startIndex, startLine, startCol, endIndex, endLine, endCol }, { offset, line, column }, n) => {
@@ -58,22 +59,10 @@ class NowikiToken extends base_1.NowikiBaseToken {
58
59
  }
59
60
  NPM: {
60
61
  rule = 'invalid-json';
61
- const sSyntax = lintConfig.getSeverity(rule);
62
- /* NOT FOR BROWSER ONLY */
63
- const sDuplicate = lintConfig.getSeverity(rule, 'duplicate');
64
- /* NOT FOR BROWSER ONLY END */
65
- if (name === 'templatedata' && (sSyntax
66
- || sDuplicate)) {
67
- // browser版本使用`lintJSONNative()`
68
- return (0, common_1.lintJSON)(innerText).map(({ message, from, to = from, line, endLine = line, column, endColumn = column,
69
- /* NOT FOR BROWSER ONLY */
70
- severity, }) => {
71
- s =
72
- /* eslint-disable @stylistic/operator-linebreak */
73
- severity === 'warning' ?
74
- sDuplicate :
75
- /* eslint-enable @stylistic/operator-linebreak */
76
- sSyntax;
62
+ const sSyntax = lintConfig.getSeverity(rule), sDuplicate = lintConfig.getSeverity(rule, 'duplicate');
63
+ if (constants_1.jsonTags.includes(name) && (sSyntax || sDuplicate)) {
64
+ return (name === 'templatedata' ? common_1.lintJSON : common_1.lintJSONC)(innerText).map(({ message, from, to = from, line, endLine = line, column, endColumn = column, severity, }) => {
65
+ s = severity === 'warning' ? sDuplicate : sSyntax;
77
66
  if (!s) {
78
67
  return false;
79
68
  }
@@ -94,7 +83,7 @@ class NowikiToken extends base_1.NowikiBaseToken {
94
83
  /* NOT FOR BROWSER ONLY */
95
84
  rule = 'invalid-math';
96
85
  s = lintConfig.getSeverity(rule);
97
- if (s && constants_1.mathTags.has(name)) {
86
+ if (s && constants_2.mathTags.has(name)) {
98
87
  const texvcjs = (0, document_1.loadTexvcjs)();
99
88
  if (texvcjs) {
100
89
  const isChem = name !== 'math', display = previousSibling?.getAttr('display') ?? 'block';
@@ -155,4 +144,4 @@ class NowikiToken extends base_1.NowikiBaseToken {
155
144
  }
156
145
  }
157
146
  exports.NowikiToken = NowikiToken;
158
- constants_1.classes['NowikiToken'] = __filename;
147
+ constants_2.classes['NowikiToken'] = __filename;
@@ -1,6 +1,6 @@
1
1
  import { Token } from './index';
2
2
  import type { Config, LintError, AST } from '../base';
3
- import type { AtomToken, SyntaxToken, TranscludeToken } from '../internal';
3
+ import type { AtomToken, TranscludeToken, SyntaxToken } from '../internal';
4
4
  /**
5
5
  * template or magic word parameter
6
6
  *