wikiparser-node 0.3.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.eslintrc.json CHANGED
@@ -3,7 +3,16 @@
3
3
  "node": true,
4
4
  "es2021": true
5
5
  },
6
- "extends": "eslint:recommended",
6
+ "plugins": [
7
+ "promise",
8
+ "regexp"
9
+ ],
10
+ "extends": [
11
+ "eslint:recommended",
12
+ "plugin:promise/recommended",
13
+ "plugin:n/recommended-script",
14
+ "plugin:regexp/recommended"
15
+ ],
7
16
  "parserOptions": {
8
17
  "ecmaVersion": 13
9
18
  },
@@ -135,7 +144,10 @@
135
144
  "no-shadow": [
136
145
  2,
137
146
  {
138
- "builtinGlobals": true
147
+ "builtinGlobals": true,
148
+ "allow": [
149
+ "root"
150
+ ]
139
151
  }
140
152
  ],
141
153
  "no-undef-init": 2,
@@ -185,7 +197,7 @@
185
197
  ],
186
198
  "require-await": 2,
187
199
  "spaced-comment": 2,
188
- "strict": 2,
200
+ "strict": 2,
189
201
  "symbol-description": 2,
190
202
  "yoda": 2,
191
203
  "array-bracket-spacing": 2,
@@ -271,6 +283,37 @@
271
283
  "wrap-iife": [
272
284
  2,
273
285
  "inside"
274
- ]
286
+ ],
287
+ "promise/no-multiple-resolved": 1,
288
+ "n/exports-style": [
289
+ 2,
290
+ "module.exports"
291
+ ],
292
+ "n/no-path-concat": 2,
293
+ "n/no-missing-require": 2,
294
+ "regexp/no-contradiction-with-assertion": 2,
295
+ "regexp/no-missing-g-flag": 2,
296
+ "regexp/no-super-linear-backtracking": [
297
+ 2,
298
+ {
299
+ "report": "potential"
300
+ }
301
+ ],
302
+ "regexp/no-super-linear-move": [
303
+ 2,
304
+ {
305
+ "report": "potential"
306
+ }
307
+ ],
308
+ "regexp/no-extra-lookaround-assertions": 2,
309
+ "regexp/no-octal": 2,
310
+ "regexp/no-standalone-backslash": 2,
311
+ "regexp/prefer-escape-replacement-dollar-char": 2,
312
+ "regexp/prefer-quantifier": 2,
313
+ "regexp/prefer-regexp-test": 2,
314
+ "regexp/use-ignore-case": 2,
315
+ "regexp/hexadecimal-escape": 2,
316
+ "regexp/letter-case": 2,
317
+ "regexp/prefer-lookaround": 2
275
318
  }
276
319
  }
@@ -124,34 +124,47 @@
124
124
  "媒体": -2,
125
125
  "媒体文件": -2,
126
126
  "媒體": -2,
127
+ "メディア": -2,
127
128
  "special": -1,
128
129
  "特殊": -1,
130
+ "特別": -1,
129
131
  "talk": 1,
130
132
  "对话": 1,
131
133
  "對話": 1,
132
134
  "讨论": 1,
133
135
  "討論": 1,
136
+ "トーク": 1,
137
+ "ノート": 1,
134
138
  "user": 2,
135
139
  "u": 2,
136
140
  "使用者": 2,
137
141
  "用戶": 2,
138
142
  "用户": 2,
139
- "user_talk": 3,
143
+ "利用者": 2,
144
+ "user talk": 3,
140
145
  "使用者討論": 3,
141
146
  "用戶對話": 3,
142
147
  "用戶討論": 3,
143
148
  "用户对话": 3,
144
149
  "用户讨论": 3,
150
+ "利用者‐会話": 3,
151
+ "利用者・トーク": 3,
145
152
  "llwiki": 4,
153
+ "mgp": 4,
154
+ "moegirlpedia": 4,
146
155
  "萌娘百科": 4,
156
+ "萌えっ娘百科事典": 4,
147
157
  "project": 4,
148
- "llwiki_talk": 5,
158
+ "llwiki talk": 5,
149
159
  "llwiki讨论": 5,
