@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.
- package/README.md +78 -78
- package/dist/bidi.d.ts +5 -0
- package/dist/bidi.js +5 -0
- package/dist/codemirror.d.ts +7 -0
- package/dist/codemirror.js +10 -3
- package/dist/color.d.ts +7 -4
- package/dist/color.js +4 -0
- package/dist/css.d.ts +5 -0
- package/dist/css.js +5 -0
- package/dist/escape.d.ts +21 -1
- package/dist/escape.js +42 -24
- package/dist/fold.d.ts +55 -3
- package/dist/fold.js +54 -30
- package/dist/hover.d.ts +14 -1
- package/dist/hover.js +49 -31
- package/dist/html.js +17 -12
- package/dist/indent.d.ts +7 -0
- package/dist/indent.js +7 -1
- package/dist/inlay.js +1 -1
- package/dist/javascript.d.ts +10 -1
- package/dist/javascript.js +6 -1
- package/dist/keybindings.d.ts +1 -0
- package/dist/keybindings.js +1 -0
- package/dist/keymap.d.ts +11 -0
- package/dist/keymap.js +3 -4
- package/dist/linter.d.ts +16 -0
- package/dist/linter.js +8 -1
- package/dist/lintsource.d.ts +36 -4
- package/dist/lintsource.js +37 -4
- package/dist/lua.js +31 -20
- package/dist/main.min.js +29 -29
- package/dist/matchBrackets.d.ts +16 -0
- package/dist/matchBrackets.js +16 -0
- package/dist/matchTag.d.ts +5 -2
- package/dist/matchTag.js +7 -4
- package/dist/mediawiki.d.ts +11 -0
- package/dist/mediawiki.js +8 -4
- package/dist/mw.min.js +31 -31
- package/dist/mwConfig.js +1 -1
- package/dist/openLinks.d.ts +8 -0
- package/dist/openLinks.js +8 -0
- package/dist/ref.d.ts +15 -1
- package/dist/ref.js +81 -65
- package/dist/signature.d.ts +6 -0
- package/dist/signature.js +22 -19
- package/dist/static.d.ts +4 -0
- package/dist/static.js +4 -0
- package/dist/theme.d.ts +1 -0
- package/dist/theme.js +3 -1
- package/dist/token.d.ts +9 -1
- package/dist/token.js +12 -6
- package/dist/util.d.ts +8 -0
- package/dist/util.js +8 -0
- package/dist/wiki.min.js +30 -30
- package/i18n/en.json +1 -1
- package/i18n/zh-hans.json +1 -1
- package/i18n/zh-hant.json +1 -1
- 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
|
|
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)));
|
package/dist/openLinks.d.ts
CHANGED
|
@@ -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 &&
|
|
75
|
+
if (node && node.name.includes('-exttag-')) {
|
|
22
76
|
const tag = getTag(state, node);
|
|
23
|
-
if (
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
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
|
-
|
|
37
|
-
}
|
|
38
|
-
|
|
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;
|
package/dist/signature.d.ts
CHANGED
|
@@ -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
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
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
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: '#
|
|
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
|
-
|
|
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 {
|
|
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
|
-
|
|
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 {
|
|
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 {
|
|
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(), {
|
|
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() === ':' ? ':' : ''),
|
|
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>', '&': '&', '<': '<' };
|
|
|
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];
|