wikiparser-node 0.7.0-m → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/README.md +39 -0
  2. package/config/llwiki.json +35 -0
  3. package/config/moegirl.json +44 -0
  4. package/config/zhwiki.json +466 -0
  5. package/index.js +259 -11
  6. package/lib/element.js +481 -7
  7. package/lib/node.js +552 -6
  8. package/lib/ranges.js +130 -0
  9. package/lib/text.js +112 -21
  10. package/lib/title.js +27 -0
  11. package/mixin/attributeParent.js +117 -0
  12. package/mixin/fixedToken.js +40 -0
  13. package/mixin/hidden.js +3 -0
  14. package/mixin/singleLine.js +31 -0
  15. package/mixin/sol.js +65 -0
  16. package/package.json +5 -4
  17. package/parser/brackets.js +1 -0
  18. package/parser/commentAndExt.js +4 -3
  19. package/parser/converter.js +1 -0
  20. package/parser/externalLinks.js +1 -0
  21. package/parser/hrAndDoubleUnderscore.js +1 -0
  22. package/parser/html.js +1 -0
  23. package/parser/links.js +5 -4
  24. package/parser/list.js +1 -0
  25. package/parser/magicLinks.js +5 -4
  26. package/parser/quotes.js +2 -1
  27. package/parser/selector.js +177 -0
  28. package/parser/table.js +1 -0
  29. package/src/arg.js +116 -2
  30. package/src/atom/hidden.js +2 -0
  31. package/src/atom/index.js +17 -0
  32. package/src/attribute.js +171 -4
  33. package/src/attributes.js +306 -4
  34. package/src/charinsert.js +57 -1
  35. package/src/converter.js +108 -2
  36. package/src/converterFlags.js +187 -0
  37. package/src/converterRule.js +184 -1
  38. package/src/extLink.js +120 -1
  39. package/src/gallery.js +55 -5
  40. package/src/hasNowiki/index.js +12 -0
  41. package/src/hasNowiki/pre.js +12 -0
  42. package/src/heading.js +55 -4
  43. package/src/html.js +118 -3
  44. package/src/imageParameter.js +176 -5
  45. package/src/imagemap.js +60 -1
  46. package/src/imagemapLink.js +13 -1
  47. package/src/index.js +527 -3
  48. package/src/link/category.js +37 -1
  49. package/src/link/file.js +159 -2
  50. package/src/link/galleryImage.js +59 -1
  51. package/src/link/index.js +269 -1
  52. package/src/magicLink.js +90 -9
  53. package/src/nested/choose.js +1 -0
  54. package/src/nested/combobox.js +1 -0
  55. package/src/nested/index.js +30 -3
  56. package/src/nested/references.js +1 -0
  57. package/src/nowiki/comment.js +25 -1
  58. package/src/nowiki/dd.js +47 -1
  59. package/src/nowiki/doubleUnderscore.js +31 -1
  60. package/src/nowiki/hr.js +20 -1
  61. package/src/nowiki/index.js +23 -1
  62. package/src/nowiki/list.js +5 -2
  63. package/src/nowiki/noinclude.js +14 -0
  64. package/src/nowiki/quote.js +16 -2
  65. package/src/onlyinclude.js +26 -1
  66. package/src/paramTag/index.js +24 -1
  67. package/src/paramTag/inputbox.js +44 -0
  68. package/src/parameter.js +148 -6
  69. package/src/syntax.js +68 -0
  70. package/src/table/index.js +940 -2
  71. package/src/table/td.js +225 -5
  72. package/src/table/tr.js +247 -2
  73. package/src/tagPair/ext.js +24 -4
  74. package/src/tagPair/include.js +24 -0
  75. package/src/tagPair/index.js +52 -2
  76. package/src/transclude.js +512 -11
  77. package/tool/index.js +1202 -0
  78. package/util/debug.js +73 -0
  79. package/util/string.js +48 -1
  80. package/config/minimum.json +0 -142
package/src/magicLink.js CHANGED
@@ -10,6 +10,34 @@ const {generateForChild} = require('../util/lint'),
10
10
  */
