wikilint 2.18.1 → 2.18.3

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 (54) hide show
  1. package/README.md +2 -2
  2. package/bin/cli.js +1 -1
  3. package/bin/config.js +2 -2
  4. package/config/.schema.json +13 -0
  5. package/config/default.json +460 -4
  6. package/config/enwiki.json +111 -0
  7. package/config/jawiki.json +954 -0
  8. package/config/llwiki.json +117 -0
  9. package/config/minimum.json +10 -0
  10. package/config/moegirl.json +104 -0
  11. package/config/zhwiki.json +109 -0
  12. package/dist/base.d.mts +3 -0
  13. package/dist/base.d.ts +3 -0
  14. package/dist/base.js +1 -0
  15. package/dist/base.mjs +2 -1
  16. package/dist/bin/config.js +82 -59
  17. package/dist/index.d.ts +3 -1
  18. package/dist/index.js +41 -29
  19. package/dist/lib/document.d.ts +6 -6
  20. package/dist/lib/document.js +43 -36
  21. package/dist/lib/lsp.d.ts +1 -0
  22. package/dist/lib/lsp.js +83 -55
  23. package/dist/lib/title.d.ts +18 -4
  24. package/dist/lib/title.js +12 -4
  25. package/dist/parser/braces.js +29 -15
  26. package/dist/parser/commentAndExt.js +5 -16
  27. package/dist/parser/links.js +1 -1
  28. package/dist/parser/redirect.js +1 -3
  29. package/dist/src/converter.js +1 -1
  30. package/dist/src/gallery.js +1 -1
  31. package/dist/src/heading.js +3 -3
  32. package/dist/src/imageParameter.js +9 -9
  33. package/dist/src/imagemap.js +3 -2
  34. package/dist/src/index.d.ts +1 -1
  35. package/dist/src/index.js +7 -5
  36. package/dist/src/link/base.js +1 -1
  37. package/dist/src/link/file.d.ts +2 -0
  38. package/dist/src/link/file.js +15 -13
  39. package/dist/src/link/galleryImage.js +1 -1
  40. package/dist/src/link/redirectTarget.js +1 -2
  41. package/dist/src/magicLink.js +1 -1
  42. package/dist/src/nested.js +5 -5
  43. package/dist/src/nowiki/index.js +3 -2
  44. package/dist/src/redirect.js +1 -2
  45. package/dist/src/syntax.d.ts +4 -2
  46. package/dist/src/syntax.js +4 -2
  47. package/dist/src/table/base.js +1 -1
  48. package/dist/src/table/index.js +2 -5
  49. package/dist/src/table/trBase.js +3 -1
  50. package/dist/src/transclude.js +23 -12
  51. package/dist/util/debug.js +11 -1
  52. package/dist/util/lint.js +31 -30
  53. package/dist/util/string.js +3 -4
  54. package/package.json +2 -3
