wikiparser-node 0.3.0 → 0.4.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 (81) hide show
  1. package/.eslintrc.json +472 -34
  2. package/README.md +1 -1
  3. package/config/default.json +58 -30
  4. package/config/llwiki.json +22 -90
  5. package/config/moegirl.json +51 -13
  6. package/config/zhwiki.json +1269 -0
  7. package/index.js +114 -104
  8. package/lib/element.js +448 -440
  9. package/lib/node.js +335 -115
  10. package/lib/ranges.js +27 -18
  11. package/lib/text.js +146 -0
  12. package/lib/title.js +13 -5
  13. package/mixin/attributeParent.js +70 -24
  14. package/mixin/fixedToken.js +14 -6
  15. package/mixin/hidden.js +6 -4
  16. package/mixin/sol.js +27 -10
  17. package/package.json +9 -3
  18. package/parser/brackets.js +22 -17
  19. package/parser/commentAndExt.js +18 -16
  20. package/parser/converter.js +14 -13
  21. package/parser/externalLinks.js +12 -11
  22. package/parser/hrAndDoubleUnderscore.js +23 -14
  23. package/parser/html.js +10 -9
  24. package/parser/links.js +15 -14
  25. package/parser/list.js +12 -11
  26. package/parser/magicLinks.js +12 -11
  27. package/parser/quotes.js +6 -5
  28. package/parser/selector.js +175 -0
  29. package/parser/table.js +25 -18
  30. package/printed/example.json +120 -0
  31. package/src/arg.js +56 -32
  32. package/src/atom/hidden.js +5 -2
  33. package/src/atom/index.js +17 -9
  34. package/src/attribute.js +182 -100
  35. package/src/converter.js +68 -41
  36. package/src/converterFlags.js +67 -45
  37. package/src/converterRule.js +117 -65
  38. package/src/extLink.js +66 -18
  39. package/src/gallery.js +42 -15
  40. package/src/heading.js +34 -15
  41. package/src/html.js +97 -35
  42. package/src/imageParameter.js +83 -54
  43. package/src/index.js +299 -178
  44. package/src/link/category.js +20 -52
  45. package/src/link/file.js +59 -28
  46. package/src/link/galleryImage.js +21 -7
  47. package/src/link/index.js +146 -60
  48. package/src/magicLink.js +34 -12
  49. package/src/nowiki/comment.js +22 -10
  50. package/src/nowiki/dd.js +37 -22
  51. package/src/nowiki/doubleUnderscore.js +16 -7
  52. package/src/nowiki/hr.js +11 -7
  53. package/src/nowiki/index.js +16 -9
  54. package/src/nowiki/list.js +2 -2
  55. package/src/nowiki/noinclude.js +8 -4
  56. package/src/nowiki/quote.js +11 -7
  57. package/src/onlyinclude.js +19 -7
  58. package/src/parameter.js +65 -38
  59. package/src/syntax.js +26 -20
  60. package/src/table/index.js +260 -165
  61. package/src/table/td.js +98 -52
  62. package/src/table/tr.js +102 -58
  63. package/src/tagPair/ext.js +27 -19
  64. package/src/tagPair/include.js +16 -11
  65. package/src/tagPair/index.js +64 -29
  66. package/src/transclude.js +170 -93
  67. package/test/api.js +83 -0
  68. package/test/real.js +133 -0
  69. package/test/test.js +28 -0
  70. package/test/util.js +80 -0
  71. package/tool/index.js +41 -31
  72. package/typings/api.d.ts +13 -0
  73. package/typings/array.d.ts +28 -0
  74. package/typings/event.d.ts +24 -0
  75. package/typings/index.d.ts +46 -4
  76. package/typings/node.d.ts +15 -9
  77. package/typings/parser.d.ts +7 -0
  78. package/typings/tool.d.ts +3 -2
  79. package/util/debug.js +21 -18
  80. package/util/string.js +40 -27
  81. package/typings/element.d.ts +0 -28
@@ -4,6 +4,13 @@ declare global {
4
4
  findEqual: boolean;
5
5
  pos: number;
6
6
  }
7
+ interface SelectorArray extends Array<string|RegExpExecArray> {
8
+ relation: string|undefined;
9
+ }
10
+
11
+ type pseudo = 'root'|'is'|'not'|'nth-child'|'nth-of-type'|'nth-last-child'|'nth-last-of-type'
12
+ |'first-child'|'first-of-type'|'last-child'|'last-of-type'|'only-child'|'only-of-type'|'empty'
13
+ |'contains'|'has'|'header'|'parent'|'hidden'|'visible';
7
14
  }
8
15
 
9
16
  export {};
package/typings/tool.d.ts CHANGED
@@ -1,10 +1,11 @@
1
1
  import Token from '../src';
2
+ import AstText from '../lib/text';
2
3
 
3
4
  declare global {
4
5
  interface CollectionCallback<T, S> extends Function {
5
- call: (thisArg: string|Token, i: number, ele: S) => T;
6
+ call: (thisArg: AstText|Token, i: number, ele: S) => T;
6
7
  }
7
- type CollectionMap = (arr: Token[]) => (string|Token)[];
8
+ type CollectionMap = (arr: Token[]) => (AstText|Token)[];
8
9
  }
