wikilint 2.30.0 → 2.32.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 (60) hide show
  1. package/bin/cli.js +1 -1
  2. package/dist/base.d.mts +13 -7
  3. package/dist/base.d.ts +13 -7
  4. package/dist/base.js +1 -1
  5. package/dist/base.mjs +2 -2
  6. package/dist/bin/cli.js +2 -2
  7. package/dist/bin/config.js +1 -1
  8. package/dist/index.d.ts +2 -1
  9. package/dist/index.js +24 -58
  10. package/dist/internal.d.ts +1 -0
  11. package/dist/lib/document.d.ts +9 -7
  12. package/dist/lib/document.js +90 -65
  13. package/dist/lib/element.d.ts +1 -7
  14. package/dist/lib/element.js +6 -29
  15. package/dist/lib/lintConfig.js +6 -2
  16. package/dist/lib/lsp.js +114 -56
  17. package/dist/lib/node.js +1 -1
  18. package/dist/mixin/elementLike.js +2 -4
  19. package/dist/parser/commentAndExt.js +4 -4
  20. package/dist/parser/hrAndDoubleUnderscore.js +9 -8
  21. package/dist/src/arg.js +7 -0
  22. package/dist/src/attribute.js +20 -18
  23. package/dist/src/attributes.d.ts +5 -0
  24. package/dist/src/attributes.js +4 -3
  25. package/dist/src/converterFlags.js +2 -2
  26. package/dist/src/converterRule.js +89 -38
  27. package/dist/src/extLink.js +1 -1
  28. package/dist/src/hidden.js +2 -1
  29. package/dist/src/imageParameter.d.ts +0 -1
  30. package/dist/src/imageParameter.js +198 -145
  31. package/dist/src/index.js +8 -11
  32. package/dist/src/link/base.js +2 -6
  33. package/dist/src/link/file.js +4 -3
  34. package/dist/src/link/galleryImage.js +1 -1
  35. package/dist/src/link/index.js +1 -1
  36. package/dist/src/nowiki/index.js +34 -31
  37. package/dist/src/nowiki/list.js +1 -3
  38. package/dist/src/nowiki/quote.d.ts +2 -2
  39. package/dist/src/nowiki/quote.js +3 -3
  40. package/dist/src/table/base.js +5 -3
  41. package/dist/src/table/index.d.ts +0 -5
  42. package/dist/src/table/index.js +4 -10
  43. package/dist/src/tag/html.js +2 -3
  44. package/dist/src/tag/index.js +6 -14
  45. package/dist/src/tag/tvar.js +2 -1
  46. package/dist/src/tagPair/ext.js +1 -1
  47. package/dist/src/tagPair/translate.d.ts +1 -0
  48. package/dist/src/transclude.js +7 -10
  49. package/dist/util/constants.js +7 -3
  50. package/dist/util/debug.js +42 -4
  51. package/dist/util/diff.js +17 -15
  52. package/dist/{parser → util}/selector.js +9 -3
  53. package/dist/util/sharable.d.mts +4 -1
  54. package/dist/util/sharable.js +7 -7
  55. package/dist/util/sharable.mjs +7 -7
  56. package/dist/util/string.js +15 -11
  57. package/i18n/en.json +1 -0
  58. package/i18n/zh-hans.json +30 -29
  59. package/i18n/zh-hant.json +31 -30
  60. package/package.json +18 -14
package/bin/cli.js CHANGED
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env node
2
2
  'use strict';