11
11
  class MagicLinkToken extends Token {
12
12
  type = 'free-ext-link';
13
+ #protocolRegex;
14
+
15
+ /** 协议 */
16
+ get protocol() {
17
+ return this.#protocolRegex.exec(this.text())?.[0];
18
+ }
19
+
20
+ set protocol(value) {
21
+ if (typeof value !== 'string') {
22
+ this.typeError('protocol', 'String');
23
+ } else if (!new RegExp(`${this.#protocolRegex.source}$`, 'iu').test(value)) {
24
+ throw new RangeError(`非法的外链协议:${value}`);
25
+ }
26
+ const {link} = this;
27
+ if (!this.#protocolRegex.test(link)) {
28
+ throw new Error(`特殊外链无法更改协议!${link}`);
29
+ }
30
+ this.replaceChildren(link.replace(this.#protocolRegex, value));
31
+ }
32
+
33
+ /** 和内链保持一致 */
34
+ get link() {
35
+ return this.text();
36
+ }
37
+
38
+ set link(url) {
39
+ this.setTarget(url);
40
+ }
13
41
 
14
42
  /**
15
43
  * @override
@@ -25,17 +53,15 @@ class MagicLinkToken extends Token {
25
53
  continue;
26
54
  }
27
55
  rect ||= {start, ...this.getRootNode().posFromIndex(start)};
28
- const refError = generateForChild(child, rect, '', 'warning'),
29
- regex = new RegExp(source, 'gu');
30
- for (let mt = regex.exec(str); mt; mt = regex.exec(str)) {
31
- const {index, 0: {0: char, length}} = mt,
32
- lines = str.slice(0, index).split('\n'),
56
+ const refError = generateForChild(child, rect, '', 'warning');
57
+ errors.push(...[...str.matchAll(new RegExp(source, 'gu'))].map(({index, 0: {0: char, length}}) => {
58
+ const lines = str.slice(0, index).split('\n'),
33
59
  {length: top} = lines,
34
- {length: left} = lines[top - 1],
60
+ {length: left} = lines.at(-1),
35
61
  startIndex = start + index,
36
62
  startLine = refError.startLine + top - 1,
37
63
  startCol = (top > 1 ? 0 : refError.startCol) + left;
38
- errors.push({
64
+ return {
39
65
  ...refError,
40
66
  message: `URL中的${char === '|' ? '"|"' : '全角标点'}`,
41
67
  startIndex,
@@ -45,8 +71,8 @@ class MagicLinkToken extends Token {
45
71
  startCol,
46
72
  endCol: startCol + length,
47
73
  excerpt: str.slice(Math.max(0, index - 25), index + 25),
48
- });
49
- }
74
+ };
75
+ }));
50
76
  }
51
77
  return errors;
52
78
  }
@@ -58,11 +84,66 @@ class MagicLinkToken extends Token {
58
84
  */
59
85
  constructor(url, doubleSlash, config = Parser.getConfig(), accum = []) {
60
86
  super(url, config, true, accum, {
87
+ 'Stage-1': ':', '!ExtToken': '',
61
88
  });
62
89
  if (doubleSlash) {
63
90
  this.type = 'ext-link-url';
64
91
  }
92
+ this.#protocolRegex = new RegExp(`^(?:${config.protocol}${doubleSlash ? '|//' : ''})`, 'iu');
93
+ }
94
+
95
+ /** @override */
96
+ cloneNode() {
97
+ const cloned = this.cloneChildNodes();
98
+ return Parser.run(() => {
99
+ const token = new MagicLinkToken(undefined, this.type === 'ext-link-url', this.getAttribute('config'));
100
+ token.append(...cloned);
101
+ token.afterBuild();
102
+ return token;
103
+ });
104
+ }
105
+
106
+ /**
107
+ * 获取网址
108
+ * @throws `Error` 非标准协议
109
+ */
110
+ getUrl() {
111
+ let url = this.text();
112
+ if (url.startsWith('//')) {
113
+ url = `https:${url}`;
114
+ }
115
+ try {
116
+ return new URL(url);
117
+ } catch (e) {
118
+ if (e instanceof TypeError && e.message === 'Invalid URL') {
119
+ throw new Error(`非标准协议的外部链接:${url}`);
120
+ }
121
+ throw e;
122
+ }
123
+ }
124
+
125
+ /**
126
+ * 设置外链目标
127
+ * @param {string|URL} url 含协议的网址
128
+ * @throws `SyntaxError` 非法的自由外链目标
129
+ */
130
+ setTarget(url) {
131
+ url = String(url);
132
+ const root = Parser.parse(url, this.getAttribute('include'), 9, this.getAttribute('config')),
133
+ {length, firstChild: freeExtLink} = root;
134
+ if (length !== 1 || freeExtLink.type !== 'free-ext-link') {
135
+ throw new SyntaxError(`非法的自由外链目标:${url}`);
136
+ }
137
+ this.replaceChildren(...freeExtLink.childNodes);
138
+ }
139
+
140
+ /** 是否是模板或魔术字参数 */
141
+ isParamValue() {
142
+ const ParameterToken = require('./parameter');
143
+ const /** @type {ParameterToken} */ parameter = this.closest('parameter');
144
+ return parameter?.getValue() === this.text();
65
145
  }
66
146
  }
67
147
 
148
+ Parser.classes.MagicLinkToken = __filename;
68
149
  module.exports = MagicLinkToken;
@@ -20,4 +20,5 @@ class ChooseToken extends NestedToken {
20
20
  }
21
21
  }
22
22
 
23
+ Parser.classes.ChooseToken = __filename;
23
24
  module.exports = ChooseToken;
@@ -19,4 +19,5 @@ class ComboboxToken extends NestedToken {
19
19
  }
20
20
  }
