wikilint 2.3.1 → 2.3.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.
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
+ import type { Config, LintError, Parser as ParserBase } from './base';
1
2
  import type { Title } from './lib/title';
2
3
  import type { Token } from './internal';
3
- import type { Config, LintError, Parser as ParserBase } from './base';
4
4
  declare interface Parser extends ParserBase {
5
5
  /**
6
6
  * 规范化页面标题
@@ -3,23 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.AstElement = void 0;
4
4
  const string_1 = require("../util/string");
5
5
  const node_1 = require("./node");
6
- const lintIgnoredExt = new Set([
7
- 'nowiki',
8
- 'pre',
9
- 'charinsert',
10
- 'score',
11
- 'syntaxhighlight',
12
- 'source',
13
- 'math',
14
- 'chem',
15
- 'ce',
16
- 'graph',
17
- 'mapframe',
18
- 'maplink',
19
- 'quiz',
20
- 'templatedata',
21
- 'timeline',
22
- ]);
23
6
  /** 类似HTMLElement */
24
7
  class AstElement extends node_1.AstNode {
25
8
  /** 子节点总数 */
@@ -123,11 +106,6 @@ class AstElement extends node_1.AstNode {
123
106
  * @param start
124
107
  */
125
108
  lint(start = this.getAbsoluteIndex()) {
126
- const { SyntaxToken } = require('../src/syntax');
127
- if (this instanceof SyntaxToken || this.constructor.hidden
128
- || this.type === 'ext-inner' && lintIgnoredExt.has(this.name)) {
129
- return [];
130
- }
131
109
  const errors = [];
132
110
  for (let i = 0, cur = start + this.getAttribute('padding'); i < this.length; i++) {
133
111
  const child = this.childNodes[i];
package/dist/lib/text.js CHANGED
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.AstText = void 0;
4
4
  const Parser = require("../index");
5
5
  const node_1 = require("./node");
6
- const errorSyntax = /https?[:/]\/+|\{+|\}+|\[{2,}|\[(?![^[]*\])|(?<=^|\])([^[]*?)\]+|\]{2,}|<\s*\/?([a-z]\w*)/giu, errorSyntaxUrl = /\{+|\}+|\[{2,}|\[(?![^[]*\])|(?<=^|\])([^[]*?)\]+|\]{2,}|<\s*\/?([a-z]\w*)/giu, disallowedTags = [
6
+ const errorSyntax = /<\s*\/?([a-z]\w*)|\{+|\}+|\[{2,}|\[(?![^[]*\])|(?<=^|\])([^[]*?)\]+|\]{2,}|https?[:/]\/+/giu, errorSyntaxUrl = /<\s*\/?([a-z]\w*)|\{+|\}+|\[{2,}|\[(?![^[]*\])|(?<=^|\])([^[]*?)\]+|\]{2,}/giu, disallowedTags = [
7
7
  'html',
8
8
  'head',
9
9
  'style',
@@ -53,14 +53,26 @@ class AstText extends node_1.AstNode {
53
53
  */
54
54
  lint(start = this.getAbsoluteIndex()) {
55
55
  const { data, parentNode, nextSibling, previousSibling } = this;
56
- const { type, name } = parentNode, nextType = nextSibling?.type, previousType = previousSibling?.type, errorRegex = type === 'free-ext-link' || type === 'ext-link-url' || type === 'image-parameter' && name === 'link'
57
- || type === 'attr-value'
58
- ? errorSyntaxUrl
59
- : errorSyntax, errors = [...data.matchAll(errorRegex)], { ext, html } = this.getRootNode().getAttribute('config');
56
+ const { NowikiToken } = require('../src/nowiki');
57
+ const { type, name } = parentNode, nextType = nextSibling?.type, previousType = previousSibling?.type;
58
+ let errorRegex;
59
+ if (type === 'ext-inner' && (name === 'pre' || parentNode instanceof NowikiToken)) {
60
+ errorRegex = new RegExp(`<\\s*\\/?(${name})\\b`, 'giu');
61
+ }
62
+ else if (type === 'free-ext-link'
63
+ || type === 'ext-link-url'
64
+ || type === 'image-parameter' && name === 'link'
65
+ || type === 'attr-value') {
66
+ errorRegex = errorSyntaxUrl;
67
+ }
68
+ else {
69
+ errorRegex = errorSyntax;
70
+ }
71
+ const errors = [...data.matchAll(errorRegex)], { ext, html } = this.getRootNode().getAttribute('config');
60
72
  if (errors.length > 0) {
61
- const root = this.getRootNode(), { top, left } = root.posFromIndex(start), tags = new Set([ext, html, disallowedTags].flat(2));
73
+ const root = this.getRootNode(), { top, left } = root.posFromIndex(start), tags = new Set(['onlyinclude', 'noinclude', 'includeonly', ext, html, disallowedTags].flat(2));
62
74
  return errors
63
- .map(({ 0: error, 1: prefix, 2: tag, index }) => {
75
+ .map(({ 0: error, 1: tag, 2: prefix, index }) => {
64
76
  if (prefix) {
65
77
  const { length } = prefix;
66
78
  index += length;
@@ -69,7 +81,8 @@ class AstText extends node_1.AstNode {
69
81
  const startIndex = start + index, lines = data.slice(0, index).split('\n'), startLine = lines.length + top - 1, line = lines.at(-1), startCol = lines.length === 1 ? left + line.length : line.length, { 0: char, length } = error, endIndex = startIndex + length, rootStr = String(root), nextChar = rootStr[endIndex], previousChar = rootStr[startIndex - 1], severity = length > 1 && (char !== '<' || /[\s/>]/u.test(nextChar ?? ''))
70
82
  || char === '{' && (nextChar === char || previousChar === '-')
71
83
  || char === '}' && (previousChar === char || nextChar === '-')
72
- || char === '[' && (nextChar === char || type === 'ext-link-text'
84
+ || char === '[' && (nextChar === char
85
+ || type === 'ext-link-text'
73
86
  || !data.slice(index + 1).trim() && nextType === 'free-ext-link')
74
87
  || char === ']' && (previousChar === char
75
88
  || !data.slice(0, index).trim() && previousType === 'free-ext-link')
@@ -14,6 +14,10 @@ const hidden = (constructor) => {
14
14
  text() {
15
15
  return '';
16
16
  }
17
+ /** @override */
18
+ lint() {
19
+ return [];
20
+ }
17
21
  }
18
22
  return AnyHiddenToken;
19
23
  };
@@ -17,8 +17,7 @@ const parseBraces = (wikitext, config = Parser.getConfig(), accum = []) => {
17
17
  const source = `${config.excludes?.includes('heading') ? '' : '^(\0\\d+c\x7F)*={1,6}|'}\\[\\[|\\{{2,}|-\\{(?!\\{)`, { parserFunction: [, , , subst] } = config, stack = [], closes = { '=': '\n', '{': '\\}{2,}|\\|', '-': '\\}-', '[': '\\]\\]' }, marks = new Map([['!', '!'], ['!!', '+'], ['(!', '{'], ['!)', '}'], ['!-', '-'], ['=', '~']]);
18
18
  let regex = new RegExp(source, 'gmu'), mt = regex.exec(wikitext), moreBraces = wikitext.includes('}}'), lastIndex;
19
19
  while (mt
20
- || lastIndex !== undefined && lastIndex <= wikitext.length
21
- && stack.at(-1)?.[0]?.startsWith('=')) {
20
+ || lastIndex !== undefined && lastIndex <= wikitext.length && stack.at(-1)?.[0]?.startsWith('=')) {
22
21
  if (mt?.[1]) {
23
22
  const [, { length }] = mt;
24
23
  mt[0] = mt[0].slice(length);
@@ -13,7 +13,7 @@ const category_1 = require("../src/link/category");
13
13
  */
14
14
  const parseLinks = (wikitext, config = Parser.getConfig(), accum = []) => {
15
15
  const { parseQuotes } = require('./quotes');
16
- const regex = /^((?:(?!\0\d+!\x7F)[^\n[\]{}|])+)(?:(\||\0\d+!\x7F)(.*?[^\]]))?\]\](.*)$/su, regexImg = /^((?:(?!\0\d+!\x7F)[^\n[\]{}|])+)(\||\0\d+!\x7F)(.*)$/su, regexExt = new RegExp(`^\\s*(?:${config.protocol})`, 'iu'), bits = wikitext.split('[[');
16
+ const regex = /^((?:(?!\0\d+!\x7F)[^\n[\]{}|])+)(?:(\||\0\d+!\x7F)(.*?[^\]]))?\]\](.*)$/su, regexImg = /^((?:(?!\0\d+!\x7F)[^\n[\]{}|])+)(\||\0\d+!\x7F)(.*)$/su, regexExt = new RegExp(`^\\s*(?:${config.protocol}|//)`, 'iu'), bits = wikitext.split('[[');
17
17
  let s = bits.shift();
18
18
  for (let i = 0; i < bits.length; i++) {
19
19
  let mightBeImg = false, link, delimiter, text, after;
@@ -201,7 +201,7 @@ class AttributeToken extends index_1.Token {
201
201
  if (!balanced) {
202
202
  const root = this.getRootNode();
203
203
  rect = { start, ...root.posFromIndex(start) };
204
- const e = (0, lint_1.generateForChild)(lastChild, rect, 'unclosed quotes', 'warning');
204
+ const e = (0, lint_1.generateForChild)(lastChild, rect, Parser.msg('unclosed $1', 'quotes'), 'warning');
205
205
  errors.push({
206
206
  ...e,
207
207
  startIndex: e.startIndex - 1,
@@ -210,7 +210,8 @@ class AttributeToken extends index_1.Token {
210
210
  }
211
211
  if (extAttrs[tag] && !extAttrs[tag].has(name)
212
212
  || (type === 'ext-attr' ? tag in htmlAttrs : !/\{\{[^{]+\}\}/u.test(name))
213
- && !htmlAttrs[tag]?.has(name) && !/^(?:xmlns:[\w:.-]+|data-[^:]*)$/u.test(name)
213
+ && !htmlAttrs[tag]?.has(name)
214
+ && !/^(?:xmlns:[\w:.-]+|data-[^:]*)$/u.test(name)
214
215
  && (tag === 'meta' || tag === 'link' || !commonHtmlAttrs.has(name))) {
215
216
  rect ??= { start, ...this.getRootNode().posFromIndex(start) };
216
217
  errors.push((0, lint_1.generateForChild)(firstChild, rect, 'illegal attribute name'));
@@ -6,6 +6,7 @@ declare const ConverterToken_base: (abstract new (...args: any[]) => {
6
6
  readonly firstChild: Parser.ConverterFlagsToken;
7
7
  toString(omit?: Set<string> | undefined, separator?: string | undefined): string;
8
8
  text(separator?: string | undefined): string;
9
+ lint(start?: number | undefined): Parser.LintError[];
9
10
  }) & typeof Parser.Token;
10
11
  /**
11
12
  * 转换
@@ -52,7 +52,9 @@ class ConverterFlagsToken extends index_1.Token {
52
52
  const rect = { start, ...this.getRootNode().posFromIndex(start) }, { childNodes, length } = this;
53
53
  for (let i = 0; i < length; i++) {
54
54
  const child = childNodes[i], flag = child.text().trim();
55
- if (flag && !variantFlags.has(flag) && !unknownFlags.has(flag)
55
+ if (flag
56
+ && !variantFlags.has(flag)
57
+ && !unknownFlags.has(flag)
56
58
  && (variantFlags.size > 0 || !validFlags.has(flag))) {
57
59
  errors.push((0, lint_1.generateForChild)(child, rect, 'invalid conversion flag'));
58
60
  }
@@ -5,6 +5,7 @@ declare const ExtLinkToken_base: (abstract new (...args: any[]) => {
5
5
  readonly firstChild: Parser.MagicLinkToken;
6
6
  toString(omit?: Set<string> | undefined, separator?: string | undefined): string;
7
7
  text(separator?: string | undefined): string;
8
+ lint(start?: number | undefined): Parser.LintError[];
8
9
  }) & typeof Parser.Token;
9
10
  /**
10
11
  * 外链
@@ -1,6 +1,7 @@
1
1
  import { Token } from './index';
2
2
  declare const HiddenToken_base: ((abstract new (...args: any[]) => {
3
3
  text(): string;
4
+ lint(): import("..").LintError[];
4
5
  toString(omit?: Set<string> | undefined, separator?: string | undefined): string;
5
6
  }) & {
6
7
  readonly hidden: true;
package/dist/src/html.js CHANGED
@@ -39,8 +39,11 @@ class HtmlToken extends index_1.Token {
39
39
  }
40
40
  /** @override */
41
41
  text() {
42
- const { closing } = this;
43
- return `<${closing ? '/' : ''}${this.#tag}${closing ? '' : super.text()}${this.#selfClosing ? '/' : ''}>`;
42
+ const { closing, name } = this, tag = `${this.#tag}${closing ? '' : super.text()}`, { html } = this.getAttribute('config');
43
+ if (html[2].includes(name)) {
44
+ return closing && name !== 'br' ? '' : `<${tag}>`;
45
+ }
46
+ return `<${closing ? '/' : ''}${tag}${this.#selfClosing && html[1].includes(name) ? '/' : ''}>`;
44
47
  }
45
48
  /** @private */
46
49
  getAttribute(key) {
@@ -57,7 +57,9 @@ class FileToken extends base_1.LinkBaseToken {
57
57
  return visibleNodes.length !== 1 || visibleNodes[0].type !== 'arg';
58
58
  }), keys = [...new Set(args.map(({ name }) => name))].filter(key => key !== 'invalid'), frameKeys = keys.filter(key => frame.has(key)), horizAlignKeys = keys.filter(key => horizAlign.has(key)), vertAlignKeys = keys.filter(key => vertAlign.has(key));
59
59
  if (args.length === keys.length
60
- && frameKeys.length < 2 && horizAlignKeys.length < 2 && vertAlignKeys.length < 2) {
60
+ && frameKeys.length < 2
61
+ && horizAlignKeys.length < 2
62
+ && vertAlignKeys.length < 2) {
61
63
  return errors;
62
64
  }
63
65
  const rect = { start, ...this.getRootNode().posFromIndex(start) };
@@ -4,6 +4,7 @@ import type { LintError } from '../../base';
4
4
  import type { Token } from '../index';
5
5
  declare const CommentToken_base: ((abstract new (...args: any[]) => {
6
6
  text(): string;
7
+ lint(): Parser.LintError[];
7
8
  toString(omit?: Set<string> | undefined, separator?: string | undefined): string;
8
9
  }) & {
9
10
  readonly hidden: true;
@@ -21,7 +21,7 @@ class CommentToken extends (0, hidden_1.hidden)(base_1.NowikiBaseToken) {
21
21
  }
22
22
  /** @override */
23
23
  lint(start = this.getAbsoluteIndex()) {
24
- return this.closed ? [] : [(0, lint_1.generateForSelf)(this, { start }, 'unclosed HTML comment')];
24
+ return this.closed ? [] : [(0, lint_1.generateForSelf)(this, { start }, Parser.msg('unclosed $1', 'HTML comment'))];
25
25
  }
26
26
  /** @private */
27
27
  toString(omit) {
@@ -3,6 +3,7 @@ import { NowikiBaseToken } from './base';
3
3
  import type { Token } from '../index';
4
4
  declare const DoubleUnderscoreToken_base: ((abstract new (...args: any[]) => {
5
5
  text(): string;
6
+ lint(): Parser.LintError[];
6
7
  toString(omit?: Set<string> | undefined, separator?: string | undefined): string;
7
8
  }) & {
8
9
  readonly hidden: true;
@@ -1,6 +1,7 @@
1
1
  import { NowikiBaseToken } from './base';
2
2
  declare const NoincludeToken_base: ((abstract new (...args: any[]) => {
3
3
  text(): string;
4
+ lint(): import("../..").LintError[];
4
5
  toString(omit?: Set<string> | undefined, separator?: string | undefined): string;
5
6
  }) & {
6
7
  readonly hidden: true;
@@ -1,10 +1,13 @@
1
1
  import * as Parser from '../index';
2
2
  import { Token } from './index';
3
+ import type { LintError } from '../base';
3
4
  declare type SyntaxTypes = 'plain' | 'heading-trail' | 'magic-word-name' | 'table-syntax';
4
5
  /** 满足特定语法格式的plain Token */
5
6
  export declare class SyntaxToken extends Token {
6
7
  type: SyntaxTypes;
7
8
  /** @param pattern 语法正则 */
8
9
  constructor(wikitext: string | undefined, pattern: RegExp, type?: SyntaxTypes, config?: Parser.Config, accum?: Token[], acceptable?: Acceptable);
10
+ /** @override */
11
+ lint(): LintError[];
9
12
  }
10
13
  export {};
@@ -10,5 +10,9 @@ class SyntaxToken extends index_1.Token {
10
10
  super(wikitext, config, accum, acceptable);
11
11
  this.type = type;
12
12
  }
13
+ /** @override */
14
+ lint() {
15
+ return [];
16
+ }
13
17
  }
14
18
  exports.SyntaxToken = SyntaxToken;
@@ -29,7 +29,7 @@ class TableToken extends trBase_1.TrBaseToken {
29
29
  lint(start = this.getAbsoluteIndex()) {
30
30
  const errors = super.lint(start);
31
31
  if (!this.closed) {
32
- errors.push((0, lint_1.generateForChild)(this.firstChild, { start }, 'unclosed table'));
32
+ errors.push((0, lint_1.generateForChild)(this.firstChild, { start }, Parser.msg('unclosed $1', 'table')));
33
33
  }
34
34
  return errors;
35
35
  }
@@ -16,7 +16,8 @@ class TrBaseToken extends base_1.TableBaseToken {
16
16
  isArg = (token) => token.type === 'arg',
17
17
  /** @ignore */
18
18
  isTransclude = (token) => token.type === 'magic-word';
19
- if (!first || tdPattern.test(String(first))
19
+ if (!first
20
+ || tdPattern.test(String(first))
20
21
  || isArg(first) && tdPattern.test(first.default || '')) {
21
22
  return errors;
22
23
  }
@@ -1,8 +1,10 @@
1
1
  import * as Parser from '../../index';
2
2
  import { TagPairToken } from './index';
3
+ import type { LintError } from '../../base';
3
4
  import type { AstText, Token } from '../../internal';
4
5
  declare const IncludeToken_base: ((abstract new (...args: any[]) => {
5
6
  text(): string;
7
+ lint(): Parser.LintError[];
6
8
  toString(omit?: Set<string> | undefined, separator?: string | undefined): string;
7
9
  }) & {
8
10
  readonly hidden: true;
@@ -23,5 +25,7 @@ export declare class IncludeToken extends IncludeToken_base {
23
25
  * @param closed 是否封闭
24
26
  */
25
27
  constructor(name: string, attr?: string, inner?: string, closed?: string, config?: Parser.Config, accum?: Token[]);
28
+ /** @override */
29
+ lint(start?: number): LintError[];
26
30
  }
27
31
  export {};
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.IncludeToken = void 0;
4
+ const lint_1 = require("../../util/lint");
4
5
  const hidden_1 = require("../../mixin/hidden");
5
6
  const Parser = require("../../index");
6
7
  const index_1 = require("./index");
@@ -19,5 +20,9 @@ class IncludeToken extends (0, hidden_1.hidden)(index_1.TagPairToken) {
19
20
  constructor(name, attr = '', inner, closed, config = Parser.getConfig(), accum = []) {
20
21
  super(name, attr, inner ?? '', inner === undefined ? closed : closed ?? '', config, accum);
21
22
  }
23
+ /** @override */
24
+ lint(start = this.getAbsoluteIndex()) {
25
+ return this.closed ? [] : [(0, lint_1.generateForSelf)(this, { start }, Parser.msg('unclosed $1', `<${this.name}>`))];
26
+ }
22
27
  }
23
28
  exports.IncludeToken = IncludeToken;
@@ -35,10 +35,11 @@ class TranscludeToken extends index_1.Token {
35
35
  title = arg.join(':').slice(mt.length);
36
36
  }
37
37
  }
38
- if (title.includes(':') || parts.length === 0 && !this.#raw) {
39
- const [magicWord, ...arg] = title.split(':'), cleaned = (0, string_1.removeComment)(magicWord), name = cleaned[arg.length > 0 ? 'trimStart' : 'trim'](), isSensitive = sensitive.includes(name), canonicalCame = insensitive[name.toLowerCase()];
38
+ const isFunction = title.includes(':');
39
+ if (isFunction || parts.length === 0 && !this.#raw) {
40
+ const [magicWord, ...arg] = title.split(':'), cleaned = (0, string_1.removeComment)(magicWord), name = cleaned[arg.length > 0 ? 'trimStart' : 'trim'](), isSensitive = sensitive.includes(name), canonicalCame = isFunction && insensitive[name.toLowerCase()];
40
41
  if (isSensitive || canonicalCame) {
41
- this.setAttribute('name', canonicalCame ?? name.toLowerCase());
42
+ this.setAttribute('name', canonicalCame || name.toLowerCase());
42
43
  this.type = 'magic-word';
43
44
  const pattern = new RegExp(`^\\s*${name}\\s*$`, isSensitive ? 'u' : 'iu'), token = new syntax_1.SyntaxToken(magicWord, pattern, 'magic-word-name', config, accum, {});
44
45
  super.insertAt(token);
@@ -91,9 +92,9 @@ class TranscludeToken extends index_1.Token {
91
92
  return false;
92
93
  }
93
94
  const magicWord = lcModifier.slice(0, -1).toLowerCase(), isRaw = raw.includes(magicWord), isSubst = subst.includes(magicWord);
94
- if (this.#raw && isRaw || !this.#raw && (isSubst || modifier === '')
95
- || this.length > 1
96
- && (isRaw || isSubst || modifier === '')) {
95
+ if (this.#raw && isRaw
96
+ || !this.#raw && (isSubst || modifier === '')
97
+ || this.length > 1 && (isRaw || isSubst || modifier === '')) {
97
98
  this.setAttribute('modifier', modifier);
98
99
  this.#raw = isRaw;
99
100
  return Boolean(modifier);
package/i18n/zh-hans.json CHANGED
@@ -14,6 +14,7 @@
14
14
  "frame": "框架",
15
15
  "full-width punctuation": "全角标点",
16
16
  "horizontal-alignment": "水平对齐",
17
+ "HTML comment": "HTML注释",
17
18
  "HTML tag in table attributes": "表格属性中的HTML标签",
18
19
  "illegal attribute name": "非法的属性名",
19
20
  "illegal module name": "非法的模块名称",
@@ -31,13 +32,13 @@
31
32
  "missing module name": "缺少模块名称",
32
33
  "nonzero tabindex": "不为0的tabindex",
33
34
  "nothing should be in <$1>": "<$1>标签内不应有任何内容",
35
+ "quotes": "引号",
34
36
  "section header in a HTML tag": "HTML标签属性中的段落标题",
37
+ "table": "表格",
35
38
  "tag that is both closing and self-closing": "同时闭合和自封闭的标签",
36
39
  "template in an internal link target": "内链目标包含模板",
37
40
  "unbalanced \"=\" in a section header": "段落标题中不平衡的\"=\"",
38
- "unclosed HTML comment": "未闭合的HTML注释",
39
- "unclosed quotes": "未闭合的引号",
40
- "unclosed table": "未闭合的表格",
41
+ "unclosed $1": "未闭合的$1",
41
42
  "unclosed tag": "未闭合的标签",
42
43
  "unescaped query string in an anonymous parameter": "匿名参数中未转义的查询参数",
43
44
  "unexpected template argument": "未预期的模板参数",
package/i18n/zh-hant.json CHANGED
@@ -14,6 +14,7 @@
14
14
  "frame": "框架",
15
15
  "full-width punctuation": "全形標點",
16
16
  "horizontal-alignment": "水瓶對齊",
17
+ "HTML comment": "HTML註釋",
17
18
  "HTML tag in table attributes": "表格屬性中的HTML標籤",
18
19
  "illegal attribute name": "非法的屬性名",
19
20
  "illegal module name": "非法的模組名稱",
@@ -31,13 +32,13 @@
31
32
  "missing module name": "缺少模組名稱",
32
33
  "nonzero tabindex": "不為0的tabindex",
33
34
  "nothing should be in <$1>": "<$1>標籤內不應有任何內容",
35
+ "quotes": "引號",
34
36
  "section header in a HTML tag": "HTML標籤屬性中的段落標題",
37
+ "table": "表格",
35
38
  "tag that is both closing and self-closing": "同時閉合和自封閉的標籤",
36
39
  "template in an internal link target": "內部連結目標包含模板",
37
40
  "unbalanced \"=\" in a section header": "段落標題中不平衡的\"=\"",
38
- "unclosed HTML comment": "未閉合的HTML註釋",
39
- "unclosed quotes": "未閉合的引號",
40
- "unclosed table": "未閉合的表格",
41
+ "unclosed $1": "未閉合的$1",
41
42
  "unclosed tag": "未閉合的標籤",
42
43
  "unescaped query string in an anonymous parameter": "匿名參數中未轉義的查詢參數",
43
44
  "unexpected template argument": "未預期的模板參數",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wikilint",
3
- "version": "2.3.1",
3
+ "version": "2.3.3",
4
4
  "description": "A Node.js linter for MediaWiki markup",
5
5
  "keywords": [
6
6
  "mediawiki",