UNPKG

wikiparser-node

Version:

A Node.js parser for MediaWiki markup with AST

108 lines (107 loc) 5.08 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.parseCommentAndExt = void 0; const common_1 = require("@bhsd/common"); const string_1 = require("../util/string"); const onlyinclude_1 = require("../src/onlyinclude"); const noinclude_1 = require("../src/nowiki/noinclude"); const translate_1 = require("../src/tagPair/translate"); const include_1 = require("../src/tagPair/include"); const ext_1 = require("../src/tagPair/ext"); const comment_1 = require("../src/nowiki/comment"); /* NOT FOR BROWSER */ const constants_1 = require("../util/constants"); /* NOT FOR BROWSER END */ const onlyincludeLeft = '<onlyinclude>', onlyincludeRight = '</onlyinclude>', { length } = onlyincludeLeft, getRegex = [false, true].map(includeOnly => { const noincludeRegex = includeOnly ? 'includeonly' : '(?:no|only)include', includeRegex = includeOnly ? 'noinclude' : 'includeonly'; // eslint-disable-next-line @typescript-eslint/no-unused-expressions /<!--[\s\S]*?(?:-->|$)|<foo(?:\s[^>]*)?\/?>|<\/foo\s*>|<(bar)(\s[^>]*?)?(?:\/>|>([\s\S]*?)<\/(\1\s*)>)|<(baz)(\s[^>]*?)?(?:\/>|>([\s\S]*?)(?:<\/(baz\s*)>|$))/giu; return (0, common_1.getObjRegex)(ext => new RegExp(String.raw `<!--[\s\S]*?(?:-->|$)|<${noincludeRegex}(?:\s[^>]*)?/?>|</${noincludeRegex}\s*>|<(${ext.join('|') // eslint-disable-next-line unicorn/prefer-string-raw })(\s[^>]*?)?(?:/>|>([\s\S]*?)</(${'\\1'}\s*)>)|<(${includeRegex})(\s[^>]*?)?(?:/>|>([\s\S]*?)(?:</(${includeRegex}\s*)>|$))`, 'giu')); }); /** * 更新`<onlyinclude>`和`</onlyinclude>`的位置 * @param wikitext */ const update = (wikitext) => { const i = wikitext.indexOf(onlyincludeLeft); return { i, j: wikitext.indexOf(onlyincludeRight, i + length) }; }; /** * 解析HTML注释和扩展标签 * @param wikitext * @param config * @param accum * @param includeOnly 是否嵌入 */ const parseCommentAndExt = (wikitext, config, accum, includeOnly) => { if (includeOnly) { let { i, j } = update(wikitext); if (i !== -1 && j !== -1) { // `<onlyinclude>`拥有最高优先级 let str = ''; /** * 忽略未被`<onlyinclude>`和`</onlyinclude>`包裹的内容 * @param text 未被包裹的内容 */ const noinclude = (text) => { // @ts-expect-error abstract class new noinclude_1.NoincludeToken(text, config, accum); str += `\0${accum.length - 1}n\x7F`; }; while (i !== -1 && j !== -1) { const token = `\0${accum.length}e\x7F`; new onlyinclude_1.OnlyincludeToken(wikitext.slice(i + length, j), config, accum); if (i > 0) { noinclude(wikitext.slice(0, i)); } str += token; wikitext = wikitext.slice(j + length + 1); ({ i, j } = update(wikitext)); } if (wikitext) { noinclude(wikitext); } return str; } } const { ext } = config, newExt = ext.filter(e => e !== 'translate' && e !== 'tvar'), newConfig = { ...config, ext: newExt }; if (ext.includes('translate')) { const stack = []; wikitext = wikitext.replace(/<nowiki>[\s\S]*?<\/nowiki>/giu, m => { stack.push(m); return `\0${stack.length - 1}\x7F`; }).replace(/<translate( nowrap)?>([\s\S]+?)?<\/translate>/gu, (_, p1, p2) => { const l = accum.length; // @ts-expect-error abstract class new translate_1.TranslateToken(p1, p2 && (0, string_1.restore)(p2, stack), newConfig, accum); return `\0${l}g\x7F`; }); wikitext = (0, string_1.restore)(wikitext, stack); } return wikitext.replace(getRegex[includeOnly ? 1 : 0](newExt), (substr, name, attr, inner, closing, include, includeAttr, includeInner, includeClosing) => { const l = accum.length; let ch = 'n'; if (name) { ch = 'e'; // @ts-expect-error abstract class new ext_1.ExtToken(name, attr, inner, closing, newConfig, include, accum); } else if (substr.startsWith('<!--')) { ch = 'c'; const closed = substr.endsWith('-->'); // @ts-expect-error abstract class new comment_1.CommentToken((0, string_1.restore)(substr, accum, 1).slice(4, closed ? -3 : undefined), closed, config, accum); } else if (include) { // @ts-expect-error abstract class new include_1.IncludeToken(include, includeAttr && (0, string_1.restore)(includeAttr, accum, 1), includeInner && (0, string_1.restore)(includeInner, accum, 1), includeClosing, config, accum); } else { // @ts-expect-error abstract class new noinclude_1.NoincludeToken(substr, config, accum); } return `\0${l}${ch}\x7F`; }); }; exports.parseCommentAndExt = parseCommentAndExt; constants_1.parsers['parseCommentAndExt'] = __filename;