21
21
 
22
+ Parser.classes.ComboboxToken = __filename;
22
23
  module.exports = ComboboxToken;
@@ -13,6 +13,7 @@ const {generateForChild} = require('../../util/lint'),
13
13
  */
14
14
  class NestedToken extends Token {
15
15
  type = 'ext-inner';
16
+ #tags;
16
17
 
17
18
  /**
18
19
  * @param {string|undefined} wikitext wikitext
@@ -33,15 +34,17 @@ class NestedToken extends Token {
33
34
  }
34
35
  return str;
35
36
  },
36
- )?.replace(/(^|\0\d+[ce]\x7F)(.*?)(?=$|\0\d+[ce]\x7F)/gsu, (_, lead, substr) => {
37
+ )?.replace(/(?<=^|\0\d+[ce]\x7F).*?(?=$|\0\d+[ce]\x7F)/gsu, substr => {
37
38
  if (substr === '') {
38
- return lead;
39
+ return '';
39
40
  }
40
41
  new NoincludeToken(substr, config, accum);
41
- return `${lead}\0${accum.length}c\x7F`;
42
+ return `\0${accum.length}c\x7F`;
42
43
  });
43
44
  super(text, config, true, accum, {
45
+ NoincludeToken: ':', ExtToken: ':',
44
46
  });
47
+ this.#tags = tags;
45
48
  }
46
49
 
47
50
  /**
@@ -64,6 +67,30 @@ class NestedToken extends Token {
64
67
  }),
65
68
  ];
66
69
  }
70
+
71
+ /**
72
+ * @override
73
+ * @template {string|Token} T
74
+ * @param {T} token 待插入的子节点
75
+ * @param {number} i 插入位置
76
+ */
77
+ insertAt(token, i = this.length) {
78
+ return token.type === 'ext' && !this.#tags.includes(token.name)
79
+ ? this.typeError(`${this.constructor.name}只能以${this.#tags.join('或')}标签作为子节点!`)
80
+ : super.insertAt(token, i);
81
+ }
82
+
83
+ /** @override */
84
+ cloneNode() {
85
+ const cloned = this.cloneChildNodes(),
86
+ config = this.getAttribute('config');
87
+ return Parser.run(() => {
88
+ const token = new this.constructor(undefined, config);
89
+ token.append(...cloned);
90
+ return token;
91
+ });
92
+ }
67
93
  }
68
94
 
95
+ Parser.classes.NestedToken = __filename;
69
96
  module.exports = NestedToken;
@@ -19,4 +19,5 @@ class ReferencesToken extends NestedToken {
19
19
  }
20
20
  }
21
21
 
22
+ Parser.classes.ReferencesToken = __filename;
22
23
  module.exports = ReferencesToken;