150
160
  "llwiki討論": 5,
151
- "萌娘百科_talk": 5,
161
+ "萌娘百科 talk": 5,
152
162
  "萌娘百科讨论": 5,
153
163
  "萌娘百科討論": 5,
154
- "project_talk": 5,
164
+ "moegirlpedia talk": 5,
165
+ "萌えっ娘百科事典‐ノート": 5,
166
+ "萌えっ娘百科事典・トーク": 5,
167
+ "project talk": 5,
155
168
  "file": 6,
156
169
  "image": 6,
157
170
  "图像": 6,
@@ -159,8 +172,10 @@
159
172
  "文件": 6,
160
173
  "档案": 6,
161
174
  "檔案": 6,
162
- "file_talk": 7,
163
- "image_talk": 7,
175
+ "ファイル": 6,
176
+ "画像": 6,
177
+ "file talk": 7,
178
+ "image talk": 7,
164
179
  "图像对话": 7,
165
180
  "图像讨论": 7,
166
181
  "圖像對話": 7,
@@ -173,16 +188,22 @@
173
188
  "档案讨论": 7,
174
189
  "檔案對話": 7,
175
190
  "檔案討論": 7,
191
+ "ファイル‐ノート": 7,
192
+ "ファイル・トーク": 7,
193
+ "画像‐ノート": 7,
176
194
  "mediawiki": 8,
177
- "mediawiki_talk": 9,
195
+ "mediawiki talk": 9,
178
196
  "mediawiki讨论": 9,
179
197
  "mediawiki討論": 9,
198
+ "mediawiki‐ノート": 9,
199
+ "mediawiki・トーク": 9,
180
200
  "template": 10,
181
201
  "t": 10,
182
202
  "样板": 10,
183
203
  "模板": 10,
184
204
  "樣板": 10,
185
- "template_talk": 11,
205
+ "テンプレート": 10,
206
+ "template talk": 11,
186
207
  "样板对话": 11,
187
208
  "样板讨论": 11,
188
209
  "模板对话": 11,
@@ -191,33 +212,44 @@
191
212
  "模板討論": 11,
192
213
  "樣板對話": 11,
193
214
  "樣板討論": 11,
215
+ "template‐ノート": 11,
216
+ "テンプレート・トーク": 11,
217
+ "h": 12,
194
218
  "help": 12,
195
219
  "使用說明": 12,
196
220
  "帮助": 12,
197
221
  "幫助": 12,
198
- "help_talk": 13,
222
+ "ヘルプ": 12,
223
+ "help talk": 13,
199
224
  "使用說明討論": 13,
200
225
  "帮助对话": 13,
201
226
  "帮助讨论": 13,
202
227
  "幫助對話": 13,
203
228
  "幫助討論": 13,
229
+ "help‐ノート": 13,
230
+ "ヘルプ・トーク": 13,
204
231
  "category": 14,
205
232
  "cat": 14,
206
233
  "分类": 14,
207
234
  "分類": 14,
208
- "category_talk": 15,
235
+ "カテゴリ": 14,
236
+ "category talk": 15,
209
237
  "分类对话": 15,
210
238
  "分类讨论": 15,
211
239
  "分類對話": 15,
212
240
  "分類討論": 15,
241
+ "category‐ノート": 15,
242
+ "カテゴリ・トーク": 15,
213
243
  "widget": 274,
214
- "widget_talk": 275,
244
+ "widget talk": 275,
215
245
  "module": 828,
216
246
  "模块": 828,
217
247
  "模組": 828,
218
- "module_talk": 829,
248
+ "モジュール": 828,
249
+ "module talk": 829,
219
250
  "模块讨论": 829,
220
- "模組討論": 829
251
+ "模組討論": 829,
252
+ "モジュール・トーク": 829
221
253
  },
