wikiparser-node 0.1.0 → 0.2.2

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/README.md CHANGED
@@ -1,1941 +1,39 @@
1
1
  [![npm version](https://badge.fury.io/js/wikiparser-node.svg)](https://www.npmjs.com/package/wikiparser-node)
2
- # 目录
3
- <details>
4
- <summary>展开</summary>
5
2
 
6
- 1. [Parser](#parser)
7
- 1. [方法](#parser.methods)
8
- 1. [parse](#parser.parse)
9
- 2. [isInterwiki](#parser.isinterwiki)
10
- 3. [normalizeTitle](#parser.normalizetitle)
11
- 4. [getTool](#parser.gettool)
12
- 2. [属性](#parser.properties)
13
- 1. [config](#parser.config)
14
- 2. [AstElement](#astelement)
15
- 1. [原型方法](#astelement.prototype.methods)
16
- 2. [实例属性](#astelement.instance.properties)
17
- 3. [原型属性](#astelement.prototype.properties)
18
- 3. [Token](#token)
19
- 1. [原型方法](#token.prototype.methods)
20
- 1. [destroy](#token.destroy)
21
- 2. [getAncestors](#token.getancestors)
22
- 3. [isPlain](#token.isplain)
23
- 4. [toString](#token.tostring)
24
- 5. [text](#token.text)
25
- 6. [safeReplaceWith](#token.safereplacewith)
26
- 7. [setText](#token.settext)
27
- 8. [sections](#token.sections)
28
- 9. [section](#token.section)
29
- 10. [findEnclosingHtml](#token.findenclosinghtml)
30
- 11. [getCategories](#token.getcategories)
31
- 12. [redoQuotes](#token.redoquotes)
32
- 13. [print](#token.print)
33
- 2. [实例属性](#token.instance.properties)
34
- 1. [type](#token.type)
35
- 3. [原型属性](#token.prototype.properties)
36
- 4. [CommentToken](#commenttoken)
37
- 1. [实例属性](#commenttoken.instance.properties)
38
- 1. [closed](#commenttoken.closed)
39
- 5. [ExtToken](#exttoken)
40
- 1. [实例属性](#exttoken.instance.properties)
41
- 1. [selfClosing](#exttoken.selfclosing)
42
- 2. [name](#exttoken.name)
43
- 6. [AttributeToken](#attributetoken)
44
- 1. [原型方法](#attributetoken.prototype.methods)
45
- 1. [hasAttr](#attributetoken.hasattr)
46
- 2. [getAttr](#attributetoken.getattr)
47
- 3. [getAttrNames](#attributetoken.getattrnames)
48
- 4. [hasAttrs](#attributetoken.hasattrs)
49
- 5. [setAttr](#attributetoken.setattr)
50
- 6. [removeAttr](#attributetoken.removeattr)
51
- 7. [toggleAttr](#attributetoken.toggleattr)
52
- 8. [sanitize](#attributetoken.sanitize)
53
- 2. [实例属性](#attributetoken.instance.properties)
54
- 1. [name](#attributetoken.name)
55
- 7. [HeadingToken](#headingtoken)
56
- 1. [原型方法](#headingtoken.prototype.methods)
57
- 1. [setLevel](#headingtoken.setlevel)
58
- 2. [实例属性](#headingtoken.instance.properties)
59
- 1. [name](#headingtoken.name)
60
- 8. [ArgToken](#argtoken)
61
- 1. [原型方法](#argtoken.prototype.methods)
62
- 1. [setName](argtoken.setname)
63
- 2. [setDefault](argtoken.setdefault)
64
- 2. [实例属性](argtoken.instance.properties)
65
- 1. [name](argtoken.name)
66
- 9. [TranscludeToken](#transcludetoken)
67
- 1. [原型方法](#transcludetoken.prototype.methods)
68
- 1. [subst](#transcludetoken.subst)
69
- 2. [safesubst](#transcludetoken.safesubst)
70
- 3. [getAllArgs](#transcludetoken.getallargs)
71
- 4. [getAnonArgs](#transcludetoken.getanonargs)
72
- 5. [getArgs](#transcludetoken.getargs)
73
- 6. [hasArg](#transcludetoken.hasarg)
74
- 7. [getArg](#transcludetoken.getarg)
75
- 8. [removeArg](#transcludetoken.removearg)
76
- 9. [getKeys](#transcludetoken.getkeys)
77
- 10. [getValues](#transcludetoken.getvalues)
78
- 11. [getValue](#transcludetoken.getvalue)
79
- 12. [newAnonArg](#transcludetoken.newanonarg)
80
- 13. [setValue](#transcludetoken.setvalue)
81
- 14. [anonToNamed](#transcludetoken.anontonamed)
82
- 15. [replaceTemplate](#transcludetoken.replacetemplate)
83
- 16. [hasDuplicatedArgs](#transcludetoken.hasduplicatedargs)
84
- 17. [getDuplicatedArgs](#transcludetoken.getduplicatedargs)
85
- 18. [fixDuplication](#transcludetoken.fixduplication)
86
- 19. [escapeTables](#transcludetoken.escapetables)
87
- 2. [实例属性](#transcludetoken.instance.properties)
88
- 1. [name](#transcludetoken.name)
89
- 2. [modifier](#transcludetoken.modifier)
90
- 10. [ParameterToken](#parametertoken)
91
- 1. [原型方法](#parametertoken.prototype.methods)
92
- 1. [getValue](#parametertoken.getvalue)
93
- 2. [setValue](#parametertoken.setvalue)
94
- 3. [rename](#parametertoken.rename)
95
- 2. [实例属性](#parametertoken.instance.properties)
96
- 1. [name](#parametertoken.name)
97
- 2. [anon](#parametertoken.anon)
98
- 11. [HtmlToken](#htmltoken)
99
- 1. [原型方法](#htmltoken.prototype.methods)
100
- 1. [replaceTag](#htmltoken.replacetag)
101
- 2. [findMatchingTag](#htmltoken.findmatchingtag)
102
- 3. [fix](#htmltoken.fix)
103
- 2. [实例属性](#htmltoken.instance.properties)
104
- 1. [name](#htmltoken.name)
105
- 2. [closing](#htmltoken.closing)
106
- 3. [selfClosing](#htmltoken.selfclosing)
107
- 12. [TableToken](#tabletoken)
108
- 1. [原型方法](#tabletoken.prototype.methods)
109
- 1. [getRowCount](#tabletoken.getrowcount)
110
- 2. [getNthRow](#tabletoken.getnthrow)
111
- 3. [getNthCell](#tabletoken.getnthcell)
112
- 4. [getFullRow](#tabletoken.getfullrow)
113
- 5. [getFullCol](#tabletoken.getfullcol)
114
- 6. [formatTableRow](#tabletoken.formattablerow)
115
- 7. [formatTableCol](#tabletoken.formattablecol)
116
- 8. [insertTableRow](#tabletoken.inserttablerow)
117
- 9. [insertTableCol](#tabletoken.inserttablecol)
118
- 10. [insertTableCell](#tabletoken.inserttablecell)
119
- 11. [removeTableRow](#tabletoken.removetablerow)
120
- 12. [removeTableCol](#tabletoken.removetablecol)
121
- 13. [mergeCells](#tabletoken.mergecells)
122
- 14. [splitIntoRows](#tabletoken.splitintorows)
123
- 15. [splitIntoCols](#tabletoken.splitintocols)
124
- 16. [splitIntoCells](#tabletoken.splitintocells)
125
- 17. [replicateTableRow](#tabletoken.replicatetablerow)
126
- 18. [replicateTableCol](#tabletoken.replicatetablecol)
127
- 19. [moveTableRowBefore](#tabletoken.movetablerowbefore)
128
- 20. [moveTableRowAfter](#tabletoken.movetablerowafter)
129
- 21. [moveTableColBefore](#tabletoken.movetablecolbefore)
130
- 22. [moveTableColAfter](#tabletoken.movetablecolafter)
131
- 13. [TdToken](#tdtoken)
132
- 1. [原型属性](#tdtoken.prototype.properties)
133
- 1. [subtype](#tdtoken.subtype)
134
- 2. [rowspan](#tdtoken.rowspan)
135
- 3. [colspan](#tdtoken.colspan)
136
- 14. [DoubleUnderscoreToken](#doubleunderscoretoken)
137
- 1. [实例属性](#doubleunderscoretoken.instance.properties)
138
- 1. [name](#doubleunderscoretoken.name)
139
- 15. [LinkToken](#linktoken)
140
- 1. [原型方法](#linktoken.prototype.methods)
141
- 1. [setTarget](#linktoken.settarget)
142
- 2. [setFragment](#linktoken.setfragment)
143
- 3. [asSelfLink](#linktoken.asselflink)
144
- 4. [setLinkText](#linktoken.setlinktext)
145
- 5. [pipeTrick](#linktoken.pipetrick)
146
- 2. [实例属性](#linktoken.instance.properties)
147
- 1. [name](#linktoken.name)
148
- 2. [selfLink](#linktoken.selflink)
149
- 3. [fragment](#linktoken.fragment)
150
- 4. [interwiki](#linktoken.interwiki)
151
- 16. [CategoryToken](#categorytoken)
152
- 1. [原型方法](#categorytoken.prototype.methods)
153
- 1. [setSortkey](#categorytoken.setsortkey)
154
- 2. [实例属性](#categorytoken.instance.properties)
155
- 1. [sortkey](#categorytoken.sortkey)
156
- 17. [FileToken](#filetoken)
157
- 1. [原型方法](#filetoken.prototype.methods)
158
- 1. [getAllArgs](#filetoken.getallargs)
159
- 2. [getArgs](#filetoken.getargs)
160
- 3. [hasArg](#filetoken.hasarg)
161
- 4. [getArg](#filetoken.getarg)
162
- 5. [removeArg](#filetoken.removearg)
163
- 6. [getKeys](#filetoken.getkeys)
164
- 7. [getValue](#filetoken.getvalue)
165
- 8. [setValue](#filetoken.setvalue)
166
- 2. [原型属性](#filetoken.prototype.properties)
167
- 1. [link](#filetoken.link)
168
- 2. [size](#filetoken.size)
169
- 3. [width](#filetoken.width)
170
- 4. [height](#filetoken.height)
171
- 18. [ImageParameterToken](#imageparametertoken)
172
- 1. [原型方法](#imageparametertoken.prototype.methods)
173
- 1. [getValue](#imageparametertoken.getvalue)
174
- 2. [setValue](#imageparametertoken.setvalue)
175
- 19. [ExtLinkToken](#extlinktoken)
176
- 1. [原型方法](#extlinktoken.prototype.methods)
177
- 1. [setLinkText](#extlinktoken.setlinktext)
178
- 20. [MagicLinkToken](#magiclinktoken)
179
- 1. [原型方法](#magiclinktoken.prototype.methods)
180
- 1. [getUrl](#magiclinktoken.geturl)
181
- 2. [setTarget](#magiclinktoken.settarget)
182
- 2. [原型属性](#magiclinktoken.prototype.properties)
183
- 1. [protocol](#magiclinktoken.protocol)
184
- 21. [选择器](#选择器)
185
- 1. [type](#selector.type)
186
- 2. [name](#selector.name)
187
- 3. [属性](#selector.attribute)
188
- 4. [伪选择器](#selector.pseudo)
189
- 22. [$ (TokenCollection)](#-tokencollection)
190
- </details>
3
+ # 简介
4
+ wikiparser-node 是一款由 Bhsd 开发的基于 [Node.js](https://nodejs.org/en/) 环境的离线[维基文本](https://www.mediawiki.org/wiki/Wikitext)语法解析器,可以解析绝大部分的维基语法并生成[语法树](https://en.wikipedia.org/wiki/Abstract_syntax_tree),还可以很方便地对语法树进行查询和修改,最后返回修改后的维基文本。语法树的每个节点对应一个仿照 [HTMLElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement) 类设计的类 [Token](https://github.com/bhsd-harry/wikiparser-node/wiki/01.-Token)。
191
5
 
192
- # Parser
193
- 这是解析工具的入口。
6
+ # 使用方法
194
7
 
195
8
  ```js
196
9
  var Parser = require('wikiparser-node');
197
10
  ```
198
11
 
199
- ## 方法<a id="parser.methods"></a>
200
-
201
- **parse**(wikitext: string, include?: boolean = false): [Token](#token)<a id="parser.parse"></a>
202
- - 解析维基文本。
203
-
204
- ```js
205
- var wikitext = '<includeonly>include</includeonly><noinclude>noinclude</noinclude>',
206
- include = Parser.parse(wikitext, true),
207
- noinclude = Parser.parse(wikitext);
208
- assert(include.text() === 'include'); // Token.text()方法只保留有效部分,详见后文Token章节
209
- assert(noinclude.text() === 'noinclude');
210
- ```
211
-
212
- **isInterwiki**(title: string): RegExpMatchArray<a id="parser.isinterwiki"></a>
213
- - 指定的标题是否是跨维基。
214
-
215
- ```js
216
- assert(Boolean(Parser.isInterwiki('zhwiki:首页')));
217
- ```
218
-
219
- **normalizeTitle**(title: string, defaultNs?: number = 0): string<a id="parser.normalizetitle"></a>
220
- - 规范化页面标题。
221
-
222
- ```js
223
- assert(Parser.normalizeTitle('lj', 10) === 'Template:Lj');
224
- ```
225
-
226
- **getTool**(): typeof [$](#-tokencollection)<a id="parser.gettool"></a>
227
- - 加载[批量操作工具](#-tokencollection)。
228
-
229
- ## 属性<a id="parser.properties"></a>
230
-
231
- **config**: string<a id="parser.config"></a>
232
- - 指定解析设置JSON文件的相对或绝对路径。
233
-
234
- ```js
235
- assert(Parser.config === './config/default'); // 这是默认设置的相对路径
236
- ```
237
-
238
- [返回目录](#目录)
239
-
240
- # AstElement
241
- 语法树的节点均为字符串或一个仿 HTMLElement 的类 AstElement,这里仅列举这些方法和属性。
242
-
243
- ## 原型方法<a id="astelement.prototype.methods"></a>
244
- <details>
245
- <summary>展开</summary>
246
-
247
- **isEqualNode**(node: this): boolean
248
- **cloneNode**(): this
249
- **hasAttribute**(key: PropertyKey): boolean
250
- **getAttribute**(key: PropertyKey): string\|undefined
251
- **getAttributeNames**(): string[]
252
- **hasAttributes**(): boolean
253
- **setAttribte**(key: PropertyKey, value: any): this
254
- **removeAttribute**(key: PropertyKey): void
255
- **toggleAttribute**(key: PropertyKey, force?: boolean): void
256
- **hasChildNodes**(): boolean
257
- **contains**(node: this): boolean
258
- **removeChild**(node: this): this
259
- **appendChild**(node: string\|this): string\|this
260
- **append**(...elements: string\|this): void
261
- **insertBefore**(node: string\|this, reference: this): string\|this
262
- **prepend**(...elements: string\|this): void
263
- **replaceChild**(newChild: string\|this, oldChild: this): this
264
- **replaceChildren**(...elements: string\|this): void
265
- **after**(...element: string\|this): void
266
- **before**(...element: string\|this): void
267
- **remove**(): void
268
- **replaceWith**(...elements: string\|this): void
269
- **normalize**(): void
270
- **getRootNode**(): this
271
- **addEventListener**(type: string, listener: (e: event, data: any) => void, options?: {once: boolean}): void
272
- **removeEventListener**(type: string, listener: (e: event, data: any) => void): void
273
- **dispatchEvent**(e: event, data: any): void
274
- **matches**(selector: string): boolean
275
- **comparePosition**(other: this): number
276
- **closest**(selector: string): this\|undefined
277
- **querySelector**(selector: string): this\|undefined
278
- **querySelectorAll**(selector: string): this[]
279
- **getBoundingClientRect**(): {height: number, width: number, top: number, left: number}
280
- **splitText**(i: number, offset: number): string
281
- </details>
282
-
283
- ## 实例属性<a id="astelement.instance.properties"></a>
284
- <details>
285
- <summary>展开</summary>
286
-
287
- **childNodes**: (string\|this)[]
288
- </details>
289
-
290
- ## 原型属性<a id="astelement.prototype.properties"></a>
291
- <details>
292
- <summary>展开</summary>
293
-
294
- **children**: this[]
295
- **firstChild**: string\|this\|undefined
296
- **firstElementChild**: this\|undefined
297
- **lastChild** string\|this\|undefined
298
- **lastElementChild**: this\|undefined
299
- **isConnected**: boolean
300
- **parentNode**: this\|undefined
301
- **parentElement**: this\|undefined
302
- **nextSibling**: string\|this\|undefined
303
- **nextElementSibling**: this\|undefined
304
- **previousSibling**: string\|this\|undefined
305
- **previousElementSibling**: this\|undefined
306
- **hidden**: boolean
307
- **offsetHeight**: number
308
- **offsetWidth**: number
309
- **offsetTop**: number
310
- **offsetLeft**: number
311
- **style**: {top: number, left: number, height: number, width: number, padding: number}
312
- </details>
313
-
314
- [返回目录](#目录)
315
-
316
- # Token
317
- 这是所有解析后的维基文本的基础类。
318
-
319
- ## 原型方法<a id="token.prototype.methods"></a>
320
- <details>
321
- <summary>展开</summary>
322
-
323
- **destroy**(): void<a id="token.destroy"></a>
324
- - 销毁节点,只能对根节点使用。
325
-
326
- **getAncestors**(): Token[]<a id="token.getancestors"></a>
327
- - 获取所有祖先节点。
328
-
329
- ```js
330
- var root = Parser.parse('<ref/>'),
331
- attr = root.querySelector('ext-attr');
332
- assert.deepStrictEqual(attr.getAncestors(), [attr.parentElement, root]);
333
- ```
334
-
335
- **isPlain**(): boolean<a id="token.isplain"></a>
336
- - 是否是基础类(即未拓展的 Token)。
337
-
338
- ```js
339
- var root = Parser.parse(wikitext);
340
- assert(root.isPlain() === true); // 根节点总是基础类
341
- ```
342
-
343
- **toString**(): string<a id="token.tostring"></a>
344
- - 还原为完整的维基文本。
345
-
346
- ```js
347
- var root = Parser.parse(wikitext);
348
- assert(root.toString() === wikitext); // 解析是可逆的
349
- ```
350
-
351
- **text**(): string<a id="token.text"></a>
352
- - 移除不可见的维基文本,包括 HTML 注释、仅用于嵌入的文字(即 `<includeonly>` 或 `<onlyinclude>` 标签内部)、无效的标签属性等。
353
-
354
- ```js
355
- var root = Parser.parse('<!-- a -->{{{||b}}}<br */>');
356
- assert(root.text() === '{{{|}}}<br/>');
357
- ```
358
-
359
- **setText**(text: string, i: number): void<a id="token.settext"></a>
360
- - 只能通过这个方法修改指定位置上的纯字符串节点。
361
-
362
- ```js
363
- var root = Parser.parse('');
364
- root.setText('string', 0);
365
- assert(root.toString() === 'string');
366
- ```
367
-
368
- **safeReplaceWith**(token: Token): void<a id="token.safereplacewith"></a>
369
- - 将节点替换为一个同类节点,相当于[replaceWith](#astelement.prototype.methods),但适用于父节点有规定的子节点顺序时。
370
-
371
- **sections**(): Token\[\]\[\]<a id="token.sections"></a>
372
- - 将页面分割为章节,每个章节对应一个 Token 数组。
373
-
374
- ```js
375
- var root = Parser.parse('a\n==b==\nc\n===d===\n'),
376
- {childNodes} = root,
377
- sections = root.sections();
378
- assert.deepStrictEqual(sections, [childNodes.slice(0, 1), childNodes.slice(1), childNodes.slice(3)]);
379
- ```
380
-
381
- **section**(n: number): Token\[\]<a id="token.section"></a>
382
- - 仅获取指定章节。
383
-
384
- ```js
385
- var root = Parser.parse('a\n==b==\nc\n===d===\n'),
386
- section = root.section(0); // 序言对应的编号为 0
387
- assert.deepStrictEqual(section, [root.firstChild]);
388
- ```
389
-
390
- **findEnclosingHtml**(tag?: string): [Token, Token]<a id="token.findenclosinghtml"></a>
391
- - 搜索包裹当前Token的HTML标签对,不指定`tag`参数时会搜索任意HTML标签。
392
-
393
- ```js
394
- var root = Parser.parse('<p>{{a}}</p>'),
395
- template = root.querySelector('template');
396
- assert.deepStrictEqual(template.findEnclosingHtml('p'), [root.firstChild, root.lastChild]);
397
- ```
398
-
399
- **getCategories**(): [string, string][]<a id="token.getcategories"></a>
400
- - 获取所有分类和对应的排序关键字。
401
-
402
- ```js
403
- var root = Parser.parse('[[category:a|*]]');
404
- assert.deepStrictEqual(root.getCategories(), [['Category:A', '*']]);
405
- ```
406
-
407
- **redoQuotes**(): void<a id="token.redoquotes"></a>
408
- - 经过一系列编辑操作后,重新局部解析`'`。注意这个方法会忽略所有 Token,只解析当前节点的直接纯文本子节点。
409
-
410
- ```js
411
- var root = Parser.parse("'''a'''");
412
- root.lastElementChild.setText("''");
413
- assert(root.toString() === "'''a''");
414
- root.redoQuotes();
415
- assert.deepStrictEqual(root.childNodes, ["'", root.firstElementChild, "a", root.lastElementChild]);
416
- ```
417
- </details>
418
-
419
- ## 实例属性<a id="token.instance.properties"></a>
420
- <details>
421
- <summary>展开</summary>
422
-
423
- **type**: string<a id="token.type"></a>
424
- - 根节点的值为 `root`,其他的基础类节点一般为 `plain`。
425
-
426
- ```js
427
- var root = Parser.parse(wikitext);
428
- assert(root.type === 'root');
429
- ```
430
-
431
- **print**(format?: 'markup'\|'json' = 'markup'): void\|object<a id="token.print"></a>
432
- - 打印解析生成的 AST。
433
-
434
- ```js
435
- var root = Parser.parse("<ref>{{T|<br>\n----\n[[File:F|thumb|''[//example.net]'']]}}</ref>");
436
- root.print();
437
- root.print('json', 'example'); // JSON格式的输出结果将保存至 /printed/example.json 文件
438
- ```
439
- </details>
440
-
441
- ## 原型属性<a id="token.prototype.properties"></a>
442
- <details>
443
- <summary>展开</summary>
444
-
445
- **previousVisibleSibling**: string\|Token\|undefined
446
- **nextVisibleSibling**: string\|Token\|undefined
447
- </details>
448
-
449
- [返回目录](#目录)
450
-
451
- # CommentToken
452
- HTML 注释。
453
-
454
- ## 实例属性<a id="commenttoken.instance.properties"></a>
455
- <details>
456
- <summary>展开</summary>
457
-
458
- **closed**: boolean<a id="commenttoken.closed"></a>
459
- - 是否闭合。
460
-
461
- ```js
462
- var root = Parser.parse('<!-- text'),
463
- comment = root.firstChild;
464
- assert(comment.closed === false);
465
- ```
466
- </details>
467
-
468
- [返回目录](#目录)
469
-
470
- # ExtToken
471
- 扩展标签。这个类同时混合了 [AttributeToken](#attributetoken) 类的方法。
472
-
473
- ## 实例属性<a id="exttoken.instance.properties"></a>
474
- <details>
475
- <summary>展开</summary>
476
-
477
- **selfClosing**: boolean<a id="exttoken.selfclosing"></a>
478
- - 是否自封闭。
479
-
480
- ```js
481
- var root = Parser.parse('<ref/>'),
482
- ref = root.firstChild;
483
- assert(ref.selfClosing === true);
484
- ```
485
-
486
- **name**: string<a id="exttoken.name"></a>
487
- - 小写的标签名。
488
-
489
- ```js
490
- var root = Parser.parse('<REF/>'),
491
- ref = root.firstChild;
492
- assert(ref.name === 'ref');
493
- ```
494
- </details>
495
-
496
- [返回目录](#目录)
497
-
498
- # AttributeToken
499
- 扩展和 HTML 标签及表格的属性。
500
-
501
- ## 原型方法<a id="attributetoken.prototype.methods"></a>
502
- <details>
503
- <summary>展开</summary>
504
-
505
- **hasAttr**(key: string): boolean<a id="attributetoken.hasattr"></a>
506
- - 是否带有指定属性。
507
-
508
- ```js
509
- var root = Parser.parse('<choose uncached before="a"></choose>'),
510
- attr = root.querySelector('ext-attr'); // 扩展标签属性的 type 值为 'ext-attr'
511
- assert(attr.hasAttr('uncached') === true);
512
- assert(attr.hasAttr('before') === true);
513
- ```
514
-
515
- **getAttr**(key: string): string\|boolean<a id="attributetoken.getattr"></a>
516
- - 获取指定属性。
517
-
518
- ```js
519
- var root = Parser.parse('<choose uncached before="a"></choose>'),
520
- attr = root.querySelector('ext-attr');
521
- assert(attr.getAttr('uncached') === true);
522
- assert(attr.getAttr('before') === 'a');
523
- ```
524
-
525
- **getAttrNames**(): string\[\]<a id="attributetoken.getattrnames"></a>
526
- - 获取属性名列表。
527
-
528
- ```js
529
- var root = Parser.parse('<ref name="a"/>'),
530
- attr = root.querySelector('ext-attr');
531
- assert.deepStrictEqual(attr.getAttrNames(), ['name']);
532
- ```
533
-
534
- **hasAttrs**(): boolean<a id="attributetoken.hasattrs"></a>
535
- - 是否带有至少一条属性。
536
-
537
- ```js
538
- var root = Parser.parse('<ref/>'),
539
- attr = root.querySelector('ext-attr');
540
- assert(attr.hasAttrs() === false);
541
- ```
542
-
543
- **setAttr**(key: string, value: string\|boolean): boolean<a id="attributetoken.setattr"></a>
544
- - 设置属性。
545
-
546
- ```js
547
- var root = Parser.parse('<choose></choose>'),
548
- attr = root.querySelector('ext-attr');
549
- assert(attr.setAttr('before', 'a') === true);
550
- assert(attr.setAttr('uncached', true) === true);
551
- assert(root.toString() === '<choose before="a" uncached></choose>');
552
- ```
553
-
554
- **removeAttr**(key: string): void<a id="attributetoken.removeattr"></a>
555
- - 移除指定属性。
556
-
557
- ```js
558
- var root = Parser.parse('<ref name="a"/>'),
559
- attr = root.querySelector('ext-attr');
560
- attr.removeAttr('name');
561
- assert(root.toString() === '<ref/>');
562
- ```
563
-
564
- **toggleAttr**(key: string): void<a id="attributetoken.toggleattr"></a>
565
- - 切换某 Boolean 属性。
566
-
567
- ```js
568
- var root = Parser.parse('<choose uncached></choose>'),
569
- attr = root.querySelector('ext-attr');
570
- attr.toggleAttr('uncached');
571
- assert(root.toString() === '<choose></choose>');
572
- attr.toggleAttr('uncached');
573
- assert(root.toString() === '<choose uncached></choose>');
574
- ```
575
-
576
- **sanitize**(): void<a id="attributetoken.sanitize"></a>
577
- - 清理无效属性。
578
-
579
- ```js
580
- var root = Parser.parse('<p ">'),
581
- attr = root.querySelector('html-attr');
582
- attr.sanitize();
583
- assert(root.toString() === '<p>');
584
- ```
585
- </details>
586
-
587
- ## 实例属性<a id="attributetoken.instance.properties"></a>
588
- <details>
589
- <summary>展开</summary>
590
-
591
- **name**: string<a id="attributetoken.name"></a>
592
- - 小写的标签名。
593
-
594
- ```js
595
- var root = Parser.parse('<REF/>'),
596
- attr = root.querySelector('ext-attr'); // 即使没有设置属性,扩展和 HTML 标签的第一个子节点也总是 AttributeToken
597
- assert(attr.name === 'ref');
598
- ```
599
- </details>
600
-
601
- [返回目录](#目录)
602
-
603
- # HeadingToken
604
- 章节标题。
605
-
606
- ## 原型方法<a id="headingtoken.prototype.methods"></a>
607
- <details>
608
- <summary>展开</summary>
609
-
610
- **setLevel**(n: number): void<a id="headingtoken.setlevel"></a>
611
- - 修改标题层级。
612
-
613
- ```js
614
- var root = Parser.parse('==a=='),
615
- header = root.firstChild;
616
- header.setLevel(3);
617
- assert(root.toString() === '===a===');
618
- ```
619
- </details>
620
-
621
- ## 实例属性<a id="headingtoken.instance.properties"></a>
622
- <details>
623
- <summary>展开</summary>
624
-
625
- **name**: string<a id="headingtoken.name"></a>
626
- - 字符串格式的标题层级。
627
-
628
- ```js
629
- var root = Parser.parse('==a=='),
630
- header = root.firstChild;
631
- assert(header.name === '2');
632
- ```
633
- </details>
634
-
635
- [返回目录](#目录)
636
-
637
- # ArgToken
638
- 被 `{{{}}}` 包裹的模板参数。
639
-
640
- ## 原型方法<a id="argtoken.prototype.methods"></a>
641
- <details>
642
- <summary>展开</summary>
643
-
644
- **setName**(name: any): void<a id="argtoken.setname"></a>
645
- - 修改参数名。
646
-
647
- ```js
648
- var root = Parser.parse('{{{a}}}'),
649
- arg = root.firstChild;
650
- arg.setName('b');
651
- assert(root.toString() === '{{{b}}}');
652
- ```
653
-
654
- **setDefault**(value: any): void<a id="argtoken.setdefault"></a>
655
- - 设置或修改参数预设值。
656
-
657
- ```js
658
- var root = Parser.parse('{{{a}}}'),
659
- arg = root.firstChild;
660
- arg.setDefault('b');
661
- assert(root.toString() === '{{{a|b}}}');
662
- ```
663
- </details>
664
-
665
- ## 实例属性<a id="argtoken.instance.properties"></a>
666
- <details>
667
- <summary>展开</summary>
668
-
669
- **name**: string<a id="argtoken.name"></a>
670
- - 参数名。
671
-
672
- ```js
673
- var root = Parser.parse('{{{a}}}'),
674
- arg = root.firstChild;
675
- assert(arg.name === 'a');
676
- ```
677
- </details>
678
-
679
- [返回目录](#目录)
680
-
681
- # TranscludeToken
682
- 模板或魔术字。
683
-
684
- ## 原型方法<a id="transcludetoken.prototype.methods"></a>
685
- <details>
686
- <summary>展开</summary>
687
-
688
- **subst**(): void<a id="transcludetoken.subst"></a>
689
- **safesubst**(): void<a id="transcludetoken.safesubst"></a>
690
- - 将引用方式修改为替换引用。
691
-
692
- ```js
693
- var root = Parser.parse('{{a}}{{!}}'),
694
- template = root.firstChild,
695
- magicWord = root.lastChild;
696
- template.subst();
697
- magicWord.safesubst();
698
- assert(root.toString() === '{{subst:a}}{{safesubst:!}}');
699
- ```
700
-
701
- **getAllArgs**(): [ParameterToken](#parametertoken)[]<a id="transcludetoken.getallargs"></a>
702
- - 获取所有参数。
703
-
704
- ```js
705
- var root = Parser.parse('{{a|b|c=1}}{{#invoke:d|e|f|g=1}}'),
706
- template = root.firstChild,
707
- invoke = root.lastChild;
708
- assert.deepStrictEqual(template.getAllArgs(), template.children.slice(1));
709
- assert.deepStrictEqual(invoke.getAllArgs(), invoke.children.slice(3));
710
- ```
711
-
712
- **getAnonArgs**(): [ParameterToken](#parametertoken)[]<a id="transcludetoken.getanonargs"></a>
713
- - 获取所有匿名参数。
714
-
715
- ```js
716
- var root = Parser.parse('{{a|b|c=1}}{{#invoke:d|e|f|g=1}}{{#if:x|y|z}}'),
717
- [template, invoke, magicWord] = root.children;
718
- assert.deepStrictEqual(template.getAnonArgs(), template.children.slice(1, 2));
719
- assert.deepStrictEqual(invoke.getAnonArgs(), invoke.children.slice(3, 4));
720
- assert.deepStrictEqual(magicWord.getAnonArgs(), magicWord.children.slice(1)); // 除#invoke外的魔术字的参数总是视为匿名参数
721
- ```
722
-
723
- **getArgs**(key: string\|number): Set\<[ParameterToken](#parametertoken)><a id="transcludetoken.getargs"></a>
724
- - 获取指定名称的参数(含重复),注意顺序可能不固定。
725
-
726
- ```js
727
- var root = Parser.parse('{{a|b|1=c}}{{#invoke:d|e|f|1=g}}'),
728
- template = root.firstChild,
729
- invoke = root.lastChild;
730
- assert.deepStrictEqual(template.getArgs(1), new Set(template.children.slice(1)));
731
- assert.deepStrictEqual(invoke.getArgs(1), new Set(invoke.children.slice(3)));
732
- ```
733
-
734
- **hasArg**(key: string\|number): boolean<a id="transcludetoken.hasarg"></a>
735
- - 是否带有指定参数。
736
-
737
- ```js
738
- var root = Parser.parse('{{a|b|c=1}}{{#invoke:d|e|f|g=1}}'),
739
- template = root.firstChild,
740
- invoke = root.lastChild;
741
- assert(template.hasArg(1) === true);
742
- assert(template.hasArg('c') === true);
743
- assert(invoke.hasArg(1) === true);
744
- assert(invoke.hasArg('g') === true);
745
- ```
746
-
747
- **getArg**(key: string\|number): [ParameterToken](#parametertoken)<a id="transcludetoken.getarg"></a>
748
- - 获取指定名称的有效参数(即最后一个)。
749
-
750
- ```js
751
- var root = Parser.parse('{{a|b|1=c}}{{#invoke:d|e|1=f|g}}'),
752
- template = root.firstChild,
753
- invoke = root.lastChild;
754
- assert(template.getArg(1) === template.lastChild);
755
- assert(invoke.getArg(1) === invoke.lastChild);
756
- ```
757
-
758
- **removeArg**(key: string\|number): void<a id="transcludetoken.removearg"></a>
759
- - 移除指定名称的参数(含重复)。
760
-
761
- ```js
762
- var root = Parser.parse('{{a|b|1=c}}{{#invoke:d|e|f|1=g}}'),
763
- template = root.firstChild,
764
- invoke = root.lastChild;
765
- template.removeArg(1);
766
- invoke.removeArg(1);
767
- assert(root.toString() === '{{a}}{{#invoke:d|e}}');
768
- ```
769
-
770
- **getKeys**(): string[]<a id="transcludetoken.getkeys"></a>
771
- - 获取所有参数名。
772
-
773
- ```js
774
- var root = Parser.parse('{{a|b=1|c=2}}{{#invoke:d|e|f=1|g=2}}'),
775
- template = root.firstChild,
776
- invoke = root.lastChild;
777
- assert.deepStrictEqual(template.getKeys(), ['b', 'c']);
778
- assert.deepStrictEqual(invoke.getKeys(), ['f', 'g']);
779
- ```
780
-
781
- **getValues**(key: string\|number): string[]<a id="transcludetoken.getvalues"></a>
782
- - 获取指定名称的参数值(含重复)。
783
-
784
- ```js
785
- var root = Parser.parse('{{a|b|1=c}}{{#invoke:d|e|f|1=g}}'),
786
- template = root.firstChild,
787
- invoke = root.lastChild;
788
- assert.deepStrictEqual(template.getValues(1), ['b', 'c']);
789
- assert.deepStrictEqual(invoke.getValues(1), ['f', 'g']);
790
- ```
791
-
792
- **getValue**(key: string\|number): string<a id="transcludetoken.getvalue"></a>
793
- - 获取指定名称的有效参数值(即最后一个)。
794
-
795
- ```js
796
- var root = Parser.parse('{{a|b|1= c }}{{#invoke:d|e|1=f| g }}'),
797
- template = root.firstChild,
798
- invoke = root.lastChild;
799
- assert(template.getValue(1) === 'c'); // 模板的命名参数不保留首尾的空白字符
800
- assert(invoke.getValue(1) === ' g '); // #invoke魔术字保留匿名参数首位的空白字符
801
- ```
802
-
803
- **newAnonArg**(val: any): void<a id="transcludetoken.newanonarg"></a>
804
- - 在末尾添加新的匿名参数。
805
-
806
- ```js
807
- var root = Parser.parse('{{a|b}}{{#invoke:d|e}}'),
808
- template = root.firstChild,
809
- invoke = root.lastChild;
810
- template.newAnonArg(' c ');
811
- invoke.newAnonArg(' f ');
812
- assert(root.toString() === '{{a|b| c }}{{#invoke:d|e| f }}');
813
- ```
814
-
815
- **setValue**(key: string, value: any): void<a id="transcludetoken.setvalue"></a>
816
- - 修改或新增参数。
817
-
818
- ```js
819
- var root = Parser.parse('{{a|b}}{{#invoke:e|f|g=3}}'),
820
- template = root.firstChild,
821
- invoke = root.lastChild;
822
- template.setValue('1', ' c ');
823
- template.setValue('d', ' 2 ');
824
- invoke.setValue('g', ' 4 ');
825
- assert(root.toString() === '{{a| c |d= 2 }}{{#invoke:e|f|g= 4 }}');
826
- ```
827
-
828
- **anonToNamed**(): void<a id="transcludetoken.anontonamed"></a>
829
- - 将所有匿名参数修改为对应的命名参数。
830
-
831
- ```js
832
- var root = Parser.parse('{{a| b | c }}{{#invoke:d|e| f }}'),
833
- template = root.firstChild,
834
- invoke = root.lastChild;
835
- template.anonToNamed();
836
- invoke.anonToNamed();
837
- assert(root.toString() === '{{a|1= b |2= c }}{{#invoke:d|e|1= f }}'); // 注意改成命名参数后会参数值的首尾空白字符失效
838
- ```
839
-
840
- **replaceTemplate**(title: string): void<a id="transcludetoken.replacetemplate"></a>
841
- - 更换模板,但保留参数。
842
-
843
- ```js
844
- var root = Parser.parse('{{a|b|c=1}}'),
845
- template = root.firstChild;
846
- template.replaceTemplate('aa');
847
- assert(root.toString() === '{{aa|b|c=1}}');
848
- ```
849
-
850
- **hasDuplicatedArgs**(): number<a id="transcludetoken.hasduplicatedargs"></a>
851
- - 重复参数计数。
852
-
853
- ```js
854
- var root = Parser.parse('{{a||1=}}'),
855
- template = root.firstChild;
856
- assert(template.hasDuplicatedArgs() === 1);
857
- ```
858
-
859
- **getDuplicatedArgs**(): \[string, Set\<[ParameterToken](#parametertoken)>][]<a id="transcludetoken.getduplicatedargs"></a>
860
- - 获取全部重复参数,注意顺序可能不固定。
861
-
862
- ```js
863
- var root = Parser.parse('{{a||1=}}'),
864
- template = root.firstChild;
865
- assert.deepStrictEqual(template.getDuplicatedArgs(), [['1', new Set(template.getAllArgs())]]);
866
- ```
867
-
868
- **fixDuplication**(): string[]<a id="transcludetoken.fixduplication"></a>
869
- - 尝试修复重复参数,返回值为无法修复的参数名列表。
870
-
871
- ```js
872
- var root = Parser.parse('{{a|b|1=|1=c}}'),
873
- template = root.firstChild;
874
- assert.deepStrictEqual(template.fixDuplication(), ['1']);
875
- assert(root.toString() === '{{a|b|1=c}}');
876
- ```
877
-
878
- **escapeTables**(): this<a id="transcludetoken.escapetables"></a>
879
- - 如果内部包含疑似未转义的表格语法且因此造成了重复参数,则对这些表格进行转义。
880
-
881
- ```js
882
- var root = Parser.parse('{{a|b=c\n{|\n|rowspan=2|d\n|rowspan=2|e\n|}}}'),
883
- template = root.firstChild;
884
- template.escapeTables();
885
- assert(root.toString() === '{{a|b=c\n{{(!}}\n{{!}}rowspan=2{{!}}d\n{{!}}rowspan=2{{!}}e\n{{!}}}}}');
886
- ```
887
- </details>
888
-
889
- ## 实例属性<a id="transcludetoken.instance.properties"></a>
890
- <details>
891
- <summary>展开</summary>
892
-
893
- **name**: string<a id="transcludetoken.name"></a>
894
- - 模板名(含名字空间)或魔术字。
895
-
896
- ```js
897
- var root = Parser.parse('{{a}}{{!}}'),
898
- template = root.firstChild,
899
- magicWord = root.lastChild;
900
- assert(template.name === 'Template:A');
901
- assert(magicWord.name === '!');
902
- ```
903
-
904
- **modifier**: string<a id="transcludetoken.modifier"></a>
905
- - subst 和 safesubst 等。
906
-
907
- ```js
908
- var root = Parser.parse('<includeonly>{{subst:REVISIONUSER}}</includeonly>', true),
909
- magicWord = root.querySelector('magic-word');
910
- assert(magicWord.modifier === 'subst');
911
- ```
912
- </details>
913
-
914
- [返回目录](#目录)
915
-
916
- # ParameterToken
917
- 模板或魔术字的参数。
918
-
919
- ## 原型方法<a id="parametertoken.prototype.methods"></a>
920
- <details>
921
- <summary>展开</summary>
12
+ 更多文档请查阅 [Wiki](https://github.com/bhsd-harry/wikiparser-node/wiki)。
922
13
 
923
- **getValue**(): string<a id="parametertoken.getvalue"></a>
924
- - 获取参数值。
925
-
926
- ```js
927
- var root = Parser.parse('{{a| b | c = 1 }}'),
928
- [anonymous, named] = root.querySelectorAll('parameter');
929
- assert(anonymous.getValue() === ' b '); // 模板的匿名参数保留首尾的空白字符
930
- assert(named.getValue() === '1'); // 模板的命名参数不保留首尾的空白字符
931
- ```
932
-
933
- **setValue**(value: any): void<a id="parametertoken.setvalue"></a>
934
- - 设置参数值。
935
-
936
- ```js
937
- var root = Parser.parse('{{a|b=1}}'),
938
- param = root.querySelector('parameter');
939
- param.setValue(' 2 ');
940
- assert(root.toString() === '{{a|b= 2 }}'); // setValue方法总是保留空白字符,哪怕是无效的
941
- ```
942
-
943
- **rename**(key: string, force?: boolean = false): void<a id="parametertoken.rename"></a>
944
- - 重命名参数,可选是否在导致重复参数时抛出错误。
945
-
946
- ```js
947
- var root = Parser.parse('{{a|b=1|c=2}}'),
948
- param = root.querySelector('parameter');
949
- try {
950
- param.rename('c');
951
- throw new Error();
952
- } catch (e) {
953
- assert(e.message === '参数更名造成重复参数:c');
954
- }
955
- ```
956
- </details>
957
-
958
- ## 实例属性<a id="parametertoken.instance.properties"></a>
959
- <details>
960
- <summary>展开</summary>
961
-
962
- **name**: string<a id="parametertoken.name"></a>
963
- - 参数名。
964
-
965
- ```js
966
- var root = Parser.parse('{{a|b| c = 1}}'),
967
- [anonymous, named] = root.querySelectorAll('parameter');
968
- assert(anonymous.name === '1');
969
- assert(named.name === 'c');
970
- ```
971
-
972
- **anon**: boolean<a id="parametertoken.anon"></a>
973
- - 是否是匿名参数。
974
-
975
- ```js
976
- var root = Parser.parse('{{a|b| c = 1}}'),
977
- [anonymous, named] = root.querySelectorAll('parameter');
978
- assert(anonymous.anon === true);
979
- assert(named.anon === false);
980
- ```
981
- </details>
982
-
983
- [返回目录](#目录)
984
-
985
- # HtmlToken
986
- HTML标签,未进行匹配。这个类同时混合了 [AttributeToken](#attributetoken) 类的方法。
987
-
988
- ## 原型方法<a id="htmltoken.prototype.methods"></a>
989
- <details>
990
- <summary>展开</summary>
991
-
992
- **replaceTag**(tag: string): void<a id="htmltoken.replacetag"></a>
993
- - 修改标签。
994
-
995
- ```js
996
- var root = Parser.parse('<b>'),
997
- html = root.firstChild;
998
- html.replaceTag('i');
999
- assert(root.toString() === '<i>');
1000
- ```
1001
-
1002
- **findMatchingTag**(): HtmlToken<a id="htmltoken.findmatchingtag"></a>
1003
- - 搜索匹配的另一个标签,找不到或无效自封闭时会抛出不同错误。
1004
-
1005
- ```js
1006
- var root = Parser.parse('<p><b/></i><u></u><br>'),
1007
- [p, b, i, u, u2, br] = root.children;
1008
- try {
1009
- p.findMatchingTag();
1010
- throw new Error();
1011
- } catch (e) {
1012
- assert(e.message === '未闭合的标签:<p>');
1013
- }
1014
- try {
1015
- b.findMatchingTag();
1016
- throw new Error();
1017
- } catch (e) {
1018
- assert(e.message === '无效自封闭标签:<b/>');
1019
- }
1020
- try {
1021
- i.findMatchingTag();
1022
- throw new Error();
1023
- } catch (e) {
1024
- assert(e.message === '未匹配的闭合标签:</i>');
1025
- }
1026
- assert(u.findMatchingTag() === u2);
1027
- assert(br.findMatchingTag() === br);
1028
- ```
1029
-
1030
- **fix**(): void<a id="htmltoken.fix"></a>
1031
- - 尝试修复无效自封闭标签,无法修复时会抛出错误。
1032
-
1033
- ```js
1034
- var root = Parser.parse('<b>a<b/><div style="height:1em"/>');
1035
- for (const html of root.querySelectorAll('html')) {
1036
- html.fix();
1037
- }
1038
- assert(root.toString() === '<b>a</b><div style="height:1em"></div>');
1039
- ```
1040
- </details>
1041
-
1042
- ## 实例属性<a id="htmltoken.instance.properties"></a>
1043
- <details>
1044
- <summary>展开</summary>
1045
-
1046
- **name**: string<a id="htmltoken.name"></a>
1047
- - 小写的标签名。
1048
-
1049
- ```js
1050
- var root = Parser.parse('<b>'),
1051
- html = root.firstChild;
1052
- assert(html.name === 'b');
1053
- ```
1054
-
1055
- **closing**: boolean<a id="htmltoken.closing"></a>
1056
- - 是否是闭合标签。
1057
-
1058
- ```js
1059
- var root = Parser.parse('</b>'),
1060
- html = root.firstChild;
1061
- assert(html.closing === true);
1062
- ```
1063
-
1064
- **selfClosing**: boolean<a id="htmltoken.selfclosing"></a>
1065
- - 是否是自闭合标签(可能不符合HTML5规范)。
1066
-
1067
- ```js
1068
- var root = Parser.parse('<b/>'),
1069
- html = root.firstChild;
1070
- assert(html.selfClosing === true);
1071
- ```
1072
- </details>
1073
-
1074
- [返回目录](#目录)
1075
-
1076
- # TableToken
1077
- 表格。
1078
-
1079
- ## 原型方法<a id="tabletoken.prototype.methods"></a>
1080
- <details>
1081
- <summary>展开</summary>
1082
-
1083
- **getRowCount**(): number<a id="tabletoken.getrowcount"></a>
1084
- - 表格的有效行数。
1085
-
1086
- ```js
1087
- var root = Parser.parse('{|\n|\n|-\n|}'),
1088
- table = root.firstChild;
1089
- assert(table.getRowCount() === 1); // 表格首行可以直接写在 TableToken 下,没有内容的表格行是无效行。
1090
- ```
1091
-
1092
- **getNthRow**(n: number): TrToken<a id="tabletoken.getnthrow"></a>
1093
- - 第 `n` 个有效行。
1094
-
1095
- ```js
1096
- var root = Parser.parse('{|\n|rowspan=2| ||\n|-\n|\n|}'),
1097
- table = root.firstChild;
1098
- assert(table.getNthRow(0) === table);
1099
- assert(table.getNthRow(1) === table.querySelector('tr'));
1100
- ```
1101
-
1102
- |表格示意|
1103
- |:-:|
1104
- |<table><tr><td rowspan=2>第 0 行</td><td>第 0 行</td></tr><tr><td>第 1 行</td></tr></table>|
1105
-
1106
- **getNthCell**(coords: {row: number, column: number}\|{x: number, y: number}): [TdToken](#tdtoken)<a id="tabletoken.getnthcell"></a>
1107
- - 获取指定位置的单元格,指定位置可以基于 raw HTML 或渲染后的表格。
1108
-
1109
- ```js
1110
- var root = Parser.parse('{|\n|rowspan=2 colspan=2| ||\n|-\n|\n|-\n| || ||\n|}'),
1111
- table = root.firstChild,
1112
- td = table.querySelector('td');
1113
- assert(table.getNthCell({row: 0, column: 0}) === td);
1114
- assert(table.getNthCell({x: 1, y: 1}) === td); // 该单元格跨了 2 行 2 列
1115
- ```
1116
-
1117
- |(row, column)|(y, x)|
1118
- |:-:|:-:|
1119
- |<table><tr><td rowspan=2 colspan=2 align="center">(0, 0)</td><td>(0, 1)</td></tr><tr><td>(1, 0)</td></tr><tr><td>(2, 0)</td><td>(2, 1)</td><td>(2, 2)</td></table>|<table><tr><td rowspan=2 colspan=2 align="center">(0, 0), (0, 1)<br>(1, 0), (1, 1)</td><td>(0, 2)</td></tr><tr><td>(1, 2)</td></tr><tr><td>(2, 0)</td><td>(2, 1)</td><td>(2, 2)</td></tr></table>|
1120
-
1121
- **getFullRow**(y: number): Map\<[TdToken](#tdtoken), boolean><a id="tabletoken.getfullrow"></a>
1122
- - 获取一行的所有单元格。
1123
-
1124
- ```js
1125
- var root = Parser.parse('{|\n|rowspan=2| ||\n|-\n|\n|}'),
1126
- table = root.firstChild,
1127
- [a,, c] = table.querySelectorAll('td');
1128
- assert.deepStrictEqual(table.getFullRow(1), new Map([[a, false], [c, true]])); // 起始位置位于该行的单元格值为 `true`
1129
- ```
1130
-
1131
- |表格|选中第 1 行|
1132
- |:-:|:-:|
1133
- |<table><tr><td rowspan=2>&nbsp;</td><td>&nbsp;</td></tr><tr><td>&nbsp;</td></tr></table>|<table><tr><td rowspan=2>`false`</td><td>&nbsp;</td></tr><tr><td>`true`</td></tr></table>|
1134
-
1135
- **getFullCol**(x: number): Map\<[TdToken](#tdtoken), boolean><a id="tabletoken.getfullcol"></a>
1136
- - 获取一列的所有单元格。
1137
-
1138
- ```js
1139
- var root = Parser.parse('{|\n|colspan=2|\n|-\n| ||\n|}'),
1140
- table = root.firstChild,
1141
- [a,, c] = table.querySelectorAll('td');
1142
- assert.deepStrictEqual(table.getFullCol(1), new Map([[a, false], [c, true]])); // 起始位置位于该列的单元格值为 `true`
1143
- ```
1144
-
1145
- |表格|选中第 1 列|
1146
- |:-:|:-:|
1147
- |<table><tr><td colspan=2>&nbsp;</td></tr><tr><td>&nbsp;</td><td>&nbsp;</td></tr></table>|<table><tr><td colspan=2 align="center">`false`</td></tr><tr><td>&nbsp;</td><td>`true`</td></tr></table>|
1148
-
1149
- **formatTableRow**(y: number, attr: string\|Record\<string, string\|boolean>, multiRow?: boolean = false): void<a id="tabletoken.formattablerow"></a>
1150
- - 批量设置一行单元格的属性。
1151
-
1152
- ```js
1153
- var root = Parser.parse('{|\n|rowspan=2| ||\n|-\n|\n|}'),
1154
- table = root.firstChild;
1155
- table.formatTableRow(1, 'th'); // `multiRow` 为假时忽略起始位置不在该行的单元格
1156
- assert(root.toString() === '{|\n|rowspan=2| ||\n|-\n!\n|}');
1157
- ```
1158
-
1159
- |原表格|将第 1 行设为`<th>`<br>`multiRow = false`|将第 1 行设为`<th>`<br>`multiRow = true`|
1160
- |:-:|:-:|:-:|
1161
- |<table><tr><td rowspan=2 align="center">td</td><td>td</td></tr><tr><td>td</td></tr></table>|<table><tr><td rowspan=2>td</td><td>td</td></tr><tr><th>th</th></tr></table>|<table><tr><th rowspan=2>th</th><td>td</td></tr><tr><th>th</th></tr></table>|
1162
-
1163
- **formatTableCol**(x: number, attr: string\|Record\<string, string\|boolean>, multiCol?: boolean = false): void<a id="tabletoken.formattablecol"></a>
1164
- - 批量设置一列单元格的属性。
1165
-
1166
- ```js
1167
- var root = Parser.parse('{|\n|colspan=2|\n|-\n| ||\n|}'),
1168
- table = root.firstChild;
1169
- table.formatTableCol(1, 'th', true); // `multiCol` 为真时包含起始位置不在该列的单元格
1170
- assert(root.toString() === '{|\n!colspan=2|\n|-\n| \n!\n|}');
1171
- ```
1172
-
1173
- |原表格|将第 1 列设为`<th>`<br>`multiCol = false`|将第 1 列设为`<th>`<br>`multiCol = true`|
1174
- |:-:|:-:|:-:|
1175
- |<table><tr><td colspan=2>td</td></tr><tr><td>td</td><td>td</td></tr></table>|<table><tr><td colspan=2>td</td></tr><tr><td>td</td><th>th</th></tr></table>|<table><tr><th colspan=2>th</th></tr><tr><td>td</td><th>th</th></tr></table>|
1176
-
1177
- **insertTableRow**(row: number, attr: Record\<string, string\|boolean>, inner?: string, subtype?: 'td'\|'th' = 'td', innerAttr?: Record\<string, string\|boolean>): TrToken<a id="tabletoken.inserttablerow"></a>
1178
- - 插入空行或一行单元格。
1179
-
1180
- ```js
1181
- var root = Parser.parse('{|\n|a||rowspan=2|b||c\n|-\n|d||e\n|}'),
1182
- table = root.firstChild;
1183
- table.insertTableRow(1, {class: 'tr'}); // 不填写 `inner` 等后续参数时会插入一个空行,且此时是无效行。
1184
- table.insertTableRow(1, {}, 'f', 'th', {class: 'th'});
1185
- assert(root.toString() === '{|\n|a|| rowspan="3"|b||c\n|- class="tr"\n|-\n! class="th"|f\n! class="th"|f\n|-\n|d||e\n|}');
1186
- ```
1187
-
1188
- |原表格|插入 1 行|
1189
- |:-:|:-:|
1190
- |<table><tr><td>a</td><td rowspan=2>b</td><td>c</td></tr><tr><td>d</td><td>e</td></tr></table>|<table><tr><td>a</td><td rowspan=3>b</td><td>c</td></tr><tr><th>f</th><th>f</th></tr><tr><td>d</td><td>e</td></tr></table>|
1191
-
1192
- **insertTableCol**(x: number, inner: string, subtype?: 'td'\|'th' = 'td', attr?: Record\<string, string\|boolean>): void<a id="tabletoken.inserttablecol"></a>
1193
- - 插入一列单元格。
1194
-
1195
- ```js
1196
- var root = Parser.parse('{|\n|colspan=2|a\n|-\n|b||c\n|}'),
1197
- table = root.firstChild;
1198
- table.insertTableCol(1, 'd', 'th', {class: 'th'});
1199
- assert(root.toString() === '{|\n| colspan="3"|a\n|-\n|b\n! class="th"|d\n|c\n|}');
1200
- ```
1201
-
1202
- |原表格|插入 1 列|
1203
- |:-:|:-:|
1204
- |<table><tr><td colspan=2 align="center">a</td></tr><tr><td>b</td><td>c</td></tr></table>|<table><tr><td colspan=3 align="center">a</td></tr><tr><td>b</td><th>d</th><td>c</td></tr></table>|
1205
-
1206
- **insertTableCell**(inner: string, coords: {row: number, column: number}\|{x: number, y: number}, subtype?: 'td'\|'th' = 'td', attr?: Record\<string, string\|boolean>): [TdToken](#tdtoken)<a id="tabletoken.inserttablecell"></a>
1207
- - 插入一个单元格。
1208
-
1209
- ```js
1210
- var root = Parser.parse('{|\n|rowspan=2 colspan=2|a||b\n|-\n|c\n|-\n|d||e||f\n|}'),
1211
- table = root.firstChild;
1212
- table.insertTableCell('g', {row: 0, column: 2}, 'th');
1213
- table.insertTableCell('h', {x: 2, y: 1}, 'th', {rowspan: 2});
1214
- assert(root.toString() === '{|\n|rowspan=2 colspan=2|a||b\n!g\n|-\n! rowspan="2"|h\n|c\n|-\n|d||e||f\n|}');
1215
- ```
1216
-
1217
- |原表格|插入 2 格|
1218
- |:-:|:-:|
1219
- |<table><tr><td rowspan=2 colspan=2 align="center">a</td><td>b</td></tr><tr><td>c</td></tr><tr><td>d</td><td>e</td><td>f</td></tr></table>|<table><tr><td rowspan=2 colspan=2 align="center">a</td><td>b</td><th>g</th></tr><tr><th rowspan=2>h</th><td>c</td></tr><tr><td>d</td><td>e</td><td>f</td></tr></table>
1220
-
1221
- **removeTableRow**(y: number): TrToken<a id="tabletoken.removetablerow"></a>
1222
- - 删除一行。
1223
-
1224
- ```js
1225
- var root = Parser.parse('{|\n|rowspan=2|a||b||c\n|-\n!rowspan=2 class="th"|d||e\n|-\n|f||g\n|}'),
1226
- table = root.firstChild;
1227
- table.removeTableRow(1);
1228
- assert(root.toString() === '{|\n|a||b||c\n|-\n|f\n! class="th"|\n|g\n|}'); // 自动调整跨行单元格的 rowspan
1229
- ```
1230
-
1231
- |原表格|删除第 1 行|
1232
- |:-:|:-:|
1233
- |<table><tr><td rowspan=2>a</td><td>b</td><td>c</td></tr><tr><th rowspan=2>d</th><th>e</th></tr><tr><td>f</td><td>g</td></tr></table>|<table><tr><td>a</td><td>b</td><td>c</td></tr><tr><td>f</td><td></td><td>g</td></tr></table>|
1234
-
1235
- **removeTableCol**(x: number): void<a id="tabletoken.removetablecol"></a>
1236
- - 删除一列。
1237
-
1238
- ```js
1239
- var root = Parser.parse('{|\n|colspan=2|a||b\n|-\n|c\n!colspan=2 class="th"|d\n|-\n|e\n!f\n|g\n|}'),
1240
- table = root.firstChild;
1241
- table.removeTableCol(1);
1242
- assert(root.toString() === '{|\n|a||b\n|-\n|c\n! class="th"|\n|-\n|e\n|g\n|}'); // 自动调整跨列单元格的 colspan
1243
- ```
1244
-
1245
- |原表格|删除第 1 列|
1246
- |:-:|:-:|
1247
- |<table><tr><td colspan=2 align="center">a</td><td>b</td></tr><tr><td>c</td><th colspan=2>d</th></tr><tr><td>e</td><th>f</th><td>g</td></tr></table>|<table><tr><td>a</td><td>b</td></tr><tr><th>c</th><th></th></tr><tr><td>e</td><td>g</td></tr></table>|
1248
-
1249
- **mergeCells**(xlim: [number, number], ylim: [number, number]): [TdToken](#tdtoken)<a id="tabletoken.mergecells"></a>
1250
- - 合并单元格。
1251
-
1252
- ```js
1253
- var root = Parser.parse('{|\n!a\n|b||c\n|-\n|d||e||f\n|-\n|g||h||i\n|}'),
1254
- table = root.firstChild;
1255
- table.mergeCells([0, 2], [0, 2]); // 被合并的单元格的属性和内部文本均会丢失
1256
- assert(root.toString() === '{|\n! rowspan="2" colspan="2"|a\n|c\n|-\n|f\n|-\n|g||h||i\n|}');
1257
- ```
1258
-
1259
- |原表格|合并单元格|
1260
- |:-:|:-:|
1261
- |<table><tr><th>a</th><td>b</td><td>c</td></tr><tr><td>d</td><td>e</td><td>f</td></tr><tr><td>g</td><td>h</td><td>i</td></tr></table>|<table><tr><th rowspan=2 colspan=2>a</th><td>c</td></tr><tr><td>f</td></tr><tr><td>g</td><td>h</td><td>i</td></tr></table>|
1262
-
1263
- **splitIntoRows**(coords: {row: number, column: number}\|{x: number, y: number}): void<a id="tabletoken.splitintorows"></a>
1264
- - 将单元格分裂到不同行。
1265
-
1266
- ```js
1267
- var root = Parser.parse('{|\n|a||b\n!rowspan=3|c\n|-\n|d\n|-\n|e||f\n|}'),
1268
- table = root.firstChild;
1269
- table.splitIntoRows({x: 2, y: 0});
1270
- assert(root.toString() === '{|\n|a||b\n!c\n|-\n|d\n|-\n|e||f\n!\n|}'); // 第 1 行由于缺失第 1 列的单元格,分裂后的第 2 列不会保留
1271
- ```
1272
-
1273
- |原表格|按行分裂单元格|
1274
- |:-:|:-:|
1275
- |<table><tr><td>a</td><td>b</td><th rowspan=3>c</th></tr><tr><td>d</td></tr><tr><td>e</td><td>f</td></tr></table>|<table><tr><td>a</td><td>b</td><th>c</th></tr><tr><td>d</td></tr><tr><td>e</td><td>f</td><th></th></tr></table>|
1276
-
1277
- **splitIntoCols**(coords: {row: number, column: number}\|{x: number, y: number}): void<a id="tabletoken.splitintocols"></a>
1278
- - 将单元格分裂到不同列。
1279
-
1280
- ```js
1281
- var root = Parser.parse('{|\n!colspan=2 class="th"|a\n|}'),
1282
- table = root.firstChild;
1283
- table.splitIntoCols({x: 1, y: 0});
1284
- assert(root.toString() === '{|\n! class="th"|a\n! class="th"|\n|}'); // 分裂继承属性
1285
- ```
1286
-
1287
- |原表格|按列分裂单元格|
1288
- |:-:|:-:|
1289
- |<table><tr><th colspan=2>a</th></tr></table>|<table><tr><th>a</th><th>&nbsp;</th></tr></table>|
1290
-
1291
- **splitIntoCells**(coords: {row: number, column: number}\|{x: number, y: number}): void<a id="tabletoken.splitintocells"></a>
1292
- - 将单元格分裂成最小单元格。
1293
-
1294
- ```js
1295
- var root = Parser.parse('{|\n!rowspan=2 colspan=2|a\n|b\n|-\n|c\n|-\n|d||e||f\n|}'),
1296
- table = root.firstChild;
1297
- table.splitIntoCells({x: 0, y: 0});
1298
- assert(root.toString() === '{|\n!a\n!\n|b\n|-\n!\n!\n|c\n|-\n|d||e||f\n|}');
1299
- ```
1300
-
1301
- |原表格|分裂单元格|
1302
- |:-:|:-:|
1303
- |<table><tr><th rowspan=2 colspan=2>a</th><td>b</td></tr><tr><td>c</td></tr><tr><td>d</td><td>e</td><td>f</td></tr></table>|<table><tr><th>a</th><th></th><td>b</td></tr><tr><th></th><th></th><td>c</td></tr><tr><td>d</td><td>e</td><td>f</td></tr></table>|
1304
-
1305
- **replicateTableRow**(row: number): TrToken<a id="tabletoken.replicatetablerow"></a>
1306
- - 复制一行并插入该行之前
1307
-
1308
- ```js
1309
- var root = Parser.parse('{|\n|rowspan=2|a||b||c\n|-\n!rowspan=2|d||e\n|-\n|f||g\n|}'),
1310
- table = root.firstChild;
1311
- table.replicateTableRow(1);
1312
- assert(root.toString() === '{|\n| rowspan="3"|a||b||c\n|-\n!d||e\n|-\n!rowspan=2|d||e\n|-\n|f||g\n|}'); // 复制行内的单元格`rowspan`总是为1
1313
- ```
1314
-
1315
- |原表格|复制第 1 行|
1316
- |:-:|:-:|
1317
- |<table><tr><td rowspan=2>a</td><td>b</td><td>c</td></tr><tr><th rowspan=2>d</th><th>e</th></tr><tr><td>f</td><td>g</td></tr></table>|<table><tr><td rowspan=3>a</td><td>b</td><td>c</td></tr><tr><th>d</th><th>e</th></tr><tr><th rowspan=2>d</th><th>e</th></tr><tr><td>f</td><td>g</td></tr></table>|
1318
-
1319
- **replicateTableCol**(x: number): [TdToken](#tdtoken)[]<a id="tabletoken.replicatetablecol"></a>
1320
- - 复制一列并插入该列之前
1321
-
1322
- ```js
1323
- var root = Parser.parse('{|\n|colspan=2|a||b\n|-\n|c\n!colspan=2|d\n|-\n|e\n!f\n|g\n|}'),
1324
- table = root.firstChild;
1325
- table.replicateTableCol(1);
1326
- assert(root.toString() === '{|\n| colspan="3"|a||b\n|-\n|c\n!d\n!colspan=2|d\n|-\n|e\n!f\n!f\n|g\n|}'); // 复制列内的单元格`colspan`总是为1
1327
- ```
1328
-
1329
- |原表格|复制第 1 列|
1330
- |:-:|:-:|
1331
- |<table><tr><td colspan=2 align="center">a</td><td>b</td></tr><tr><td>c</td><th colspan=2>d</th></tr><tr><td>e</td><th>f</th><td>g</td></tr></table>|<table><tr><td colspan=3 align="center">a</td><td>b</td></tr><tr><td>c</td><th>d</th><th colspan=2>d</th></tr><tr><td>e</td><th>f</th><th>f</th><td>g</td></tr></table>|
1332
-
1333
- **moveTableRowBefore**(y: number, before: number): TrToken<a id="tabletoken.movetablerowbefore"></a>
1334
- - 移动表格行。
1335
-
1336
- ```js
1337
- var root = Parser.parse('{|\n|rowspan=2|a||b||c||d\n|-\n|colspan=2|e||f\n|-\n|rowspan=2|g||h||i||j\n|-\n!rowspan=2|k||colspan=2|l\n|-\n|m||n||o\n|}'),
1338
- table = root.firstChild;
1339
- table.moveTableRowBefore(3, 1);
1340
- assert(root.toString() === '{|\n| rowspan="3"|a||b||c||d\n|-\n!k||colspan=2|l\n|-\n|colspan=2|e||f\n|-\n|g||h||i||j\n|-\n|m\n!\n|n||o\n|}');
1341
- ```
1342
-
1343
- |原表格|移动第 3 行至第 1 行前|
1344
- |:-:|:-:|
1345
- |<table><tr><td rowspan=2>a</td><td>b</td><td>c</td><td>d</td></tr><tr><td colspan=2 align="center">e</td><td>f</td></tr><tr><td rowspan=2>g</td><td>h</td><td>i</td><td>j</td></tr><tr><th rowspan=2>k</th><th colspan=2>l</th></tr><tr><td>m</td><td>n</td><td>o</td></tr></table>|<table><tr><td rowspan=3>a</td><td>b</td><td>c</td><td>d</td></tr><tr><th>k</th><th colspan=2>l</th></tr><tr><td colspan=2 align="center">e</td><td>f</td></tr><tr><td>g</td><td>h</td><td>i</td><td>j</td></tr><tr><td>m</td><th></th><td>n</td><td>o</td></tr></table>|
1346
-
1347
- **moveTableRowAfter**(y: number, after: number): TrToken<a id="tabletoken.movetablerowafter"></a>
1348
- - 移动表格行。
1349
-
1350
- ```js
1351
- var root = Parser.parse('{|\n|rowspan=2|a||colspan=2|b||c\n|-\n|d||e||f\n|-\n|rowspan=2|g||h||i||j\n|-\n!rowspan=2|k||colspan=2|l\n|-\n|m||n||o\n|}'),
1352
- table = root.firstChild;
1353
- table.moveTableRowAfter(3, 0);
1354
- assert(root.toString() === '{|\n| rowspan="3"|a||colspan=2|b||c\n|-\n!k||colspan=2|l\n|-\n|d||e||f\n|-\n|g||h||i||j\n|-\n|m\n!\n|n||o\n|}');
1355
- ```
1356
-
1357
- |原表格|移动第 3 行至第 0 行后|
1358
- |:-:|:-:|
1359
- |<table><tr><td rowspan=2>a</td><td colspan=2 align="center">b</td><td>c</td></tr><tr><td>d</td><td>e</td><td>f</td></tr><tr><td rowspan=2>g</td><td>h</td><td>i</td><td>j</td></tr><tr><th rowspan=2>k</th><th colspan=2>l</th></tr><tr><td>m</td><td>n</td><td>o</td></tr></table>|<table><tr><td rowspan=3>a</td><td colspan=2 align="center">b</td><td>c</td></tr><tr><th>k</th><th colspan=2>l</th></tr><tr><td>d</td><td>e</td><td>f</td></tr><tr><td>g</td><td>h</td><td>i</td><td>j</td></tr><tr><td>m</td><th></th><td>n</td><td>o</td></tr></table>|
1360
-
1361
- **moveTableColBefore**(x: number, before: number): void<a id="tabletoken.movetablecolbefore"></a>
1362
- - 移动表格列。
1363
-
1364
- ```js
1365
- var root = Parser.parse('{|\n|colspan=2|a||colspan=2|b||c\n|-\n|d||rowspan=2|e||f\n!colspan=2|g\n|-\n|h||i\n!rowspan=2|j\n|k\n|-\n|l||m||n||o\n|}'),
1366
- table = root.firstChild;
1367
- table.moveTableColBefore(3, 1);
1368
- assert(root.toString() === '{|\n| colspan="3"|a||b||c\n|-\n|d\n!g\n|rowspan=2|e||f\n!\n|-\n|h\n!rowspan=2|j\n|i\n|k\n|-\n|l||m||n||o\n|}');
1369
- ```
1370
-
1371
- |原表格|移动第 3 列至第 1 列前|
1372
- |:-:|:-:|
1373
- |<table><tr><td colspan=2 align="center">a</td><td colspan=2 align="center">b</td><td>c</td></tr><tr><td>d</td><td rowspan=2>e</td><td>f</td><th colspan=2>g</th></tr><tr><td>h</td><td>i</td><th rowspan=2>j</th><td>k</td></tr><tr><td>l</td><td>m</td><td>n</td><td>o</td></tr></table>|<table><tr><td colspan=3 align="center">a</td><td>b</td><td>c</td></tr><tr><td>d</td><th>g</th><td rowspan=2>e</td><td>f</td><th></th></tr><tr><td>h</td><th rowspan=2>j</th><td>i</td><td>k</td></tr><tr><td>l</td><td>m</td><td>n</td><td>o</td></tr></table>|
1374
-
1375
- **moveTableColAfter**(x: number, after: number): void<a id="tabletoken.movetablecolafter"></a>
1376
- - 移动表格列。
1377
-
1378
- ```js
1379
- var root = Parser.parse('{|\n|colspan=2|a||colspan=2|b||c\n|-\n|rowspan=2|d||e||f\n!colspan=2|g\n|-\n|h||i\n!rowspan=2|j\n|k\n|-\n|l||m||n||o\n|}'),
1380
- table = root.firstChild;
1381
- table.moveTableColAfter(3, 0);
1382
- assert(root.toString() === '{|\n| colspan="3"|a||b||c\n|-\n|rowspan=2|d\n!g\n|e||f\n!\n|-\n!rowspan=2|j\n|h||i\n|k\n|-\n|l||m||n||o\n|}');
1383
- ```
1384
-
1385
- |原表格|移动第 3 列至第 0 列后|
1386
- |:-:|:-:|
1387
- |<table><tr><td colspan=2 align="center">a</td><td colspan=2 align="center">b</td><td>c</td></tr><tr><td rowspan=2>d</td><td>e</td><td>f</td><th colspan=2>g</th></tr><tr><td>h</td><td>i</td><th rowspan=2>j</th><td>k</td></tr><tr><td>l</td><td>m</td><td>n</td><td>o</td></tr></table>|<table><tr><td colspan=3 align="center">a</td><td>b</td><td>c</td></tr><tr><td rowspan=2>d</td><th>g</th><td>e</td><td>f</td><th></th></tr><tr><th rowspan=2>j</th><td>h</td><td>i</td><td>k</td></tr><tr><td>l</td><td>m</td><td>n</td><td>o</td></tr></table>|
1388
- </details>
1389
-
1390
- [返回目录](#目录)
1391
-
1392
- # TdToken
1393
- 表格单元格。
1394
-
1395
- ## 原型属性<a id="tdtoken.prototype.properties"></a>
1396
- <details>
1397
- <summary>展开</summary>
1398
-
1399
- **subtype**: 'td'\|'th'\|'caption'<a id="tdtoken.subtype"></a>
1400
-
1401
- ```js
1402
- var root = Parser.parse('{|\n|+\n!\n|\n|}'),
1403
- [caption, th, td] = root.querySelectorAll('td');
1404
- assert(caption.subtype === 'caption');
1405
- assert(th.subtype === 'th');
1406
- assert(td.subtype === 'td');
1407
- ```
1408
-
1409
- **rowspan**: number<a id="tdtoken.rowspan"></a>
1410
-
1411
- ```js
1412
- var root = Parser.parse('{|\n|\n|}'),
1413
- td = root.querySelector('td');
1414
- assert(td.rowspan === 1);
1415
- ```
1416
-
1417
- **colspan**: number<a id="tdtoken.colspan"></a>
1418
-
1419
- ```js
1420
- var root = Parser.parse('{|\n|\n|}'),
1421
- td = root.querySelector('td');
1422
- assert(td.colspan === 1);
1423
- ```
1424
- </details>
1425
-
1426
- [返回目录](#目录)
1427
-
1428
- # DoubleUnderscoreToken
1429
- 状态开关。
1430
-
1431
- ## 实例属性<a id="doubleunderscoretoken.instance.properties"></a>
1432
- <details>
1433
- <summary>展开</summary>
1434
-
1435
- **name**: string<a id="doubleunderscoretoken.name"></a>
1436
- - 小写的状态开关名。
1437
-
1438
- ```js
1439
- var root = Parser.parse('__NOTOC__'),
1440
- doubleUnderscore = root.firstChild;
1441
- assert(doubleUnderscore.name === 'notoc');
1442
- ```
1443
- </details>
1444
-
1445
- [返回目录](#目录)
1446
-
1447
- # LinkToken
1448
- 内链,包括跨维基链接。
1449
-
1450
- ## 原型方法<a id="linktoken.prototype.methods"></a>
1451
- <details>
1452
- <summary>展开</summary>
1453
-
1454
- **setTarget**(link: string): void<a id="linktoken.settarget"></a>
1455
- - 修改内链目标。
1456
-
1457
- ```js
1458
- var root = Parser.parse('[[a]]'),
1459
- link = root.firstChild;
1460
- link.setTarget('b');
1461
- assert(root.toString() === '[[:b]]'); // 自动在开头添加':'
1462
- ```
1463
-
1464
- **setFragment**(fragment: string): void<a id="linktoken.setfragment"></a>
1465
- - 不改变目标页面,仅修改 fragment。
1466
-
1467
- ```js
1468
- var root = Parser.parse('[[:file:a]]'),
1469
- link = root.firstChild;
1470
- link.setFragment('b');
1471
- assert(root.toString() === '[[:File:A#b]]'); // 这个方法会同时规范化页面名
1472
- ```
1473
-
1474
- **asSelfLink**(fragment?: string): void<a id="linktoken.asselflink"></a>
1475
- - 当原链接带有或指定 fragment 时,将内链修改为 selfLink 格式。
1476
-
1477
- ```js
1478
- var root = Parser.parse('[[a#b]]'),
1479
- link = root.firstChild;
1480
- link.asSelfLink();
1481
- assert(root.toString() === '[[#b]]');
1482
- ```
1483
-
1484
- **setLinkText**(linkText: string)<a id="linktoken.setlinktext"></a>
1485
- - 修改链接文本。
1486
-
1487
- ```js
1488
- var root = Parser.parse('[[a]]'),
1489
- link = root.firstChild;
1490
- link.setLinkText('b');
1491
- assert(root.toString() === '[[a|b]]');
1492
- link.removeAt(1); // 若要移除链接文本,直接使用removeAt方法即可
1493
- assert(root.toString() === '[[a]]');
1494
- ```
1495
-
1496
- **pipeTrick**(): void<a id="linktoken.pipetrick"></a>
1497
- - 模拟解析器预转换的 pipe trick。
1498
-
1499
- ```js
1500
- var root = Parser.parse('[[help:a (b)]]'),
1501
- link = root.firstChild;
1502
- link.pipeTrick();
1503
- assert(root.toString() === '[[help:a (b)|a]]');
1504
- ```
1505
- </details>
1506
-
1507
- ## 实例属性<a id="linktoken.instance.properties"></a>
1508
- <details>
1509
- <summary>展开</summary>
1510
-
1511
- **name**: string<a id="linktoken.name"></a>
1512
- - 规范化的目标页面名称。
1513
-
1514
- ```js
1515
- var root = Parser.parse('[[:文件:a]]'),
1516
- link = root.firstChild;
1517
- assert(link.name === 'File:A');
1518
- ```
1519
-
1520
- **selfLink**: boolean<a id="linktoken.selflink"></a>
1521
- - 是否是 selfLink。
1522
-
1523
- ```js
1524
- var root = Parser.parse('[[#a]]'),
1525
- link = root.firstChild;
1526
- assert(link.selfLink === true);
1527
- ```
1528
-
1529
- **fragment**: string<a id="linktoken.fragment"></a>
1530
- - URL 解码后的 fragment。
1531
-
1532
- ```js
1533
- var root = Parser.parse('[[#.7B.7D]]'), // 兼容 MediaWiki 式的 fragment 编码
1534
- link = root.firstChild;
1535
- assert(link.fragment === '{}');
1536
- ```
1537
-
1538
- **interwiki**: string<a id="linktoken.interwiki"></a>
1539
- - 跨维基前缀。
1540
-
1541
- ```js
1542
- var root = Parser.parse('[[zhwiki:a]]'),
1543
- link = root.firstChild;
1544
- assert(link.interwiki === 'zhwiki');
1545
- ```
1546
- </details>
1547
-
1548
- [返回目录](#目录)
1549
-
1550
- # CategoryToken
1551
- 分类。这个类继承了 [LinkToken](#linktoken) 类。
1552
-
1553
- ## 原型方法<a id="categorytoken.prototype.methods"></a>
1554
- <details>
1555
- <summary>展开</summary>
1556
-
1557
- **setSortkey**(text: string): void<a id="categorytoken.setsortkey"></a>
1558
- - 修改分类关键字,实际上就是 [setLinkText](#linktoken.setlinktext) 方法的别名。
1559
-
1560
- ```js
1561
- var root = Parser.parse('[[category:a]]'),
1562
- category = root.firstChild;
1563
- category.setSortkey('*');
1564
- assert(root.toString() === '[[category:a|*]]');
1565
- ````
1566
- </details>
1567
-
1568
- ## 实例属性<a id="categorytoken.instance.properties"></a>
1569
- <details>
1570
- <summary>展开</summary>
1571
-
1572
- **sortkey**: string<a id="categorytoken.sortkey"></a>
1573
- - 分类关键字。
1574
-
1575
- ```js
1576
- var root = Parser.parse('[[category:a|*]]'),
1577
- category = root.firstChild;
1578
- assert(category.sortkey === '*');
1579
- ```
1580
- </details>
1581
-
1582
- [返回目录](#目录)
1583
-
1584
- # FileToken
1585
- 文件。这个类继承了 [LinkToken](#linktoken) 类。
1586
-
1587
- ## 原型方法<a id="filetoken.prototype.methods"></a>
1588
- <details>
1589
- <summary>展开</summary>
1590
-
1591
- **getAllArgs**(): [ImageParameterToken](#imageparametertoken)[]<a id="filetoken.getallargs"></a>
1592
- - 获取所有图片参数,类似 [TranscludeToken.getAllArgs](#transcludetoken.getallargs) 方法。
1593
-
1594
- ```js
1595
- var root = Parser.parse('[[file:a|thumb|1px|link=b|alt=c|d]]'),
1596
- file = root.firstChild;
1597
- assert.deepStrictEqual(file.getAllArgs(), file.children.slice(1));
1598
- ```
1599
-
1600
- **getArgs**(key: string): Set\<[ImageParameterToken](#imageparametertoken)><a id="filetoken.getargs"></a>
1601
- - 获取指定的图片参数,类似 [TranscludeToken.getArgs](#transcludetoken.getargs) 方法。
1602
-
1603
- ```js
1604
- var root = Parser.parse('[[file:a|link=b|链接=c]]'), // 这里故意使用一个错误语法的例子,请勿模仿
1605
- file = root.firstChild;
1606
- assert.deepStrictEqual(file.getArgs('link'), new Set(file.children.slice(1)));
1607
- ```
1608
-
1609
- **hasArg**(key: string): boolean<a id="filetoken.hasarg"></a>
1610
- - 是否带有指定的图片参数,类似 [TranscludeToken.hasArg](#transcludetoken.hasarg) 方法。
1611
-
1612
- ```js
1613
- var root = Parser.parse('[[file:a|b]]'),
1614
- file = root.firstChild;
1615
- assert(file.hasArg('caption') === true);
1616
- ```
1617
-
1618
- **getArg**(key: string): [ImageParameterToken](#imageparametertoken)<a id="filetoken.getarg"></a>
1619
- - 获取最后一个指定的图片参数,类似 [TranscludeToken.getArg](#transcludetoken.getarg) 方法。
1620
-
1621
- ```js
1622
- var root = Parser.parse('[[file:a|link=b|链接=c]]'), // 这里故意使用一个错误语法的例子,请勿模仿
1623
- file = root.firstChild;
1624
- assert(file.getArg('link'), file.lastChild);
1625
- ```
1626
-
1627
- **removeArg**(key: string): void<a id="filetoken.removearg"></a>
1628
- - 移除指定的图片参数,类似 [TranscludeToken.removeArg](#transcludetoken.removearg) 方法。
1629
-
1630
- ```js
1631
- var root = Parser.parse('[[file:a|link=b|链接=c]]'), // 这里故意使用一个错误语法的例子,请勿模仿
1632
- file = root.firstChild;
1633
- file.removeArg('link');
1634
- assert(root.toString() === '[[file:a]]');
1635
- ```
1636
-
1637
- **getKeys**(): string[]<a id="filetoken.getkeys"></a>
1638
- - 获取所有图片参数名,类似 [TranscludeToken.getKeys](#transcludetoken.getkeys) 方法。
1639
-
1640
- ```js
1641
- var root = Parser.parse('[[file:a|thumb|1px|link=b|alt=c|d]]'),
1642
- file = root.firstChild;
1643
- assert.deepStrictEqual(file.getKeys(), ['thumbnail', 'width', 'link', 'alt', 'caption']);
1644
- ```
1645
-
1646
- **getValue**(key: string): string\|true<a id="filetoken.getvalue"></a>
1647
- - 获取指定的图片参数值,类似 [TranscludeToken.getValue](#transcludetoken.getvalue) 方法。
1648
-
1649
- ```js
1650
- var root = Parser.parse('[[file:a|thumb|100px]]'),
1651
- file = root.firstChild;
1652
- assert(file.getValue('thumbnail') === true);
1653
- assert(file.getValue('width') === '100');
1654
- ```
1655
-
1656
- **setValue**(key: string, value: string\|boolean): void<a id="filetoken.setvalue"></a>
1657
- - 修改或设置指定的图片参数,类似 [TranscludeToken.setValue](#transcludetoken.setvalue) 方法。
1658
-
1659
- ```js
1660
- var root = Parser.parse('[[file:a|thumb]]'),
1661
- file = root.firstChild;
1662
- file.setValue('thumbnail', false);
1663
- file.setValue('width', '100');
1664
- file.setValue('framed', true);
1665
- assert(root.toString() === '[[file:a|100px|framed]]');
1666
- ```
1667
- </details>
1668
-
1669
- ## 原型属性<a id="filetoken.prototype.properties"></a>
1670
- <details>
1671
- <summary>展开</summary>
1672
-
1673
- **link**: string\|symbol<a id="filetoken.link"></a>
1674
- - 链接目标。
1675
-
1676
- ```js
1677
- var root = Parser.parse('[[file:a|link=[[talk:b]]]]'),
1678
- file = root.firstChild;
1679
- assert(file.link === 'Talk:B');
1680
- file.link = '//c';
1681
- assert(root.toString() === '[[file:a|link=//c]]');
1682
- ```
1683
-
1684
- **size**: {width: string, height: string}<a id="filetoken.size"></a>
1685
- - 图片尺寸。
1686
-
1687
- ```js
1688
- var root = Parser.parse('[[file:a|x1px]]'),
1689
- file = root.firstChild;
1690
- assert.deepStrictEqual(file.size, {width: '', height: '1'});
1691
- ```
1692
-
1693
- **width**: number<a id="filetoken.width"></a>
1694
- - 图片宽度。
1695
-
1696
- ```js
1697
- var root = Parser.parse('[[file:a|1x1px]]'),
1698
- file = root.firstChild;
1699
- assert(file.width === '1');
1700
- file.width = undefined;
1701
- assert(root.toString() === '[[file:a|x1px]]');
1702
- ```
1703
-
1704
- **height**: number<a id="filetoken.height"></a>
1705
- - 图片高度。
1706
-
1707
- ```js
1708
- var root = Parser.parse('[[file:a|1x1px]]'),
1709
- file = root.firstChild;
1710
- assert(file.height === '1');
1711
- file.height = undefined;
1712
- assert(root.toString() === '[[file:a|1px]]');
1713
- ```
1714
- </details>
1715
-
1716
- [返回目录](#目录)
1717
-
1718
- # ImageParameterToken
1719
- 图片参数。
1720
-
1721
- ## 原型方法<a id="imageparametertoken.prototype.methods"></a>
1722
- <details>
1723
- <summary>展开</summary>
1724
-
1725
- **getValue**(): string\|true<a id="imageparametertoken.getvalue"></a>
1726
- - 获取图片参数值,类似 [ParameterToken.getValue](#parametertoken.getvalue) 方法。
1727
-
1728
- ```js
1729
- var root = Parser.parse('[[file:a|thumb|100px]]'),
1730
- [thumbnail, width] = root.querySelectorAll('image-parameter');
1731
- assert(thumbnail.getValue() === true);
1732
- assert(width.getValue() === '100');
1733
- ```
1734
-
1735
- **setValue**(value: string\|boolean): void<a id="imageparametertoken.setvalue"></a>
1736
- - 修改或移除图片参数,类似 [ParameterToken.setValue](#parametertoken.setvalue) 方法。
1737
-
1738
- ```js
1739
- var root = Parser.parse('[[file:a|thumb|100px]]'),
1740
- [thumbnail, width] = root.querySelectorAll('image-parameter');
1741
- thumbnail.setValue(false);
1742
- width.setValue('x100');
1743
- assert(root.toString() === '[[file:a|x100px]]');
1744
- ```
1745
- </details>
1746
-
1747
- [返回目录](#目录)
1748
-
1749
- # ExtLinkToken
1750
- `[]`内的外部链接。这个类同时混合了 [MagicLinkToken](#magiclinktoken) 类的方法和原型属性。
1751
-
1752
- ## 原型方法<a id="extlinktoken.prototype.methods"></a>
1753
- <details>
1754
- <summary>展开</summary>
1755
-
1756
- **setLinkText**(text: string): void<a id="extlinktoken.setlinktext"></a>
1757
- - 修改外链文本。
1758
-
1759
- ```js
1760
- var root = Parser.parse('[//example.org example]'),
1761
- extlink = root.firstChild;
1762
- extlink.setLinkText(''); // 清空外链文本
1763
- assert(root.toString() === '[//example.org]');
1764
- ```
1765
- </details>
1766
-
1767
- [返回目录](#目录)
1768
-
1769
- # MagicLinkToken
1770
- 自由外链。
1771
-
1772
- ## 原型方法<a id="magiclinktoken.prototype.methods"></a>
1773
- <details>
1774
- <summary>展开</summary>
1775
-
1776
- **getUrl**(): URL<a id="magiclinktoken.geturl"></a>
1777
- - 生成一个 URL 对象,以方便解析和修改外链目标。
1778
-
1779
- **setTarget**(url: string\|URL): void<a id="magiclinktoken.settarget"></a>
1780
- - 修改外链目标。可以和 [getUrl](#magiclinktoken.geturl) 方法联合使用(见以下示例)。
1781
-
1782
- ```js
1783
- var root = Parser.parse('https://www.mediawiki.org/wiki/Manual:Parser.php'),
1784
- magiclink = root.firstChild,
1785
- url = magiclink.getUrl();
1786
- url.searchParams.set('action', 'info');
1787
- magiclink.setTarget(url);
1788
- assert(root.toString() === 'https://www.mediawiki.org/wiki/Manual:Parser.php?action=info');
1789
- ```
1790
- </details>
1791
-
1792
- ## 原型属性<a id="magiclinktoken.prototype.properties"></a>
1793
- <details>
1794
- <summary>展开</summary>
1795
-
1796
- **protocol**: string<a id="magiclinktoken.protocol"></a>
1797
- - 外链协议。
1798
-
1799
- ```js
1800
- var root = Parser.parse('ftp://example.org'),
1801
- magiclink = root.firstChild;
1802
- assert(magiclink.protocol === 'ftp://');
1803
- magiclink.protocol = 'https://';
1804
- assert(root.toString() === 'https://example.org');
1805
- ```
1806
- </details>
1807
-
1808
- [返回目录](#目录)
1809
-
1810
- # 选择器
1811
- Token 选择器的设计仿照了 CSS 和 jQuery 的选择器。
1812
- <details>
1813
- <summary>展开</summary>
1814
-
1815
- **type**<a id="selector.type"></a>
1816
- - 类比 CSS tag 选择器。
1817
-
1818
- ```js
1819
- var root = Parser.parse(wikitext);
1820
- assert(root.matches('root') === true)
1821
- ```
1822
-
1823
- **name**<a id="selector.name"></a>
1824
- - 类比 CSS id 选择器。
1825
-
1826
- ```js
1827
- var root = Parser.parse('<ref/>'),
1828
- ref = root.firstChild;
1829
- assert(ref.matches('#ref') === true);
1830
- ```
1831
-
1832
- **属性**<a id="selector.attribute"></a>
1833
- - 类比 CSS 属性选择器。
1834
-
1835
- ```js
1836
- var root = Parser.parse('<!-- --><ref name="abc"/>'),
1837
- comment = root.firstChild,
1838
- attr = root.querySelector('ext-attr');
1839
- assert(comment.matches('[closed]') === true); // 非 AttributeToken 的属性选择器对应自身属性
1840
- assert(attr.matches('[name^=a]') === true); // AttributeToken 的属性选择器对应维基文本中的属性
1841
- assert(attr.matches('[name$=c]') === true);
1842
- assert(attr.matches('[name*=b]') === true);
1843
- assert(attr.matches('[name!=x]') === true);
1844
- assert(attr.matches('[name=abc]') === true);
1845
- ```
1846
-
1847
- **伪选择器**<a id="selector.pseudo"></a>
1848
- - 类比 CSS 和 jQuery 伪选择器。
1849
-
1850
- ```js
1851
- var root = Parser.parse('text <!--'),
1852
- comment = root.lastChild;
1853
- assert(root.matches(':root') === true);
1854
- assert(root.matches(':is(root)') === true);
1855
- assert(comment.matches(':not(root)') === true);
1856
- assert(comment.matches(':nth-child(2)') === true);
1857
- assert(comment.matches(':nth-last-of-type(1)') === true);
1858
- assert(comment.matches(':last-child') === true);
1859
- assert(comment.matches(':first-of-type') === true);
1860
- assert(root.matches(':only-child') === true);
1861
- assert(comment.matches(':only-of-type') === true);
1862
- assert(root.matches(':contains(text)') === true);
1863
- assert(root.matches(':has(comment)') === true);
1864
- assert(root.matches(':parent') === true);
1865
- assert(comment.matches(':empty') === true);
1866
- assert(comment.matches(':hidden') === true);
1867
- assert(root.matches(':visible') === true);
1868
- ```
1869
- </details>
1870
-
1871
- [返回目录](#目录)
1872
-
1873
- # $ (TokenCollection)
1874
- 这是一个仿 jQuery 的批量操作工具,这里仅列举方法和属性。
1875
- <details>
1876
- <summary>展开</summary>
1877
-
1878
- **toArray**(): (string\|Token)[]
1879
- **get**(num: number): string\|Token
1880
- **each**(callback: function(this: string\|Token, number, string\|Token): void): this
1881
- **map**(callback: function(this: string\|Token, number, string\|Token): any): any[]\|TokenCollection
1882
- **slice**(start: number, end: number): TokenCollection
1883
- **first**(): TokenCollection
1884
- **last**(): TokenCollection
1885
- **eq**(i: number): TokenCollection
1886
- **toString**(): string
1887
- **text**(text?: string): string\|this
1888
- **is**(selector: string): boolean
1889
- **filter**(selector: string\|function(this: string\|Token, number, string\|Token): boolean): TokenCollection
1890
- **not**(selector: string\|function(this: string\|Token, number, string\|Token): boolean): TokenCollection
1891
- **find**(selector: string): TokenCollection
1892
- **has**(selector: string): boolean
1893
- **closest**(selector?: string): TokenCollection
1894
- **index**(): number
1895
- **add**(elements: string\|Token\|TokenCollection\|(string\|Token)[]): TokenCollection
1896
- **addBack**(selector?: string): TokenCollection
1897
- **parent**(selector?: string): TokenCollection
1898
- **parents**(selector?: string): TokenCollection
1899
- **parentsUntil**(selector?: string, filter?: string): TokenCollection
1900
- **next**(selector?: string): TokenCollection
1901
- **nextAll**(selector?: string): TokenCollection
1902
- **nextUntil**(selector?: string, filter?: string): TokenCollection
1903
- **prev**(selector?: string): TokenCollection
1904
- **prevAll**(selector?: string): TokenCollection
1905
- **prevUntil**(selector?: string, filter?: string): TokenCollection
1906
- **siblings**(selector?: string): TokenCollection
1907
- **children**(selector?: string): TokenCollection
1908
- **contents**(): TokenCollection
1909
- **data**(key: string\|Record\<string, any>, value?: any): this\|any
1910
- **removeData**(name: string\|string[]): this
1911
- **on**(events: string\|Record\<string, (e: Event, data: any) => any, [selector: string], handler: (e: Event, data: any) => any): this
1912
- **one**(events: string\|Record\<string, (e: Event, data: any) => any, [selector: string], handler: (e: Event, data: any) => any): this
1913
- **off**(events: string\|Record\<string, (e: Event, data: any) => any, [selector: string], [handler: (e: Event, data: any) => any]): this
1914
- **trigger**(event: Event, data?: any): this
1915
- **tiggerHandler**(event: Event, data?: any): any
1916
- **append**(content: string\|Token\|TokenCollection\|(string\|Token)[]\|function(this: Token, number, string): string\|Token\|TokenCollection\|(string\|Token)[]): this
1917
- **prepend**(content: string\|Token\|TokenCollection\|(string\|Token)[]\|function(this: Token, number, string): string\|Token\|TokenCollection\|(string\|Token)[]): this
1918
- **before**(content: string\|Token\|TokenCollection\|(string\|Token)[]\|function(this: Token, number, string): string\|Token\|TokenCollection\|(string\|Token)[]): this
1919
- **after**(content: string\|Token\|TokenCollection\|(string\|Token)[]\|function(this: Token, number, string): string\|Token\|TokenCollection\|(string\|Token)[]): this
1920
- **html**(content: string\|Token\|TokenCollection\|(string\|Token)[]\|function(this: Token, number, string): string\|Token\|TokenCollection\|(string\|Token)[]): this
1921
- **replaceWith**(content: string\|Token\|TokenCollection\|(string\|Token)[]\|function(this: Token, number, string): string\|Token\|TokenCollection\|(string\|Token)[]): this
1922
- **remove**(selector?: string): this
1923
- **detach**(selector?: string): this
1924
- **empty**(): this
1925
- **appendTo**(target: Token\|Token[]): this
1926
- **prependTo**(target: Token\|Token[]): this
1927
- **insertBefore**(target: Token\|Token[]): this
1928
- **insertAfter**(target: Token\|Token[]): this
1929
- **replaceAll**(target: Token\|Token[]): this
1930
- **val**(value: string\|string[]\|function(this: Token, number, string): string): this
1931
- **attr**(name: string\|Record\<string, string>, value?: string): this\|string
1932
- **removeAttr**(name: string): this
1933
- **prop**(name: string\|Record\<string, any>, value?: any): this\|any
1934
- **removeProp**(name: string): this
1935
- **wrapAll**(wrapper: string[]\|function(this: Token, string): string[]): this
1936
- **wrapInner**(wrapper: string[]\|function(this: Token, string): string[]): this
1937
- **wrap**(wrapper: string[]\|function(this: Token, string): string[]): this
1938
-
1939
- </details>
14
+ # 目录
1940
15
 
1941
- [返回目录](#目录)
16
+ 1. [Parser](https://github.com/bhsd-harry/wikiparser-node/wiki/Home#parser)
17
+ 2. [AstElement](https://github.com/bhsd-harry/wikiparser-node/wiki/01.-Token#astelement)
18
+ 3. [Token](https://github.com/bhsd-harry/wikiparser-node/wiki/01.-Token#token)
19
+ 4. [CommentToken](https://github.com/bhsd-harry/wikiparser-node/wiki/02.-CommentToken等#commenttoken)
20
+ 5. [ExtToken](https://github.com/bhsd-harry/wikiparser-node/wiki/03.-ExtToken)
21
+ 6. [AttributeToken](https://github.com/bhsd-harry/wikiparser-node/wiki/04.-AttributeToken)
22
+ 7. [HeadingToken](https://github.com/bhsd-harry/wikiparser-node/wiki/05.-HeadingToken)
23
+ 8. [ArgToken](https://github.com/bhsd-harry/wikiparser-node/wiki/06.-ArgToken)
24
+ 9. [TranscludeToken](https://github.com/bhsd-harry/wikiparser-node/wiki/07.-TranscludeToken)
25
+ 10. [ParameterToken](https://github.com/bhsd-harry/wikiparser-node/wiki/08.-ParameterToken)
26
+ 11. [HtmlToken](https://github.com/bhsd-harry/wikiparser-node/wiki/09.-HtmlToken)
27
+ 12. [TableToken](https://github.com/bhsd-harry/wikiparser-node/wiki/10.-TableToken)
28
+ 13. [TdToken](https://github.com/bhsd-harry/wikiparser-node/wiki/11.-TdToken)
29
+ 14. [DoubleUnderscoreToken](https://github.com/bhsd-harry/wikiparser-node/wiki/12.-DoubleUnderscoreToken)
30
+ 15. [LinkToken](https://github.com/bhsd-harry/wikiparser-node/wiki/13.-LinkToken)
31
+ 16. [CategoryToken](https://github.com/bhsd-harry/wikiparser-node/wiki/14.-CategoryToken)
32
+ 17. [FileToken](https://github.com/bhsd-harry/wikiparser-node/wiki/15.-FileToken)
33
+ 18. [ImageParameterToken](https://github.com/bhsd-harry/wikiparser-node/wiki/16.-ImageParameterToken)
34
+ 19. [ExtLinkToken](https://github.com/bhsd-harry/wikiparser-node/wiki/17.-ExtLinkToken和MagicLinkToken#extlinktoken)
35
+ 20. [MagicLinkToken](https://github.com/bhsd-harry/wikiparser-node/wiki/17.-ExtLinkToken和MagicLinkToken#magiclinktoken)
36
+ 21. [ConverterToken](https://github.com/bhsd-harry/wikiparser-node/wiki/18.-ConverterToken)
37
+ 22. [ConverterRuleToken](https://github.com/bhsd-harry/wikiparser-node/wiki/19.-ConverterRuleToken)
38
+ 23. [选择器](https://github.com/bhsd-harry/wikiparser-node/wiki/20.-选择器)
39
+ 24. [$ (TokenCollection)](https://github.com/bhsd-harry/wikiparser-node/wiki/21.-$-(TokenCollection))