@bhsd/codemirror-mediawiki 3.10.0 → 3.10.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.
Files changed (58) hide show
  1. package/README.md +78 -78
  2. package/dist/bidi.d.ts +5 -0
  3. package/dist/bidi.js +5 -0
  4. package/dist/codemirror.d.ts +7 -0
  5. package/dist/codemirror.js +10 -3
  6. package/dist/color.d.ts +7 -4
  7. package/dist/color.js +4 -0
  8. package/dist/css.d.ts +5 -0
  9. package/dist/css.js +5 -0
  10. package/dist/escape.d.ts +21 -1
  11. package/dist/escape.js +42 -24
  12. package/dist/fold.d.ts +55 -3
  13. package/dist/fold.js +54 -30
  14. package/dist/hover.d.ts +14 -1
  15. package/dist/hover.js +49 -31
  16. package/dist/html.js +17 -12
  17. package/dist/indent.d.ts +7 -0
  18. package/dist/indent.js +7 -1
  19. package/dist/inlay.js +1 -1
  20. package/dist/javascript.d.ts +10 -1
  21. package/dist/javascript.js +6 -1
  22. package/dist/keybindings.d.ts +1 -0
  23. package/dist/keybindings.js +1 -0
  24. package/dist/keymap.d.ts +11 -0
  25. package/dist/keymap.js +3 -4
  26. package/dist/linter.d.ts +16 -0
  27. package/dist/linter.js +8 -1
  28. package/dist/lintsource.d.ts +36 -4
  29. package/dist/lintsource.js +37 -4
  30. package/dist/lua.js +31 -20
  31. package/dist/main.min.js +29 -29
  32. package/dist/matchBrackets.d.ts +16 -0
  33. package/dist/matchBrackets.js +16 -0
  34. package/dist/matchTag.d.ts +5 -2
  35. package/dist/matchTag.js +7 -4
  36. package/dist/mediawiki.d.ts +11 -0
  37. package/dist/mediawiki.js +8 -4
  38. package/dist/mw.min.js +31 -31
  39. package/dist/mwConfig.js +1 -1
  40. package/dist/openLinks.d.ts +8 -0
  41. package/dist/openLinks.js +8 -0
  42. package/dist/ref.d.ts +15 -1
  43. package/dist/ref.js +81 -65
  44. package/dist/signature.d.ts +6 -0
  45. package/dist/signature.js +22 -19
  46. package/dist/static.d.ts +4 -0
  47. package/dist/static.js +4 -0
  48. package/dist/theme.d.ts +1 -0
  49. package/dist/theme.js +3 -1
  50. package/dist/token.d.ts +9 -1
  51. package/dist/token.js +12 -6
  52. package/dist/util.d.ts +8 -0
  53. package/dist/util.js +8 -0
  54. package/dist/wiki.min.js +30 -30
  55. package/i18n/en.json +1 -1
  56. package/i18n/zh-hans.json +1 -1
  57. package/i18n/zh-hant.json +1 -1
  58. package/package.json +22 -22
package/dist/mwConfig.js CHANGED
@@ -161,7 +161,7 @@ var getMwConfig = async (modes) => {
161
161
  formatversion: 2
162
162
  });