222
254
  "parserFunction": [
223
255
  [
@@ -126,7 +126,7 @@
126
126
  "使用者": 2,
127
127
  "用戶": 2,
128
128
  "用户": 2,
129
- "user_talk": 3,
129
+ "user talk": 3,
130
130
  "使用者討論": 3,
131
131
  "用戶對話": 3,
132
132
  "用戶討論": 3,
@@ -134,10 +134,10 @@
134
134
  "用户讨论": 3,
135
135
  "llwiki": 4,
136
136
  "project": 4,
137
- "llwiki_talk": 5,
137
+ "llwiki talk": 5,
138
138
  "llwiki讨论": 5,
139
139
  "llwiki討論": 5,
140
- "project_talk": 5,
140
+ "project talk": 5,
141
141
  "file": 6,
142
142
  "image": 6,
143
143
  "图像": 6,
@@ -145,8 +145,8 @@
145
145
  "文件": 6,
146
146
  "档案": 6,
147
147
  "檔案": 6,
148
- "file_talk": 7,
149
- "image_talk": 7,
148
+ "file talk": 7,
149
+ "image talk": 7,
150
150
  "图像对话": 7,
151
151
  "图像讨论": 7,
152
152
  "圖像對話": 7,
@@ -160,14 +160,14 @@
160
160
  "檔案對話": 7,
161
161
  "檔案討論": 7,
162
162
  "mediawiki": 8,
163
- "mediawiki_talk": 9,
163
+ "mediawiki talk": 9,
164
164
  "mediawiki讨论": 9,
165
165
  "mediawiki討論": 9,
166
166
  "template": 10,
167
167
  "样板": 10,
168
168
  "模板": 10,
169
169
  "樣板": 10,
170
- "template_talk": 11,
170
+ "template talk": 11,
171
171
  "样板对话": 11,
172
172
  "样板讨论": 11,
173
173
  "模板对话": 11,
@@ -180,7 +180,7 @@
180
180
  "使用說明": 12,
181
181
  "帮助": 12,
182
182
  "幫助": 12,
183
- "help_talk": 13,
183
+ "help talk": 13,
184
184
  "使用說明討論": 13,
185
185
  "帮助对话": 13,
186
186
  "帮助讨论": 13,
@@ -189,17 +189,17 @@
189
189
  "category": 14,
190
190
  "分类": 14,
191
191
  "分類": 14,
192
- "category_talk": 15,
192
+ "category talk": 15,
193
193
  "分类对话": 15,
194
194
  "分类讨论": 15,
195
195
  "分類對話": 15,
196
196
  "分類討論": 15,
197
197
  "widget": 274,
198
- "widget_talk": 275,
198
+ "widget talk": 275,
199
199
  "module": 828,
200
200
  "模块": 828,
201
201
  "模組": 828,
202
- "module_talk": 829,
202
+ "module talk": 829,
203
203
  "模块讨论": 829,
204
204
  "模組討論": 829
205
205
  },
@@ -119,30 +119,43 @@
119
119
  "媒体": -2,
120
120
  "媒体文件": -2,
121
121
  "媒體": -2,
122
+ "メディア": -2,
122
123
  "special": -1,
123
124
  "特殊": -1,
125
+ "特別": -1,
124
126
  "talk": 1,
125
127
  "对话": 1,
126
128
  "對話": 1,
127
129
  "讨论": 1,
128
130
  "討論": 1,
131
+ "トーク": 1,
132
+ "ノート": 1,
129
133
  "user": 2,
130
134
  "u": 2,
131
135
  "使用者": 2,
132
136
  "用戶": 2,
133
137
  "用户": 2,
134
- "user_talk": 3,
138
+ "利用者": 2,
139
+ "user talk": 3,
135
140
  "使用者討論": 3,
136
141
  "用戶對話": 3,
137
142
  "用戶討論": 3,
138
143
  "用户对话": 3,
139
144
  "用户讨论": 3,
145
+ "利用者‐会話": 3,
146
+ "利用者・トーク": 3,
147
+ "mgp": 4,
148
+ "moegirlpedia": 4,
140
149
  "萌娘百科": 4,
150
+ "萌えっ娘百科事典": 4,
141
151
  "project": 4,
142
- "萌娘百科_talk": 5,
152
+ "萌娘百科 talk": 5,
143
153
  "萌娘百科讨论": 5,
144
154
  "萌娘百科討論": 5,
145
- "project_talk": 5,
155
+ "moegirlpedia talk": 5,
156
+ "萌えっ娘百科事典‐ノート": 5,
157
+ "萌えっ娘百科事典・トーク": 5,
158
+ "project talk": 5,
146
159
  "file": 6,
147
160
  "image": 6,
148
161
  "图像": 6,
@@ -150,8 +163,10 @@
150
163
  "文件": 6,
151
164
  "档案": 6,
152
165
  "檔案": 6,
153
- "file_talk": 7,
154
- "image_talk": 7,
166
+ "ファイル": 6,
167
+ "画像": 6,
168
+ "file talk": 7,
169
+ "image talk": 7,
155
170
  "图像对话": 7,
156
171
  "图像讨论": 7,
157
172
  "圖像對話": 7,
@@ -164,16 +179,22 @@
164
179
  "档案讨论": 7,
165
180
  "檔案對話": 7,
166
181
  "檔案討論": 7,
182
+ "ファイル‐ノート": 7,
183
+ "ファイル・トーク": 7,
184
+ "画像‐ノート": 7,
167
185
  "mediawiki": 8,
168
- "mediawiki_talk": 9,
186
+ "mediawiki talk": 9,
169
187
  "mediawiki讨论": 9,
170
188
  "mediawiki討論": 9,
189
+ "mediawiki‐ノート": 9,
190
+ "mediawiki・トーク": 9,
171
191
  "template": 10,
172
192
  "t": 10,
173
193
  "样板": 10,
174
194
  "模板": 10,
175
195
  "樣板": 10,
176
- "template_talk": 11,
196
+ "テンプレート": 10,
197
+ "template talk": 11,
177
198
  "样板对话": 11,
178
199
  "样板讨论": 11,
179
200
  "模板对话": 11,
@@ -182,33 +203,44 @@
182
203
  "模板討論": 11,
183
204
  "樣板對話": 11,
184
205
  "樣板討論": 11,
206
+ "template‐ノート": 11,
207
+ "テンプレート・トーク": 11,
208
+ "h": 12,
185
209
  "help": 12,
186
210
  "使用說明": 12,
187
211
  "帮助": 12,
188
212
  "幫助": 12,
189
- "help_talk": 13,
213
+ "ヘルプ": 12,
214
+ "help talk": 13,
190
215
  "使用說明討論": 13,
191
216
  "帮助对话": 13,
192
217
  "帮助讨论": 13,
193
218
  "幫助對話": 13,
194
219
  "幫助討論": 13,
220
+ "help‐ノート": 13,
221
+ "ヘルプ・トーク": 13,
195
222
  "category": 14,
196
223
  "cat": 14,
197
224
  "分类": 14,
198
225
  "分類": 14,
199
- "category_talk": 15,
226
+ "カテゴリ": 14,
227
+ "category talk": 15,
200
228
  "分类对话": 15,
201
229
  "分类讨论": 15,
202
230
  "分類對話": 15,
203
231
  "分類討論": 15,
232
+ "category‐ノート": 15,
233
+ "カテゴリ・トーク": 15,
204
234
  "widget": 274,
205
- "widget_talk": 275,
235
+ "widget talk": 275,
206
236
  "module": 828,
207
237
  "模块": 828,
208
238
  "模組": 828,
209
- "module_talk": 829,
239
+ "モジュール": 828,
240
+ "module talk": 829,
210
241
  "模块讨论": 829,
211
- "模組討論": 829
242
+ "模組討論": 829,
243
+ "モジュール・トーク": 829
212
244
  },