@@ -13,6 +13,11 @@ class CommentToken extends hidden(NowikiToken) {
13
13
  type = 'comment';
14
14
  closed;
15
15
 
16
+ /** 内部wikitext */
17
+ get innerText() {
18
+ return String(this.firstChild);
19
+ }
20
+
16
21
  /**
17
22
  * @param {string} wikitext wikitext
18
23
  * @param {boolean} closed 是否闭合
@@ -21,6 +26,7 @@ class CommentToken extends hidden(NowikiToken) {
21
26
  constructor(wikitext, closed = true, config = Parser.getConfig(), accum = []) {
22
27
  super(wikitext, config, accum);
23
28
  this.closed = closed;
29
+ Object.defineProperty(this, 'closed', {enumerable: false});
24
30
  }
25
31
 
26
32
  /** @override */
@@ -28,6 +34,11 @@ class CommentToken extends hidden(NowikiToken) {
28
34
  return 4;
29
35
  }
30
36
 
37
+ /** @override */
38
+ print() {
39
+ return super.print({pre: '&lt;!--', post: this.closed ? '--&gt;' : ''});
40
+ }
41
+
31
42
  /**
32
43
  * @override
33
44
  * @param {number} start 起始位置
@@ -38,10 +49,23 @@ class CommentToken extends hidden(NowikiToken) {
38
49
 
39
50
  /**
40
51
  * @override
52
+ * @param {string} selector
41
53
  */
42
54
  toString(selector) {
43
- return `<!--${String(this.firstChild)}${this.closed ? '-->' : ''}`;
55
+ if (!this.closed && this.nextSibling) {
56
+ Parser.error('自动闭合HTML注释', this);
57
+ this.closed = true;
58
+ }
59
+ return selector && this.matches(selector)
60
+ ? ''
61
+ : `<!--${String(this.firstChild)}${this.closed ? '-->' : ''}`;
62
+ }
63
+
64
+ /** @override */
65
+ cloneNode() {
66
+ return Parser.run(() => new CommentToken(String(this.firstChild), this.closed, this.getAttribute('config')));
44
67
  }
45
68
  }
46
69
 
70
+ Parser.classes.CommentToken = __filename;
47
71
  module.exports = CommentToken;
package/src/nowiki/dd.js CHANGED
@@ -1,6 +1,7 @@
1
1
  'use strict';
2
2
 
3
- const NowikiToken = require('.');
3
+ const Parser = require('../..'),
4
+ NowikiToken = require('.');
4
5
 
5
6
  /**
6
7
  * :
@@ -8,6 +9,51 @@ const NowikiToken = require('.');
8
9
  */
9
10
  class DdToken extends NowikiToken {
10
11
  type = 'dd';
12
+
13
+ /** 是否包含<dt> */
14
+ get dt() {
15
+ return String(this).includes(';');
16
+ }
17
+
18
+ /** 是否包含<ul> */
19
+ get ul() {
20
+ return String(this).includes('*');
21
+ }
22
+
23
+ /** 是否包含<ol> */
24
+ get ol() {
25
+ return String(this).includes('#');
26
+ }
27
+
28
+ /** 缩进数 */
29
+ get indent() {
30
+ return String(this).split(':').length - 1;
31
+ }
32
+
33
+ set indent(indent) {
34
+ if (this.type === 'dd') {
35
+ if (!Number.isInteger(indent)) {
36
+ this.typeError('set indent', 'Number');
37
+ } else if (indent < 0) {
38
+ throw new RangeError(`indent 应为自然数!${indent}`);
39
+ }
40
+ this.setText(':'.repeat(indent));
41
+ }
42
+ }
43
+
44
+ /**
45
+ * @override
46
+ * @param {string} str 新文本
47
+ * @throws `RangeError` 错误的列表语法
48
+ */
49
+ setText(str) {
50
+ const src = this.type === 'dd' ? ':' : ';:*#';
51
+ if (new RegExp(`[^${src}]`, 'u').test(str)) {
52
+ throw new RangeError(`${this.constructor.name} 仅能包含${[...src].map(c => `"${c}"`).join('、')}!`);
53
+ }
54
+ return super.setText(str);
55
+ }
11
56
  }
12
57
 
58
+ Parser.classes.DdToken = __filename;
13
59
  module.exports = DdToken;
@@ -1,6 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  const hidden = require('../../mixin/hidden'),
4
+ Parser = require('../..'),
4
5
  NowikiToken = require('.');
