wikiparser-node 0.10.0 → 0.11.0-m

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 (155) hide show
  1. package/README.md +44 -32
  2. package/config/.schema.json +1 -8
  3. package/config/default.json +1 -2
  4. package/config/llwiki.json +1 -36
  5. package/config/moegirl.json +1 -45
  6. package/config/zhwiki.json +1 -467
  7. package/dist/index.d.ts +110 -0
  8. package/dist/lib/element.d.ts +48 -0
  9. package/dist/lib/node.d.ts +108 -0
  10. package/dist/lib/text.d.ts +30 -0
  11. package/dist/lib/title.d.ts +15 -0
  12. package/dist/mixin/hidden.d.ts +8 -0
  13. package/dist/parser/brackets.d.ts +12 -0
  14. package/dist/parser/commentAndExt.d.ts +8 -0
  15. package/dist/parser/converter.d.ts +7 -0
  16. package/dist/parser/externalLinks.d.ts +7 -0
  17. package/dist/parser/hrAndDoubleUnderscore.d.ts +11 -0
  18. package/dist/parser/html.d.ts +7 -0
  19. package/dist/parser/links.d.ts +7 -0
  20. package/dist/parser/list.d.ts +7 -0
  21. package/dist/parser/magicLinks.d.ts +7 -0
  22. package/dist/parser/quotes.d.ts +7 -0
  23. package/dist/parser/table.d.ts +11 -0
  24. package/dist/src/arg.d.ts +25 -0
  25. package/dist/src/atom/hidden.d.ts +5 -0
  26. package/dist/src/atom/index.d.ts +14 -0
  27. package/dist/src/attribute.d.ts +42 -0
  28. package/dist/src/attributes.d.ts +33 -0
  29. package/dist/src/converter.d.ts +29 -0
  30. package/dist/src/converterFlags.d.ts +27 -0
  31. package/dist/src/converterRule.d.ts +29 -0
  32. package/dist/src/extLink.d.ts +22 -0
  33. package/dist/src/gallery.d.ts +19 -0
  34. package/dist/src/hasNowiki/index.d.ts +14 -0
  35. package/dist/src/hasNowiki/pre.d.ts +13 -0
  36. package/dist/src/heading.d.ts +24 -0
  37. package/dist/src/html.d.ts +33 -0
  38. package/dist/src/imageParameter.d.ts +23 -0
  39. package/dist/src/imagemap.d.ts +26 -0
  40. package/dist/src/imagemapLink.d.ts +16 -0
  41. package/dist/src/index.d.ts +53 -0
  42. package/dist/src/link/category.d.ts +8 -0
  43. package/dist/src/link/file.d.ts +27 -0
  44. package/dist/src/link/galleryImage.d.ts +15 -0
  45. package/dist/src/link/index.d.ts +29 -0
  46. package/dist/src/magicLink.d.ts +14 -0
  47. package/dist/src/nested/choose.d.ts +13 -0
  48. package/dist/src/nested/combobox.d.ts +13 -0
  49. package/dist/src/nested/index.d.ts +20 -0
  50. package/dist/src/nested/references.d.ts +13 -0
  51. package/dist/src/nowiki/comment.d.ts +19 -0
  52. package/dist/src/nowiki/dd.d.ts +8 -0
  53. package/dist/src/nowiki/doubleUnderscore.d.ts +12 -0
  54. package/dist/src/nowiki/hr.d.ts +13 -0
  55. package/dist/src/nowiki/index.d.ts +18 -0
  56. package/dist/src/nowiki/list.d.ts +8 -0
  57. package/dist/src/nowiki/noinclude.d.ts +8 -0
  58. package/dist/src/nowiki/quote.d.ts +20 -0
  59. package/dist/src/onlyinclude.d.ts +17 -0
  60. package/dist/src/paramTag/index.d.ts +24 -0
  61. package/dist/src/paramTag/inputbox.d.ts +8 -0
  62. package/dist/src/parameter.d.ts +28 -0
  63. package/dist/src/syntax.d.ts +15 -0
  64. package/dist/src/table/index.d.ts +16 -0
  65. package/dist/src/table/td.d.ts +39 -0
  66. package/dist/src/table/tr.d.ts +17 -0
  67. package/dist/src/tagPair/ext.d.ts +17 -0
  68. package/dist/src/tagPair/include.d.ts +16 -0
  69. package/dist/src/tagPair/index.d.ts +28 -0
  70. package/dist/src/transclude.d.ts +75 -0
  71. package/dist/util/lint.d.ts +28 -0
  72. package/dist/util/string.d.ts +31 -0
  73. package/i18n/zh-hans.json +1 -1
  74. package/i18n/zh-hant.json +1 -1
  75. package/index.js +5 -257
  76. package/lib/element.js +7 -482
  77. package/lib/node.js +11 -540
  78. package/lib/text.js +3 -96
  79. package/lib/title.js +1 -28
  80. package/mixin/hidden.js +0 -3
  81. package/package.json +11 -5
  82. package/parser/brackets.js +3 -2
  83. package/parser/commentAndExt.js +8 -6
  84. package/parser/converter.js +1 -2
  85. package/parser/externalLinks.js +1 -2
  86. package/parser/hrAndDoubleUnderscore.js +1 -2
  87. package/parser/html.js +1 -2
  88. package/parser/links.js +5 -6
  89. package/parser/list.js +1 -2
  90. package/parser/magicLinks.js +1 -2
  91. package/parser/quotes.js +1 -2
  92. package/parser/table.js +1 -2
  93. package/src/arg.js +4 -118
  94. package/src/atom/hidden.js +0 -2
  95. package/src/atom/index.js +1 -18
  96. package/src/attribute.js +6 -190
  97. package/src/attributes.js +5 -308
  98. package/src/converter.js +3 -109
  99. package/src/converterFlags.js +1 -188
  100. package/src/converterRule.js +2 -184
  101. package/src/extLink.js +2 -122
  102. package/src/gallery.js +2 -56
  103. package/src/hasNowiki/index.js +1 -13
  104. package/src/hasNowiki/pre.js +1 -13
  105. package/src/heading.js +4 -55
  106. package/src/html.js +5 -120
  107. package/src/imageParameter.js +3 -165
  108. package/src/imagemap.js +3 -62
  109. package/src/imagemapLink.js +2 -14
  110. package/src/index.js +9 -530
  111. package/src/link/category.js +1 -32
  112. package/src/link/file.js +3 -158
  113. package/src/link/galleryImage.js +3 -61
  114. package/src/link/index.js +4 -273
  115. package/src/magicLink.js +6 -87
  116. package/src/nested/choose.js +1 -2
  117. package/src/nested/combobox.js +1 -2
  118. package/src/nested/index.js +8 -32
  119. package/src/nested/references.js +1 -2
  120. package/src/nowiki/comment.js +2 -26
  121. package/src/nowiki/dd.js +1 -47
  122. package/src/nowiki/doubleUnderscore.js +1 -31
  123. package/src/nowiki/hr.js +2 -21
  124. package/src/nowiki/index.js +2 -24
  125. package/src/nowiki/list.js +2 -5
  126. package/src/nowiki/noinclude.js +0 -14
  127. package/src/nowiki/quote.js +2 -16
  128. package/src/onlyinclude.js +2 -27
  129. package/src/paramTag/index.js +2 -25
  130. package/src/paramTag/inputbox.js +2 -5
  131. package/src/parameter.js +6 -148
  132. package/src/syntax.js +1 -69
  133. package/src/table/index.js +2 -939
  134. package/src/table/td.js +6 -226
  135. package/src/table/tr.js +3 -248
  136. package/src/tagPair/ext.js +4 -23
  137. package/src/tagPair/include.js +1 -25
  138. package/src/tagPair/index.js +3 -52
  139. package/src/transclude.js +6 -513
  140. package/typings/api.d.ts +9 -0
  141. package/typings/index.d.ts +51 -0
  142. package/typings/node.d.ts +16 -0
  143. package/typings/parser.d.ts +5 -0
  144. package/typings/token.d.ts +28 -0
  145. package/util/lint.js +2 -0
  146. package/util/string.js +0 -51
  147. package/lib/ranges.js +0 -130
  148. package/mixin/attributeParent.js +0 -117
  149. package/mixin/fixedToken.js +0 -40
  150. package/mixin/singleLine.js +0 -31
  151. package/mixin/sol.js +0 -54
  152. package/parser/selector.js +0 -177
  153. package/src/charinsert.js +0 -97
  154. package/tool/index.js +0 -1202
  155. package/util/debug.js +0 -73