213
245
  "parserFunction": [
214
246
  [
package/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  const fs = require('fs'),
4
+ path = require('path'),
4
5
  {text} = require('./util/string');
5
6
 
6
7
  const /** @type {Parser} */ Parser = {
@@ -49,12 +50,12 @@ const /** @type {Parser} */ Parser = {
49
50
  ...Object.entries(this.mixins),
50
51
  ...Object.entries(this.parsers),
51
52
  ];
52
- for (const [, path] of entries) {
53
- delete require.cache[require.resolve(path)];
53
+ for (const [, filePath] of entries) {
54
+ delete require.cache[require.resolve(filePath)];
54
55
  }
55
- for (const [name, path] of entries) {
56
+ for (const [name, filePath] of entries) {
56
57
  if (name in global) {
57
- global[name] = require(path);
58
+ global[name] = require(filePath);
58
59
  }
59
60
  }
60
61
  },
@@ -88,8 +89,7 @@ const /** @type {Parser} */ Parser = {
88
89
 
89
90
  isInterwiki(title, {interwiki} = Parser.getConfig()) {
90
91
  title = String(title);
91
- return title.replaceAll('_', ' ').replace(/^\s*:?\s*/, '')
92
- .match(new RegExp(`^(${interwiki.join('|')})\\s*:`, 'i'));
92
+ return RegExp(`^(${interwiki.join('|')})\\s*:`, 'i').exec(title.replaceAll('_', ' ').replace(/^\s*:?\s*/, ''));
93
93
  },
94
94
 
95
95
  normalizeTitle(title, defaultNs = 0, include = false, config = Parser.getConfig(), halfParsed = false) {
@@ -105,7 +105,7 @@ const /** @type {Parser} */ Parser = {
105
105
  if (token) {
106
106
  const build = /** @param {string[]} keys */ keys => {
107
107
  for (const key of keys) {
108
- if (titleObj[key].includes('\x00')) {
108
+ if (titleObj[key].includes('\0')) {
109
109
  titleObj[key] = text(token.buildFromStr(titleObj[key]));
110
110
  }
111
111
  }
@@ -135,7 +135,7 @@ const /** @type {Parser} */ Parser = {
135
135
  token.parse(maxStage, include);
136
136
  } catch (e) {
137
137
  if (e instanceof Error) {
138
- const file = `${__dirname}/errors/${new Date().toISOString()}`,
138
+ const file = path.join(__dirname, 'errors', new Date().toISOString()),
139
139
  stage = token.getAttribute('stage');
140
140
  fs.writeFileSync(file, stage === this.MAX_STAGE ? wikitext : token.toString());
141
141
  fs.writeFileSync(`${file}.err`, e.stack);
@@ -150,13 +150,13 @@ const /** @type {Parser} */ Parser = {
150
150
  },
151
151
 
152
152
  reparse(date) {
153
- const path = `${__dirname}/errors/`,
154
- main = fs.readdirSync(path).find(name => name.startsWith(date) && name.endsWith('Z'));
153
+ const main = fs.readdirSync(path.join(__dirname, 'errors'))
154
+ .find(name => name.startsWith(date) && name.endsWith('Z'));
155
155
  if (!main) {
156
156
  throw new RangeError(`找不到对应时间戳的错误记录:${date}`);
157
157
  }
158
158
  const Token = require('./src'),
159
- file = `${path}${main}`,
159
+ file = path.join(__dirname, 'errors', main),
160
160
  wikitext = fs.readFileSync(file, 'utf8'),
161
161
  {stage, include, config} = require(`${file}.json`);
162
162
  this.config = config;
package/lib/element.js CHANGED
@@ -346,11 +346,11 @@ class AstElement extends AstNode {
346
346
  visible: false,
347
347
  };
348
348
  /** @type {pseudo[]} */ static #pseudoKeys = Object.keys(AstElement.#pseudo);
349
- static #pseudoRegex = new RegExp(
349
+ static #pseudoRegex = RegExp(
350
350
  `:(${this.#pseudoKeys.join('|')})(?:\\(\\s*("[^"]*"|'[^']*'|[^()]*?)\\s*\\))?(?=:|\\s*(?:,|$))`,
351
351
  'g',
352
352
  );
353
- static #simplePseudoRegex = new RegExp(`:(?:${this.#pseudoKeys.join('|')})(?:\\(.*?\\))?(?=:|\\s*(?:,|$))`, 'g');
353
+ static #simplePseudoRegex = RegExp(`:(?:${this.#pseudoKeys.join('|')})(?:\\(.*?\\))?(?=:|\\s*(?:,|$))`, 'g');
354
354
 
355
355
  /**
356
356
  * @returns {boolean}
@@ -365,7 +365,7 @@ class AstElement extends AstNode {
365
365
  simple &&= Parser.running;
366
366
  const /** @type {Record<string, string>} */ escapedQuotes = {'"': '&quot;', "'": '&apos;'},
367
367
  escapedSelector = selector.replace(/\\["']/g, m => escapedQuotes[m[1]]);
368
- if (simple || !AstElement.#pseudoRegex.test(escapedSelector)) {
368
+ if (simple || escapedSelector.search(AstElement.#pseudoRegex) === -1) {
369
369
  if (!simple && selector.includes(',')) {
370
370
  return Parser.run(() => selector.split(',').some(str => this.matches(str, true)));
371
371
  }
@@ -384,10 +384,10 @@ class AstElement extends AstNode {
384
384
  plainSelector = selector.replace(
385
385
  /&(comma|ratio);/g, /** @param {string} name */ (_, name) => entities[name],
386
386
  ).replace(
387
- /\[\s*(\w+)\s*(?:([~|^$*!]?=)\s*("[^"]*"|'[^']*'|[^[\]]*?)\s*(\si)?\s*)?]/g,
387
+ /\[\s*(\w+)\s*(?:([~|^$*!]?=)\s*("[^"]*"|'[^']*'|[^\s[\]]+)(?:\s+(i))?\s*)?\]/g,
388
388
  /** @type {function(...string): ''} */ (_, key, equal, val, i) => {
389
389
  if (equal) {
390
- const quotes = val.match(/^(["']).*\1$/)?.[1];
390
+ const quotes = /^(["']).*\1$/.exec(val)?.[1];
391
391
  attributes.push([
392
392
  key,
393
393
  equal,
@@ -418,7 +418,7 @@ class AstElement extends AstNode {
418
418
  calls[f].push('');
419
419
  return m;
420
420
  }
421
- const quotes = arg.match(/^(["']).*\1$/)?.[1];
421
+ const quotes = /^(["']).*\1$/.exec(arg)?.[1];
422
422
  calls[f].push(quotes ? arg.slice(1, -1).replaceAll(escapedQuotes[quotes], quotes) : arg);
423
423
  return `:${f}(${calls[f].length - 1})`;
424
424
  },
package/lib/ranges.js CHANGED
@@ -32,7 +32,7 @@ class Range {
32
32
  throw new RangeError(`步长 ${this.step} 应为整数!`);
33
33
  }
34
34
  } else {
35
- const mt = str.match(/^([+-])?(\d+)?n(?:([+-])(\d+))?$/);
35
+ const mt = /^([+-])?(\d+)?n(?:([+-])(\d+))?$/.exec(str);
36
36
  if (mt) {
37
37
  const [, sgnA = '+', a = 1, sgnB = '+'] = mt,
38
38
  b = Number(mt[4] ?? 0);
package/lib/title.js CHANGED
@@ -53,7 +53,7 @@ class Title {
53
53
  this.main = ucfirst(title);
54
54
  this.prefix = `${namespace}${namespace && ':'}`;
55
55
  this.title = `${iw ? `${this.interwiki}:` : ''}${this.prefix}${this.main}`;
56
- this.valid = Boolean(this.main) && !/\x00\d+[eh!+-]\x7f|[<>[\]{}|]/.test(this.title);
56
+ this.valid = Boolean(this.main || this.fragment) && !/\0\d+[eh!+-]\x7f|[<>[\]{}|]/.test(this.title);
57
57
  }
58
58
  }
59
59
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wikiparser-node",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "A Node.js parser for MediaWiki markup with AST",
5
5
  "keywords": [
6
6
  "mediawiki",
@@ -22,7 +22,10 @@
22
22
  },
23
23
  "devDependencies": {
24
24
  "@types/node": "^17.0.23",
25
- "eslint": "^8.30.0"
25
+ "eslint": "^8.30.0",
26
+ "eslint-plugin-promise": "^6.1.1",
27
+ "eslint-plugin-n": "^15.6.0",
28
+ "eslint-plugin-regexp": "^1.11.0"
26
29
  },
27
30
  "engines": {
28
31
  "node": "^18.4.0"
@@ -8,15 +8,20 @@ const {removeComment} = require('../util/string'),
8
8
  * @param {accum} accum
9
9
  */
10
10
  const parseBrackets = (text, config = Parser.getConfig(), accum = []) => {
11
- const source = '(?<=^(?:\x00\\d+c\x7f)*)={1,6}|\\[\\[|{{2,}|-{(?!{)',
11
+ const source = '^(\0\\d+c\x7f)*={1,6}|\\[\\[|\\{{2,}|-\\{(?!\\{)',
12
12
  /** @type {BracketExecArray[]} */ stack = [],
13
13
  closes = {'=': '\n', '{': '}{2,}|\\|', '-': '}-', '[': ']]'},
14
14
  /** @type {Record<string, string>} */ marks = {'!': '!', '!!': '+', '(!': '{', '!)': '}', '!-': '-', '=': '~'};
15
- let regex = new RegExp(source, 'gm'),
15
+ let regex = RegExp(source, 'gm'),
16
16
  /** @type {BracketExecArray} */ mt = regex.exec(text),
17
17
  moreBraces = text.includes('}}'),
18
18
  lastIndex;
19
19
  while (mt || lastIndex <= text.length && stack.at(-1)?.[0]?.[0] === '=') {
20
+ if (mt?.[1]) {
21
+ const [, {length}] = mt;
22
+ mt[0] = mt[0].slice(length);
23
+ mt.index += length;
24
+ }
20
25
  const {0: syntax, index: curIndex} = mt ?? {0: '\n', index: text.length},
21
26
  /** @type {BracketExecArray} */ top = stack.pop() ?? {},
22
27
  {0: open, index, parts} = top,
@@ -27,9 +32,9 @@ const parseBrackets = (text, config = Parser.getConfig(), accum = []) => {
27
32
  lastIndex = curIndex + 1;
28
33
  const {pos, findEqual} = stack.at(-1) ?? {};
29
34
  if (!pos || findEqual || removeComment(text.slice(pos, index)) !== '') {
30
- const rmt = text.slice(index, curIndex).match(/^(={1,6})(.+)\1((?:\s|\x00\d+c\x7f)*)$/);
35
+ const rmt = /^(={1,6})(.+)\1((?:\s|\0\d+c\x7f)*)$/.exec(text.slice(index, curIndex));
31
36
  if (rmt) {
32
- text = `${text.slice(0, index)}\x00${accum.length}h\x7f${text.slice(curIndex)}`;
37
+ text = `${text.slice(0, index)}\0${accum.length}h\x7f${text.slice(curIndex)}`;
33
38
  lastIndex = index + 4 + String(accum.length).length;
34
39
  const HeadingToken = require('../src/heading');
35
40
  new HeadingToken(rmt[1].length, rmt.slice(2), config, accum);
@@ -71,7 +76,7 @@ const parseBrackets = (text, config = Parser.getConfig(), accum = []) => {
71
76
  }
72
77
  if (!skip) {
73
78
  /* 标记{{!}}结束 */
74
- text = `${text.slice(0, index + rest)}\x00${length}${ch}\x7f${text.slice(lastIndex)}`;
79
+ text = `${text.slice(0, index + rest)}\0${length}${ch}\x7f${text.slice(lastIndex)}`;
75
80
  lastIndex = index + rest + 3 + String(length).length;
76
81
  if (rest > 1) {
77
82
  stack.push({0: open.slice(0, rest), index, pos: index + rest, parts: [[]]});
@@ -93,7 +98,7 @@ const parseBrackets = (text, config = Parser.getConfig(), accum = []) => {
93
98
  stack.pop();
94
99
  curTop = stack.at(-1);
95
100
  }
96
- regex = new RegExp(source + (curTop
101
+ regex = RegExp(source + (curTop
97
102
  ? `|${closes[curTop[0][0]]}${curTop.findEqual ? '|=' : ''}`
98
103
  : ''
99
104
  ), 'gm');