5
6
 
6
7
  /**
@@ -15,12 +16,41 @@ class DoubleUnderscoreToken extends hidden(NowikiToken) {
15
16
  return 2;
16
17
  }
17
18
 
19
+ /** @override */
20
+ print() {
21
+ return super.print({pre: '__', post: '__'});
22
+ }
23
+
18
24
  /**
19
25
  * @override
26
+ * @param {string} selector
20
27
  */
21
28
  toString(selector) {
22
- return `__${String(this.firstChild)}__`;
29
+ return selector && this.matches(selector) ? '' : `__${String(this.firstChild)}__`;
30
+ }
31
+
32
+ /**
33
+ * @param {string} word 状态开关名
34
+ * @param {accum} accum
35
+ */
36
+ constructor(word, config = Parser.getConfig(), accum = []) {
37
+ super(word, config, accum);
38
+ this.setAttribute('name', word.toLowerCase());
39
+ }
40
+
41
+ /** @override */
42
+ cloneNode() {
43
+ return Parser.run(() => new DoubleUnderscoreToken(String(this.firstChild), this.getAttribute('config')));
44
+ }
45
+
46
+ /**
47
+ * @override
48
+ * @throws `Error` 禁止修改
49
+ */
50
+ setText() {
51
+ throw new Error(`禁止修改 ${this.constructor.name}!`);
23
52
  }
24
53
  }
25
54
 
55
+ Parser.classes.DoubleUnderscoreToken = __filename;
26
56
  module.exports = DoubleUnderscoreToken;
package/src/nowiki/hr.js CHANGED
@@ -1,13 +1,14 @@
1
1
  'use strict';
2
2
 
3
3
  const Parser = require('../..'),
4
+ sol = require('../../mixin/sol'),
4
5
  NowikiToken = require('.');
5
6
 
6
7
  /**
7
8
  * `<hr>`
8
9
  * @classdesc `{childNodes: [AstText]}`
9
10
  */
