wikiparser-node 1.7.0-beta.4 → 1.7.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 (172) hide show
  1. package/config/.schema.json +181 -0
  2. package/config/enwiki.json +814 -1
  3. package/config/llwiki.json +35 -1
  4. package/config/moegirl.json +44 -1
  5. package/config/zhwiki.json +466 -1
  6. package/dist/addon/table.d.ts +1 -0
  7. package/dist/addon/table.js +485 -0
  8. package/dist/addon/token.d.ts +1 -0
  9. package/dist/addon/token.js +220 -0
  10. package/dist/addon/transclude.d.ts +1 -0
  11. package/dist/addon/transclude.js +183 -0
  12. package/dist/base.d.ts +71 -0
  13. package/dist/base.js +38 -0
  14. package/dist/index.d.ts +31 -0
  15. package/dist/index.js +211 -0
  16. package/dist/internal.d.ts +46 -0
  17. package/dist/lib/element.d.ts +151 -0
  18. package/dist/lib/element.js +628 -0
  19. package/dist/lib/node.d.ts +145 -0
  20. package/dist/lib/node.js +420 -0
  21. package/dist/lib/range.d.ts +105 -0
  22. package/dist/lib/range.js +406 -0
  23. package/dist/lib/ranges.d.ts +28 -0
  24. package/dist/lib/ranges.js +126 -0
  25. package/dist/lib/text.d.ts +63 -0
  26. package/dist/lib/text.js +355 -0
  27. package/dist/lib/title.d.ts +40 -0
  28. package/dist/lib/title.js +197 -0
  29. package/dist/mixin/attributesParent.d.ts +50 -0
  30. package/dist/mixin/attributesParent.js +81 -0
  31. package/dist/mixin/fixed.d.ts +6 -0
  32. package/dist/mixin/fixed.js +30 -0
  33. package/dist/mixin/flagsParent.d.ts +72 -0
  34. package/dist/mixin/flagsParent.js +59 -0
  35. package/dist/mixin/hidden.d.ts +5 -0
  36. package/dist/mixin/hidden.js +24 -0
  37. package/dist/mixin/magicLinkParent.d.ts +41 -0
  38. package/dist/mixin/magicLinkParent.js +42 -0
  39. package/dist/mixin/singleLine.d.ts +6 -0
  40. package/dist/mixin/singleLine.js +26 -0
  41. package/dist/mixin/sol.d.ts +6 -0
  42. package/dist/mixin/sol.js +43 -0
  43. package/dist/mixin/syntax.d.ts +9 -0
  44. package/dist/mixin/syntax.js +50 -0
  45. package/dist/parser/braces.js +130 -0
  46. package/dist/parser/commentAndExt.js +89 -0
  47. package/dist/parser/converter.js +40 -0
  48. package/dist/parser/externalLinks.js +44 -0
  49. package/dist/parser/hrAndDoubleUnderscore.js +40 -0
  50. package/dist/parser/html.js +38 -0
  51. package/dist/parser/links.js +99 -0
  52. package/dist/parser/list.js +97 -0
  53. package/dist/parser/magicLinks.js +42 -0
  54. package/dist/parser/quotes.js +67 -0
  55. package/dist/parser/redirect.js +26 -0
  56. package/dist/parser/selector.js +190 -0
  57. package/dist/parser/table.js +123 -0
  58. package/dist/src/arg.d.ts +58 -0
  59. package/dist/src/arg.js +214 -0
  60. package/dist/src/atom.d.ts +12 -0
  61. package/dist/src/atom.js +27 -0
  62. package/dist/src/attribute.d.ts +71 -0
  63. package/dist/src/attribute.js +502 -0
  64. package/dist/src/attributes.d.ts +109 -0
  65. package/dist/src/attributes.js +356 -0
  66. package/dist/src/converter.d.ts +33 -0
  67. package/dist/src/converter.js +134 -0
  68. package/dist/src/converterFlags.d.ts +87 -0
  69. package/dist/src/converterFlags.js +242 -0
  70. package/dist/src/converterRule.d.ts +77 -0
  71. package/dist/src/converterRule.js +209 -0
  72. package/dist/src/extLink.d.ts +43 -0
  73. package/dist/src/extLink.js +191 -0
  74. package/dist/src/gallery.d.ts +54 -0
  75. package/dist/src/gallery.js +139 -0
  76. package/dist/src/heading.d.ts +47 -0
  77. package/dist/src/heading.js +190 -0
  78. package/dist/src/hidden.d.ts +7 -0
  79. package/dist/src/hidden.js +23 -0
  80. package/dist/src/html.d.ts +65 -0
  81. package/dist/src/html.js +358 -0
  82. package/dist/src/imageParameter.d.ts +65 -0
  83. package/dist/src/imageParameter.js +257 -0
  84. package/dist/src/imagemap.d.ts +54 -0
  85. package/dist/src/imagemap.js +144 -0
  86. package/dist/src/imagemapLink.d.ts +31 -0
  87. package/dist/src/imagemapLink.js +93 -0
  88. package/dist/src/index.d.ts +143 -0
  89. package/dist/src/index.js +701 -0
  90. package/dist/src/link/base.d.ts +52 -0
  91. package/dist/src/link/base.js +228 -0
  92. package/dist/src/link/category.d.ts +22 -0
  93. package/dist/src/link/category.js +30 -0
  94. package/dist/src/link/file.d.ts +98 -0
  95. package/dist/src/link/file.js +272 -0
  96. package/dist/src/link/galleryImage.d.ts +32 -0
  97. package/dist/src/link/galleryImage.js +158 -0
  98. package/dist/src/link/index.d.ts +56 -0
  99. package/dist/src/link/index.js +133 -0
  100. package/dist/src/link/redirectTarget.d.ts +51 -0
  101. package/dist/src/link/redirectTarget.js +101 -0
  102. package/dist/src/magicLink.d.ts +59 -0
  103. package/dist/src/magicLink.js +220 -0
  104. package/dist/src/nested.d.ts +43 -0
  105. package/dist/src/nested.js +105 -0
  106. package/dist/src/nowiki/base.d.ts +31 -0
  107. package/dist/src/nowiki/base.js +93 -0
  108. package/dist/src/nowiki/comment.d.ts +25 -0
  109. package/dist/src/nowiki/comment.js +76 -0
  110. package/dist/src/nowiki/dd.d.ts +8 -0
  111. package/dist/src/nowiki/dd.js +24 -0
  112. package/dist/src/nowiki/doubleUnderscore.d.ts +18 -0
  113. package/dist/src/nowiki/doubleUnderscore.js +101 -0
  114. package/dist/src/nowiki/hr.d.ts +5 -0
  115. package/dist/src/nowiki/hr.js +63 -0
  116. package/dist/src/nowiki/index.d.ts +16 -0
  117. package/dist/src/nowiki/index.js +27 -0
  118. package/dist/src/nowiki/list.d.ts +16 -0
  119. package/dist/src/nowiki/list.js +109 -0
  120. package/dist/src/nowiki/listBase.d.ts +5 -0
  121. package/dist/src/nowiki/listBase.js +61 -0
  122. package/dist/src/nowiki/noinclude.d.ts +10 -0
  123. package/dist/src/nowiki/noinclude.js +23 -0
  124. package/dist/src/nowiki/quote.d.ts +14 -0
  125. package/dist/src/nowiki/quote.js +131 -0
  126. package/dist/src/onlyinclude.d.ts +16 -0
  127. package/dist/src/onlyinclude.js +57 -0
  128. package/dist/src/paramTag/index.d.ts +37 -0
  129. package/dist/src/paramTag/index.js +77 -0
  130. package/dist/src/paramTag/inputbox.d.ts +8 -0
  131. package/dist/src/paramTag/inputbox.js +22 -0
  132. package/dist/src/parameter.d.ts +70 -0
  133. package/dist/src/parameter.js +264 -0
  134. package/dist/src/pre.d.ts +31 -0
  135. package/dist/src/pre.js +59 -0
  136. package/dist/src/redirect.d.ts +34 -0
  137. package/dist/src/redirect.js +119 -0
  138. package/dist/src/syntax.d.ts +19 -0
  139. package/dist/src/syntax.js +86 -0
  140. package/dist/src/table/base.d.ts +27 -0
  141. package/dist/src/table/base.js +81 -0
  142. package/dist/src/table/index.d.ts +242 -0
  143. package/dist/src/table/index.js +498 -0
  144. package/dist/src/table/td.d.ts +86 -0
  145. package/dist/src/table/td.js +355 -0
  146. package/dist/src/table/tr.d.ts +32 -0
  147. package/dist/src/table/tr.js +58 -0
  148. package/dist/src/table/trBase.d.ts +53 -0
  149. package/dist/src/table/trBase.js +156 -0
  150. package/dist/src/tagPair/ext.d.ts +32 -0
  151. package/dist/src/tagPair/ext.js +203 -0
  152. package/dist/src/tagPair/include.d.ts +35 -0
  153. package/dist/src/tagPair/include.js +74 -0
  154. package/dist/src/tagPair/index.d.ts +27 -0
  155. package/dist/src/tagPair/index.js +128 -0
  156. package/dist/src/transclude.d.ts +166 -0
  157. package/dist/src/transclude.js +584 -0
  158. package/dist/util/constants.js +27 -0
  159. package/dist/util/debug.js +81 -0
  160. package/dist/util/diff.js +83 -0
  161. package/dist/util/lint.js +31 -0
  162. package/dist/util/string.js +60 -0
  163. package/errors/README +1 -0
  164. package/package.json +18 -30
  165. package/printed/README +1 -0
  166. package/bundle/bundle.min.js +0 -38
  167. package/extensions/dist/base.js +0 -64
  168. package/extensions/dist/editor.js +0 -159
  169. package/extensions/dist/highlight.js +0 -58
  170. package/extensions/dist/lint.js +0 -72
  171. package/extensions/editor.css +0 -64
  172. package/extensions/ui.css +0 -144
