diff --git a/config/default.json b/config/default.json index 74d28a8f..d4f1ff35 100644 --- a/config/default.json +++ b/config/default.json @@ -140,10 +140,6 @@ "711": "TimedText talk", "828": "Module", "829": "Module talk", - "2300": "Gadget", - "2301": "Gadget talk", - "2302": "Gadget definition", - "2303": "Gadget definition talk", "2600": "Topic" }, "nsid": { @@ -300,11 +296,7 @@ "模組討論": 829, "模组对话": 829, "模组讨论": 829, - "モジュール・トーク": 829, - "gadget": 2300, - "gadget talk": 2301, - "gadget definition": 2302, - "gadget definition talk": 2303 + "モジュール・トーク": 829 }, "parserFunction": [ { diff --git a/config/enwiki.json b/config/enwiki.json index f2689407..113e3b8b 100644 --- a/config/enwiki.json +++ b/config/enwiki.json @@ -125,11 +125,7 @@ "710": "TimedText", "711": "TimedText talk", "828": "Module", - "829": "Module talk", - "2300": "Gadget", - "2301": "Gadget talk", - "2302": "Gadget definition", - "2303": "Gadget definition talk" + "829": "Module talk" }, "nsid": { "": 0, @@ -165,11 +161,7 @@ "timedtext": 710, "timedtext talk": 711, "module": 828, - "module talk": 829, - "gadget": 2300, - "gadget talk": 2301, - "gadget definition": 2302, - "gadget definition talk": 2303 + "module talk": 829 }, "parserFunction": [ { diff --git a/i18n/zh-hans.json b/i18n/zh-hans.json index d2fef698..9f412049 100644 --- a/i18n/zh-hans.json +++ b/i18n/zh-hans.json @@ -53,6 +53,7 @@ "unexpected template argument": "未预期的模板参数", "unmatched closing tag": "未匹配的闭合标签", "unnecessary URL encoding in an internal link": "内链中不必要的URL编码", + "useless attribute": "无用的属性", "useless fragment": "无用的fragment", "useless link text": "无用的链接文字", "variable anchor in a section header": "段落标题中可变的锚点", diff --git a/i18n/zh-hant.json b/i18n/zh-hant.json index ebc0170f..b1db0231 100644 --- a/i18n/zh-hant.json +++ b/i18n/zh-hant.json @@ -53,6 +53,7 @@ "unexpected template argument": "未預期的模板參數", "unmatched closing tag": "未匹配的閉合標籤", "unnecessary URL encoding in an internal link": "內部連結中不必要的URL編碼", + "useless attribute": "無用的屬性", "useless fragment": "無用的fragment", "useless link text": "無用的連結文字", "variable anchor in a section header": "段落標題中可變的錨點", diff --git a/package.json b/package.json index 2f9467af..386a31f2 100644 --- a/package.json +++ b/package.json @@ -51,7 +51,7 @@ "chalk": "^4.1.2" }, "devDependencies": { - "@bhsd/common": "^0.2.0", + "@bhsd/common": "^0.3.0", "@types/node": "^20.11.6", "v8r": "^3.0.0" }, diff --git a/src/paramTag/index.ts b/src/paramTag/index.ts index 26ca1f04..ec5f6efe 100644 --- a/src/paramTag/index.ts +++ b/src/paramTag/index.ts @@ -56,9 +56,9 @@ export abstract class ParamTagToken extends Token { override lint(start = this.getAbsoluteIndex()): LintError[] { const rect = new BoundingRect(this, start); return this.childNodes.filter(child => { - const {childNodes} = child, + const childNodes = child.childNodes.filter(({type}) => type !== 'comment'), i = childNodes.findIndex(({type}) => type !== 'text'), - str = (i >= 0 ? childNodes.slice(0, i).map(String).join('') : child.toString()).trim(); + str = childNodes.slice(0, i >= 0 ? i : undefined).map(String).join(''); return str && !(i >= 0 ? /^[a-z]+(?:\[\])?\s*(?:=|$)/iu : /^[a-z]+(?:\[\])?\s*=/iu).test(str); }).map(child => { const e = generateForChild(child, rect, 'no-ignored', Parser.msg('invalid parameter of <$1>', this.name)); diff --git a/src/paramTag/inputbox.ts b/src/paramTag/inputbox.ts index bafeefe4..799c72f3 100644 --- a/src/paramTag/inputbox.ts +++ b/src/paramTag/inputbox.ts @@ -1,12 +1,32 @@ import {parseBraces} from '../../parser/braces'; import Parser from '../../index'; import {ParamTagToken} from './index'; +import {CommentToken} from '../nowiki/comment'; +import type {Config} from '../../base'; import type {Token} from '../index'; +/** + * 解析注释 + * @param wikitext 维基文本 + * @param config + * @param accum + */ +const parseComment = (wikitext: string, config: Config, accum: Token[]): string => wikitext.replace( + /|$)/gsu, + comment => { + const str = `\0${accum.length + 1}c\x7F`, + closed = comment.endsWith('-->'); + // @ts-expect-error abstract class + new CommentToken(comment.slice(4, closed ? -3 : undefined), closed, config, accum); + return str; + }, +); + /** `` */ export abstract class InputboxToken extends ParamTagToken { /** @class */ constructor(wikitext?: string, config = Parser.getConfig(), accum: Token[] = []) { + wikitext &&= parseComment(wikitext, config, accum); const placeholder = Symbol('InputboxToken'), {length} = accum; accum.push(placeholder as unknown as Token); diff --git a/src/pre.ts b/src/pre.ts index d016e1d3..b2bf21f1 100644 --- a/src/pre.ts +++ b/src/pre.ts @@ -28,25 +28,33 @@ export abstract class PreToken extends Token { /** @class */ constructor(wikitext?: string, config = Parser.getConfig(), accum: Token[] = []) { if (wikitext) { - const opening = '', - closing = '', - {length} = opening; - let i = wikitext.indexOf(opening), - j = wikitext.indexOf(closing, i + length), + const opening = //giu, + closing = /<\/nowiki>/giu, + {length} = opening.source; + let i = opening.exec(wikitext); + if (i) { + closing.lastIndex = i.index + length; + } + let j = closing.exec(wikitext), + lastIndex = 0, str = ''; - while (i !== -1 && j !== -1) { + while (i && j) { // @ts-expect-error abstract class - new NoincludeToken(opening, config, accum); + new NoincludeToken(i[0], config, accum); // @ts-expect-error abstract class - new NoincludeToken(closing, config, accum); - str += `${wikitext.slice(0, i)}\0${accum.length - 1}n\x7F${ - wikitext.slice(i + length, j) + new NoincludeToken(j[0], config, accum); + str += `${wikitext.slice(lastIndex, i.index)}\0${accum.length - 1}n\x7F${ + wikitext.slice(i.index + length, j.index) }\0${accum.length}n\x7F`; - wikitext = wikitext.slice(j + length + 1); - i = wikitext.indexOf(opening); - j = wikitext.indexOf(closing, i + length); + lastIndex = j.index + length + 1; + opening.lastIndex = lastIndex; + i = opening.exec(wikitext); + if (i) { + closing.lastIndex = i.index + length; + } + j = closing.exec(wikitext); } - wikitext = str + wikitext; + wikitext = str + wikitext.slice(lastIndex); } super(wikitext, config, accum, { }); diff --git a/src/tagPair/include.ts b/src/tagPair/include.ts index 1083c1f5..2d1a61b4 100644 --- a/src/tagPair/include.ts +++ b/src/tagPair/include.ts @@ -1,4 +1,5 @@ -import {generateForSelf} from '../../util/lint'; +import {generateForSelf, generateForChild} from '../../util/lint'; +import {BoundingRect} from '../../lib/rect'; import {hiddenToken} from '../../mixin/hidden'; import Parser from '../../index'; import {TagPairToken} from './index'; @@ -36,17 +37,31 @@ export abstract class IncludeToken extends TagPairToken { /** @private */ override lint(start = this.getAbsoluteIndex()): LintError[] { - if (this.closed) { - return []; + const errors: LintError[] = [], + {firstChild, closed, name} = this, + rect = new BoundingRect(this, start); + if (firstChild.data.trim()) { + const e = generateForChild(firstChild, rect, 'no-ignored', 'useless attribute', 'warning'); + e.suggestions = [ + { + desc: 'remove', + range: [e.startIndex, e.endIndex], + text: '', + }, + ]; + errors.push(e); } - const e = generateForSelf(this, {start}, 'unclosed-comment', Parser.msg('unclosed $1', `<${this.name}>`)); - e.suggestions = [ - { - desc: 'close', - range: [e.endIndex, e.endIndex], - text: ``, - }, - ]; - return [e]; + if (!closed) { + const e = generateForSelf(this, rect, 'unclosed-comment', Parser.msg('unclosed $1', `<${name}>`)); + e.suggestions = [ + { + desc: 'close', + range: [e.endIndex, e.endIndex], + text: ``, + }, + ]; + errors.push(e); + } + return errors; } }