wikiparser-node 0.11.0 → 1.0.0-beta.1

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 (252) hide show
  1. package/config/.schema.json +26 -0
  2. package/dist/index.d.ts +61 -113
  3. package/dist/index.js +314 -0
  4. package/dist/lib/element.d.ts +122 -108
  5. package/dist/lib/element.js +656 -0
  6. package/dist/lib/node.d.ts +115 -221
  7. package/dist/lib/node.js +473 -0
  8. package/dist/lib/ranges.d.ts +27 -26
  9. package/dist/lib/ranges.js +130 -0
  10. package/dist/lib/text.d.ts +36 -28
  11. package/dist/lib/text.js +215 -0
  12. package/dist/lib/title.d.ts +26 -12
  13. package/dist/lib/title.js +108 -0
  14. package/dist/mixin/attributesParent.js +90 -0
  15. package/dist/mixin/fixed.js +29 -0
  16. package/dist/mixin/hidden.js +19 -0
  17. package/dist/mixin/singleLine.js +23 -0
  18. package/dist/mixin/sol.js +41 -0
  19. package/dist/parser/brackets.js +118 -0
  20. package/dist/parser/commentAndExt.js +48 -0
  21. package/dist/parser/converter.js +31 -0
  22. package/dist/parser/externalLinks.js +22 -0
  23. package/dist/parser/hrAndDoubleUnderscore.js +35 -0
  24. package/dist/parser/html.js +29 -0
  25. package/dist/parser/links.js +86 -0
  26. package/dist/parser/list.js +51 -0
  27. package/dist/parser/magicLinks.js +32 -0
  28. package/dist/parser/quotes.js +57 -0
  29. package/dist/parser/selector.js +158 -0
  30. package/dist/parser/table.js +108 -0
  31. package/dist/src/arg.d.ts +47 -23
  32. package/dist/src/arg.js +196 -0
  33. package/dist/src/atom.d.ts +12 -0
  34. package/dist/src/atom.js +22 -0
  35. package/dist/src/attribute.d.ts +74 -33
  36. package/dist/src/attribute.js +433 -0
  37. package/dist/src/attributes.d.ts +61 -55
  38. package/dist/src/attributes.js +371 -0
  39. package/dist/src/converter.d.ts +45 -71
  40. package/dist/src/converter.js +135 -0
  41. package/dist/src/converterFlags.d.ts +64 -39
  42. package/dist/src/converterFlags.js +235 -0
  43. package/dist/src/converterRule.d.ts +49 -27
  44. package/dist/src/converterRule.js +255 -0
  45. package/dist/src/extLink.d.ts +41 -38
  46. package/dist/src/extLink.js +154 -0
  47. package/dist/src/gallery.d.ts +59 -18
  48. package/dist/src/gallery.js +132 -0
  49. package/dist/src/heading.d.ts +60 -22
  50. package/dist/src/heading.js +135 -0
  51. package/dist/src/hidden.d.ts +20 -0
  52. package/dist/src/hidden.js +24 -0
  53. package/dist/src/html.d.ts +83 -29
  54. package/dist/src/html.js +242 -0
  55. package/dist/src/imageParameter.d.ts +59 -40
  56. package/dist/src/imageParameter.js +251 -0
  57. package/dist/src/imagemap.d.ts +65 -21
  58. package/dist/src/imagemap.js +169 -0
  59. package/dist/src/imagemapLink.d.ts +46 -14
  60. package/dist/src/imagemapLink.js +38 -0
  61. package/dist/src/index.d.ts +71 -105
  62. package/dist/src/index.js +826 -0
  63. package/dist/src/link/base.d.ts +71 -0
  64. package/dist/src/link/base.js +225 -0
  65. package/dist/src/link/category.d.ts +10 -11
  66. package/dist/src/link/category.js +26 -0
  67. package/dist/src/link/file.d.ts +61 -39
  68. package/dist/src/link/file.js +242 -0
  69. package/dist/src/link/galleryImage.d.ts +34 -12
  70. package/dist/src/link/galleryImage.js +98 -0
  71. package/dist/src/link/index.d.ts +25 -63
  72. package/dist/src/link/index.js +136 -0
  73. package/dist/src/magicLink.d.ts +22 -15
  74. package/dist/src/magicLink.js +126 -0
  75. package/dist/src/nested.d.ts +47 -0
  76. package/dist/src/nested.js +84 -0
  77. package/dist/src/nowiki/base.d.ts +39 -0
  78. package/dist/src/nowiki/base.js +29 -0
  79. package/dist/src/nowiki/comment.d.ts +31 -20
  80. package/dist/src/nowiki/comment.js +61 -0
  81. package/dist/src/nowiki/dd.d.ts +17 -11
  82. package/dist/src/nowiki/dd.js +50 -0
  83. package/dist/src/nowiki/doubleUnderscore.d.ts +28 -13
  84. package/dist/src/nowiki/doubleUnderscore.js +45 -0
  85. package/dist/src/nowiki/hr.d.ts +28 -10
  86. package/dist/src/nowiki/hr.js +33 -0
  87. package/dist/src/nowiki/index.d.ts +17 -23
  88. package/dist/src/nowiki/index.js +21 -0
  89. package/dist/src/nowiki/list.d.ts +15 -7
  90. package/dist/src/nowiki/list.js +11 -0
  91. package/dist/src/nowiki/noinclude.d.ts +20 -7
  92. package/dist/src/nowiki/noinclude.js +22 -0
  93. package/dist/src/nowiki/quote.d.ts +25 -10
  94. package/dist/src/nowiki/quote.js +55 -0
  95. package/dist/src/onlyinclude.d.ts +28 -12
  96. package/dist/src/onlyinclude.js +64 -0
  97. package/dist/src/paramTag/index.d.ts +40 -17
  98. package/dist/src/paramTag/index.js +76 -0
  99. package/dist/src/paramTag/inputbox.d.ts +8 -7
  100. package/dist/src/paramTag/inputbox.js +19 -0
  101. package/dist/src/parameter.d.ts +62 -41
  102. package/dist/src/parameter.js +201 -0
  103. package/dist/src/pre.d.ts +32 -0
  104. package/dist/src/pre.js +39 -0
  105. package/dist/src/syntax.d.ts +17 -14
  106. package/dist/src/syntax.js +65 -0
  107. package/dist/src/table/base.d.ts +55 -0
  108. package/dist/src/table/base.js +77 -0
  109. package/dist/src/table/index.d.ts +123 -156
  110. package/dist/src/table/index.js +811 -0
  111. package/dist/src/table/td.d.ts +90 -67
  112. package/dist/src/table/td.js +276 -0
  113. package/dist/src/table/tr.d.ts +30 -85
  114. package/dist/src/table/tr.js +48 -0
  115. package/dist/src/table/trBase.d.ts +72 -0
  116. package/dist/src/table/trBase.js +153 -0
  117. package/dist/src/tagPair/ext.d.ts +47 -11
  118. package/dist/src/tagPair/ext.js +127 -0
  119. package/dist/src/tagPair/include.d.ts +32 -13
  120. package/dist/src/tagPair/include.js +40 -0
  121. package/dist/src/tagPair/index.d.ts +44 -29
  122. package/dist/src/tagPair/index.js +111 -0
  123. package/dist/src/transclude.d.ts +88 -85
  124. package/dist/src/transclude.js +739 -0
  125. package/dist/util/base.js +26 -0
  126. package/dist/util/debug.js +52 -0
  127. package/dist/util/diff.js +69 -0
  128. package/dist/util/lint.js +38 -0
  129. package/dist/util/string.js +103 -0
  130. package/errors/README +1 -0
  131. package/i18n/zh-hans.json +1 -0
  132. package/i18n/zh-hant.json +1 -0
  133. package/package.json +21 -24
  134. package/printed/README +1 -0
  135. package/dist/mixin/attributeParent.d.ts +0 -9
  136. package/dist/mixin/fixedToken.d.ts +0 -8
  137. package/dist/mixin/hidden.d.ts +0 -8
  138. package/dist/mixin/singleLine.d.ts +0 -8
  139. package/dist/mixin/sol.d.ts +0 -8
  140. package/dist/parser/brackets.d.ts +0 -12
  141. package/dist/parser/commentAndExt.d.ts +0 -8
  142. package/dist/parser/converter.d.ts +0 -7
  143. package/dist/parser/externalLinks.d.ts +0 -7
  144. package/dist/parser/hrAndDoubleUnderscore.d.ts +0 -11
  145. package/dist/parser/html.d.ts +0 -7
  146. package/dist/parser/links.d.ts +0 -7
  147. package/dist/parser/list.d.ts +0 -7
  148. package/dist/parser/magicLinks.d.ts +0 -7
  149. package/dist/parser/quotes.d.ts +0 -7
  150. package/dist/parser/selector.d.ts +0 -12
  151. package/dist/parser/table.d.ts +0 -11
  152. package/dist/src/atom/hidden.d.ts +0 -5
  153. package/dist/src/atom/index.d.ts +0 -15
  154. package/dist/src/charinsert.d.ts +0 -32
  155. package/dist/src/hasNowiki/index.d.ts +0 -14
  156. package/dist/src/hasNowiki/pre.d.ts +0 -13
  157. package/dist/src/nested/choose.d.ts +0 -13
  158. package/dist/src/nested/combobox.d.ts +0 -13
  159. package/dist/src/nested/index.d.ts +0 -18
  160. package/dist/src/nested/references.d.ts +0 -13
  161. package/dist/tool/index.d.ts +0 -420
  162. package/dist/util/base.d.ts +0 -10
  163. package/dist/util/debug.d.ts +0 -20
  164. package/dist/util/diff.d.ts +0 -8
  165. package/dist/util/lint.d.ts +0 -28
  166. package/dist/util/string.d.ts +0 -55
  167. package/index.js +0 -333
  168. package/lib/element.js +0 -618
  169. package/lib/node.js +0 -730
  170. package/lib/ranges.js +0 -130
  171. package/lib/text.js +0 -265
  172. package/lib/title.js +0 -83
  173. package/mixin/attributeParent.js +0 -117
  174. package/mixin/fixedToken.js +0 -40
  175. package/mixin/hidden.js +0 -21
  176. package/mixin/singleLine.js +0 -31
  177. package/mixin/sol.js +0 -54
  178. package/parser/brackets.js +0 -128
  179. package/parser/commentAndExt.js +0 -62
  180. package/parser/converter.js +0 -46
  181. package/parser/externalLinks.js +0 -33
  182. package/parser/hrAndDoubleUnderscore.js +0 -49
  183. package/parser/html.js +0 -42
  184. package/parser/links.js +0 -94
  185. package/parser/list.js +0 -59
  186. package/parser/magicLinks.js +0 -41
  187. package/parser/quotes.js +0 -64
  188. package/parser/selector.js +0 -180
  189. package/parser/table.js +0 -114
  190. package/src/arg.js +0 -207
  191. package/src/atom/hidden.js +0 -13
  192. package/src/atom/index.js +0 -43
  193. package/src/attribute.js +0 -472
  194. package/src/attributes.js +0 -453
  195. package/src/charinsert.js +0 -97
  196. package/src/converter.js +0 -176
  197. package/src/converterFlags.js +0 -284
  198. package/src/converterRule.js +0 -256
  199. package/src/extLink.js +0 -180
  200. package/src/gallery.js +0 -149
  201. package/src/hasNowiki/index.js +0 -44
  202. package/src/hasNowiki/pre.js +0 -40
  203. package/src/heading.js +0 -134
  204. package/src/html.js +0 -254
  205. package/src/imageParameter.js +0 -303
  206. package/src/imagemap.js +0 -199
  207. package/src/imagemapLink.js +0 -41
  208. package/src/index.js +0 -938
  209. package/src/link/category.js +0 -44
  210. package/src/link/file.js +0 -287
  211. package/src/link/galleryImage.js +0 -120
  212. package/src/link/index.js +0 -388
  213. package/src/magicLink.js +0 -151
  214. package/src/nested/choose.js +0 -24
  215. package/src/nested/combobox.js +0 -23
  216. package/src/nested/index.js +0 -96
  217. package/src/nested/references.js +0 -23
  218. package/src/nowiki/comment.js +0 -71
  219. package/src/nowiki/dd.js +0 -59
  220. package/src/nowiki/doubleUnderscore.js +0 -56
  221. package/src/nowiki/hr.js +0 -41
  222. package/src/nowiki/index.js +0 -56
  223. package/src/nowiki/list.js +0 -16
  224. package/src/nowiki/noinclude.js +0 -28
  225. package/src/nowiki/quote.js +0 -69
  226. package/src/onlyinclude.js +0 -64
  227. package/src/paramTag/index.js +0 -89
  228. package/src/paramTag/inputbox.js +0 -35
  229. package/src/parameter.js +0 -239
  230. package/src/syntax.js +0 -91
  231. package/src/table/index.js +0 -985
  232. package/src/table/td.js +0 -343
  233. package/src/table/tr.js +0 -319
  234. package/src/tagPair/ext.js +0 -146
  235. package/src/tagPair/include.js +0 -50
  236. package/src/tagPair/index.js +0 -131
  237. package/src/transclude.js +0 -843
  238. package/tool/index.js +0 -1209
  239. package/typings/api.d.ts +0 -9
  240. package/typings/array.d.ts +0 -29
  241. package/typings/event.d.ts +0 -22
  242. package/typings/index.d.ts +0 -118
  243. package/typings/node.d.ts +0 -35
  244. package/typings/parser.d.ts +0 -12
  245. package/typings/table.d.ts +0 -10
  246. package/typings/token.d.ts +0 -31
  247. package/typings/tool.d.ts +0 -6
  248. package/util/base.js +0 -17
  249. package/util/debug.js +0 -73
  250. package/util/diff.js +0 -76
  251. package/util/lint.js +0 -57
  252. package/util/string.js +0 -126
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ const parseBrackets = require("../../parser/brackets");
3
+ const Parser = require("../../index");
4
+ const ParamTagToken = require(".");
5
+ /** `<inputbox>` */
6
+ class InputboxToken extends ParamTagToken {
7
+ /** @browser */
8
+ constructor(wikitext, config = Parser.getConfig(), accum = []) {
9
+ const placeholder = Symbol('InputboxToken');
10
+ accum.push(placeholder);
11
+ const text = wikitext && parseBrackets(wikitext, config, accum);
12
+ accum.splice(accum.indexOf(placeholder), 1);
13
+ super(text, config, accum, {
14
+ ArgToken: ':', TranscludeToken: ':',
15
+ });
16
+ }
17
+ }
18
+ Parser.classes['InputboxToken'] = __filename;
19
+ module.exports = InputboxToken;
@@ -1,75 +1,96 @@
1
- export = ParameterToken;
1
+ import * as Parser from '../index';
2
+ import Token = require('.');
3
+ import AtomToken = require('./atom');
4
+ import SyntaxToken = require('./syntax');
5
+ declare const ParameterToken_base: ((abstract new (...args: any[]) => {
6
+ removeAt(): never;
7
+ insertAt(token: string, i?: number | undefined): import("../lib/text");
8
+ insertAt<T extends import("../lib/node").AstNodeTypes>(token: T, i?: number | undefined): T;
9
+ length: number;
10
+ toString(selector?: string | undefined, separator?: string | undefined): string;
11
+ text(separator?: string | undefined): string;
12
+ }) & {
13
+ readonly fixed: true;
14
+ }) & typeof Token;
2
15
  /**
3
16
  * 模板或魔术字参数
4
17
  * @classdesc `{childNodes: [Token, Token]}`
5
18
  */