@@ -0,0 +1,51 @@
1
+ import Parser from '../../index';
2
+ import { LinkBaseToken } from './base';
3
+ import { NoincludeToken } from '../nowiki/noinclude';
4
+ import type { LintError } from '../../base';
5
+ import type { Title } from '../../lib/title';
6
+ import type { Token, AtomToken } from '../../internal';
7
+ /**
8
+ * 重定向目标
9
+ * @classdesc `{childNodes: [AtomToken, ?Token]}`
10
+ */
11
+ export declare abstract class RedirectTargetToken extends LinkBaseToken {
12
+ readonly type = "redirect-target";
13
+ readonly childNodes: readonly [AtomToken] | readonly [AtomToken, NoincludeToken];
14
+ abstract get lastChild(): AtomToken | NoincludeToken;
15
+ abstract get children(): [AtomToken] | [AtomToken, NoincludeToken];
16
+ abstract get lastElementChild(): AtomToken | NoincludeToken;
17
+ abstract get link(): Title;
18
+ abstract set link(link: string);
19
+ /** @override */
20
+ get fragment(): string | undefined;
21
+ set fragment(fragment: string | undefined);
22
+ /** interwiki */
23
+ get interwiki(): string;
24
+ /** @throws `RangeError` 非法的跨维基前缀 */
25
+ set interwiki(interwiki: string);
26
+ /**
27
+ * @param link 链接标题
28
+ * @param linkText 链接显示文字
29
+ * @param delimiter `|`
30
+ */
31
+ constructor(link: string, linkText?: string, config?: Parser.Config, accum?: Token[]);
32
+ /** @override */
33
+ text(): string;
34
+ /** @override */
35
+ lint(start?: number): LintError[];
36
+ /**
37
+ * 设置链接目标
38
+ * @param link 链接目标
39
+ */
40
+ setTarget(link: string): void;
41
+ /**
42
+ * 设置fragment
43
+ * @param fragment fragment
44
+ */
45
+ setFragment(fragment?: string): void;
46
+ /**
47
+ * 设置链接显示文字
48
+ * @param linkStr 链接显示文字
49
+ */
50
+ setLinkText(linkStr?: string): void;
51
+ }
@@ -0,0 +1,101 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RedirectTargetToken = void 0;
4
+ const lint_1 = require("../../util/lint");
5
+ const constants_1 = require("../../util/constants");
6
+ const index_1 = require("../../index");
7
+ const base_1 = require("./base");
8
+ const noinclude_1 = require("../nowiki/noinclude");
9
+ /**
10
+ * 重定向目标
11
+ * @classdesc `{childNodes: [AtomToken, ?Token]}`
12
+ */
13
+ class RedirectTargetToken extends base_1.LinkBaseToken {
14
+ type = 'redirect-target';
15
+ /** @override */
16
+ get fragment() {
17
+ return super.fragment;
18
+ }
19
+ set fragment(fragment) {
20
+ this.setFragment(fragment);
21
+ }
22
+ /** interwiki */
23
+ get interwiki() {
24
+ return this.link.interwiki;
25
+ }
26
+ /** @throws `RangeError` 非法的跨维基前缀 */
27
+ set interwiki(interwiki) {
28
+ const { link: { prefix, main, fragment } } = this, link = `${interwiki}:${prefix}${main}${fragment === undefined ? '' : `#${fragment}`}`;
29
+ if (interwiki && !this.isInterwiki(link)) {
30
+ throw new RangeError(`${interwiki} 不是合法的跨维基前缀!`);
31
+ }
32
+ this.setTarget(link);
33
+ }
34
+ /* NOT FOR BROWSER END */
35
+ /**
36
+ * @param link 链接标题
37
+ * @param linkText 链接显示文字
38
+ * @param delimiter `|`
39
+ */
40
+ constructor(link, linkText, config = index_1.default.getConfig(), accum = []) {
41
+ super(link, undefined, config, accum);
42
+ if (linkText !== undefined) {
43
+ // @ts-expect-error abstract class
44
+ this.insertAt(new noinclude_1.NoincludeToken(linkText, config, accum));
45
+ }
46
+ /* NOT FOR BROWSER */
47
+ this.setAttribute('acceptable', { AtomToken: 0, NoincludeToken: 1 });
48
+ // @ts-expect-error abstract getter
49
+ this.firstChild.setAttribute('acceptable', { AstText: ':' });
50
+ }
51
+ /** @private */
52
+ getTitle() {
53
+ return this.normalizeTitle(String(this.firstChild), 0, true, true);
54
+ }
55
+ /** @override */
56
+ text() {
57
+ return `[[${String(this.firstChild)}]]`;
58
+ }
59
+ /** @override */
60
+ lint(start = this.getAbsoluteIndex()) {
61
+ const errors = super.lint(start, /\]\]/u);
62
+ if (this.length === 2) {
63
+ const e = (0, lint_1.generateForChild)(this.lastChild, { start }, 'no-ignored', 'useless link text');
64
+ e.startIndex--;
65
+ e.startCol--;
66
+ e.fix = {
67
+ range: [e.startIndex, e.endIndex],
68
+ text: '',
69
+ };
70
+ errors.push(e);
71
+ }
72
+ return errors;
73
+ }
74
+ /* NOT FOR BROWSER */
75
+ /**
76
+ * 设置链接目标
77
+ * @param link 链接目标
78
+ */
79
+ setTarget(link) {
80
+ this.firstChild.setText(link);
81
+ }
82
+ /**
83
+ * 设置fragment
84
+ * @param fragment fragment
85
+ */
86
+ setFragment(fragment) {
87
+ fragment &&= fragment.replace(/[\]|]/gu, p => encodeURIComponent(p));
88
+ this.setTarget(`${this.name}${fragment === undefined ? '' : `#${fragment}`}`);
89
+ }
90
+ /**
91
+ * 设置链接显示文字
92
+ * @param linkStr 链接显示文字
93
+ */
94
+ setLinkText(linkStr) {
95
+ if (!linkStr) {
96
+ this.childNodes[1]?.remove();
97
+ }
98
+ }
99
+ }
100
+ exports.RedirectTargetToken = RedirectTargetToken;
101
+ constants_1.classes['RedirectTargetToken'] = __filename;
@@ -0,0 +1,59 @@
1
+ import Parser from '../index';
2
+ import { Token } from './index';
3
+ import type { LintError } from '../base';
4
+ import type { SyntaxBase } from '../mixin/syntax';
5
+ import type { AstText, CommentToken, IncludeToken, NoincludeToken, TranscludeToken, AstNodes } from '../internal';
6
+ /** NOT FOR BROWSER */
7
+ export interface MagicLinkToken extends SyntaxBase {
8
+ }
9
+ /** NOT FOR BROWSER END */
10
+ /**
11
+ * 自由外链
12
+ * @classdesc `{childNodes: ...AstText|CommentToken|IncludeToken|NoincludeToken}`
13
+ */
14
+ export declare abstract class MagicLinkToken extends Token {
15
+ type: 'free-ext-link' | 'ext-link-url';
16
+ readonly childNodes: readonly (AstText | CommentToken | IncludeToken | NoincludeToken | TranscludeToken)[];
17
+ abstract get firstChild(): AstText | TranscludeToken;
18
+ abstract get lastChild(): AstText | CommentToken | IncludeToken | NoincludeToken | TranscludeToken;
19
+ abstract get children(): (CommentToken | IncludeToken | NoincludeToken | TranscludeToken)[];
20
+ abstract get firstElementChild(): CommentToken | IncludeToken | NoincludeToken | TranscludeToken | undefined;
21
+ abstract get lastElementChild(): CommentToken | IncludeToken | NoincludeToken | TranscludeToken | undefined;
22
+ /** 协议 */
23
+ get protocol(): string | undefined;
24
+ /** @throws `Error` 特殊外链无法更改协议n */
25
+ set protocol(value: string);
26
+ /** 和内链保持一致 */
27
+ get link(): string;
28
+ set link(url: string);
29
+ /**
30
+ * @param url 网址
31
+ * @param doubleSlash 是否接受"//"作为协议
32
+ */
33
+ constructor(url?: string, doubleSlash?: boolean, config?: Parser.Config, accum?: Token[]);
34
+ /** @override */
35
+ lint(start?: number, re?: RegExp): LintError[];
36
+ /** @override */
37
+ cloneNode(): this;
38
+ /**
39
+ * @override
40
+ * @param token 待插入的节点
41
+ * @param i 插入位置
42
+ */
43
+ insertAt(token: string, i?: number): AstText;
44
+ insertAt<T extends AstNodes>(token: T, i?: number): T;
45
+ /**
46
+ * 获取网址
47
+ * @throws `Error` 非标准协议
48
+ */
49
+ getUrl(): URL;
50
+ /**
51
+ * 设置外链目标
52
+ * @param url 含协议的网址
53
+ */
54
+ setTarget(url: string): void;
55
+ /** 是否是模板或魔术字参数 */
56
+ isParamValue(): boolean;
57
+ /** 转义 `=` */
58
+ escape(): void;
59
+ }
@@ -0,0 +1,220 @@
1
+ "use strict";
2
+ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
3
+ function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
4
+ var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
5
+ var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
6
+ var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
7
+ var _, done = false;
8
+ for (var i = decorators.length - 1; i >= 0; i--) {
9
+ var context = {};
10
+ for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
11
+ for (var p in contextIn.access) context.access[p] = contextIn.access[p];
12
+ context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
13
+ var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
14
+ if (kind === "accessor") {
15
+ if (result === void 0) continue;
16
+ if (result === null || typeof result !== "object") throw new TypeError("Object expected");
17
+ if (_ = accept(result.get)) descriptor.get = _;
18
+ if (_ = accept(result.set)) descriptor.set = _;
19
+ if (_ = accept(result.init)) initializers.unshift(_);
20
+ }
21
+ else if (_ = accept(result)) {
22
+ if (kind === "field") initializers.unshift(_);
23
+ else descriptor[key] = _;
24
+ }
25
+ }
26
+ if (target) Object.defineProperty(target, contextIn.name, descriptor);
27
+ done = true;
28
+ };
29
+ var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
30
+ var useValue = arguments.length > 2;
31
+ for (var i = 0; i < initializers.length; i++) {
32
+ value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
33
+ }
34
+ return useValue ? value : void 0;
35
+ };
36
+ Object.defineProperty(exports, "__esModule", { value: true });
37
+ exports.MagicLinkToken = void 0;
38
+ const lint_1 = require("../util/lint");
39
+ const debug_1 = require("../util/debug");
40
+ const constants_1 = require("../util/constants");
41
+ const string_1 = require("../util/string");
42
+ const syntax_1 = require("../mixin/syntax");
43
+ const index_1 = require("../index");
44
+ const index_2 = require("./index");
45
+ /** NOT FOR BROWSER END */
46
+ /**
47
+ * 自由外链
48
+ * @classdesc `{childNodes: ...AstText|CommentToken|IncludeToken|NoincludeToken}`
49
+ */
50
+ let MagicLinkToken = (() => {
51
+ let _classDecorators = [(0, syntax_1.syntax)()];
52
+ let _classDescriptor;
53
+ let _classExtraInitializers = [];
54
+ let _classThis;
55
+ let _classSuper = index_2.Token;
56
+ var MagicLinkToken = class extends _classSuper {
57
+ static { _classThis = this; }
58
+ static {
59
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
60
+ __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
61
+ MagicLinkToken = _classThis = _classDescriptor.value;
62
+ if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
63
+ __runInitializers(_classThis, _classExtraInitializers);
64
+ }
65
+ /** 协议 */
66
+ get protocol() {
67
+ return this.pattern.exec(this.text())?.[0];
68
+ }
69
+ /** @throws `Error` 特殊外链无法更改协议n */
70
+ set protocol(value) {
71
+ const { link, pattern } = this;
72
+ if (!pattern.test(link)) {
73
+ throw new Error(`特殊外链无法更改协议:${link}`);
74
+ }
75
+ this.setTarget(link.replace(pattern, value));
76
+ }
77
+ /** 和内链保持一致 */
78
+ get link() {
79
+ const map = { '!': '|', '=': '=' };
80
+ return (0, string_1.text)(this.childNodes.map(child => {
81
+ const { type, name } = child;
82
+ return type === 'magic-word' && name in map ? map[name] : child;
83
+ }));
84
+ }
85
+ set link(url) {
86
+ this.setTarget(url);
87
+ }
88
+ /* NOT FOR BROWSER END */
89
+ /**
90
+ * @param url 网址
91
+ * @param doubleSlash 是否接受"//"作为协议
92
+ */
93
+ constructor(url, doubleSlash, config = index_1.default.getConfig(), accum = []) {
94
+ super(url, config, accum, {
95
+ 'Stage-1': '1:', '!ExtToken': '', AstText: ':', TranscludeToken: ':',
96
+ });
97
+ this.type = doubleSlash ? 'ext-link-url' : 'free-ext-link';
98
+ /* NOT FOR BROWSER */
99
+ this.setAttribute('pattern', new RegExp(`^(?:${config.protocol}${doubleSlash ? '|//' : ''})`, 'iu'));
100
+ }
101
+ /** @override */
102
+ lint(start = this.getAbsoluteIndex(), re) {
103
+ const errors = super.lint(start, re), source = `[,;。:!?()]+${this.type === 'ext-link-url' ? '|\\|+' : ''}`, regex = new RegExp(source, 'u'), regexGlobal = new RegExp(source, 'gu');
104
+ let rect;
105
+ for (const child of this.childNodes) {
106
+ const { type, data } = child;
107
+ if (type !== 'text' || !regex.test(data)) {
108
+ continue;
109
+ }
110
+ rect ??= { start, ...this.getRootNode().posFromIndex(start) };
111
+ const refError = (0, lint_1.generateForChild)(child, rect, 'unterminated-url', '', 'warning');
112
+ regexGlobal.lastIndex = 0;
113
+ for (let mt = regexGlobal.exec(data); mt; mt = regexGlobal.exec(data)) {
114
+ const { index, 0: s } = mt, lines = data.slice(0, index).split('\n'), top = lines.length, left = lines[top - 1].length, startIndex = refError.startIndex + index, startLine = refError.startLine + top - 1, startCol = top === 1 ? refError.startCol + left : left, pipe = s.startsWith('|');
115
+ const e = {
116
+ ...refError,
117
+ message: index_1.default.msg('$1 in URL', pipe ? '"|"' : 'full-width punctuation'),
118
+ startIndex,
119
+ endIndex: startIndex + s.length,
120
+ startLine,
121
+ endLine: startLine,
122
+ startCol,
123
+ endCol: startCol + s.length,
124
+ };
125
+ if (!pipe) {
126
+ e.suggestions = [
127
+ {
128
+ desc: 'whitespace',
129
+ range: [startIndex, startIndex],
130
+ text: ' ',
131
+ },
132
+ {
133
+ desc: 'escape',
134
+ range: [startIndex, e.endIndex],
135
+ text: encodeURI(s),
136
+ },
137
+ ];
138
+ }
139
+ else if (s.length === 1) {
140
+ e.suggestions = [
141
+ {
142
+ desc: 'whitespace',
143
+ range: [startIndex, startIndex + 1],
144
+ text: ' ',
145
+ },
146
+ ];
147
+ }
148
+ errors.push(e);
149
+ }
150
+ }
151
+ return errors;
152
+ }
153
+ /* NOT FOR BROWSER */
154
+ /** @override */
155
+ cloneNode() {
156
+ const cloned = this.cloneChildNodes();
157
+ return debug_1.Shadow.run(() => {
158
+ // @ts-expect-error abstract class
159
+ const token = new MagicLinkToken(undefined, this.type === 'ext-link-url', this.getAttribute('config'));
160
+ token.append(...cloned);
161
+ token.afterBuild();
162
+ return token;
163
+ });
164
+ }
165
+ insertAt(token, i) {
166
+ if (typeof token !== 'string') {
167
+ const { type, name } = token;
168
+ if (type === 'template') {
169
+ this.constructorError('不可插入模板');
170
+ }
171
+ else if (!debug_1.Shadow.running && type === 'magic-word' && name !== '!' && name !== '=') {
172
+ this.constructorError('不可插入 "{{!}}" 或 "{{=}}" 以外的魔术字');
173
+ }
174
+ }
175
+ return super.insertAt(token, i);
176
+ }
177
+ /**
178
+ * 获取网址
179
+ * @throws `Error` 非标准协议
180
+ */
181
+ getUrl() {
182
+ let { link } = this;
183
+ if (link.startsWith('//')) {
184
+ link = `https:${link}`;
185
+ }
186
+ try {
187
+ return new URL(link);
188
+ }
189
+ catch (e) {
190
+ if (e instanceof TypeError && e.message === 'Invalid URL') {
191
+ throw new Error(`非标准协议的外部链接:${link}`);
192
+ }
193
+ throw e;
194
+ }
195
+ }
196
+ /**
197
+ * 设置外链目标
198
+ * @param url 含协议的网址
199
+ */
200
+ setTarget(url) {
201
+ const { childNodes } = index_1.default.parse(url, this.getAttribute('include'), 2, this.getAttribute('config'));
202
+ this.replaceChildren(...childNodes);
203
+ }
204
+ /** 是否是模板或魔术字参数 */
205
+ isParamValue() {
206
+ return this.closest('parameter')?.getValue() === this.text();
207
+ }
208
+ /** 转义 `=` */
209
+ escape() {
210
+ for (const child of this.childNodes) {
211
+ if (child.type === 'text') {
212
+ child.escape();
213
+ }
214
+ }
215
+ }
216
+ };
217
+ return MagicLinkToken = _classThis;
218
+ })();
219
+ exports.MagicLinkToken = MagicLinkToken;
220
+ constants_1.classes['MagicLinkToken'] = __filename;
@@ -0,0 +1,43 @@
1
+ import Parser from '../index';
2
+ import { Token } from './index';
3
+ import { ExtToken } from './tagPair/ext';
4
+ import { NoincludeToken } from './nowiki/noinclude';
5
+ import { CommentToken } from './nowiki/comment';
6
+ import type { LintError } from '../base';
7
+ import type { AttributesToken } from './attributes';
8
+ /**
9
+ * 嵌套式的扩展标签
10
+ * @classdesc `{childNodes: ...ExtToken|NoincludeToken|CommentToken}`
11
+ */
12
+ export declare abstract class NestedToken extends Token {
13
+ #private;
14
+ readonly type = "ext-inner";
15
+ readonly name: string;
16
+ readonly childNodes: readonly (ExtToken | NoincludeToken | CommentToken)[];
17
+ abstract get firstChild(): ExtToken | NoincludeToken | CommentToken | undefined;
18
+ abstract get lastChild(): ExtToken | NoincludeToken | CommentToken | undefined;
19
+ abstract get nextSibling(): undefined;
20
+ abstract get previousSibling(): AttributesToken;
21
+ abstract get parentNode(): ExtToken | undefined;
22
+ abstract get children(): (ExtToken | NoincludeToken | CommentToken)[];
23
+ abstract get firstElementChild(): ExtToken | NoincludeToken | CommentToken | undefined;
24
+ abstract get lastElementChild(): ExtToken | NoincludeToken | CommentToken | undefined;
25
+ abstract get previousElementSibling(): AttributesToken;
26
+ abstract get nextElementSibling(): undefined;
27
+ abstract get parentElement(): ExtToken | undefined;
28
+ /**
29
+ * @param regex 内层正则
30
+ * @param tags 内层标签名
31
+ */
32
+ constructor(wikitext: string | undefined, regex: RegExp, tags: readonly string[], config?: Parser.Config, accum?: Token[]);
33
+ /** @override */
34
+ lint(start?: number, re?: RegExp): LintError[];
35
+ /**
36
+ * @override
37
+ * @param token 待插入的子节点
38
+ * @param i 插入位置
39
+ */
40
+ insertAt<T extends Token>(token: T, i?: number): T;
41
+ /** @override */
42
+ cloneNode(): this;
43
+ }
@@ -0,0 +1,105 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NestedToken = void 0;
4
+ const lint_1 = require("../util/lint");
5
+ const debug_1 = require("../util/debug");
6
+ const constants_1 = require("../util/constants");
7
+ const index_1 = require("../index");
8
+ const index_2 = require("./index");
9
+ const ext_1 = require("./tagPair/ext");
10
+ const noinclude_1 = require("./nowiki/noinclude");
11
+ const comment_1 = require("./nowiki/comment");
12
+ /**
13
+ * 嵌套式的扩展标签
14
+ * @classdesc `{childNodes: ...ExtToken|NoincludeToken|CommentToken}`
15
+ */
16
+ class NestedToken extends index_2.Token {
17
+ type = 'ext-inner';
18
+ /* NOT FOR BROWSER */
19
+ #tags;
20
+ #regex;
21
+ /* NOT FOR BROWSER END */
22
+ /**
23
+ * @param regex 内层正则
24
+ * @param tags 内层标签名
25
+ */
26
+ constructor(wikitext, regex, tags, config = index_1.default.getConfig(), accum = []) {
27
+ wikitext = wikitext?.replace(regex, (comment, name, attr, inner, closing) => {
28
+ const str = `\0${accum.length + 1}${name ? 'e' : 'c'}\x7F`;
29
+ if (name) {
30
+ // @ts-expect-error abstract class
31
+ new ext_1.ExtToken(name, attr, inner, closing, config, accum);
32
+ }
33
+ else {
34
+ const closed = comment.endsWith('-->');
35
+ // @ts-expect-error abstract class
36
+ new comment_1.CommentToken(comment.slice(4, closed ? -3 : undefined), closed, config, accum);
37
+ }
38
+ return str;
39
+ }).replace(/(^|\0\d+[ce]\x7F)([^\0]+)(?=$|\0\d+[ce]\x7F)/gu, (_, lead, substr) => {
40
+ // @ts-expect-error abstract class
41
+ new noinclude_1.NoincludeToken(substr, config, accum);
42
+ return `${lead}\0${accum.length}c\x7F`;
43
+ });
44
+ super(wikitext, config, accum, {
45
+ NoincludeToken: ':', ExtToken: ':',
46
+ });
47
+ /* NOT FOR BROWSER */
48
+ this.#tags = [...tags];
49
+ this.#regex = regex;
50
+ }
51
+ /** @override */
52
+ lint(start = this.getAbsoluteIndex(), re) {
53
+ let rect;
54
+ return [
55
+ ...super.lint(start, re),
56
+ ...this.childNodes.filter(child => {
57
+ if (child.type === 'ext' || child.type === 'comment') {
58
+ return false;
59
+ }
60
+ const str = String(child).trim();
61
+ return str && !/^<!--.*-->$/su.test(str);
62
+ }).map(child => {
63
+ rect ??= { start, ...this.getRootNode().posFromIndex(start) };
64
+ const e = (0, lint_1.generateForChild)(child, rect, 'no-ignored', index_1.default.msg('invalid content in <$1>', this.name));
65
+ e.suggestions = [
66
+ {
67
+ desc: 'remove',
68
+ range: [e.startIndex, e.endIndex],
69
+ text: '',
70
+ },
71
+ {
72
+ desc: 'comment',
73
+ range: [e.startIndex, e.startIndex],
74
+ text: `<!--${String(child)}-->`,
75
+ },
76
+ ];
77
+ return e;
78
+ }),
79
+ ];
80
+ }
81
+ /* NOT FOR BROWSER */
82
+ /**
83
+ * @override
84
+ * @param token 待插入的子节点
85
+ * @param i 插入位置
86
+ */
87
+ insertAt(token, i) {
88
+ if (typeof token !== 'string' && token.type === 'ext' && !this.#tags.includes(token.name)) {
89
+ this.constructorError(`只能以 ${this.#tags.join(' 或 ')} 标签作为子节点`);
90
+ }
91
+ return super.insertAt(token, i);
92
+ }
93
+ /** @override */
94
+ cloneNode() {
95
+ const cloned = this.cloneChildNodes(), config = this.getAttribute('config');
96
+ return debug_1.Shadow.run(() => {
97
+ // @ts-expect-error abstract class
98
+ const token = new NestedToken(undefined, this.#regex, this.#tags, config);
99
+ token.append(...cloned);
100
+ return token;
101
+ });
102
+ }
103
+ }
104
+ exports.NestedToken = NestedToken;
105
+ constants_1.classes['NestedToken'] = __filename;
@@ -0,0 +1,31 @@
1
+ import Parser from '../../index';
2
+ import { Token } from '../index';
3
+ import type { AstText } from '../../lib/text';
4
+ declare type NowikiTypes = 'ext-inner' | 'comment' | 'dd' | 'double-underscore' | 'hr' | 'list' | 'noinclude' | 'quote';
5
+ /**
6
+ * 纯文字Token,不会被解析
7
+ * @classdesc `{childNodes: [AstText]}`
8
+ */
9
+ export declare abstract class NowikiBaseToken extends Token {
10
+ type: NowikiTypes;
11
+ readonly childNodes: readonly [AstText];
12
+ abstract get firstChild(): AstText;
13
+ abstract get lastChild(): AstText;
14
+ abstract get children(): [];
15
+ abstract get firstElementChild(): undefined;
16
+ abstract get lastElementChild(): undefined;
17
+ /** 纯文本部分 */
18
+ get innerText(): string;
19
+ /** @param wikitext default: `''` */
20
+ constructor(wikitext?: string, config?: Parser.Config, accum?: Token[]);
21
+ /** @override */
22
+ cloneNode(this: this & {
23
+ constructor: new (...args: any[]) => unknown;
24
+ }): this;
25
+ /**
26
+ * @override
27
+ * @param str 新文本
28
+ */
29
+ setText(str: string): string;
30
+ }
31
+ export {};