163
163
  if (config && !isIPE) {
164
- const { functionSynonyms: [insensitive] } = config;
164
+ const [insensitive] = config.functionSynonyms;
165
165
  if (!("subst" in insensitive)) {
166
166
  cleanAliases(insensitive);
167
167
  Object.assign(insensitive, getConfig(magicwords, ({ name }) => others.has(name)));
@@ -3,7 +3,15 @@ import type { Extension } from '@codemirror/state';
3
3
  import type { CodeMirror6 } from './codemirror';
4
4
  import type { MwConfig } from './token';
5
5
  declare type ISBNParser = (link: string) => string;
6
+ /**
7
+ * @implements
8
+ * @test
9
+ */
6
10
  export declare const getISBNParser: (articlePath?: string) => ISBNParser | undefined;
11
+ /**
12
+ * @ignore
13
+ * @test
14
+ */
7
15
  export declare const mouseEventListener: (e: MouseEvent, view: EditorView, isbnParser?: ISBNParser, titleParser?: MwConfig["titleParser"]) => string | undefined;
8
16
  declare const _default: (articlePath?: string) => ({ langConfig }: CodeMirror6) => Extension;
9
17
  export default _default;
package/dist/openLinks.js CHANGED
@@ -14,6 +14,10 @@ const toggleOpenLinks = ({ contentDOM }, toggle) => {
14
14
  contentDOM.style[toggle ? 'setProperty' : 'removeProperty']('--codemirror-cursor', 'pointer');
15
15
  };
16
16
  const wrapURL = (url) => url.startsWith('//') ? location.protocol + url : url;
17
+ /**
18
+ * @implements
19
+ * @test
20
+ */
17
21
  export const getISBNParser = (articlePath) => articlePath
18
22
  ? (link) => {
19
23
  const page = `Special:Booksources/${link.slice(4).replace(/[\p{Zs}\t-]/gu, '')
@@ -23,6 +27,10 @@ export const getISBNParser = (articlePath) => articlePath
23
27
  : articlePath + (articlePath.endsWith('/') ? '' : '/') + page;
24
28
  }
25
29
  : undefined;
30
+ /**
31
+ * @ignore
32
+ * @test
33
+ */
26
34
  export const mouseEventListener = (e, view, isbnParser, titleParser) => {
27
35
  if (!e[modKey]
28
36
  || !(e.target instanceof Element && getComputedStyle(e.target).textDecorationLine === 'underline')) {
package/dist/ref.d.ts CHANGED
@@ -1,4 +1,18 @@
1
- import type { Extension } from '@codemirror/state';
1
+ import type { EditorState, Extension } from '@codemirror/state';
2
2
  import type { CodeMirror6 } from './codemirror';
3
+ import type { Tag } from './matchTag';
4
+ /**
5
+ * 高亮<ref>内容
6
+ * @param state 编辑器EditorState
7
+ * @param text <ref>内容
8
+ * @test
9
+ */
10
+ export declare const highlightRef: (state: EditorState, text: string) => string;
11
+ /**
12
+ * 判断是否需要显示悬停提示
13
+ * @ignore
14
+ * @test
15
+ */
16
+ export declare const needHover: (state: EditorState, { name, selfClosing, first, last }: Tag) => boolean;
3
17
  declare const _default: (articlePath?: string) => (cm: CodeMirror6) => Extension;
4
18
  export default _default;
package/dist/ref.js CHANGED
@@ -14,77 +14,93 @@ const trees = new WeakMap(), selector = '.cm-tooltip-ref', noDef = '.cm-tooltip-
14
14
  * @param node 语法树节点
15
15
  */
16
16
  const getName = (state, node) => sliceDoc(state, node).trim();
17
+ /**
18
+ * 高亮<ref>内容
19
+ * @param state 编辑器EditorState
20
+ * @param text <ref>内容
21
+ * @test
22
+ */
23
+ export const highlightRef = (state, text) => {
24
+ let result = '';
25
+ highlightCode(text, state.facet(language).parser.parse(text), {
26
+ style(tags) {
27
+ return highlightingFor(state, tags);
28
+ },
29
+ }, (code, classes) => {
30
+ const escaped = escHTML(code);
31
+ result += classes
32
+ ? `<span class="${classes}">${escaped}</span>`
33
+ : escaped;
34
+ }, () => {
35
+ result += '<br>';
36
+ });
37
+ return result;
38
+ };
39
+ /**
40
+ * 判断是否需要显示悬停提示
41
+ * @ignore
42
+ * @test
43
+ */
44
+ export const needHover = (state, { name, selfClosing, first, last }) => {
45
+ if (name === 'ref' && selfClosing) {
46
+ let prevSibling = last, nextSibling = null;
47
+ while (prevSibling && prevSibling.from > first.to) {
48
+ const key = getName(state, prevSibling);
49
+ if (prevSibling.name.split('_').includes(tokens.extTagAttribute)
50
+ && /(?:^|\s)name(?:$|[\s=])/iu.test(key)) {
51
+ if (/(?:^|\s)name\s*=/iu.test(key)) {
52
+ ({ nextSibling } = prevSibling);
53
+ }
54
+ break;
55
+ }
56
+ ({ prevSibling } = prevSibling);
57
+ }
58
+ if (nextSibling?.name.includes(tokens.extTagAttributeValue)) {
59
+ let target = getName(state, nextSibling);
60
+ const quote = target.charAt(0);
61
+ if (quote === '"' || quote === "'") {
62
+ target = target.slice(1, target.slice(-1) === quote ? -1 : undefined).trim();
63
+ }
64
+ if (target) {
65
+ return true;
66
+ }
67
+ }
68
+ }
69
+ return false;
70
+ };
17
71
  export default (articlePath) => (cm) => {
18
72
  return [
19
73
  hoverTooltip(async (view, pos, side) => {
20
74
  const { state } = view, node = ensureSyntaxTree(state, pos)?.resolve(pos, side);
21
- if (node && /-exttag-(?!bracket)/u.test(node.name)) {
75
+ if (node && node.name.includes('-exttag-')) {
22
76
  const tag = getTag(state, node);
23
- if (!tag) {
24
- return null;
25
- }
26
- const { name, selfClosing, first, last, to } = tag;
27
- if (name === 'ref' && selfClosing) {
28
- let prevSibling = last, nextSibling = null;
29
- while (prevSibling && prevSibling.from > first.to) {
30
- const key = getName(state, prevSibling);
31
- if (prevSibling.name.split('_').includes(tokens.extTagAttribute)
32
- && /(?:^|\s)name(?:$|[\s=])/iu.test(key)) {
33
- if (/(?:^|\s)name\s*=/iu.test(key)) {
34
- ({ nextSibling } = prevSibling);
77
+ if (tag && needHover(state, tag)) {
78
+ const { doc } = state, ref = await getLSP(view, false, toConfigGetter(cm.getWikiConfig, articlePath), base.CDN)?.provideDefinition(doc.toString(), indexToPos(doc, tag.first.to));
79
+ return {
80
+ pos,
81
+ end: tag.to,
82
+ above: true,
83
+ create() {
84
+ const dom = elt('div', { class: selector.slice(1) });
85
+ dom.style.font = getComputedStyle(view.contentDOM).font;
86
+ if (ref) {
87
+ const { start, end } = ref[0].range, anchor = posToIndex(doc, start), head = posToIndex(doc, end);
88
+ dom.innerHTML = highlightRef(state, state.sliceDoc(anchor, head));
89
+ dom.addEventListener('click', () => {
90
+ view.dispatch({
91
+ selection: { anchor, head },
92
+ scrollIntoView: true,
93
+ });
94
+ view.focus();
95
+ });
96
+ }
97
+ else {
98
+ dom.textContent = state.phrase('No definition found');
99
+ dom.classList.add(noDef.slice(1));
35
100
  }
36
- break;
37
- }
38
- ({ prevSibling } = prevSibling);
39
- }
40
- if (nextSibling?.name.includes(tokens.extTagAttributeValue)) {
41
- let target = getName(state, nextSibling);
42
- const quote = target.charAt(0);
43
- if (quote === '"' || quote === "'") {
44
- target = target.slice(1, target.slice(-1) === quote ? -1 : undefined).trim();
45
- }
46
- if (target) {
47
- const { doc } = state, ref = await getLSP(view, false, toConfigGetter(cm.getWikiConfig, articlePath), base.CDN)?.provideDefinition(doc.toString(), indexToPos(doc, first.to));
48
- return {
49
- pos,
50
- end: to,
51
- above: true,
52
- create() {
53
- const dom = elt('div', { class: selector.slice(1) });
54
- dom.style.font = getComputedStyle(view.contentDOM).font;
55
- if (ref) {
56
- const { range: { start, end } } = ref[0], anchor = posToIndex(doc, start), head = posToIndex(doc, end), text = state.sliceDoc(anchor, head);
57
- let result = '';
58
- highlightCode(text, state.facet(language).parser.parse(text), {
59
- style(tags) {
60
- return highlightingFor(state, tags);
61
- },
62
- }, (code, classes) => {
63
- const escaped = escHTML(code);
64
- result += classes
65
- ? `<span class="${classes}">${escaped}</span>`
66
- : escaped;
67
- }, () => {
68
- result += '<br>';
69
- });
70
- dom.innerHTML = result;
71
- dom.addEventListener('click', () => {
72
- view.dispatch({
73
- selection: { anchor, head },
74
- scrollIntoView: true,
75
- });
76
- view.focus();
77
- });
78
- }
79
- else {
80
- dom.textContent = state.phrase('No definition found');
81
- dom.classList.add(noDef.slice(1));
82
- }
83
- return { dom };
84
- },
85
- };
86
- }
87
- }
101
+ return { dom };
102
+ },
103
+ };
88
104
  }
89
105
  }
90
106
  return null;
@@ -1,4 +1,10 @@
1
1
  import type { Extension } from '@codemirror/state';
2
+ import type { SignatureHelp } from 'vscode-languageserver-types';
2
3
  import type { CodeMirror6 } from './codemirror';
4
+ /**
5
+ * @ignore
6
+ * @test
7
+ */
8
+ export declare const getSignatureHelp: ({ signatures, activeParameter: active }: SignatureHelp) => string;
3
9
  declare const _default: (articlePath?: string) => (cm: CodeMirror6) => Extension;
4
10
  export default _default;
package/dist/signature.js CHANGED
@@ -20,6 +20,19 @@ const stateEffect = StateEffect.define(), field = StateField.define({
20
20
  return oldValue;
21
21
  },
22
22
  });
23
+ /**
24
+ * @ignore
25
+ * @test
26
+ */
27
+ export const getSignatureHelp = ({ signatures, activeParameter: active }) => signatures.map(({ label, parameters, activeParameter = active }) => {
28
+ const safeLabel = escHTML(label);
29
+ if (activeParameter < 0 || activeParameter >= parameters.length) {
30
+ return safeLabel;
31
+ }
32
+ const colon = safeLabel.indexOf(':'), parts = safeLabel.slice(colon + 1, -2).split('|');
33
+ parts[activeParameter] = `<b>${parts[activeParameter]}</b>`;
34
+ return `${safeLabel.slice(0, colon)}:${parts.join('|')}}}`;
35
+ }).join('<br>');
23
36
  export default (articlePath) => (cm) => {
24
37
  return [
25
38
  field,
@@ -48,25 +61,15 @@ export default (articlePath) => (cm) => {
48
61
  return null;
49
62
  }
50
63
  const { cursor, signatureHelp } = value;
51
- if (!signatureHelp || signatureHelp.signatures.length === 0) {
52
- return null;
53
- }
54
- const { signatures, activeParameter: active } = signatureHelp;
55
- return {
56
- pos: cursor,
57
- above: true,
58
- create(view) {
59
- return createTooltipView(view, signatures.map(({ label, parameters, activeParameter = active }) => {
60
- const safeLabel = escHTML(label);
61
- if (activeParameter < 0 || activeParameter >= parameters.length) {
62
- return safeLabel;
63
- }
64
- const colon = safeLabel.indexOf(':'), parts = safeLabel.slice(colon + 1, -2).split('|');
65
- parts[activeParameter] = `<b>${parts[activeParameter]}</b>`;
66
- return `${safeLabel.slice(0, colon)}:${parts.join('|')}}}`;
67
- }).join('<br>'));
68
- },
69
- };
64
+ return signatureHelp && signatureHelp.signatures.length > 0
65
+ ? {
66
+ pos: cursor,
67
+ above: true,
68
+ create(view) {
69
+ return createTooltipView(view, getSignatureHelp(signatureHelp));
70
+ },
71
+ }
72
+ : null;
70
73
  }),
71
74
  ];
72
75
  };
package/dist/static.d.ts CHANGED
@@ -22,4 +22,8 @@ export declare const tagModes: {
22
22
  combooption: string;
23
23
  inputbox: string;
24
24
  };
25
+ /**
26
+ * @ignore
27
+ * @test
28
+ */
25
29
  export declare const getStaticMwConfig: ({ variable, parserFunction: [p0, p1, ...p2], protocol, nsid, functionHook, variants, redirection, ext, doubleUnderscore: [d0, d1, d2, d3], img, }: ConfigData, modes: Record<string, string>) => MwConfig;
package/dist/static.js CHANGED
@@ -21,6 +21,10 @@ export const tagModes = {
21
21
  combooption: 'mediawiki',
22
22
  inputbox: 'text/inputbox',
23
23
  };
24
+ /**
25
+ * @ignore
26
+ * @test
27
+ */
24
28
  export const getStaticMwConfig = ({ variable, parserFunction: [p0, p1, ...p2], protocol, nsid, functionHook, variants, redirection, ext, doubleUnderscore: [d0, d1, d2, d3], img, }, modes) => ({
25
29
  tags: Object.fromEntries(ext.map(s => [s, true])),
26
30
  tagModes: modes,
package/dist/theme.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import type { Extension } from '@codemirror/state';
2
+ export declare const getLightHighlightStyle: () => Extension;
2
3
  export declare const light: Extension,
3
4
  /**
4
5
  * @author 鬼影233
package/dist/theme.js CHANGED
@@ -1,7 +1,9 @@
1
1
  import { EditorView } from '@codemirror/view';
2
+ import { syntaxHighlighting, HighlightStyle, defaultHighlightStyle } from '@codemirror/language';
2
3
  import { nord as nordBase } from 'cm6-theme-nord';
3
4
  import { matchingCls, nonmatchingCls, actionSelector, panelsSelector, bgDark, } from './constants.js';
4
5
  const focused = '&.cm-focused', matching = `${focused} .${matchingCls}`, nonmatching = `${focused} .${nonmatchingCls}`;
6
+ export const getLightHighlightStyle = () => syntaxHighlighting(HighlightStyle.define(defaultHighlightStyle.specs, { themeType: 'light' }));
5
7
  export const light = /* @__PURE__ */ EditorView.theme({
6
8
  '&': {
7
9
  backgroundColor: '#fff',
@@ -26,7 +28,7 @@ export const light = /* @__PURE__ */ EditorView.theme({
26
28
  '--cm-ref': 'rgb(223,242,235,.5)',
27
29
  },
28
30
  '.cm-globals, .cm-globals>*': {
29
- color: '#256',
31
+ color: '#164',
30
32
  },
31
33
  [matching]: {
32
34
  backgroundColor: 'rgb(50,140,130,.32)',
package/dist/token.d.ts CHANGED
@@ -13,7 +13,7 @@ declare type Style = string | [string];
13
13
  declare type Tokenizer<T = Style> = ((stream: StringStream, state: State) => T) & {
14
14
  args?: unknown[];
15
15
  };
16
- declare type NestCount = 'nTemplate' | 'nExt' | 'nVar' | 'nLink' | 'nExtLink';
16
+ export type NestCount = 'nTemplate' | 'nExt' | 'nVar' | 'nLink' | 'nExtLink';
17
17
  declare interface Nesting extends Record<NestCount, number> {
18
18
  extName: string | false;
19
19
  extState: object | false;
@@ -37,6 +37,7 @@ export interface State extends Nesting {
37
37
  imgLink: boolean;
38
38
  data: MediaWikiData;
39
39
  }
40
+ declare type ExtState = Omit<State, 'dt'> & Partial<Pick<State, 'dt'>>;
40
41
  declare interface Token {
41
42
  readonly char?: string | undefined;
42
43
  readonly string: string;
@@ -89,14 +90,21 @@ declare class MediaWikiData {
89
90
  * @param stream
90
91
  * @param table 是否允许表格
91
92
  * @param file 是否为文件
93
+ * @test
92
94
  */
93
95
  export declare const isSolSyntax: (stream: StringStream, table?: boolean, file?: boolean) => unknown;
94
96
  /**
95
97
  * 获取负向先行断言
96
98
  * @param chars
97
99
  * @param comment 是否仅排除注释
100
+ * @test
98
101
  */
99
102
  export declare const lookahead: (chars: string, comment?: boolean | State) => string;
103
+ /**
104
+ * @ignore
105
+ * @test
106
+ */
107
+ export declare const makeLocalStyle: (style: string, state: ExtState, endGround?: NestCount) => string;
100
108
  /** Adapted from the original CodeMirror 5 stream parser by Pavel Astakhov */
101
109
  export declare class MediaWiki {
102
110
  readonly config: MwConfig;
package/dist/token.js CHANGED
@@ -153,6 +153,7 @@ const pop = (state) => {
153
153
  * @param stream
154
154
  * @param table 是否允许表格
155
155
  * @param file 是否为文件
156
+ * @test
156
157
  */
157
158
  export const isSolSyntax = (stream, table, file) => stream.sol() && (table && stream.match(/^\s*(?::+\s*)?\{\|/u, false)
158
159
  || stream.match(/^(?:-{4}|=)/u, false)
@@ -161,6 +162,7 @@ export const isSolSyntax = (stream, table, file) => stream.sol() && (table && st
161
162
  * 获取负向先行断言
162
163
  * @param chars
163
164
  * @param comment 是否仅排除注释
165
+ * @test
164
166
  */
165
167
  export const lookahead = (chars, comment) => {
166
168
  const table = {
@@ -177,7 +179,7 @@ export const lookahead = (chars, comment) => {
177
179
  '-': String.raw `-(?!\{(?!\{))`,
178
180
  };
179
181
  if (typeof comment === 'object') {
180
- const { data: { tags } } = comment;
182
+ const { tags } = comment.data;
181
183
  table['<'] = String.raw `<(?!!--${tags.includes('onlyinclude') ? '|onlyinclude>' : ''}|(?:${tags.filter(tag => tag !== 'onlyinclude').join('|')})(?:[\s/>]|$))`;
182
184
  }
183
185
  return [...chars].map(ch => table[ch]).join('|');
@@ -212,7 +214,11 @@ const getTokenizer = (method, context) => function (...args) {
212
214
  const makeFullStyle = (style, state) => (typeof style === 'string'
213
215
  ? style
214
216
  : `${style[0]} ${state.bold || state.dt?.n ? tokens.strong : ''} ${state.italic ? tokens.em : ''}`).trim().replace(/\s{2,}/gu, ' ') || ' ';
215
- const makeLocalStyle = (style, state, endGround) => {
217
+ /**
218
+ * @ignore
219
+ * @test
220
+ */
221
+ export const makeLocalStyle = (style, state, endGround) => {
216
222
  let ground = '';
217
223
  switch (state.nTemplate) {
218
224
  case 0:
@@ -988,7 +994,7 @@ let MediaWiki = (() => {
988
994
  return makeLocalTagStyle('list', state);
989
995
  }
990
996
  eatDoubleUnderscore(style, ch, stream, state) {
991
- const { config: { doubleUnderscore } } = this, underscore = ch.repeat(2), name = stream.match(doubleUnderscoreRegex[ch]);
997
+ const { doubleUnderscore } = this.config, underscore = ch.repeat(2), name = stream.match(doubleUnderscoreRegex[ch]);
992
998
  if (name) {
993
999
  if (Object.prototype.hasOwnProperty.call(doubleUnderscore[0], underscore + name[0].toLowerCase())
994
1000
  || Object.prototype.hasOwnProperty.call(doubleUnderscore[1], underscore + name[0])) {
@@ -1277,7 +1283,7 @@ let MediaWiki = (() => {
1277
1283
  return makeLocalTagStyle('extTagBracket', state);
1278
1284
  }
1279
1285
  else if (stream.eat('>')) {
1280
- const { config: { tagModes } } = this;
1286
+ const { tagModes } = this.config;
1281
1287
  state.extName = name;
1282
1288
  state.extMode ||= name in tagModes && (tagModes[name]) in this
1283
1289
  && this[tagModes[name]]([
@@ -1415,7 +1421,7 @@ let MediaWiki = (() => {
1415
1421
  else if (delimiter !== ':') {
1416
1422
  ff = f.trim();
1417
1423
  }
1418
- const ffLower = ff.toLowerCase(), { config: { functionSynonyms, variableIDs, functionHooks } } = this, canonicalName = Object.prototype.hasOwnProperty.call(functionSynonyms[1], ff)
1424
+ const ffLower = ff.toLowerCase(), { functionSynonyms, variableIDs, functionHooks } = this.config, canonicalName = Object.prototype.hasOwnProperty.call(functionSynonyms[1], ff)
1419
1425
  && functionSynonyms[1][ff]
1420
1426
  || Object.prototype.hasOwnProperty.call(functionSynonyms[0], ffLower)
1421
1427
  && functionSynonyms[0][ffLower];
@@ -1482,7 +1488,7 @@ let MediaWiki = (() => {
1482
1488
  }
1483
1489
  const mt = stream.match(/^(?:[^::}{|<>[\]\s]|\s(?![::]))+/u);
1484
1490
  if (mt) {
1485
- const name = mt[0].trim().toLowerCase() + (stream.peek() === ':' ? ':' : ''), { config: { functionSynonyms: [insensitive] } } = this;
1491
+ const name = mt[0].trim().toLowerCase() + (stream.peek() === ':' ? ':' : ''), [insensitive] = this.config.functionSynonyms;
1486
1492
  if (name.startsWith('#')) {
1487
1493
  switch (insensitive[name] ?? insensitive[name.slice(1)]) {
1488
1494
  case 'invoke':
package/dist/util.d.ts CHANGED
@@ -7,18 +7,21 @@ import type { TagName } from './config';
7
7
  /**
8
8
  * 转义HTML字符串
9
9
  * @param text 原字符串
10
+ * @test
10
11
  */
11
12
  export declare const escHTML: (text: string) => string;
12
13
  /**
13
14
  * 将索引转换为位置
14
15
  * @param doc Text 实例
15
16
  * @param index 索引
17
+ * @test
16
18
  */
17
19
  export declare const indexToPos: (doc: Text, index: number) => Position;
18
20
  /**
19
21
  * 将位置转换为索引
20
22
  * @param doc Text 实例
21
23
  * @param pos 位置
24
+ * @test
22
25
  */
23
26
  export declare const posToIndex: (doc: Text, pos: Position) => number;
24
27
  /**
@@ -31,29 +34,34 @@ export declare const createTooltipView: (view: EditorView, innerHTML: string) =>
31
34
  * 获取节点对应的字符串
32
35
  * @param state EditorState 实例
33
36
  * @param node 语法树节点
37
+ * @test
34
38
  */
35
39
  export declare const sliceDoc: (state: EditorState, node: SyntaxNode | SelectionRange) => string;
36
40
  /**
37
41
  * Update the stack of opening (+) or closing (-) brackets
38
42
  * @param state
39
43
  * @param node 语法树节点
44
+ * @test
40
45
  */
41
46
  export declare const braceStackUpdate: (state: EditorState, node: SyntaxNode) => [number, number];
42
47
  /**
43
48
  * Find the current template name
44
49
  * @param state
45
50
  * @param node 语法树节点
51
+ * @test
46
52
  */
47
53
  export declare const findTemplateName: (state: EditorState, node: SyntaxNode) => string | null;
48
54
  /**
49
55
  * 判断节点是否包含指定类型
50
56
  * @param types 节点类型
51
57
  * @param names 指定类型
58
+ * @test
52
59
  */
53
60
  export declare const hasTag: (types: Set<string>, names: TagName | TagName[]) => boolean;
54
61
  export declare const toConfigGetter: (configGetter?: ConfigGetter, articlePath?: string) => ConfigGetter | undefined;
55
62
  /**
56
63
  * 获取字符串开头的空白字符
57
64
  * @param str 字符串
65
+ * @test
58
66
  */
59
67
  export declare const leadingSpaces: (str: string) => string;
package/dist/util.js CHANGED
@@ -5,12 +5,14 @@ const dict = { '\n': '<br>', '&': '&amp;', '<': '&lt;' };
5
5
  /**
6
6
  * 转义HTML字符串
7
7
  * @param text 原字符串
8
+ * @test
8
9
  */
9
10
  export const escHTML = (text) => text.replace(/[\n<&]/gu, ch => dict[ch]);
10
11
  /**
11
12
  * 将索引转换为位置
12
13
  * @param doc Text 实例
13
14
  * @param index 索引
15
+ * @test
14
16
  */
15
17
  export const indexToPos = (doc, index) => {
16
18
  const line = doc.lineAt(index);
@@ -20,6 +22,7 @@ export const indexToPos = (doc, index) => {
20
22
  * 将位置转换为索引
21
23
  * @param doc Text 实例
22
24
  * @param pos 位置
25
+ * @test
23
26
  */
24
27
  export const posToIndex = (doc, pos) => {
25
28
  const line = doc.line(pos.line + 1);
@@ -40,12 +43,14 @@ export const createTooltipView = (view, innerHTML) => {
40
43
  * 获取节点对应的字符串
41
44
  * @param state EditorState 实例
42
45
  * @param node 语法树节点
46
+ * @test
43
47
  */
44
48
  export const sliceDoc = (state, node) => state.sliceDoc(node.from, node.to);
45
49
  /**
46
50
  * Update the stack of opening (+) or closing (-) brackets
47
51
  * @param state
48
52
  * @param node 语法树节点
53
+ * @test
49
54
  */
50
55
  export const braceStackUpdate = (state, node) => {
51
56
  const brackets = sliceDoc(state, node);
@@ -55,6 +60,7 @@ export const braceStackUpdate = (state, node) => {
55
60
  * Find the current template name
56
61
  * @param state
57
62
  * @param node 语法树节点
63
+ * @test
58
64
  */
59
65
  export const findTemplateName = (state, node) => {
60
66
  let stack = -1, { prevSibling } = node,
@@ -84,6 +90,7 @@ export const findTemplateName = (state, node) => {
84
90
  * 判断节点是否包含指定类型
85
91
  * @param types 节点类型
86
92
  * @param names 指定类型
93
+ * @test
87
94
  */
88
95
  export const hasTag = (types, names) => (Array.isArray(names) ? names : [names]).some(name => types.has(name in tokens ? tokens[name] : name));
89
96
  export const toConfigGetter = (configGetter, articlePath) => articlePath
@@ -92,5 +99,6 @@ export const toConfigGetter = (configGetter, articlePath) => articlePath
92
99
  /**
93
100
  * 获取字符串开头的空白字符
94
101
  * @param str 字符串
102
+ * @test
95
103
  */
96
104
  export const leadingSpaces = (str) => /^\s*/u.exec(str)[0];