3
- require('../dist/bin/cli.js'); // eslint-disable-line n/no-missing-require
3
+ require('../dist/bin/cli.js');
package/dist/base.d.mts CHANGED
@@ -6,7 +6,7 @@ export interface Config {
6
6
  readonly nsid: Record<string, number>;
7
7
  readonly variable: string[];
8
8
  readonly functionHook: string[];
9
- readonly parserFunction: [Record<string, string>, Record<string, string> | string[], string[], string[]];
9
+ readonly parserFunction: [Record<string, string>, Record<string, string>, string[], string[]];
10
10
  readonly doubleUnderscore: [string[], string[], Record<string, string>?, Record<string, string>?];
11
11
  readonly protocol: string;
12
12
  readonly interwiki: string[];
@@ -16,7 +16,7 @@ export interface Config {
16
16
  readonly articlePath?: string;
17
17
  }
18
18
  export type ConfigData = Omit<Config, 'excludes'>;
19
- export type TokenTypes = 'root' | 'plain' | 'redirect' | 'redirect-syntax' | 'redirect-target' | 'translate' | 'translate-attr' | 'translate-inner' | 'tvar' | 'tvar-name' | 'onlyinclude' | 'noinclude' | 'include' | 'comment' | 'ext' | 'ext-attrs' | 'ext-attr-dirty' | 'ext-attr' | 'attr-key' | 'attr-value' | 'ext-inner' | 'arg' | 'arg-name' | 'arg-default' | 'hidden' | 'magic-word' | 'magic-word-name' | 'invoke-function' | 'invoke-module' | 'template' | 'template-name' | 'parameter' | 'parameter-key' | 'parameter-value' | 'heading' | 'heading-title' | 'heading-trail' | 'html' | 'html-attrs' | 'html-attr-dirty' | 'html-attr' | 'table' | 'tr' | 'td' | 'table-syntax' | 'table-attrs' | 'table-attr-dirty' | 'table-attr' | 'table-inter' | 'td-inner' | 'hr' | 'double-underscore' | 'link' | 'link-target' | 'link-text' | 'category' | 'file' | 'gallery-image' | 'imagemap-image' | 'image-parameter' | 'quote' | 'ext-link' | 'ext-link-text' | 'ext-link-url' | 'free-ext-link' | 'magic-link' | 'list' | 'dd' | 'list-range' | 'converter' | 'converter-flags' | 'converter-flag' | 'converter-rule' | 'converter-rule-variant' | 'converter-rule-to' | 'converter-rule-from' | 'param-line' | 'imagemap-link';
19
+ export type TokenTypes = 'root' | 'plain' | 'redirect' | 'redirect-syntax' | 'redirect-target' | 'translate' | 'translate-attr' | 'translate-inner' | 'tvar' | 'tvar-name' | 'onlyinclude' | 'noinclude' | 'include' | 'comment' | 'ext' | 'ext-attrs' | 'ext-attr-dirty' | 'ext-attr' | 'attr-key' | 'attr-value' | 'ext-inner' | 'arg' | 'arg-name' | 'arg-default' | 'hidden' | 'magic-word' | 'magic-word-name' | 'invoke-function' | 'invoke-module' | 'template' | 'template-name' | 'parameter' | 'parameter-key' | 'parameter-value' | 'heading' | 'heading-title' | 'heading-trail' | 'html' | 'html-attrs' | 'html-attr-dirty' | 'html-attr' | 'table' | 'tr' | 'td' | 'table-syntax' | 'table-attrs' | 'table-attr-dirty' | 'table-attr' | 'table-inter' | 'td-inner' | 'hr' | 'double-underscore' | 'link' | 'link-target' | 'link-text' | 'category' | 'file' | 'gallery-image' | 'imagemap-image' | 'image-parameter' | 'quote' | 'ext-link' | 'ext-link-text' | 'ext-link-url' | 'free-ext-link' | 'magic-link' | 'list' | 'dd' | 'converter' | 'converter-flags' | 'converter-flag' | 'converter-rule' | 'converter-rule-variant' | 'converter-rule-to' | 'converter-rule-from' | 'param-line' | 'imagemap-link';
20
20
  export declare const stages: {
21
21
  redirect: number;
22
22
  onlyinclude: number;
@@ -42,10 +42,9 @@ export declare const stages: {
42
42
  list: number;
43
43
  dd: number;
44
44
  converter: number;
45
- 'list-range': number;
46
45
  };
47
46
  export type Stage = keyof typeof stages;
48
- export declare const rules: readonly ["bold-header", "format-leakage", "fostered-content", "h1", "illegal-attr", "insecure-style", "invalid-gallery", "invalid-imagemap", "invalid-invoke", "invalid-isbn", "invalid-url", "lonely-apos", "lonely-bracket", "lonely-http", "nested-link", "no-arg", "no-duplicate", "no-ignored", "obsolete-attr", "obsolete-tag", "parsing-order", "pipe-like", "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"];
47
+ export declare const rules: readonly ["arg-in-ext", "bold-header", "format-leakage", "fostered-content", "h1", "illegal-attr", "insecure-style", "invalid-gallery", "invalid-imagemap", "invalid-invoke", "invalid-isbn", "invalid-url", "lonely-apos", "lonely-bracket", "lonely-http", "nested-link", "no-arg", "no-duplicate", "no-ignored", "obsolete-attr", "obsolete-tag", "parsing-order", "pipe-like", "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"];
49
48
  export declare namespace LintError {
50
49
  type Severity = 'error' | 'warning';
51
50
  type Rule = typeof rules[number];
@@ -285,12 +284,11 @@ export interface LintConfiguration extends FullLintConfig {
285
284
  getSeverity(rule: LintError.Rule, key?: string): LintError.Severity | false;
286
285
  }
287
286
  export interface Parser {
288
- config: ConfigData | string;
287
+ config: string | // eslint-disable-line @stylistic/operator-linebreak
288
+ ConfigData;
289
289
  i18n: Record<string, string> | string | undefined;
290
290
  /** @since v1.22.0 */
291
291
  lintConfig: LintConfig;
292
- /** @since v1.9.0 */
293
- viewOnly: boolean;
294
292
  /**
295
293
  * Get the current parser configuration
296
294
  *
@@ -316,5 +314,13 @@ export interface Parser {
316
314
  * @since v1.16.1
317
315
  */
318
316
  createLanguageService(uri?: object): LanguageService;
317
+ /**
318
+ * Linter
319
+ * @param include whether to be transcluded / 是否嵌入
320
+ * @param page page name / 页面名称
321
+ * @since v1.32.0
322
+ */
323
+ lint(wikitext: string, include?: boolean, config?: Config, page?: string): LintError[];
324
+ lint(wikitext: string, page: string, include?: boolean, config?: Config): LintError[];
319
325
  }
320
326
  export {};
package/dist/base.d.ts CHANGED
@@ -6,7 +6,7 @@ export interface Config {
6
6
  readonly nsid: Record<string, number>;
7
7
  readonly variable: string[];
8
8
  readonly functionHook: string[];
9
- readonly parserFunction: [Record<string, string>, Record<string, string> | string[], string[], string[]];
9
+ readonly parserFunction: [Record<string, string>, Record<string, string>, string[], string[]];
10
10
  readonly doubleUnderscore: [string[], string[], Record<string, string>?, Record<string, string>?];
11
11
  readonly protocol: string;
12
12
  readonly interwiki: string[];
@@ -16,7 +16,7 @@ export interface Config {
16
16
  readonly articlePath?: string;
17
17
  }
18
18
  export type ConfigData = Omit<Config, 'excludes'>;
19
- export type TokenTypes = 'root' | 'plain' | 'redirect' | 'redirect-syntax' | 'redirect-target' | 'translate' | 'translate-attr' | 'translate-inner' | 'tvar' | 'tvar-name' | 'onlyinclude' | 'noinclude' | 'include' | 'comment' | 'ext' | 'ext-attrs' | 'ext-attr-dirty' | 'ext-attr' | 'attr-key' | 'attr-value' | 'ext-inner' | 'arg' | 'arg-name' | 'arg-default' | 'hidden' | 'magic-word' | 'magic-word-name' | 'invoke-function' | 'invoke-module' | 'template' | 'template-name' | 'parameter' | 'parameter-key' | 'parameter-value' | 'heading' | 'heading-title' | 'heading-trail' | 'html' | 'html-attrs' | 'html-attr-dirty' | 'html-attr' | 'table' | 'tr' | 'td' | 'table-syntax' | 'table-attrs' | 'table-attr-dirty' | 'table-attr' | 'table-inter' | 'td-inner' | 'hr' | 'double-underscore' | 'link' | 'link-target' | 'link-text' | 'category' | 'file' | 'gallery-image' | 'imagemap-image' | 'image-parameter' | 'quote' | 'ext-link' | 'ext-link-text' | 'ext-link-url' | 'free-ext-link' | 'magic-link' | 'list' | 'dd' | 'list-range' | 'converter' | 'converter-flags' | 'converter-flag' | 'converter-rule' | 'converter-rule-variant' | 'converter-rule-to' | 'converter-rule-from' | 'param-line' | 'imagemap-link';
19
+ export type TokenTypes = 'root' | 'plain' | 'redirect' | 'redirect-syntax' | 'redirect-target' | 'translate' | 'translate-attr' | 'translate-inner' | 'tvar' | 'tvar-name' | 'onlyinclude' | 'noinclude' | 'include' | 'comment' | 'ext' | 'ext-attrs' | 'ext-attr-dirty' | 'ext-attr' | 'attr-key' | 'attr-value' | 'ext-inner' | 'arg' | 'arg-name' | 'arg-default' | 'hidden' | 'magic-word' | 'magic-word-name' | 'invoke-function' | 'invoke-module' | 'template' | 'template-name' | 'parameter' | 'parameter-key' | 'parameter-value' | 'heading' | 'heading-title' | 'heading-trail' | 'html' | 'html-attrs' | 'html-attr-dirty' | 'html-attr' | 'table' | 'tr' | 'td' | 'table-syntax' | 'table-attrs' | 'table-attr-dirty' | 'table-attr' | 'table-inter' | 'td-inner' | 'hr' | 'double-underscore' | 'link' | 'link-target' | 'link-text' | 'category' | 'file' | 'gallery-image' | 'imagemap-image' | 'image-parameter' | 'quote' | 'ext-link' | 'ext-link-text' | 'ext-link-url' | 'free-ext-link' | 'magic-link' | 'list' | 'dd' | 'converter' | 'converter-flags' | 'converter-flag' | 'converter-rule' | 'converter-rule-variant' | 'converter-rule-to' | 'converter-rule-from' | 'param-line' | 'imagemap-link';
20
20
  export declare const stages: {
21
21
  redirect: number;
22
22
  onlyinclude: number;
@@ -42,10 +42,9 @@ export declare const stages: {
42
42
  list: number;
43
43
  dd: number;
44
44
  converter: number;
45
- 'list-range': number;
46
45
  };
47
46
  export type Stage = keyof typeof stages;
48
- export declare const rules: readonly ["bold-header", "format-leakage", "fostered-content", "h1", "illegal-attr", "insecure-style", "invalid-gallery", "invalid-imagemap", "invalid-invoke", "invalid-isbn", "invalid-url", "lonely-apos", "lonely-bracket", "lonely-http", "nested-link", "no-arg", "no-duplicate", "no-ignored", "obsolete-attr", "obsolete-tag", "parsing-order", "pipe-like", "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"];
47
+ export declare const rules: readonly ["arg-in-ext", "bold-header", "format-leakage", "fostered-content", "h1", "illegal-attr", "insecure-style", "invalid-gallery", "invalid-imagemap", "invalid-invoke", "invalid-isbn", "invalid-url", "lonely-apos", "lonely-bracket", "lonely-http", "nested-link", "no-arg", "no-duplicate", "no-ignored", "obsolete-attr", "obsolete-tag", "parsing-order", "pipe-like", "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"];
49
48
  export declare namespace LintError {
50
49
  type Severity = 'error' | 'warning';
51
50
  type Rule = typeof rules[number];
@@ -285,12 +284,11 @@ export interface LintConfiguration extends FullLintConfig {
285
284
  getSeverity(rule: LintError.Rule, key?: string): LintError.Severity | false;
286
285
  }
287
286
  export interface Parser {
288
- config: ConfigData | string;
287
+ config: string | // eslint-disable-line @stylistic/operator-linebreak
288
+ ConfigData;
289
289
  i18n: Record<string, string> | string | undefined;
290
290
  /** @since v1.22.0 */
291
291
  lintConfig: LintConfig;
292
- /** @since v1.9.0 */
293
- viewOnly: boolean;
294
292
  /**
295
293
  * Get the current parser configuration
296
294
  *
@@ -316,5 +314,13 @@ export interface Parser {
316
314
  * @since v1.16.1
317
315
  */
318
316
  createLanguageService(uri?: object): LanguageService;
317
+ /**
318
+ * Linter
319
+ * @param include whether to be transcluded / 是否嵌入
320
+ * @param page page name / 页面名称
321
+ * @since v1.32.0
322
+ */
323
+ lint(wikitext: string, include?: boolean, config?: Config, page?: string): LintError[];
324
+ lint(wikitext: string, page: string, include?: boolean, config?: Config): LintError[];
319
325
  }
320
326
  export {};
package/dist/base.js CHANGED
@@ -27,13 +27,13 @@ exports.stages = (() => {
27
27
  list: 10,
28
28
  dd: 10,
29
29
  converter: 11,
30
- 'list-range': 11,
31
30
  };
32
31
  Object.setPrototypeOf(obj, null);
33
32
  return obj;
34
33
  })();
35
34
  exports.rules = (() => {
36
35
  const arr = [
36
+ 'arg-in-ext',
37
37
  'bold-header',
38
38
  'format-leakage',
39
39
  'fostered-content',
package/dist/base.mjs CHANGED
@@ -23,14 +23,14 @@ const stages = /* @__PURE__ */ (() => {
23
23
  "magic-link": 9,
24
24
  list: 10,
25
25
  dd: 10,
26
- converter: 11,
27
- "list-range": 11
26
+ converter: 11
28
27
  };
29
28
  Object.setPrototypeOf(obj, null);
30
29
  return obj;
31
30
  })();
32
31
  const rules = /* @__PURE__ */ (() => {
33
32
  const arr = [
33
+ "arg-in-ext",
34
34
  "bold-header",
35
35
  "format-leakage",
36
36
  "fostered-content",
package/dist/bin/cli.js CHANGED
@@ -353,13 +353,13 @@ catch {
353
353
  [, , , problems] = fileCache;
354
354
  }
355
355
  else {
356
- problems = index_1.default.parse(wikitext, include).lint();
356
+ problems = index_1.default.lint(wikitext, include);
357
357
  update = true;
358
358
  }
359
359
  if (fixing && problems.output !== undefined) {
360
360
  wikitext = problems.output;
361
361
  jobs.push(fs_1.default.promises.writeFile(file, wikitext));
362
- problems = index_1.default.parse(wikitext, include).lint();
362
+ problems = index_1.default.lint(wikitext, include);
363
363
  update = true;
364
364
  }
365
365
  if (caching && update) {
@@ -77,7 +77,7 @@ const mw = {
77
77
  },
78
78
  },
79
79
  };
80
- const pkg = "wikilint", version = "2.30.0";
80
+ const pkg = "wikilint", version = "2.32.0";
81
81
  let mwConfig;
82
82
  /**
83
83
  * Get the parser configuration for a Wikimedia Foundation project.
package/dist/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { LintConfiguration } from './lib/lintConfig';
2
+ import { Title } from './lib/title';
2
3
  import type { Config, ConfigData, LintError, LintConfig, TokenTypes, Parser as ParserBase, Stage } from './base';
3
- import type { Title, TitleOptions } from './lib/title';
4
+ import type { TitleOptions } from './lib/title';
4
5
  import type { LanguageService, QuickFixData } from './lib/lsp';
5
6
  import type { Token } from './internal';
6
7
  declare interface Parser extends ParserBase {
package/dist/index.js CHANGED
@@ -8,12 +8,12 @@ const debug_1 = require("./util/debug");
8
8
  const constants_1 = require("./util/constants");
9
9
  const string_1 = require("./util/string");
10
10
  const lintConfig_1 = require("./lib/lintConfig");
11
+ const title_1 = require("./lib/title");
11
12
  /* NOT FOR BROWSER ONLY */
12
13
  const fs_1 = __importDefault(require("fs"));
13
14
  const path_1 = __importDefault(require("path"));
14
15
  const common_1 = require("@bhsd/common");
15
16
  const diff_1 = require("./util/diff");
16
- const config_1 = __importDefault(require("./bin/config"));
17
17
  /* NOT FOR BROWSER ONLY */
18
18
  const re = new RegExp(String.raw `^https?:\/\/([^./]+)\.(${common_1.wmf})\.org`, 'iu');
19
19
  /**
@@ -29,6 +29,15 @@ let viewOnly = true;
29
29
  let lintConfig = (() => {
30
30
  LINT: return new lintConfig_1.LintConfiguration();
31
31
  })(), i18n;
32
+ /**
33
+ * 判断参数顺序
34
+ * @param includeOrPage include or page
35
+ * @param configOrInclude config or include
36
+ * @param pageOrConfig page or config
37
+ */
38
+ const getParams = (includeOrPage, configOrInclude, pageOrConfig) => typeof includeOrPage === 'string'
39
+ ? [Boolean(configOrInclude), pageOrConfig, includeOrPage]
40
+ : [Boolean(includeOrPage), configOrInclude, pageOrConfig];
32
41
  const Parser = {
33
42
  config: 'default',
34
43
  /** @implements */
@@ -86,9 +95,7 @@ const Parser = {
86
95
  this.config = rootRequire(this.config, 'config');
87
96
  }
88
97
  /* istanbul ignore if */
89
- if (this.config.doubleUnderscore.length < 3
90
- || Array.isArray(this.config.parserFunction[1])
91
- || !('functionHook' in this.config)) {
98
+ if (this.config.doubleUnderscore.length < 3 || !('functionHook' in this.config)) {
92
99
  (0, diff_1.error)(`The schema (${path_1.default.join(__dirname, '..', 'config', '.schema.json')}) of parser configuration is updated.`);
93
100
  }
94
101
  return this.getConfig();
@@ -102,13 +109,7 @@ const Parser = {
102
109
  }
103
110
  if (ext.includes('translate') && !variable.includes('translationlanguage')) {
104
111
  variable.push('translationlanguage');
105
- /* istanbul ignore if */
106
- if (Array.isArray(parserFunction[1])) {
107
- parserFunction[1].push('TRANSLATIONLANGUAGE');
108
- }
109
- else {
110
- parserFunction[1]['TRANSLATIONLANGUAGE'] = 'translationlanguage';
111
- }
112
+ parserFunction[1]['TRANSLATIONLANGUAGE'] = 'translationlanguage';
112
113
  }
113
114
  return {
114
115
  ...parserConfig,
@@ -122,10 +123,9 @@ const Parser = {
122
123
  },
123
124
  /** @implements */
124
125
  normalizeTitle(title, defaultNs = 0, include, config = Parser.getConfig(), opt) {
125
- const { Title } = require('./lib/title');
126
126
  let titleObj;
127
127
  if (opt?.halfParsed) {
128
- titleObj = new Title(title, defaultNs, config, opt);
128
+ titleObj = new title_1.Title(title, defaultNs, config, opt);
129
129
  }
130
130
  else {
131
131
  const { Token } = require('./src/index');
@@ -134,7 +134,7 @@ const Parser = {
134
134
  root.type = 'root';
135
135
  root.pageName = opt?.page;
136
136
  root.parseOnce(0, include).parseOnce();
137
- const t = new Title(root.toString(), defaultNs, config, opt);
137
+ const t = new title_1.Title(root.firstChild.toString(), defaultNs, config, opt);
138
138
  root.build();
139
139
  for (const key of ['main', 'fragment']) {
140
140
  const str = t[key];
@@ -149,7 +149,7 @@ const Parser = {
149
149
  }
150
150
  }
151
151
  return t;
152
- });
152
+ }, this);
153
153
  }
154
154
  return titleObj;
155
155
  },
@@ -210,52 +210,17 @@ const Parser = {
210
210
  return this.parse(wikitext, include, maxStage, ref.getAttribute('config'), ref.pageName);
211
211
  },
212
212
  /** @implements */
213
- async partialParse(wikitext, watch, include, config = Parser.getConfig()) {
213
+ createLanguageService(uri = {}) {
214
214
  LSP: {
215
- const { Token } = require('./src/index');
216
- const set = typeof setImmediate === 'function' ? setImmediate : /* istanbul ignore next */ setTimeout, { running } = debug_1.Shadow;
217
- debug_1.Shadow.running = true;
218
- const token = new Token((0, string_1.tidy)(wikitext), config);
219
- token.type = 'root';
220
- let i = 0;
221
- try {
222
- await new Promise(resolve => {
223
- const /** @ignore */ check = () => {
224
- if (watch() === wikitext) {
225
- i++;
226
- set(parseOnce, 0);
227
- }
228
- else {
229
- resolve();
230
- }
231
- },
232
- /** @ignore */ parseOnce = () => {
233
- if (i === constants_1.MAX_STAGE + 1) {
234
- token.afterBuild();
235
- resolve();
236
- }
237
- else {
238
- token[i === constants_1.MAX_STAGE ? 'build' : 'parseOnce'](i, include);
239
- check();
240
- }
241
- };
242
- set(parseOnce, 0);
243
- });
244
- }
245
- catch (e) /* istanbul ignore next */ {
246
- debug_1.Shadow.running = running;
247
- throw e;
248
- }
249
- debug_1.Shadow.running = running;
250
- return token;
215
+ const { LanguageService, tasks } = require('./lib/lsp');
216
+ return tasks.get(uri) ?? new LanguageService(uri);
251
217
  }
252
218
  },
253
219
  /** @implements */
254
- createLanguageService(uri = {}) {
255
- LSP: {
256
- const mod = require('./lib/lsp');
257
- const { LanguageService, tasks } = mod;
258
- return tasks.get(uri) ?? new LanguageService(uri);
220
+ lint(wikitext, includeOrPage, configOrInclude, pageOrConfig) {
221
+ LINT: {
222
+ const [include, config, page] = getParams(includeOrPage, configOrInclude, pageOrConfig);
223
+ return debug_1.Shadow.internal(() => this.parse(wikitext, include, undefined, config, page).lint(), this);
259
224
  }
260
225
  },
261
226
  /* NOT FOR BROWSER ONLY */
@@ -272,7 +237,8 @@ const Parser = {
272
237
  /* istanbul ignore next */
273
238
  /** @implements */
274
239
  async fetchConfig(site, url, user) {
275
- return this.getConfig(await (0, config_1.default)(site, url, user, false, true));
240
+ const { default: fetchConfig } = require('./bin/config');
241
+ return this.getConfig(await fetchConfig(site, url, user, false, true));
276
242
  },
277
243
  };
278
244
  const def = {
@@ -46,3 +46,4 @@ export type { ImagemapLinkToken } from './src/imagemapLink';
46
46
  export type { ImagemapToken } from './src/multiLine/imagemap';
47
47
  export type { CommentedToken } from './src/commented';
48
48
  export type { TranslateToken } from './src/tagPair/translate';
49
+ export type { TvarToken } from './src/tag/tvar';
@@ -1,7 +1,9 @@
1
1
  import type { Position } from 'vscode-languageserver-types';
2
2
  import type { TextDocument } from 'vscode-languageserver-textdocument';
3
- import type { JSONDocument } from 'vscode-json-languageservice';
4
- import type { Stylesheet } from 'vscode-css-languageservice';
3
+ import type { JSONDocument, LanguageService as JSONLanguageService } from 'vscode-json-languageservice';
4
+ import type { Stylesheet, LanguageService as CSSLanguageService } from 'vscode-css-languageservice';
5
+ import type { IHTMLDataProvider } from 'vscode-html-languageservice';
6
+ import type { PublicApi } from 'stylelint';
5
7
  import type { Token } from '../internal';
6
8
  export interface TexvcLocation {
7
9
  offset: number;
@@ -26,12 +28,12 @@ declare interface Texvcjs {
26
28
  };
27
29
  };
28
30
  }
29
- export declare const texvcjs: Texvcjs | undefined;
31
+ export declare const loadTexvcjs: () => Texvcjs | null;
30
32
  export declare const jsonTags: string[];
31
- export declare const jsonLSP: import("vscode-json-languageservice").LanguageService | undefined;
32
- export declare const cssLSP: import("vscode-css-languageservice").LanguageService | undefined;
33
- export declare const htmlData: import("vscode-html-languageservice").IHTMLDataProvider | undefined;
34
- export declare const stylelint: Promise<import("stylelint").PublicApi | undefined>;
33
+ export declare const loadJsonLSP: () => JSONLanguageService | null;
34
+ export declare const loadCssLSP: () => CSSLanguageService | null;
35
+ export declare const loadHtmlData: () => IHTMLDataProvider | null;
36
+ export declare const loadStylelint: () => Promise<PublicApi | null>;
35
37
  /** embedded document */
36
38
  declare class EmbeddedDocument implements TextDocument {
37
39
  #private;
@@ -3,85 +3,110 @@ 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.stylelint = exports.htmlData = exports.cssLSP = exports.jsonLSP = exports.jsonTags = exports.texvcjs = void 0;
6
+ exports.EmbeddedCSSDocument = exports.EmbeddedJSONDocument = exports.loadStylelint = exports.loadHtmlData = exports.loadCssLSP = exports.loadJsonLSP = exports.jsonTags = exports.loadTexvcjs = void 0;
7
7
  const path_1 = __importDefault(require("path"));
8
8
  const common_1 = require("@bhsd/common");
9
- exports.texvcjs = (() => {
9
+ let texcvjs;
10
+ const loadTexvcjs = () => {
10
11
  NPM: {
12
+ if (texcvjs === undefined) {
13
+ try {
14
+ texcvjs = require('mathoid-texvcjs');
15
+ }
16
+ catch {
17
+ /* istanbul ignore next */
18
+ texcvjs = null;
19
+ }
20
+ }
21
+ return texcvjs;
22
+ }
23
+ };
24
+ exports.loadTexvcjs = loadTexvcjs;
25
+ exports.jsonTags = ['templatedata', 'mapframe', 'maplink'];
26
+ let jsonLSP;
27
+ const loadJsonLSP = () => {
28
+ if (jsonLSP === undefined) {
11
29
  try {
12
- return require('mathoid-texvcjs');
30
+ jsonLSP = require('vscode-json-languageservice')
31
+ .getLanguageService({
32
+ /** @implements */
33
+ async schemaRequestService(uri) {
34
+ return (await fetch(uri)).text();
35
+ },
36
+ });
37
+ const dir = path_1.default.join('..', '..', 'data', 'ext');
38
+ jsonLSP.configure({
39
+ schemas: exports.jsonTags.map((tag) => {
40
+ const uri = path_1.default.join(dir, tag);
41
+ try {
42
+ const schema = require(tag === 'maplink' ? path_1.default.join(dir, 'mapframe') : uri);
43
+ return {
44
+ uri,
45
+ fileMatch: [tag],
46
+ schema,
47
+ };
48
+ }
49
+ catch {
50
+ /* istanbul ignore next */
51
+ return false;
52
+ }
53
+ }).filter(schema => schema !== false),
54
+ });
13
55
  }
14
56
  catch {
15
57
  /* istanbul ignore next */
16
- return undefined;
58
+ jsonLSP = null;
17
59
  }
18
60
  }
19
- })();
20
- exports.jsonTags = ['templatedata', 'mapframe', 'maplink'];
21
- exports.jsonLSP = (() => {
22
- try {
23
- const lsp = require('vscode-json-languageservice')
24
- .getLanguageService({
25
- /** @implements */
26
- async schemaRequestService(uri) {
27
- return (await fetch(uri)).text();
28
- },
29
- }), dir = path_1.default.join('..', '..', 'data', 'ext');
30
- lsp.configure({
31
- schemas: exports.jsonTags.map((tag) => {
32
- const uri = path_1.default.join(dir, tag);
33
- try {
34
- const schema = require(tag === 'maplink' ? path_1.default.join(dir, 'mapframe') : uri);
35
- return {
36
- uri,
37
- fileMatch: [tag],
38
- schema,
39
- };
40
- }
41
- catch {
42
- /* istanbul ignore next */
43
- return false;
44
- }
45
- }).filter(Boolean),
46
- });
47
- return lsp;
48
- }
49
- catch {
50
- /* istanbul ignore next */
51
- return undefined;
52
- }
53
- })();
54
- exports.cssLSP = (() => {
55
- try {
56
- return require('vscode-css-languageservice')
57
- .getCSSLanguageService();
58
- }
59
- catch {
60
- /* istanbul ignore next */
61
- return undefined;
62
- }
63
- })();
64
- exports.htmlData = (() => {
65
- try {
66
- return require('vscode-html-languageservice')
67
- .getDefaultHTMLDataProvider();
68
- }
69
- catch {
70
- /* istanbul ignore next */
71
- return undefined;
61
+ return jsonLSP;
62
+ };
63
+ exports.loadJsonLSP = loadJsonLSP;
64
+ let cssLSP;
65
+ const loadCssLSP = () => {
66
+ if (cssLSP === undefined) {
67
+ try {
68
+ cssLSP = require('vscode-css-languageservice')
69
+ .getCSSLanguageService();
70
+ }
71
+ catch {
72
+ /* istanbul ignore next */
73
+ cssLSP = null;
74
+ }
72
75
  }
73
- })();
74
- exports.stylelint = (async () => {
75
- NPM: {
76
+ return cssLSP;
77
+ };
78
+ exports.loadCssLSP = loadCssLSP;
79
+ let htmlData;
80
+ const loadHtmlData = () => {
81
+ if (htmlData === undefined) {
76
82
  try {
77
- return (await import('stylelint')).default;
83
+ htmlData = require('vscode-html-languageservice')
84
+ .getDefaultHTMLDataProvider();
78
85
  }
79
86
  catch {
80
87
  /* istanbul ignore next */
81
- return undefined;
88
+ htmlData = null;
82
89
  }
83
90
  }
84
- })();
91
+ return htmlData;
92
+ };
93
+ exports.loadHtmlData = loadHtmlData;
94
+ let stylelint;
95
+ const loadStylelint = () => {
96
+ NPM: {
97
+ stylelint ??= (async () => {
98
+ try {
99
+ return (await import('stylelint')).default;
100
+ }
101
+ catch {
102
+ /* istanbul ignore next */
103
+ return null;
104
+ }
105
+ })();
106
+ return stylelint;
107
+ }
108
+ };
109
+ exports.loadStylelint = loadStylelint;
85
110
  /** embedded document */
86
111
  class EmbeddedDocument {
87
112
  uri = '';
@@ -134,7 +159,7 @@ class EmbeddedJSONDocument extends EmbeddedDocument {
134
159
  constructor(root, token) {
135
160
  super('json', root, token);
136
161
  this.uri = token.name;
137
- this.jsonDoc = exports.jsonLSP.parseJSONDocument(this);
162
+ this.jsonDoc = (0, exports.loadJsonLSP)().parseJSONDocument(this);
138
163
  }
139
164
  }
140
165
  exports.EmbeddedJSONDocument = EmbeddedJSONDocument;
@@ -147,7 +172,7 @@ class EmbeddedCSSDocument extends EmbeddedDocument {
147
172
  constructor(root, token) {
148
173
  const { type, tag } = token.parentNode;
149
174
  super('css', root, token, `${type === 'ext-attr' ? 'div' : tag}{`, '}');
150
- this.styleSheet = exports.cssLSP.parseStylesheet(this);
175
+ this.styleSheet = (0, exports.loadCssLSP)().parseStylesheet(this);
151
176
  }
152
177
  getContent() {
153
178
  return (0, common_1.sanitizeInlineStyle)(super.getContent());
@@ -1,5 +1,5 @@
1
1
  import { AstNode } from './node';
2
- import type { LintError } from '../base';
2
+ import type { TokenTypes, LintError } from '../base';
3
3
  import type { ElementLike } from '../mixin/elementLike';
4
4
  import type { AstNodes, Token } from '../internal';
5
5
  export interface CaretPosition {
@@ -18,12 +18,6 @@ export declare abstract class AstElement extends AstNode {
18
18
  readonly data: undefined;
19
19
  /** number of child nodes / 子节点总数 */
20
20
  get length(): number;
21
- /**
22
- * Merge adjacent text child nodes
23
- *
24
- * 合并相邻的文本子节点
25
- */
26
- normalize(): void;
27
21
  /**
28
22
  * Remove a child node
29
23
  *