10
- class HrToken extends NowikiToken {
11
+ class HrToken extends sol(NowikiToken) {
11
12
  type = 'hr';
12
13
 
13
14
  /**
@@ -17,6 +18,24 @@ class HrToken extends NowikiToken {
17
18
  constructor(n, config = Parser.getConfig(), accum = []) {
18
19
  super('-'.repeat(n), config, accum);
19
20
  }
21
+
22
+ /** @override */
23
+ cloneNode() {
24
+ return Parser.run(() => new HrToken(String(this).length, this.getAttribute('config')));
25
+ }
26
+
27
+ /**
28
+ * @override
29
+ * @param {string} str 新文本
30
+ * @throws `RangeError` 错误的\<hr\>语法
31
+ */
32
+ setText(str) {
33
+ if (str.length < 4 || /[^-]/u.test(str)) {
34
+ throw new RangeError('<hr>总是写作不少于4个的连续"-"!');
35
+ }
36
+ return super.setText(str);
37
+ }
20
38
  }
21
39
 
40
+ Parser.classes.HrToken = __filename;
22
41
  module.exports = HrToken;
@@ -1,14 +1,16 @@
1
1
  'use strict';
2
2
 
3
3
  const {generateForSelf} = require('../../util/lint'),
4
+ fixedToken = require('../../mixin/fixedToken'),
4
5
  Parser = require('../..'),
6
+ AstText = require('../../lib/text'),
5
7
  Token = require('..');
6
8
 
7
9
  /**
8
10
  * 纯文字Token,不会被解析
9
11
  * @classdesc `{childNodes: [AstText]}`
10
12
  */
11
- class NowikiToken extends Token {
13
+ class NowikiToken extends fixedToken(Token) {
12
14
  type = 'ext-inner';
13
15
 
14
16
  /**
@@ -29,6 +31,26 @@ class NowikiToken extends Token {
29
31
  ? [generateForSelf(this, {start}, `<${name}>标签内不应有任何内容`)]
30
32
  : super.lint(start);
31
33
  }
34
+
35
+ /**
36
+ * @override
37
+ * @this {NowikiToken & {firstChild: AstText, constructor: typeof NowikiToken}}
38
+ */
39
+ cloneNode() {
40
+ const {constructor, firstChild: {data}, type} = this,
41
+ token = Parser.run(() => new constructor(data, this.getAttribute('config')));
42
+ token.type = type;
43
+ return token;
44
+ }
45
+
46
+ /**
47
+ * @override
48
+ * @param {string} str 新文本
49
+ */
50
+ setText(str) {
51
+ return super.setText(str, 0);
52
+ }
32
53
  }
33
54
 
55
+ Parser.classes.NowikiToken = __filename;
34
56
  module.exports = NowikiToken;
@@ -1,13 +1,16 @@
1
1
  'use strict';
2
2
 
3
- const DdToken = require('./dd');
3
+ const sol = require('../../mixin/sol'),
4
+ Parser = require('../..'),
5
+ DdToken = require('./dd');
4
6
 
5
7
  /**
6
8
  * ;:*#
7
9
  * @classdesc `{childNodes: [AstText]}`
8
10
  */
9
- class ListToken extends DdToken {
11
+ class ListToken extends sol(DdToken) {
10
12
  type = 'list';
11
13
  }
12
14
 
15
+ Parser.classes.ListToken = __filename;
13
16
  module.exports = ListToken;
@@ -1,6 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  const hidden = require('../../mixin/hidden'),
4
+ Parser = require('../..'),
4
5
  NowikiToken = require('.');
5
6
 
6
7
  /**
@@ -9,6 +10,19 @@ const hidden = require('../../mixin/hidden'),
9
10
  */
10
11
  class NoincludeToken extends hidden(NowikiToken) {
11
12
  type = 'noinclude';
13
+
14
+ /**
15
+ * @override
16
+ * @param {string} str 新文本
17
+ * @throws `Error` 不可更改
18
+ */
19
+ setText(str) {
20
+ if (/^<\/?(?:(?:no|only)include|includeonly)(?:\s.*)?\/?>$/isu.test(String(this))) {
21
+ throw new Error(`${this.constructor.name} 不可更改文字内容!`);
22
+ }
23
+ return super.setText(str);
24
+ }
12
25
  }
13
26
 
27
+ Parser.classes.NoincludeToken = __filename;
14
28
  module.exports = NoincludeToken;
@@ -18,6 +18,7 @@ class QuoteToken extends NowikiToken {
18
18
  */
19
19
  constructor(n, config = Parser.getConfig(), accum = []) {
20
20
  super("'".repeat(n), config, accum);
21
+ this.setAttribute('name', String(n));
21
22
  }
22
23
 
23
24
  /**
@@ -30,11 +31,11 @@ class QuoteToken extends NowikiToken {
30
31
  message = `孤立的"'"`,
31
32
  /** @type {LintError[]} */ errors = [];
32
33
  let refError, wikitext;
33
- if (previousSibling?.type === 'text' && previousSibling.data.endsWith("'")) {
34
+ if (previousSibling?.type === 'text' && previousSibling.data.at(-1) === "'") {
34
35
  refError = generateForSelf(this, {start}, message);
35
36
  wikitext = String(this.getRootNode());
36
37
  const {startIndex: endIndex, startLine: endLine, startCol: endCol} = refError,
37
- [, {length}] = previousSibling.data.match(/(?:^|[^'])('+)$/u),
38
+ [{length}] = previousSibling.data.match(/(?<!')'+$/u),
38
39
  startIndex = start - length,
39
40
  excerpt = wikitext.slice(startIndex, startIndex + 50);
40
41
  errors.push({...refError, startIndex, endIndex, startCol: endCol - length, endLine, endCol, excerpt});
@@ -50,6 +51,19 @@ class QuoteToken extends NowikiToken {
50
51
  }
51
52
  return errors;
52
53
  }
54
+
55
+ /**
56
+ * @override
57
+ * @param {string} str 新文本
58
+ * @throws `RangeError` 错误的单引号语法
59
+ */
60
+ setText(str) {
61
+ if (str === "''" || str === "'''" || str === "'''''") {
62
+ return super.setText(str);
63
+ }
64
+ throw new RangeError(`${this.constructor.name} 的内部文本只能为连续 2/3/5 个"'"!`);
65
+ }
53
66
  }
54
67
 
68
+ Parser.classes.QuoteToken = __filename;
55
69
  module.exports = QuoteToken;
@@ -10,6 +10,11 @@ const Parser = require('..'),
10
10
  class OnlyincludeToken extends Token {
11
11
  type = 'onlyinclude';
12
12
 
13
+ /** 内部wikitext */
14
+ get innerText() {
15
+ return this.text();
16
+ }
17
+
13
18
  /**
14
19
  * @param {string} inner 标签内部wikitext
15
20
  * @param {accum} accum
@@ -20,9 +25,10 @@ class OnlyincludeToken extends Token {
20
25
 
21
26
  /**
22
27
  * @override
28
+ * @param {string} selector
23
29
  */
24
30
  toString(selector) {
25
- return `<onlyinclude>${super.toString()}</onlyinclude>`;
31
+ return selector && this.matches(selector) ? '' : `<onlyinclude>${super.toString(selector)}</onlyinclude>`;
26
32
  }
27
33
 
28
34
  /** @override */
@@ -30,10 +36,29 @@ class OnlyincludeToken extends Token {
30
36
  return 13;
31
37
  }
32
38
 
39
+ /** @override */
40
+ print() {
41
+ return super.print({
42
+ pre: '<span class="wpb-ext">&lt;onlyinclude&gt;</span>',
43
+ post: '<span class="wpb-ext">&lt;/onlyinclude&gt;</span>',
44
+ });
45
+ }
46
+
33
47
  /** @override */
34
48
  isPlain() {
35
49
  return true;
36
50
  }
51
+
52
+ /** @override */
53
+ cloneNode() {
54
+ const cloned = this.cloneChildNodes();
55
+ return Parser.run(() => {
56
+ const token = new OnlyincludeToken(undefined, this.getAttribute('config'));
57
+ token.append(...cloned);
58
+ return token;
59
+ });
60
+ }
37
61
  }
38
62
 
63
+ Parser.classes.OnlyincludeToken = __filename;
39
64
  module.exports = OnlyincludeToken;
@@ -1,6 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  const {generateForChild} = require('../../util/lint'),
4
+ singleLine = require('../../mixin/singleLine'),
4
5
  Parser = require('../..'),
5
6
  Token = require('..'),
6
7
  AtomToken = require('../atom');
@@ -18,11 +19,13 @@ class ParamTagToken extends Token {
18
19
  */
19
20
  constructor(wikitext, config = Parser.getConfig(), accum = []) {
20
21
  super(undefined, config, true, accum, {
22
+ SingleLineAtomToken: ':',
21
23
  });
22
24
  if (wikitext) {
23
- const SingleLineAtomToken = AtomToken;
25
+ const SingleLineAtomToken = singleLine(AtomToken);
24
26
  this.append(
25
27
  ...wikitext.split('\n').map(line => new SingleLineAtomToken(line, 'param-line', config, accum, {
28
+ AstText: ':',
26
29
  })),
27
30
  );
28
31
  }
@@ -30,6 +33,7 @@ class ParamTagToken extends Token {
30
33
 
31
34
  /**
32
35
  * @override
36
+ * @param {string} selector
33
37
  */
34
38
  toString(selector) {
35
39
  return super.toString(selector, '\n');
@@ -45,6 +49,11 @@ class ParamTagToken extends Token {
45
49
  return 1;
46
50
  }
47
51
 
52
+ /** @override */
53
+ print() {
54
+ return super.print({sep: '\n'});
55
+ }
56
+
48
57
  /**
49
58
  * @override
50
59
  * @param {number} start 起始位置
@@ -61,6 +70,20 @@ class ParamTagToken extends Token {
61
70
  return generateForChild(child, rect, `${this.name}的无效参数`);
62
71
  });
63
72
  }
73
+
74
+ /**
75
+ * @override
76
+ * @this {ParamTagToken & {constructor: typeof ParamTagToken}}
77
+ */
78
+ cloneNode() {
79
+ const cloned = this.cloneChildNodes();
80
+ return Parser.run(() => {
81
+ const token = new this.constructor(undefined, this.getAttribute('config'));
82
+ token.append(...cloned);
83
+ return token;
84
+ });
85
+ }
64
86
  }
65
87
 
88
+ Parser.classes.ParamTagToken = __filename;
66
89
  module.exports = ParamTagToken;