package/src/extLink.js CHANGED
@@ -1,7 +1,6 @@
1
1
  'use strict';
2
2
 
3
3
  const Parser = require('..'),
4
- {noWrap, normalizeSpace} = require('../util/string'),
5
4
  Token = require('.'),
6
5
  MagicLinkToken = require('./magicLink');
7
6
 
@@ -13,78 +12,37 @@ class ExtLinkToken extends Token {
13
12
  type = 'ext-link';
14
13
  #space;
15
14
 
16
- /**
17
- * 协议
18
- * @this {{firstChild: MagicLinkToken}}
19
- */
20
- get protocol() {
21
- return this.firstChild.protocol;
22
- }
23
-
24
- /** @this {{firstChild: MagicLinkToken}} */
25
- set protocol(value) {
26
- this.firstChild.protocol = value;
27
- }
28
-
29
- /**
30
- * 和内链保持一致
31
- * @this {{firstChild: MagicLinkToken}}
32
- */
33
- get link() {
34
- return this.firstChild.link;
35
- }
36
-
37
- set link(url) {
38
- this.setTarget(url);
39
- }
40
-
41
- /** 链接显示文字 */
42
- get innerText() {
43
- return this.length > 1
44
- ? this.lastChild.text()
45
- : `[${this.getRootNode().querySelectorAll('ext-link[childElementCount=1]').indexOf(this) + 1}]`;
46
- }
47
-
48
15
  /**
49
16
  * @param {string} url 网址
50
17
  * @param {string} space 空白字符
51
18
  * @param {string} text 链接文字
52
- * @param {accum} accum
19
+ * @param {import('../typings/token').accum} accum
53
20
  */
54
21
  constructor(url, space = '', text = '', config = Parser.getConfig(), accum = []) {
55
22
  super(undefined, config, true, accum, {
56
- MagicLinkToken: 0, Token: 1,
57
23
  });
58
24
  this.insertAt(new MagicLinkToken(url, true, config, accum));
59
25
  this.#space = space;
60
26
  if (text) {
61
27
  const inner = new Token(text, config, true, accum, {
62
- 'Stage-7': ':', ConverterToken: ':',
63
28
  });
64
29
  inner.type = 'ext-link-text';
65
30
  this.insertAt(inner.setAttribute('stage', Parser.MAX_STAGE - 1));
66
31
  }
67
- this.getAttribute('protectChildren')(0);
68
32
  }
69
33
 
70
34
  /**
71
35
  * @override
72
- * @param {string} selector
73
36
  */
74
37
  toString(selector) {
75
- if (selector && this.matches(selector)) {
76
- return '';
77
- } else if (this.length === 1) {
38
+ if (this.length === 1) {
78
39
  return `[${super.toString(selector)}${this.#space}]`;
79
40
  }
80
- this.#correct();
81
- normalizeSpace(this.lastChild);
82
41
  return `[${super.toString(selector, this.#space)}]`;
83
42
  }
84
43
 
85
44
  /** @override */
86
45
  text() {
87
- normalizeSpace(this.childNodes[1]);
88
46
  return `[${super.text(' ')}]`;
89
47
  }
90
48
 
@@ -95,86 +53,8 @@ class ExtLinkToken extends Token {
95
53
 
96
54
  /** @override */
97
55
  getGaps() {
98
- this.#correct();
99
56
  return this.#space.length;
100
57
  }
101
-
102
- /** @override */
103
- print() {
104
- return super.print(
105
- this.length > 1 ? {pre: '[', sep: this.#space, post: ']'} : {pre: '[', post: `${this.#space}]`},
106
- );
107
- }
108
-
109
- /** @override */
110
- cloneNode() {
111
- const [url, text] = this.cloneChildNodes();
112
- return Parser.run(() => {
113
- const token = new ExtLinkToken(undefined, '', '', this.getAttribute('config'));
114
- token.firstChild.safeReplaceWith(url);
115
- if (text) {
116
- token.insertAt(text);
117
- }
118
- return token;
119
- });
120
- }
121
-
122
- /** 修正空白字符 */
123
- #correct() {
124
- if (!this.#space && this.length > 1
125
- // 都替换成`<`肯定不对,但无妨
126
- && /^[^[\]<>"{\0-\x1F\x7F\p{Zs}\uFFFD]/u.test(this.lastChild.text().replace(/&[lg]t;/u, '<'))
127
- ) {
128
- this.#space = ' ';
129
- }
130
- }
131
-
132
- /**
133
- * 获取网址
134
- * @this {{firstChild: MagicLinkToken}}
135
- */
136
- getUrl() {
137
- return this.firstChild.getUrl();
138
- }
139
-
140
- /**
141
- * 设置链接目标
142
- * @param {string|URL} url 网址
143
- * @throws `SyntaxError` 非法的外链目标
144
- */
145
- setTarget(url) {
146
- url = String(url);
147
- const root = Parser.parse(`[${url}]`, this.getAttribute('include'), 8, this.getAttribute('config')),
148
- {length, firstChild: extLink} = root;
149
- if (length !== 1 || extLink.type !== 'ext-link' || extLink.length !== 1) {
150
- throw new SyntaxError(`非法的外链目标:${url}`);
151
- }
152
- const {firstChild} = extLink;
153
- extLink.destroy(true);
154
- this.firstChild.safeReplaceWith(firstChild);
155
- }
156
-
157
- /**
158
- * 设置链接显示文字
159
- * @param {string} text 链接显示文字
160
- * @throws `SyntaxError` 非法的链接显示文字
161
- */
162
- setLinkText(text) {
163
- text = String(text);
164
- const root = Parser.parse(`[//url ${text}]`, this.getAttribute('include'), 8, this.getAttribute('config')),
165
- {length, firstChild: extLink} = root;
166
- if (length !== 1 || extLink.type !== 'ext-link' || extLink.length !== 2) {
167
- throw new SyntaxError(`非法的外链文字:${noWrap(text)}`);
168
- }
169
- const {lastChild} = extLink;
170
- if (this.length === 1) {
171
- this.insertAt(lastChild);
172
- } else {
173
- this.lastChild.safeReplaceWith(lastChild);
174
- }
175
- this.#space ||= ' ';
176
- }
177
58
  }
178
59
 
179
- Parser.classes.ExtLinkToken = __filename;
180
60
  module.exports = ExtLinkToken;
package/src/gallery.js CHANGED
@@ -13,25 +13,18 @@ class GalleryToken extends Token {
13
13
  type = 'ext-inner';
14
14
  name = 'gallery';
15
15
 
16
- /** 所有图片 */
17
- get images() {
18
- return this.childNodes.filter(({type}) => type === 'gallery-image');
19
- }
20
-
21
16
  /**
22
17
  * @param {string} inner 标签内部wikitext
23
- * @param {accum} accum
18
+ * @param {import('../typings/token').accum} accum
24
19
  */
25
20
  constructor(inner, config = Parser.getConfig(), accum = []) {
26
21
  super(undefined, config, true, accum, {
27
- AstText: ':', GalleryImageToken: ':', HiddenToken: ':',
28
22
  });
29
23
  for (const line of inner?.split('\n') ?? []) {
30
24
  const matches = /^([^|]+)(?:\|(.*))?/u.exec(line);
31
25
  if (!matches) {
32
26
  super.insertAt(line.trim()
33
27
  ? new HiddenToken(line, undefined, config, [], {
34
- AstText: ':',
35
28
  })
36
29
  : line);
37
30
  continue;
@@ -42,7 +35,6 @@ class GalleryToken extends Token {
42
35
  super.insertAt(new GalleryImageToken(file, alt, config, accum));
43
36
  } else {
44
37
  super.insertAt(new HiddenToken(line, undefined, config, [], {
45
- AstText: ':',
46
38
  }));
47
39
  }
48
40
  }
@@ -50,7 +42,6 @@ class GalleryToken extends Token {
50
42
 
51
43
  /**
52
44
  * @override
53
- * @param {string} selector
54
45
  */
55
46
  toString(selector) {
56
47
  return super.toString(selector, '\n');
@@ -66,18 +57,13 @@ class GalleryToken extends Token {
66
57
  return 1;
67
58
  }
68
59
 
69
- /** @override */
70
- print() {
71
- return super.print({sep: '\n'});
72
- }
73
-
74
60
  /**
75
61
  * @override
76
62
  * @param {number} start 起始位置
77
63
  */
78
64
  lint(start = this.getAbsoluteIndex()) {
79
65
  const {top, left} = this.getRootNode().posFromIndex(start),
80
- /** @type {LintError[]} */ errors = [];
66
+ /** @type {import('../typings/token').LintError[]} */ errors = [];
81
67
  for (let i = 0, startIndex = start; i < this.length; i++) {
82
68
  const child = this.childNodes[i],
83
69
  str = String(child),
@@ -104,46 +90,6 @@ class GalleryToken extends Token {
104
90
  }
105
91
  return errors;
106
92
  }
107
-
108
- /** @override */
109
- cloneNode() {
110
- const cloned = this.cloneChildNodes();
111
- return Parser.run(() => {
112
- const token = new GalleryToken(undefined, this.getAttribute('config'));
113
- token.append(...cloned);
114
- return token;
115
- });
116
- }
117
-
118
- /**
119
- * 插入图片
120
- * @param {string} file 图片文件名
121
- * @param {number} i 插入位置
122
- * @throws `SyntaxError` 非法的文件名
123
- */
124
- insertImage(file, i = this.length) {
125
- const title = this.normalizeTitle(file, 6, true, true);
126
- if (title.valid) {
127
- const token = Parser.run(() => new GalleryImageToken(file, undefined, this.getAttribute('config')));
128
- return this.insertAt(token, i);
129
- }
130
- throw new SyntaxError(`非法的文件名:${file}`);
131
- }
132
-
133
- /**
134
- * @override
135
- * @template {string|Token} T
136
- * @param {T} token 待插入的节点
137
- * @param {number} i 插入位置
138
- * @throws `RangeError` 插入不可见内容
139
- */
140
- insertAt(token, i = 0) {
141
- if (typeof token === 'string' && token.trim() || token instanceof HiddenToken) {
142
- throw new RangeError('请勿向图库中插入不可见内容!');
143
- }
144
- return super.insertAt(token, i);
145
- }
146
93
  }
147
94
 
148
- Parser.classes.GalleryToken = __filename;
149
95
  module.exports = GalleryToken;
@@ -12,7 +12,7 @@ class HasNowikiToken extends Token {
12
12
  /**
13
13
  * @param {string} wikitext wikitext
14
14
  * @param {string} type type
15
- * @param {accum} accum
15
+ * @param {import('../../typings/token').accum} accum
16
16
  */
17
17
  constructor(wikitext, type, config = Parser.getConfig(), accum = []) {
18
18
  wikitext = wikitext.replace(
@@ -24,21 +24,9 @@ class HasNowikiToken extends Token {
24
24
  },
25
25
  );
26
26
  super(wikitext, config, true, accum, {
27
- AstText: ':', NoincludeToken: ':',
28
27
  });
29
28
  this.type = type;
30
29
  }
31
-
32
- /** @override */
33
- cloneNode() {
34
- const cloned = this.cloneChildNodes();
35
- return Parser.run(() => {
36
- const token = new HasNowikiToken(undefined, this.type, this.getAttribute('config'));
37
- token.append(...cloned);
38
- return token;
39
- });
40
- }
41
30
  }
42
31
 
43
- Parser.classes.HasNowikiToken = __filename;
44
32
  module.exports = HasNowikiToken;
@@ -12,29 +12,17 @@ class PreToken extends HasNowikiToken {
12
12
 
13
13
  /**
14
14
  * @param {string} wikitext wikitext
15
- * @param {accum} accum
15
+ * @param {import('../../typings/token').accum} accum
16
16
  */
17
17
  constructor(wikitext, config = Parser.getConfig(), accum = []) {
18
18
  super(wikitext, 'ext-inner', config, accum);
19
19
  this.setAttribute('stage', Parser.MAX_STAGE - 1);
20
- this.setAttribute('acceptable', {AstText: ':', NoincludeToken: ':', ConverterToken: ':'});
21
20
  }
22
21
 
23
22
  /** @override */
24
23
  isPlain() {
25
24
  return true;
26
25
  }
27
-
28
- /** @override */
29
- cloneNode() {
30
- const cloned = this.cloneChildNodes();
31
- return Parser.run(() => {
32
- const token = new PreToken(undefined, this.getAttribute('config'));
33
- token.append(...cloned);
34
- return token;
35
- });
36
- }
37
26
  }
38
27
 
39
- Parser.classes.PreToken = __filename;
40
28
  module.exports = PreToken;
package/src/heading.js CHANGED
@@ -1,8 +1,6 @@
1
1
  'use strict';
2
2
 
3
3
  const {generateForSelf} = require('../util/lint'),
4
- fixedToken = require('../mixin/fixedToken'),
5
- sol = require('../mixin/sol'),
6
4
  Parser = require('..'),
7
5
  Token = require('.'),
8
6
  SyntaxToken = require('./syntax');
@@ -11,55 +9,41 @@ const {generateForSelf} = require('../util/lint'),
11
9
  * 章节标题
12
10
  * @classdesc `{childNodes: [Token, SyntaxToken]}`
13
11
  */
14
- class HeadingToken extends fixedToken(sol(Token)) {
12
+ class HeadingToken extends Token {
15
13
  type = 'heading';
16
14
 
17
- /** 内部wikitext */
18
- get innerText() {
19
- return this.firstChild.text();
20
- }
21
-
22
15
  /**
23
16
  * @param {number} level 标题层级
24
17
  * @param {string[]} input 标题文字
25
- * @param {accum} accum
18
+ * @param {import('../typings/token').accum} accum
26
19
  */
27
20
  constructor(level, input, config = Parser.getConfig(), accum = []) {
28
21
  super(undefined, config, true, accum);
29
22
  this.setAttribute('name', String(level));
30
23
  const token = new Token(input[0], config, true, accum);
31
24
  token.type = 'heading-title';
32
- token.setAttribute('name', this.name);
33
25
  token.setAttribute('stage', 2);
34
26
  const trail = new SyntaxToken(input[1], /^[^\S\n]*$/u, 'heading-trail', config, accum, {
35
- 'Stage-1': ':', '!ExtToken': '',
36
27
  });
37
28
  this.append(token, trail);
38
29
  }
39
30
 
40
31
  /**
41
32
  * @override
42
- * @this {{prependNewLine(): ''|'\n'} & HeadingToken}
43
- * @param {string} selector
44
33
  * @returns {string}
45
34
  */
46
35
  toString(selector) {
47
36
  const equals = '='.repeat(Number(this.name));
48
- return selector && this.matches(selector)
49
- ? ''
50
- : `${this.prependNewLine()}${equals}${
51
- this.firstChild.toString(selector)
52
- }${equals}${this.lastChild.toString(selector)}`;
37
+ return `${equals}${this.firstChild.toString()}${equals}${this.lastChild.toString()}`;
53
38
  }
54
39
 
55
40
  /**
56
41
  * @override
57
- * @this {HeadingToken & {prependNewLine(): ''|'\n'}}
58
42
  * @returns {string}
59
43
  */
60
44
  text() {
61
45
  const equals = '='.repeat(Number(this.name));
62
- return `${this.prependNewLine()}${equals}${this.firstChild.text()}${equals}`;
46
+ return `${equals}${this.firstChild.text()}${equals}`;
63
47
  }
64
48
 
65
49
  /** @override */
@@ -72,12 +56,6 @@ class HeadingToken extends fixedToken(sol(Token)) {
72
56
  return Number(this.name);
73
57
  }
74
58
 
75
- /** @override */
76
- print() {
77
- const equals = '='.repeat(Number(this.name));
78
- return super.print({pre: equals, sep: equals});
79
- }
80
-
81
59
  /**
82
60
  * @override
83
61
  * @param {number} start 起始位置
@@ -100,35 +78,6 @@ class HeadingToken extends fixedToken(sol(Token)) {
100
78
  }
101
79
  return errors;
102
80
  }
103
-
104
- /** @override */
105
- cloneNode() {
106
- const [title, trail] = this.cloneChildNodes();
107
- return Parser.run(() => {
108
- const token = new HeadingToken(Number(this.name), [], this.getAttribute('config'));
109
- token.firsthild.safeReplaceWith(title);
110
- token.lastChild.safeReplaceWith(trail);
111
- return token;
112
- });
113
- }
114
-
115
- /**
116
- * 设置标题层级
117
- * @param {number} n 标题层级
118
- */
119
- setLevel(n) {
120
- if (!Number.isInteger(n)) {
121
- this.typeError('setLevel', 'Number');
122
- }
123
- n = Math.min(Math.max(n, 1), 6);
124
- this.setAttribute('name', String(n)).firstChild.setAttribute('name', this.name);
125
- }
126
-
127
- /** 移除标题后的不可见内容 */
128
- removeTrail() {
129
- this.lastChild.replaceChildren();
130
- }
131
81
  }
132
82
 
133
- Parser.classes.HeadingToken = __filename;
134
83
  module.exports = HeadingToken;
package/src/html.js CHANGED
@@ -1,9 +1,6 @@
1
1
  'use strict';
2
2
 
3
3
  const {generateForSelf} = require('../util/lint'),
4
- {noWrap} = require('../util/string'),
5
- fixedToken = require('../mixin/fixedToken'),
6
- attributeParent = require('../mixin/attributeParent'),
7
4
  Parser = require('..'),
8
5
  Token = require('.');
9
6
 
@@ -13,7 +10,7 @@ const magicWords = new Set(['if', 'ifeq', 'ifexpr', 'ifexist', 'iferror', 'switc
13
10
  * HTML标签
14
11
  * @classdesc `{childNodes: [AttributesToken]}`
15
12
  */
16
- class HtmlToken extends attributeParent(fixedToken(Token)) {
13
+ class HtmlToken extends Token {
17
14
  type = 'html';
18
15
  #closing;
19
16
  #selfClosing;
@@ -24,47 +21,12 @@ class HtmlToken extends attributeParent(fixedToken(Token)) {
24
21
  return this.#closing;
25
22
  }
26
23
 
27
- /** @throws `Error` 自闭合标签或空标签 */
28
- set closing(value) {
29
- if (!value) {
30
- this.#closing = false;
31
- return;
32
- } else if (this.#selfClosing) {
33
- throw new Error('这是一个自闭合标签!');
34
- }
35
- const {html: [,, tags]} = this.getAttribute('config');
36
- if (tags.includes(this.name)) {
37
- throw new Error('这是一个空标签!');
38
- }
39
- this.#closing = true;
40
- }
41
-
42
- /** getter */
43
- get selfClosing() {
44
- return this.#selfClosing;
45
- }
46
-
47
- /** @throws `Error` 闭合标签或无效自闭合标签 */
48
- set selfClosing(value) {
49
- if (!value) {
50
- this.#selfClosing = false;
51
- return;
52
- } else if (this.#closing) {
53
- throw new Error('这是一个闭合标签!');
54
- }
55
- const {html: [tags]} = this.getAttribute('config');
56
- if (tags.includes(this.name)) {
57
- throw new Error(`<${this.name}>标签自闭合无效!`);
58
- }
59
- this.#selfClosing = true;
60
- }
61
-
62
24
  /**
63
25
  * @param {string} name 标签名
64
26
  * @param {AttributesToken} attr 标签属性
65
27
  * @param {boolean} closing 是否闭合
66
28
  * @param {boolean} selfClosing 是否自封闭
67
- * @param {accum} accum
29
+ * @param {import('../typings/token').accum} accum
68
30
  */
69
31
  constructor(name, attr, closing, selfClosing, config = Parser.getConfig(), accum = []) {
70
32
  super(undefined, config, true, accum);
@@ -77,12 +39,9 @@ class HtmlToken extends attributeParent(fixedToken(Token)) {
77
39
 
78
40
  /**
79
41
  * @override
80
- * @param {string} selector
81
42
  */
82
43
  toString(selector) {
83
- return selector && this.matches(selector)
84
- ? ''
85
- : `<${this.#closing ? '/' : ''}${this.#tag}${super.toString(selector)}${this.#selfClosing ? '/' : ''}>`;
44
+ return `<${this.#closing ? '/' : ''}${this.#tag}${super.toString()}${this.#selfClosing ? '/' : ''}>`;
86
45
  }
87
46
 
88
47
  /** @override */
@@ -97,21 +56,13 @@ class HtmlToken extends attributeParent(fixedToken(Token)) {
97
56
  return this.#tag.length + (this.#closing ? 2 : 1);
98
57
  }
99
58
 
100
- /** @override */
101
- print() {
102
- return super.print({
103
- pre: `&lt;${this.#closing ? '/' : ''}${this.#tag}`,
104
- post: `${this.#selfClosing ? '/' : ''}&gt;`,
105
- });
106
- }
107
-
108
59
  /**
109
60
  * @override
110
61
  * @param {number} start 起始位置
111
62
  */
112
63
  lint(start = this.getAbsoluteIndex()) {
113
64
  const errors = super.lint(start);
114
- let wikitext, /** @type {LintError} */ refError;
65
+ let wikitext, /** @type {import('../typings/token').LintError} */ refError;
115
66
  if (this.name === 'h1' && !this.#closing) {
116
67
  wikitext = String(this.getRootNode());
117
68
  refError = generateForSelf(this, {start}, '<h1>');
@@ -155,7 +106,7 @@ class HtmlToken extends attributeParent(fixedToken(Token)) {
155
106
  findMatchingTag() {
156
107
  const {html} = this.getAttribute('config'),
157
108
  {name: tagName, parentNode} = this,
158
- string = noWrap(String(this));
109
+ string = String(this);
159
110
  if (this.#closing && (this.#selfClosing || html[2].includes(tagName))) {
160
111
  throw new SyntaxError(`tag that is both closing and self-closing: ${string}`);
161
112
  } else if (html[2].includes(tagName) || this.#selfClosing && html[1].includes(tagName)) { // 自封闭标签
@@ -183,72 +134,6 @@ class HtmlToken extends attributeParent(fixedToken(Token)) {
183
134
  }
184
135
  throw new SyntaxError(`${this.#closing ? 'unmatched closing' : 'unclosed'} tag: ${string}`);
185
136
  }
186
-
187
- /** @override */
188
- cloneNode() {
189
- const [attr] = this.cloneChildNodes(),
190
- config = this.getAttribute('config');
191
- return Parser.run(() => new HtmlToken(this.#tag, attr, this.#closing, this.#selfClosing, config));
192
- }
193
-
194
- /**
195
- * @override
196
- * @template {string} T
197
- * @param {T} key 属性键
198
- * @returns {TokenAttribute<T>}
199
- */
200
- getAttribute(key) {
201
- return key === 'tag' ? this.#tag : super.getAttribute(key);
202
- }
203
-
204
- /**
205
- * 更换标签名
206
- * @param {string} tag 标签名
207
- * @throws `RangeError` 非法的HTML标签
208
- */
209
- replaceTag(tag) {
210
- const name = tag.toLowerCase();
211
- if (!this.getAttribute('config').html.flat().includes(name)) {
212
- throw new RangeError(`非法的HTML标签:${tag}`);
213
- }
214
- this.setAttribute('name', name).#tag = tag;
215
- }
216
-
217
- /** 局部闭合 */
218
- #localMatch() {
219
- this.#selfClosing = false;
220
- const root = Parser.parse(`</${this.name}>`, false, 3, this.getAttribute('config'));
221
- this.after(root.firstChild);
222
- }
223
-
224
- /**
225
- * 修复无效自封闭标签
226
- * @complexity `n`
227
- * @throws `Error` 无法修复无效自封闭标签
228
- */
229
- fix() {
230
- const config = this.getAttribute('config'),
231
- {parentNode, name: tagName, firstChild} = this;
232
- if (!parentNode || !this.#selfClosing || !config.html[0].includes(tagName)) {
233
- return;
234
- } else if (firstChild.text().trim()) {
235
- this.#localMatch();
236
- return;
237
- }
238
- const {childNodes} = parentNode,
239
- i = childNodes.indexOf(this),
240
- /** @type {HtmlToken[]} */
241
- prevSiblings = childNodes.slice(0, i).filter(({type, name}) => type === 'html' && name === tagName),
242
- imbalance = prevSiblings.reduce((acc, {closing}) => acc + (closing ? 1 : -1), 0);
243
- if (imbalance < 0) {
244
- this.#selfClosing = false;
245
- this.#closing = true;
246
- } else {
247
- Parser.warn('无法修复无效自封闭标签', noWrap(String(this)));
248
- throw new Error(`无法修复无效自封闭标签:前文共有 ${imbalance} 个未匹配的闭合标签`);
249
- }
250
- }
251
137
  }
252
138
 
253
- Parser.classes.HtmlToken = __filename;
254
139
  module.exports = HtmlToken;