@@ -19,6 +19,7 @@ const syntax_1 = require("./syntax");
19
19
  class TranscludeToken extends index_1.Token {
20
20
  modifier = '';
21
21
  #type = 'template';
22
+ #colon = ':';
22
23
  #raw = false;
23
24
  #args = new Map();
24
25
  #title;
@@ -38,7 +39,7 @@ class TranscludeToken extends index_1.Token {
38
39
  title = title.replace(`\0${heading}h\x7F`, accum[heading].toString().replace(/^\n/u, ''));
39
40
  }
40
41
  super(undefined, config, accum, {});
41
- const { parserFunction: [insensitive, sensitive], variable } = config, argSubst = /^(?:\s|\0\d+[cn]\x7F)*\0\d+s\x7F/u.exec(title)?.[0];
42
+ const { parserFunction: [insensitive, sensitive], variable, functionHook } = config, argSubst = /^(?:\s|\0\d+[cn]\x7F)*\0\d+s\x7F/u.exec(title)?.[0];
42
43
  if (argSubst) {
43
44
  this.setAttribute('modifier', argSubst);
44
45
  title = title.slice(argSubst.length);
@@ -49,19 +50,25 @@ class TranscludeToken extends index_1.Token {
49
50
  title = arg.join(':').slice(mt.length);
50
51
  }
51
52
  }
52
- const isFunction = title.includes(':');
53
+ const colon = title.search(/[::]/u), fullWidth = title[colon] === '', isFunction = colon !== -1;
53
54
  if (isFunction || parts.length === 0 && !this.#raw) {
54
- const colon = title.indexOf(':'), magicWord = colon === -1 ? title : title.slice(0, colon), arg = colon === -1 ? undefined : title.slice(colon + 1), cleaned = (0, string_1.removeComment)(magicWord), name = cleaned[arg === undefined ? 'trim' : 'trimStart'](), lcName = name.toLowerCase(), isOldSchema = Array.isArray(sensitive), isSensitive = isOldSchema
55
+ const magicWord = isFunction ? title.slice(0, colon) : title, arg = isFunction && title.slice(colon + 1), cleaned = (0, string_1.removeComment)(magicWord), name = isFunction
56
+ ? cleaned.slice(cleaned.search(/\S/u)) + (fullWidth ? ':' : '')
57
+ : cleaned.trim(), lcName = name.toLowerCase(), isOldSchema = Array.isArray(sensitive), isSensitive = isOldSchema
55
58
  ? sensitive.includes(name)
56
59
  : Object.prototype.hasOwnProperty.call(sensitive, name), canonicalName = !isOldSchema && isSensitive
57
60
  ? sensitive[name]
58
- : Object.prototype.hasOwnProperty.call(insensitive, lcName) && insensitive[lcName], isVar = isOldSchema && isSensitive || variable.includes(canonicalName);
59
- if (isVar || isFunction && canonicalName) {
60
- this.setAttribute('name', canonicalName || lcName.replace(/^#/u, ''));
61
+ : Object.prototype.hasOwnProperty.call(insensitive, lcName) && insensitive[lcName], isFunc = isOldSchema && isSensitive
62
+ || !('functionHook' in config) || functionHook.includes(canonicalName), isVar = isOldSchema && isSensitive || variable.includes(canonicalName);
63
+ if (isFunction ? canonicalName && isFunc : isVar) {
64
+ this.setAttribute('name', canonicalName || lcName.replace(/^#|:$/u, ''));
61
65
  this.#type = 'magic-word';
62
- const pattern = new RegExp(String.raw `^\s*${name}\s*$`, isSensitive ? 'u' : 'iu'), token = new syntax_1.SyntaxToken(magicWord, pattern, 'magic-word-name', config, accum, {});
66
+ if (fullWidth) {
67
+ this.#colon = ':';
68
+ }
69
+ const token = new syntax_1.SyntaxToken(magicWord, 'magic-word-name', config, accum);
63
70
  super.insertAt(token);
64
- if (arg !== undefined) {
71
+ if (arg !== false) {
65
72
  parts.unshift([arg]);
66
73
  }
67
74
  if (this.name === 'invoke') {
@@ -78,7 +85,7 @@ class TranscludeToken extends index_1.Token {
78
85
  }
79
86
  if (this.type === 'template') {
80
87
  const name = (0, string_1.removeComment)(title).trim();
81
- if (!this.normalizeTitle(name, 10, true, true).valid) {
88
+ if (!this.normalizeTitle(name, 10, { halfParsed: true, temporary: true }).valid) {
82
89
  accum.pop();
83
90
  throw new SyntaxError('Invalid template name');
84
91
  }
@@ -137,7 +144,7 @@ class TranscludeToken extends index_1.Token {
137
144
  }
138
145
  /** 获取模板或模块名 */
139
146
  #getTitle() {
140
- const isTemplate = this.type === 'template', title = this.normalizeTitle(this.childNodes[isTemplate ? 0 : 1].toString(true), isTemplate ? 10 : 828, true);
147
+ const isTemplate = this.type === 'template', title = this.normalizeTitle(this.childNodes[isTemplate ? 0 : 1].toString(true), isTemplate ? 10 : 828, { temporary: true });
141
148
  return title;
142
149
  }
143
150
  /**
@@ -177,7 +184,7 @@ class TranscludeToken extends index_1.Token {
177
184
  toString(skip) {
178
185
  return `{{${this.modifier}${this.type === 'magic-word'
179
186
  ? this.firstChild.toString(skip)
180
- + (this.length === 1 ? '' : ':')
187
+ + (this.length === 1 ? '' : this.#colon)
181
188
  + this.childNodes.slice(1).map(child => child.toString(skip)).join('|')
182
189
  : super.toString(skip, '|')}}}`;
183
190
  }
@@ -187,7 +194,9 @@ class TranscludeToken extends index_1.Token {
187
194
  return type === 'magic-word' && name === 'vardefine'
188
195
  ? ''
189
196
  : `{{${modifier}${type === 'magic-word'
190
- ? firstChild.text() + (length === 1 ? '' : ':') + (0, string_1.text)(childNodes.slice(1), '|')
197
+ ? firstChild.text()
198
+ + (length === 1 ? '' : this.#colon)
199
+ + (0, string_1.text)(childNodes.slice(1), '|')
191
200
  : super.text('|')}}}`;
192
201
  }
193
202
  /** @private */
@@ -197,6 +206,8 @@ class TranscludeToken extends index_1.Token {
197
206
  return this.modifier.length + 2;
198
207
  case 'title':
199
208
  return this.#title;
209
+ case 'colon':
210
+ return this.#colon;
200
211
  default:
201
212
  return super.getAttribute(key);
202
213
  }
@@ -37,7 +37,14 @@ exports.isToken = isToken;
37
37
  * @param inserted 插入的子节点
38
38
  */
39
39
  const setChildNodes = (parent, position, deleteCount, inserted = []) => {
40
- const nodes = parent.getChildNodes(), removed = nodes.splice(position, deleteCount, ...inserted);
40
+ let nodes = parent.getChildNodes(), removed;
41
+ if (nodes.length === deleteCount) {
42
+ removed = nodes;
43
+ nodes = inserted;
44
+ }
45
+ else {
46
+ removed = nodes.splice(position, deleteCount, ...inserted);
47
+ }
41
48
  for (let i = 0; i < inserted.length; i++) {
42
49
  const node = inserted[i];
43
50
  node.setAttribute('parentNode', parent);
@@ -46,6 +53,9 @@ const setChildNodes = (parent, position, deleteCount, inserted = []) => {
46
53
  }
47
54
  nodes[position - 1]?.setAttribute('nextSibling', nodes[position]);
48
55
  nodes[position + inserted.length]?.setAttribute('previousSibling', nodes[position + inserted.length - 1]);
56
+ if (nodes === inserted) {
57
+ parent.setAttribute('childNodes', nodes);
58
+ }
49
59
  return removed;
50
60
  };
51
61
  exports.setChildNodes = setChildNodes;
package/dist/util/lint.js CHANGED
@@ -61,33 +61,34 @@ const cache = (store, compute, update) => {
61
61
  return result;
62
62
  };
63
63
  exports.cache = cache;
64
- let htmlData;
65
- try {
66
- exports.htmlData = htmlData = require('vscode-html-languageservice')
67
- .getDefaultHTMLDataProvider();
68
- }
69
- catch {
70
- /**
71
- * 获取HTML属性值可选列表
72
- * @param tag 标签名
73
- * @param attribute 属性名
74
- */
75
- const provideValues = (tag, attribute) => {
76
- if (tag === 'ol' && attribute === 'type') {
77
- return ['1', 'a', 'A', 'i', 'I'];
78
- }
79
- else if (tag === 'th' && attribute === 'scope') {
80
- return ['row', 'col', 'rowgroup', 'colgroup'];
81
- }
82
- else if (attribute === 'dir') {
83
- return ['ltr', 'rtl', 'auto'];
84
- }
85
- return attribute === 'aria-hidden' ? ['true', 'false'] : [];
86
- };
87
- exports.htmlData = htmlData = {
88
- /** @implements */
89
- provideValues(tag, attribute) {
90
- return provideValues(tag, attribute).map(value => ({ name: value }));
91
- },
92
- };
93
- }
64
+ exports.htmlData = (() => {
65
+ try {
66
+ return require('vscode-html-languageservice')
67
+ .getDefaultHTMLDataProvider();
68
+ }
69
+ catch {
70
+ /**
71
+ * 获取HTML属性值可选列表
72
+ * @param tag 标签名
73
+ * @param attribute 属性名
74
+ */
75
+ const provideValues = (tag, attribute) => {
76
+ if (tag === 'ol' && attribute === 'type') {
77
+ return ['1', 'a', 'A', 'i', 'I'];
78
+ }
79
+ else if (tag === 'th' && attribute === 'scope') {
80
+ return ['row', 'col', 'rowgroup', 'colgroup'];
81
+ }
82
+ else if (attribute === 'dir') {
83
+ return ['ltr', 'rtl', 'auto'];
84
+ }
85
+ return attribute === 'aria-hidden' ? ['true', 'false'] : [];
86
+ };
87
+ return {
88
+ /** @implements */
89
+ provideValues(tag, attribute) {
90
+ return provideValues(tag, attribute).map(value => ({ name: value }));
91
+ },
92
+ };
93
+ }
94
+ })();
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.noWrap = exports.decodeNumber = exports.decodeHtml = exports.text = exports.escapeRegExp = exports.removeComment = exports.tidy = exports.extUrlChar = exports.extUrlCharFirst = exports.zs = exports.rawurldecode = void 0;
3
+ exports.noWrap = exports.decodeNumber = exports.decodeHtml = exports.decodeHtmlBasic = exports.text = exports.escapeRegExp = exports.removeComment = exports.tidy = exports.extUrlChar = exports.extUrlCharFirst = exports.zs = exports.rawurldecode = void 0;
4
4
  var common_1 = require("@bhsd/common");
5
5
  Object.defineProperty(exports, "rawurldecode", { enumerable: true, get: function () { return common_1.rawurldecode; } });
6
6
  exports.zs = String.raw ` \xA0\u1680\u2000-\u200A\u202F\u205F\u3000`;
@@ -27,9 +27,8 @@ exports.escapeRegExp = factory(/[\\{}()|.?*+^$[\]]/gu, String.raw `\$&`);
27
27
  const text = (childNodes, separator = '') => childNodes.map(child => typeof child === 'string' ? child : child.text()).join(separator);
28
28
  exports.text = text;
29
29
  const names = { lt: '<', gt: '>', lbrack: '[', rbrack: ']', lbrace: '{', rbrace: '}', nbsp: ' ', amp: '&', quot: '"' };
30
- /* istanbul ignore next */
31
30
  /** decode HTML entities */
32
- const decodeHtmlBasic = factory(/&(?:#(\d+|[Xx][\da-fA-F]+)|([lg]t|[LG]T|[lr]brac[ke]|nbsp|amp|AMP|quot|QUOT));/gu, (_, code, name) => code
31
+ exports.decodeHtmlBasic = factory(/&(?:#(\d+|[Xx][\da-fA-F]+)|([lg]t|[LG]T|[lr]brac[ke]|nbsp|amp|AMP|quot|QUOT));/gu, (_, code, name) => code
33
32
  ? String.fromCodePoint(Number((/^x/iu.test(code) ? '0' : '') + code))
34
33
  : names[name.toLowerCase()]);
35
34
  /**
@@ -48,7 +47,7 @@ const decodeHtml = (str) => {
48
47
  }
49
48
  /* istanbul ignore next */
50
49
  /* NOT FOR BROWSER ONLY END */
51
- return decodeHtmlBasic(str);
50
+ return (0, exports.decodeHtmlBasic)(str);
52
51
  };
53
52
  exports.decodeHtml = decodeHtml;
54
53
  /** decode numbered HTML entities */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wikilint",
3
- "version": "2.18.1",
3
+ "version": "2.18.3",
4
4
  "description": "A Node.js linter for MediaWiki markup",
5
5
  "keywords": [
6
6
  "mediawiki",
@@ -17,7 +17,6 @@
17
17
  "files": [
18
18
  "/errors/README",
19
19
  "/config/",
20
- "!/config/jawiki.json",
21
20
  "/data/",
22
21
  "/i18n/",
23
22
  "/coverage/badge.svg",
@@ -66,7 +65,7 @@
66
65
  ]
67
66
  },
68
67
  "dependencies": {
69
- "@bhsd/common": "^0.8.0",
68
+ "@bhsd/common": "^0.9.0",
70
69
  "vscode-languageserver-types": "^3.17.5"
71
70
  },
72
71
  "optionalDependencies": {