6
- declare class ParameterToken extends Token {
19
+ declare abstract class ParameterToken extends ParameterToken_base {
20
+ /** @browser */
21
+ readonly type = "parameter";
22
+ name: string;
23
+ childNodes: [Token, Token];
24
+ abstract get children(): [Token, Token];
25
+ abstract get firstChild(): Token;
26
+ abstract get firstElementChild(): Token;
27
+ abstract get lastChild(): Token;
28
+ abstract get lastElementChild(): Token;
29
+ abstract get parentNode(): import('./transclude') | undefined;
30
+ abstract get parentElement(): import('./transclude') | undefined;
31
+ abstract get nextSibling(): this | undefined;
32
+ abstract get nextElementSibling(): this | undefined;
33
+ abstract get previousSibling(): AtomToken | SyntaxToken | this;
34
+ abstract get previousElementSibling(): AtomToken | SyntaxToken | this;
7
35
  /**
8
- * @param {string|number} key 参数名
9
- * @param {string} value 参数值
10
- * @param {import('../../typings/token').accum} accum
36
+ * 是否是匿名参数
37
+ * @browser
11
38
  */
12
- constructor(key: string | number, value: string, config?: import("../../typings/token").ParserConfig, accum?: import('../../typings/token').accum);
13
- /** 是否是匿名参数 */
14
39
  get anon(): boolean;
15
- set value(arg: string);
16
40
  /** getValue()的getter */
17
41
  get value(): string;
42
+ set value(value: string);
43
+ /** 是否是重复参数 */
44
+ get duplicated(): boolean;
18
45
  /**
19
- * 是否是重复参数
20
- * @this {ParameterToken & {parentNode: TranscludeToken}}
46
+ * @browser
47
+ * @param key 参数名
48
+ * @param value 参数值
21
49
  */
22
- get duplicated(): boolean;
50
+ constructor(key?: string | number, value?: string, config?: Parser.Config, accum?: Token[]);
23
51
  /**
24
52
  * @override
25
- * @param {string} selector
26
- * @returns {string}
53
+ * @browser
27
54
  */
28
- override toString(selector: string): string;
55
+ toString(selector?: string): string;
29
56
  /**
30
57
  * @override
31
- * @returns {string}
58
+ * @browser
32
59
  */
33
- override text(): string;
34
- /** @override */
35
- override getGaps(): 1 | 0;
36
- /** @override */
37
- override print(): string;
60
+ text(): string;
38
61
  /**
39
- * 获取参数值
40
- * @this {ParameterToken & {parentNode: TranscludeToken}}
62
+ * @override
63
+ * @browser
41
64
  */
42
- getValue(this: ParameterToken & {
43
- parentNode: import("./transclude");
44
- }): string;
65
+ print(): string;
66
+ /**
67
+ * @override
68
+ * @browser
69
+ */
70
+ lint(start?: number): Parser.LintError[];
45
71
  /** @override */
46
- override cloneNode(): ParameterToken;
72
+ cloneNode(): this;
47
73
  /**
48
74
  * @override
49
- * @param {ParameterToken} token 待替换的节点
50
- * @complexity `n`
75
+ * @param token 待替换的节点
51
76
  */
52
- override safeReplaceWith(token: ParameterToken): void;
77
+ safeReplaceWith(token: this): void;
78
+ /** 获取参数值 */
79
+ getValue(): string;
53
80
  /**
54
81
  * 设置参数值
55
- * @this {ParameterToken & {parentNode: TranscludeToken}}
56
- * @param {string} value 参数值
82
+ * @param value 参数值
57
83
  * @throws `SyntaxError` 非法的模板参数
58
84
  */
59
- setValue(this: ParameterToken & {
60
- parentNode: import("./transclude");
61
- }, value: string): void;
85
+ setValue(value: string): void;
62
86
  /**
63
87
  * 修改参数名
64
- * @this {ParameterToken & {parentNode: TranscludeToken}}
65
- * @param {string} key 新参数名
66
- * @param {boolean} force 是否无视冲突命名
88
+ * @param key 新参数名
89
+ * @param force 是否无视冲突命名
67
90
  * @throws `Error` 仅用于模板参数
68
91
  * @throws `SyntaxError` 非法的模板参数名
69
92
  * @throws `RangeError` 更名造成重复参数
70
93
  */
71
- rename(this: ParameterToken & {
72
- parentNode: import("./transclude");
73
- }, key: string, force: boolean): void;
94
+ rename(key: string, force?: boolean): void;
74
95
  }
75
- import Token = require(".");
96
+ export = ParameterToken;
@@ -0,0 +1,201 @@
1
+ "use strict";
2
+ const string_1 = require("../util/string");
3
+ const lint_1 = require("../util/lint");
4
+ const fixed = require("../mixin/fixed");
5
+ const Parser = require("../index");
6
+ const Token = require(".");
7
+ /**
8
+ * 模板或魔术字参数
9
+ * @classdesc `{childNodes: [Token, Token]}`
10
+ */
11
+ class ParameterToken extends fixed(Token) {
12
+ /** @browser */
13
+ type = 'parameter';
14
+ /**
15
+ * 是否是匿名参数
16
+ * @browser
17
+ */
18
+ get anon() {
19
+ return this.firstChild.length === 0;
20
+ }
21
+ /** getValue()的getter */
22
+ get value() {
23
+ return this.getValue();
24
+ }
25
+ set value(value) {
26
+ this.setValue(value);
27
+ }
28
+ /** 是否是重复参数 */
29
+ get duplicated() {
30
+ try {
31
+ return Boolean(this.parentNode?.getDuplicatedArgs()?.some(([key]) => key === this.name));
32
+ }
33
+ catch {
34
+ return false;
35
+ }
36
+ }
37
+ /**
38
+ * @browser
39
+ * @param key 参数名
40
+ * @param value 参数值
41
+ */
42
+ constructor(key, value, config = Parser.getConfig(), accum = []) {
43
+ super(undefined, config, true, accum);
44
+ const keyToken = new Token(typeof key === 'number' ? undefined : key, config, true, accum, {
45
+ 'Stage-11': ':', '!HeadingToken': '',
46
+ }), token = new Token(value, config, true, accum);
47
+ keyToken.type = 'parameter-key';
48
+ token.type = 'parameter-value';
49
+ this.append(keyToken, token.setAttribute('stage', 2));
50
+ }
51
+ /** @private */
52
+ afterBuild() {
53
+ if (!this.anon) {
54
+ const name = this.firstChild.toString('comment, noinclude, include')
55
+ .replace(/^[ \t\n\0\v]+|(?<=[^ \t\n\0\v])[ \t\n\0\v]+$/gu, ''), { parentNode } = this;
56
+ this.setAttribute('name', name);
57
+ if (parentNode) {
58
+ parentNode.getAttribute('keys').add(name);
59
+ parentNode.getArgs(name, false, false).add(this);
60
+ }
61
+ }
62
+ const /** @implements */ parameterListener = ({ prevTarget }, data) => {
63
+ if (!this.anon) { // 匿名参数不管怎么变动还是匿名
64
+ const { firstChild, name } = this;
65
+ if (prevTarget === firstChild) {
66
+ const newKey = firstChild.toString('comment, noinclude, include')
67
+ .replace(/^[ \t\n\0\v]+|(?<=[^ \t\n\0\v])[ \t\n\0\v]+$/gu, '');
68
+ data.oldKey = name;
69
+ data.newKey = newKey;
70
+ this.setAttribute('name', newKey);
71
+ }
72
+ }
73
+ };
74
+ this.addEventListener(['remove', 'insert', 'replace', 'text'], parameterListener);
75
+ }
76
+ /**
77
+ * @override
78
+ * @browser
79
+ */
80
+ toString(selector) {
81
+ return this.anon && !(selector && this.matches(selector))
82
+ ? this.lastChild.toString(selector)
83
+ : super.toString(selector, '=');
84
+ }
85
+ /**
86
+ * @override
87
+ * @browser
88
+ */
89
+ text() {
90
+ return this.anon ? this.lastChild.text() : super.text('=');
91
+ }
92
+ /** @private */
93
+ getGaps() {
94
+ return this.anon ? 0 : 1;
95
+ }
96
+ /**
97
+ * @override
98
+ * @browser
99
+ */
100
+ print() {
101
+ return super.print({ sep: this.anon ? '' : '=' });
102
+ }
103
+ /**
104
+ * @override
105
+ * @browser
106
+ */
107
+ lint(start = this.getAbsoluteIndex()) {
108
+ const errors = super.lint(start), { firstChild, lastChild } = this, link = new RegExp(`https?://${string_1.extUrlCharFirst}${string_1.extUrlChar}$`, 'iu')
109
+ .exec(firstChild.toString('comment, noinclude, include'))?.[0];
110
+ if (link && new URL(link).search) {
111
+ const e = (0, lint_1.generateForChild)(firstChild, { start }, 'unescaped query string in an anonymous parameter');
112
+ errors.push({
113
+ ...e,
114
+ startIndex: e.endIndex,
115
+ endIndex: e.endIndex + 1,
116
+ startLine: e.endLine,
117
+ startCol: e.endCol,
118
+ endCol: e.endCol + 1,
119
+ excerpt: `${String(firstChild).slice(-25)}=${String(lastChild).slice(0, 25)}`,
120
+ });
121
+ }
122
+ return errors;
123
+ }
124
+ /** @override */
125
+ cloneNode() {
126
+ const [key, value] = this.cloneChildNodes(), config = this.getAttribute('config');
127
+ return Parser.run(() => {
128
+ const token = new ParameterToken(this.anon ? Number(this.name) : undefined, undefined, config);
129
+ token.firstChild.safeReplaceWith(key);
130
+ token.lastChild.safeReplaceWith(value);
131
+ token.afterBuild();
132
+ return token;
133
+ });
134
+ }
135
+ /**
136
+ * @override
137
+ * @param token 待替换的节点
138
+ */
139
+ safeReplaceWith(token) {
140
+ Parser.warn(`${this.constructor.name}.safeReplaceWith 方法退化到 replaceWith。`);
141
+ this.replaceWith(token);
142
+ }
143
+ /** 获取参数值 */
144
+ getValue() {
145
+ const value = this.lastChild.text();
146
+ return this.anon && this.parentNode?.isTemplate() !== false ? value : value.trim();
147
+ }
148
+ /**
149
+ * 设置参数值
150
+ * @param value 参数值
151
+ * @throws `SyntaxError` 非法的模板参数
152
+ */
153
+ setValue(value) {
154
+ const templateLike = this.parentNode?.isTemplate() !== false, wikitext = `{{${templateLike ? ':T|' : 'lc:'}${this.anon ? '' : '1='}${value}}}`, root = Parser.parse(wikitext, this.getAttribute('include'), 2, this.getAttribute('config')), { length, firstChild: transclude } = root, targetType = templateLike ? 'template' : 'magic-word';
155
+ if (length !== 1 || transclude.type !== targetType) {
156
+ throw new SyntaxError(`非法的模板参数:${(0, string_1.noWrap)(value)}`);
157
+ }
158
+ const { lastChild: parameter, name } = transclude, targetName = templateLike ? 'T' : 'lc';
159
+ if (name !== targetName || transclude.length !== 2 || parameter.anon !== this.anon || parameter.name !== '1') {
160
+ throw new SyntaxError(`非法的模板参数:${(0, string_1.noWrap)(value)}`);
161
+ }
162
+ const { lastChild } = parameter;
163
+ parameter.destroy();
164
+ this.lastChild.safeReplaceWith(lastChild);
165
+ }
166
+ /**
167
+ * 修改参数名
168
+ * @param key 新参数名
169
+ * @param force 是否无视冲突命名
170
+ * @throws `Error` 仅用于模板参数
171
+ * @throws `SyntaxError` 非法的模板参数名
172
+ * @throws `RangeError` 更名造成重复参数
173
+ */
174
+ rename(key, force = false) {
175
+ const { parentNode } = this;
176
+ // 必须检测是否是TranscludeToken
177
+ if (parentNode?.isTemplate() === false) {
178
+ throw new Error(`${this.constructor.name}.rename 方法仅用于模板参数!`);
179
+ }
180
+ const root = Parser.parse(`{{:T|${key}=}}`, this.getAttribute('include'), 2, this.getAttribute('config')), { length, firstChild: template } = root;
181
+ if (length !== 1 || template.type !== 'template' || template.name !== 'T' || template.length !== 2) {
182
+ throw new SyntaxError(`非法的模板参数名:${key}`);
183
+ }
184
+ const { lastChild: parameter } = template, { name, firstChild } = parameter;
185
+ if (this.name === name) {
186
+ Parser.warn('未改变实际参数名', name);
187
+ }
188
+ else if (parentNode?.hasArg(name)) {
189
+ if (force) {
190
+ Parser.warn('参数更名造成重复参数', name);
191
+ }
192
+ else {
193
+ throw new RangeError(`参数更名造成重复参数:${name}`);
194
+ }
195
+ }
196
+ parameter.destroy();
197
+ this.firstChild.safeReplaceWith(firstChild);
198
+ }
199
+ }
200
+ Parser.classes['ParameterToken'] = __filename;
201
+ module.exports = ParameterToken;
@@ -0,0 +1,32 @@
1
+ import * as Parser from '../index';
2
+ import AstText = require('../lib/text');
3
+ import Token = require('.');
4
+ import NoincludeToken = require('./nowiki/noinclude');
5
+ import AttributesToken = require('./attributes');
6
+ import ExtToken = require('./tagPair/ext');
7
+ import ConverterToken = require('./converter');
8
+ /**
9
+ * `<pre>`
10
+ * @classdesc `{childNodes: [...AstText|NoincludeToken|ConverterToken]}`
11
+ */
12
+ declare abstract class PreToken extends Token {
13
+ /** @browser */
14
+ readonly type = "ext-inner";
15
+ childNodes: (AstText | NoincludeToken | ConverterToken)[];
16
+ abstract get children(): (NoincludeToken | ConverterToken)[];
17
+ abstract get firstChild(): AstText | NoincludeToken | ConverterToken | undefined;
18
+ abstract get firstElementChild(): NoincludeToken | ConverterToken | undefined;
19
+ abstract get lastChild(): AstText | NoincludeToken | ConverterToken | undefined;
20
+ abstract get lastElementChild(): NoincludeToken | ConverterToken | undefined;
21
+ abstract get nextSibling(): undefined;
22
+ abstract get nextElementSibling(): undefined;
23
+ abstract get previousSibling(): AttributesToken;
24
+ abstract get previousElementSibling(): AttributesToken;
25
+ abstract get parentNode(): ExtToken | undefined;
26
+ abstract get parentElement(): ExtToken | undefined;
27
+ /** @browser */
28
+ constructor(wikitext?: string, config?: Parser.Config, accum?: Token[]);
29
+ /** @override */
30
+ cloneNode(): this;
31
+ }
32
+ export = PreToken;
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ const Parser = require("../index");
3
+ const Token = require(".");
4
+ const NoincludeToken = require("./nowiki/noinclude");
5
+ /**
6
+ * `<pre>`
7
+ * @classdesc `{childNodes: [...AstText|NoincludeToken|ConverterToken]}`
8
+ */
9
+ class PreToken extends Token {
10
+ /** @browser */
11
+ type = 'ext-inner';
12
+ /** @browser */
13
+ constructor(wikitext, config = Parser.getConfig(), accum = []) {
14
+ const text = wikitext?.replace(/(<nowiki>)(.*?)(<\/nowiki>)/giu, (_, opening, inner, closing) => {
15
+ new NoincludeToken(opening, config, accum);
16
+ new NoincludeToken(closing, config, accum);
17
+ return `\0${accum.length - 1}c\x7F${inner}\0${accum.length}c\x7F`;
18
+ });
19
+ super(text, config, true, accum, {
20
+ AstText: ':', NoincludeToken: ':', ConverterToken: ':',
21
+ });
22
+ this.setAttribute('stage', Parser.MAX_STAGE - 1);
23
+ }
24
+ /** @private */
25
+ isPlain() {
26
+ return true;
27
+ }
28
+ /** @override */
29
+ cloneNode() {
30
+ const cloned = this.cloneChildNodes();
31
+ return Parser.run(() => {
32
+ const token = new PreToken(undefined, this.getAttribute('config'));
33
+ token.append(...cloned);
34
+ return token;
35
+ });
36
+ }
37
+ }
38
+ Parser.classes['PreToken'] = __filename;
39
+ module.exports = PreToken;
@@ -1,20 +1,23 @@
1
- export = SyntaxToken;
2
- /**
3
- * 满足特定语法格式的plain Token
4
- * @classdesc `{childNodes: ...AstText|Token}`
5
- */
1
+ import * as Parser from '../index';
2
+ import Token = require('.');
3
+ import type { TokenAttributeGetter, AstNodeTypes } from '../lib/node';
4
+ declare type SyntaxTypes = 'plain' | 'heading-trail' | 'magic-word-name' | 'table-syntax';
5
+ /** 满足特定语法格式的plain Token */
6
6
  declare class SyntaxToken extends Token {
7
+ #private;
8
+ type: SyntaxTypes;
7
9
  /**
8
- * @param {string} wikitext 语法wikitext
9
- * @param {RegExp} pattern 语法正则
10
- * @param {string} type Token.type
11
- * @param {import('../../typings/token').accum} accum
12
- * @param {import('../../typings/token').acceptable} acceptable 可接受的子节点设置
10
+ * @browser
11
+ * @param pattern 语法正则
13
12
  * @throws `RangeError` 含有g修饰符的语法正则
14
13
  */
15
- constructor(wikitext: string, pattern: RegExp, type?: string, config?: import("../../typings/token").ParserConfig, accum?: import('../../typings/token').accum, acceptable?: import('../../typings/token').acceptable);
14
+ constructor(wikitext: string | undefined, pattern: RegExp, type?: SyntaxTypes, config?: Parser.Config, accum?: Token[], acceptable?: Acceptable);
16
15
  /** @override */
17
- override cloneNode(): SyntaxToken;
18
- #private;
16
+ cloneNode(): this;
17
+ /**
18
+ * @override
19
+ * @param elements 待替换的子节点
20
+ */
21
+ replaceChildren(...elements: (AstNodeTypes | string)[]): void;
19
22
  }
20
- import Token = require(".");
23
+ export = SyntaxToken;
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+ const Parser = require("../index");
3
+ const debug_1 = require("../util/debug");
4
+ const string_1 = require("../util/string");
5
+ const Token = require(".");
6
+ /** 满足特定语法格式的plain Token */
7
+ class SyntaxToken extends Token {
8
+ #pattern;
9
+ /**
10
+ * @browser
11
+ * @param pattern 语法正则
12
+ * @throws `RangeError` 含有g修饰符的语法正则
13
+ */
14
+ constructor(wikitext, pattern, type = 'plain', config = Parser.getConfig(), accum = [], acceptable) {
15
+ if (pattern.global) {
16
+ throw new RangeError(`SyntaxToken 的语法正则不能含有 g 修饰符:${String(pattern)}`);
17
+ }
18
+ super(wikitext, config, true, accum, acceptable);
19
+ this.type = type;
20
+ this.#pattern = pattern;
21
+ }
22
+ /** @override */
23
+ cloneNode() {
24
+ const cloned = this.cloneChildNodes(), config = this.getAttribute('config'), acceptable = this.getAttribute('acceptable');
25
+ return Parser.run(() => {
26
+ const token = new SyntaxToken(undefined, this.#pattern, this.type, config, [], acceptable);
27
+ token.append(...cloned);
28
+ token.afterBuild();
29
+ return token;
30
+ });
31
+ }
32
+ /** @private */
33
+ afterBuild() {
34
+ const /** @implements */ syntaxListener = (e, data) => {
35
+ const pattern = this.#pattern;
36
+ if (!Parser.running && !pattern.test(this.text())) {
37
+ (0, debug_1.undo)(e, data);
38
+ Parser.error(`不可修改 ${this.constructor.name} 的语法!`, pattern);
39
+ throw new Error(`不可修改 ${this.constructor.name} 的语法!`);
40
+ }
41
+ };
42
+ this.addEventListener(['remove', 'insert', 'replace', 'text'], syntaxListener);
43
+ }
44
+ /** @private */
45
+ getAttribute(key) {
46
+ return key === 'pattern' ? this.#pattern : super.getAttribute(key);
47
+ }
48
+ /** @private */
49
+ hasAttribute(key) {
50
+ return key === 'pattern' || super.hasAttribute(key);
51
+ }
52
+ /**
53
+ * @override
54
+ * @param elements 待替换的子节点
55
+ */
56
+ replaceChildren(...elements) {
57
+ if (this.#pattern.test((0, string_1.text)(elements))) {
58
+ Parser.run(() => {
59
+ super.replaceChildren(...elements);
60
+ });
61
+ }
62
+ }
63
+ }
64
+ Parser.classes['SyntaxToken'] = __filename;
65
+ module.exports = SyntaxToken;
@@ -0,0 +1,55 @@
1
+ import * as Parser from '../../index';
2
+ import Token = require('..');
3
+ import SyntaxToken = require('../syntax');
4
+ import AttributesToken = require('../attributes');
5
+ declare const TableBaseToken_base: (abstract new (...args: any[]) => {
6
+ childNodes: import("../../lib/node").AstNodeTypes[];
7
+ readonly "__#12@#attributesChild": AttributesToken;
8
+ readonly attributes: Record<string, string | true>;
9
+ className: string;
10
+ readonly classList: Set<string>;
11
+ id: string;
12
+ hasAttr(key: string): boolean;
13
+ getAttr(key: string): string | true | undefined;
14
+ getAttrNames(): Set<string>;
15
+ hasAttrs(): boolean;
16
+ getAttrs(): Record<string, string | true>;
17
+ setAttr(key: string, value: string | boolean): void;
18
+ removeAttr(key: string): void;
19
+ toggleAttr(key: string, force?: boolean | undefined): void;
20
+ length: number;
21
+ toString(selector?: string | undefined, separator?: string | undefined): string;
22
+ text(separator?: string | undefined): string;
23
+ insertAt(token: unknown, i?: number | undefined): unknown;
24
+ }) & typeof Token;
25
+ /**
26
+ * 表格行,含开头的换行,不含结尾的换行
27
+ * @classdesc `{childNodes: [SyntaxToken, AttributesToken, ?Token, ...TdToken]}`
28
+ */
29
+ declare abstract class TableBaseToken extends TableBaseToken_base {
30
+ type: 'table' | 'tr' | 'td';
31
+ childNodes: [SyntaxToken, AttributesToken, ...Token[]];
32
+ abstract get children(): [SyntaxToken, AttributesToken, ...Token[]];
33
+ abstract get firstChild(): SyntaxToken;
34
+ abstract get firstElementChild(): SyntaxToken;
35
+ abstract get lastChild(): Token;
36
+ abstract get lastElementChild(): Token;
37
+ /**
38
+ * @browser
39
+ * @param pattern 表格语法正则
40
+ * @param syntax 表格语法
41
+ * @param attr 表格属性
42
+ */
43
+ constructor(pattern: RegExp, syntax: string | undefined, attr?: string, config?: Parser.Config, accum?: Token[], acceptable?: Acceptable);
44
+ /** @override */
45
+ cloneNode(): this;
46
+ /** 转义表格语法 */
47
+ escape(): void;
48
+ /**
49
+ * 设置表格语法
50
+ * @param syntax 表格语法
51
+ * @param esc 是否需要转义
52
+ */
53
+ setSyntax(syntax: string, esc?: boolean): void;
54
+ }
55
+ export = TableBaseToken;
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ const attributesParent = require("../../mixin/attributesParent");
3
+ const Parser = require("../../index");
4
+ const Token = require("..");
5
+ const SyntaxToken = require("../syntax");
6
+ const AttributesToken = require("../attributes");
7
+ /**
8
+ * 转义表格语法
9
+ * @param syntax 表格语法节点
10
+ */
11
+ const escapeTable = (syntax) => {
12
+ const templates = { '{|': '(!', '|}': '!)', '||': '!!', '|': '!' }, wikitext = syntax.childNodes.map(child => child.type === 'text'
13
+ ? String(child).replace(/\{\||\|\}|\|{1,2}/gu, p => `{{${templates[p]}}}`)
14
+ : String(child)).join(''), token = Parser.parse(wikitext, syntax.getAttribute('include'), 2, syntax.getAttribute('config'));
15
+ syntax.replaceChildren(...token.childNodes);
16
+ };
17
+ /**
18
+ * 表格行,含开头的换行,不含结尾的换行
19
+ * @classdesc `{childNodes: [SyntaxToken, AttributesToken, ?Token, ...TdToken]}`
20
+ */
21
+ class TableBaseToken extends attributesParent(Token, 1) {
22
+ /**
23
+ * @browser
24
+ * @param pattern 表格语法正则
25
+ * @param syntax 表格语法
26
+ * @param attr 表格属性
27
+ */
28
+ constructor(pattern, syntax, attr = '', config = Parser.getConfig(), accum = [], acceptable = {}) {
29
+ super(undefined, config, true, accum, acceptable);
30
+ this.append(new SyntaxToken(syntax, pattern, 'table-syntax', config, accum, {
31
+ 'Stage-1': ':', '!ExtToken': '', TranscludeToken: ':',
32
+ }),
33
+ new AttributesToken(attr, 'table-attrs', this.type, config, accum));
34
+ this.protectChildren(0, 1);
35
+ }
36
+ /** @override */
37
+ cloneNode() {
38
+ const [syntax, attr, ...cloned] = this.cloneChildNodes();
39
+ return Parser.run(() => {
40
+ const { constructor } = this, token = new constructor(undefined, undefined, this.getAttribute('config'));
41
+ token.firstChild.safeReplaceWith(syntax);
42
+ token.childNodes[1].safeReplaceWith(attr);
43
+ if (token.type === 'td') { // TdToken
44
+ token.childNodes[2].safeReplaceWith(cloned[0]);
45
+ }
46
+ else {
47
+ token.append(...cloned);
48
+ }
49
+ return token;
50
+ });
51
+ }
52
+ /** 转义表格语法 */
53
+ escape() {
54
+ for (const child of this.childNodes) {
55
+ if (child instanceof SyntaxToken) {
56
+ escapeTable(child);
57
+ }
58
+ else if (child instanceof TableBaseToken) {
59
+ child.escape();
60
+ }
61
+ }
62
+ }
63
+ /**
64
+ * 设置表格语法
65
+ * @param syntax 表格语法
66
+ * @param esc 是否需要转义
67
+ */
68
+ setSyntax(syntax, esc = false) {
69
+ const { firstChild } = this;
70
+ firstChild.replaceChildren(syntax);
71
+ if (esc) {
72
+ escapeTable(firstChild);
73
+ }
74
+ }
75
+ }
76
+ Parser.classes['TableBaseToken'] = __filename;
77
+ module.exports = TableBaseToken;