9
10
 
10
11
  export {};
package/util/debug.js CHANGED
@@ -1,9 +1,11 @@
1
1
  'use strict';
2
2
 
3
3
  /**
4
- * @param {function}
5
- * @param {string} method
6
- * @param {...string} args
4
+ * 定制TypeError消息
5
+ * @param {Function} constructor 类
6
+ * @param {string} method 方法名称
7
+ * @param {...string} args 可接受的参数类型
8
+ * @throws `TypeError`
7
9
  */
8
10
  const typeError = ({name}, method, ...args) => {
9
11
  throw new TypeError(`${name}.${method} 方法仅接受 ${args.join('、')} 作为输入参数!`);
@@ -11,28 +13,30 @@ const typeError = ({name}, method, ...args) => {
11
13
 
12
14
  /**
13
15
  * 不是被构造器或原型方法调用
14
- * @param {string} name
16
+ * @param {string} name 方法名称
15
17
  */
16
- const externalUse = (name, proxy = false) => {
17
- if (!proxy && require('..').running) {
18
+ const externalUse = name => {
19
+ const Parser = require('..');
20
+ if (Parser.running) {
18
21
  return false;
19
22
  }
20
- const regex = new RegExp(`^${
21
- proxy ? 'Proxy' : 'new \\w*Token$|^(?:AstNode|AstElement|\\w*Token)'
22
- }\\.(?!${name}$)`);
23
+ const regex = new RegExp(`^new \\w*Token$|^(?:Ast\\w*|\\w*Token)\\.(?!${name}$)`, 'u');
23
24
  try {
24
- throw new Error();
25
+ throw new Error(); // eslint-disable-line unicorn/error-message
25
26
  } catch (e) {
26
27
  if (e instanceof Error) {
27
- const mt = e.stack.match(/(?<=^\s+at )(?:new )?[\w.]+(?= \(\/)/gm);
28
+ const mt = e.stack.match(/(?<=^\s+at )(?:new )?[\w.]+(?= \(\/)/gmu);
28
29
  return !mt.slice(2).some(func => regex.test(func));
29
30
  }
30
31
  }
32
+ return false;
31
33
  };
32
34
 
33
35
  /**
34
- * @param {AstEvent} e
35
- * @param {AstEventData} data
36
+ * 撤销最近一次Mutation
37
+ * @param {AstEvent} e 事件
38
+ * @param {AstEventData} data 事件数据
39
+ * @throws `RangeError` 无法撤销的事件类型
36
40
  */
37
41
  const undo = (e, data) => {
38
42
  const {target, type} = e;
@@ -40,6 +44,7 @@ const undo = (e, data) => {
40
44
  case 'remove': {
41
45
  const childNodes = [...target.childNodes];
42
46
  childNodes.splice(data.position, 0, data.removed);
47
+ data.removed.setAttribute('parentNode', target);
43
48
  target.setAttribute('childNodes', childNodes);
44
49
  break;
45
50
  }
@@ -53,15 +58,13 @@ const undo = (e, data) => {
53
58
  const {parentNode} = target,
54
59
  childNodes = [...parentNode.childNodes];
55
60
  childNodes.splice(data.position, 1, data.oldToken);
61
+ data.oldToken.setAttribute('parentNode', parentNode);
56
62
  parentNode.setAttribute('childNodes', childNodes);
57
63
  break;
58
64
  }
59
- case 'text': {
60
- const childNodes = [...target.childNodes];
61
- childNodes[data.position] = data.oldText;
62
- target.setAttribute('childNodes', childNodes);
65
+ case 'text':
66
+ target.replaceData(data.oldText);
63
67
  break;
64
- }
65
68
  default:
66
69
  throw new RangeError(`无法撤销未知类型的事件:${type}`);
67
70
  }
package/util/string.js CHANGED
@@ -2,40 +2,45 @@
2
2
 
3
3
  /**
4
4
  * optionally convert to lower cases
5
- * @param {string} val
6
- * @param {boolean} i
5
+ * @param {string} val 属性值
6
+ * @param {string|undefined} i 是否对大小写不敏感
7
7
  */
8
8
  const toCase = (val, i) => i ? val.toLowerCase() : val;
9
9
 
10
10
  /**
11
11
  * remove half-parsed comment-like tokens
12
- * @param {string} str
12
+ * @param {string} str 原字符串
13
13
  */
14
- const removeComment = str => str.replace(/\x00\d+c\x7f/g, '');
14
+ const removeComment = str => str.replaceAll(/\0\d+c\x7F/gu, '');
15
15
 
16
- /** @param {string} str */
17
- const ucfirst = str => str && `${str[0].toUpperCase()}${str.slice(1)}`;
18
-
19
- /** @param {string} str */
20
- const escapeRegExp = str => str.replace(/[\\{}()|.?*+\-^$[\]]/g, '\\$&');
16
+ /**
17
+ * escape special chars for RegExp constructor
18
+ * @param {string} str RegExp source
19
+ */
20
+ const escapeRegExp = str => str.replaceAll(/[\\{}()|.?*+^$[\]]/gu, '\\$&');
21
21
 
22
- /** @param {(string|AstNode)[]} childNodes */
22
+ /**
23
+ * extract effective wikitext
24
+ * @param {(string|AstNode)[]} childNodes a Token's contents
25
+ * @param {string} separator delimiter between nodes
26
+ */
23
27
  const text = (childNodes, separator = '') => {
24
28
  const AstNode = require('../lib/node');
25
29
  return childNodes.map(child => typeof child === 'string' ? child : child.text()).join(separator);
26
30
  };
27
31
 
28
32
  /**
29
- * @param {string} start
30
- * @param {string} end
31
- * @param {string} separator
32
- * @param {string} str
33
+ * a more sophisticated string-explode function
34
+ * @param {string} start start syntax of a nested AST node
35
+ * @param {string} end end syntax of a nested AST node
36
+ * @param {string} separator syntax for explosion
37
+ * @param {string} str string to be exploded
33
38
  */
34
39
  const explode = (start, end, separator, str) => {
35
40
  if (str === undefined) {
36
41
  return [];
37
42
  }
38
- const regex = new RegExp(`${[start, end, separator].map(escapeRegExp).join('|')}`, 'g'),
43
+ const regex = new RegExp(`${[start, end, separator].map(escapeRegExp).join('|')}`, 'gu'),
39
44
  /** @type {string[]} */ exploded = [];
40
45
  let mt = regex.exec(str),
41
46
  depth = 0,
@@ -54,22 +59,30 @@ const explode = (start, end, separator, str) => {
54
59
  return exploded;
55
60
  };
56
61
 
57
- /** @param {string} str */
62
+ /**
63
+ * escape newlines
64
+ * @param {string} str 原字符串
65
+ */
58
66
  const noWrap = str => str.replaceAll('\n', '\\n');
59
67
 
60
68
  /**
61
- * @param {string|Token} token
62
- * @returns {string}
69
+ * convert newline in text nodes to single whitespace
70
+ * @param {Token & {childNodes: AstText[]}} token 父节点
63
71
  */
64
- const normalizeSpace = (token = '', separator = '') => {
65
- const Token = require('../src');
66
- return typeof token === 'string'
67
- ? token.replaceAll('\n', ' ')
68
- : token.childNodes.map(child => typeof child === 'string' ? normalizeSpace(child) : child.toString())
69
- .join(separator);
72
+ const normalizeSpace = token => {
73
+ if (token === undefined) {
74
+ return;
75
+ }
76
+ const Token = require('../src'),
77
+ AstText = require('../lib/text');
78
+ for (const child of token.childNodes) {
79
+ if (child.type === 'text') {
80
+ child.replaceData(child.data.replaceAll('\n', ' '));
81
+ }
82
+ }
70
83
  };
71
84
 
72
- const extUrlChar = '(?:[\\d.]+|\\[[\\da-f:.]+\\]|[^[\\]<>"\\x00-\\x20\\x7f\\p{Zs}\\ufffd])'
73
- + '(?:[^[\\]<>"\\x00-\\x20\\x7f\\p{Zs}\\ufffd]|\\x00\\d+c\\x7f)*';
85
+ const extUrlChar = '(?:\\[[\\da-f:.]+\\]|[^[\\]<>"\\0-\\x1f\\x7f\\p{Zs}\\ufffd])'
86
+ + '(?:[^[\\]<>"\\0-\\x1f\\x7f\\p{Zs}\\ufffd]|\\0\\d+c\\x7f)*';
74
87
 
75
- module.exports = {toCase, removeComment, ucfirst, escapeRegExp, text, explode, noWrap, normalizeSpace, extUrlChar};
88
+ module.exports = {toCase, removeComment, escapeRegExp, text, explode, noWrap, normalizeSpace, extUrlChar};
@@ -1,28 +0,0 @@
1
- import Token from '../src';
2
-
3
- declare global {
4
- interface AstEvent extends Event {
5
- readonly target: Token;
6
- currentTarget: Token;
7
- prevTarget: ?Token;
8
- };
9
- interface AstEventData {
10
- position: number;
11
- removed: string|Token;
12
- inserted: string|Token;
13
- oldToken: Token;
14
- newToken: Token;
15
- oldText: string;
16
- newText: string;
17
- oldKey: string;
18
- newKey: string;
19
- }
20
- type AstListener = (e: AstEvent, data: AstEventData) => any;
21
-
22
- type pseudo = 'root'|'is'|'not'|'nth-child'|'nth-of-type'|'nth-last-child'|'nth-last-of-type'
23
- |'first-child'|'first-of-type'|'last-child'|'last-of-type'|'only-child'|'only-of-type'|'empty'
24
- |'contains'|'has'|'header'|'parent'|'hidden'|'visible';
25
- type pseudoCall = Record<pseudo, string[]>;
26
- }
27
-
28
- export {};