@wenyan-md/core 1.0.13 → 1.0.15
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 +95 -133
- package/dist/browser/wenyan-core.js +51 -51
- package/dist/core.js +430 -278
- package/dist/hltheme.js +39 -22
- package/dist/math/wenyan-math.js +9 -40
- package/dist/publish.js +166 -346
- package/dist/styles/wenyan-styles.js +19 -19
- package/dist/theme.js +388 -34
- package/dist/types/core.d.ts +17 -0
- package/dist/types/runtimeEnv.d.ts +6 -0
- package/dist/types/utils.d.ts +1 -0
- package/dist/utils-YieK94fG.js +9 -0
- package/dist/wrapper.js +15 -10
- package/package.json +8 -5
- package/dist/atom-one-dark.min-hABhDLRj.js +0 -4
- package/dist/atom-one-light.min-CwiVhPEv.js +0 -4
- package/dist/default-D-dyLptq.js +0 -184
- package/dist/dracula.min-OeyC4Nkp.js +0 -11
- package/dist/github-dark.min-DOlD5Ewr.js +0 -13
- package/dist/github.min-BZ2GvPsn.js +0 -14
- package/dist/juejin_default-13x4lhT9.js +0 -134
- package/dist/lapis-BUlsdDG6.js +0 -194
- package/dist/maize-DFW0x6O3.js +0 -194
- package/dist/medium_default-Zyy9RBMn.js +0 -135
- package/dist/monokai.min-CH2iHqHz.js +0 -4
- package/dist/orangeheart-Da7uQj8U.js +0 -184
- package/dist/phycat-CATVZm-R.js +0 -338
- package/dist/pie-Q9UMu3CB.js +0 -240
- package/dist/purple-Da1-Vfos.js +0 -183
- package/dist/rainbow-Bv0kNhYA.js +0 -168
- package/dist/solarized-dark.min-BxbYljx4.js +0 -11
- package/dist/solarized-light.min-Bb25xgOC.js +0 -11
- package/dist/toutiao_default-CLGOaI2x.js +0 -145
- package/dist/xcode.min-CG-lWQgl.js +0 -4
- package/dist/zhihu_default-Cz8bIkGO.js +0 -133
package/dist/core.js
CHANGED
|
@@ -1,357 +1,509 @@
|
|
|
1
|
-
import { marked
|
|
2
|
-
import { markedHighlight
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import * as
|
|
6
|
-
import { mathjax
|
|
7
|
-
import { TeX
|
|
8
|
-
import { SVG
|
|
9
|
-
import { liteAdaptor
|
|
10
|
-
import { RegisterHTMLHandler
|
|
11
|
-
import { AllPackages
|
|
12
|
-
import { themes
|
|
13
|
-
import { hlThemes
|
|
14
|
-
const
|
|
15
|
-
inlineMath: [
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
1
|
+
import { marked } from "marked";
|
|
2
|
+
import { markedHighlight } from "marked-highlight";
|
|
3
|
+
import hljs from "highlight.js";
|
|
4
|
+
import fm from "front-matter";
|
|
5
|
+
import * as csstree from "css-tree";
|
|
6
|
+
import { mathjax } from "mathjax-full/js/mathjax.js";
|
|
7
|
+
import { TeX } from "mathjax-full/js/input/tex.js";
|
|
8
|
+
import { SVG } from "mathjax-full/js/output/svg.js";
|
|
9
|
+
import { liteAdaptor } from "mathjax-full/js/adaptors/liteAdaptor.js";
|
|
10
|
+
import { RegisterHTMLHandler } from "mathjax-full/js/handlers/html.js";
|
|
11
|
+
import { AllPackages } from "mathjax-full/js/input/tex/AllPackages.js";
|
|
12
|
+
import { themes } from "./theme.js";
|
|
13
|
+
import { hlThemes } from "./hltheme.js";
|
|
14
|
+
const texConfig = {
|
|
15
|
+
inlineMath: [
|
|
16
|
+
["$", "$"],
|
|
17
|
+
["\\(", "\\)"]
|
|
18
|
+
],
|
|
19
|
+
displayMath: [
|
|
20
|
+
["$$", "$$"],
|
|
21
|
+
["\\[", "\\]"]
|
|
22
|
+
],
|
|
23
|
+
processEscapes: true,
|
|
24
|
+
packages: AllPackages
|
|
25
|
+
};
|
|
26
|
+
const svgConfig = {
|
|
20
27
|
fontCache: "none"
|
|
21
28
|
};
|
|
22
|
-
let
|
|
23
|
-
if (!
|
|
24
|
-
|
|
29
|
+
let adaptor;
|
|
30
|
+
if (!adaptor) {
|
|
31
|
+
adaptor = liteAdaptor();
|
|
25
32
|
try {
|
|
26
|
-
|
|
27
|
-
} catch {
|
|
33
|
+
RegisterHTMLHandler(adaptor);
|
|
34
|
+
} catch (e) {
|
|
28
35
|
}
|
|
29
36
|
}
|
|
30
|
-
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
+
RegisterHTMLHandler(adaptor);
|
|
38
|
+
const tex = new TeX(texConfig);
|
|
39
|
+
const svg = new SVG(svgConfig);
|
|
40
|
+
function addContainer(math, doc) {
|
|
41
|
+
const tag = math.display ? "section" : "span";
|
|
42
|
+
const cls = math.display ? "block-equation" : "inline-equation";
|
|
43
|
+
const container = math.typesetRoot;
|
|
44
|
+
if (math.math) {
|
|
45
|
+
doc.adaptor.setAttribute(container, "math", math.math);
|
|
46
|
+
}
|
|
47
|
+
const node = doc.adaptor.node(tag, { class: cls }, [container]);
|
|
48
|
+
math.typesetRoot = node;
|
|
37
49
|
}
|
|
38
|
-
async function
|
|
50
|
+
async function renderMathInHtml(htmlString) {
|
|
39
51
|
try {
|
|
40
|
-
const
|
|
41
|
-
InputJax:
|
|
42
|
-
OutputJax:
|
|
52
|
+
const html = mathjax.document(htmlString, {
|
|
53
|
+
InputJax: tex,
|
|
54
|
+
OutputJax: svg,
|
|
43
55
|
renderActions: {
|
|
44
|
-
addContainer: [
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
56
|
+
addContainer: [
|
|
57
|
+
190,
|
|
58
|
+
(doc) => {
|
|
59
|
+
for (const math of doc.math) {
|
|
60
|
+
addContainer(math, doc);
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
addContainer
|
|
64
|
+
]
|
|
48
65
|
}
|
|
49
66
|
});
|
|
50
|
-
|
|
51
|
-
const
|
|
52
|
-
return
|
|
53
|
-
} catch (
|
|
54
|
-
|
|
67
|
+
html.render();
|
|
68
|
+
const body = adaptor.body(html.document);
|
|
69
|
+
return adaptor.innerHTML(body);
|
|
70
|
+
} catch (error) {
|
|
71
|
+
console.error("Error rendering MathJax:", error);
|
|
72
|
+
throw error;
|
|
55
73
|
}
|
|
56
74
|
}
|
|
57
|
-
const
|
|
75
|
+
const macStyleCss = `#wenyan pre::before {
|
|
58
76
|
display: block;
|
|
59
77
|
content: "";
|
|
60
78
|
background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="45" height="12" viewBox="0 0 450 130"><ellipse cx="65" cy="65" rx="50" ry="52" stroke="rgb(220,60,54)" stroke-width="2" fill="rgb(237,108,96)"/><ellipse cx="225" cy="65" rx="50" ry="52" stroke="rgb(218,151,33)" stroke-width="2" fill="rgb(247,193,81)"/><ellipse cx="385" cy="65" rx="50" ry="52" stroke="rgb(27,161,37)" stroke-width="2" fill="rgb(100,200,86)"/></svg>');
|
|
61
79
|
background-repeat: no-repeat;
|
|
62
80
|
width: 100%;
|
|
63
81
|
height: 16px;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
82
|
+
}`;
|
|
83
|
+
const serif = "Georgia, Cambria, 'Noto Serif', 'Times New Roman', serif";
|
|
84
|
+
const sansSerif = "system-ui, 'Apple Color Emoji', 'Segoe UI', 'Segoe UI Symbol', 'Noto Sans', 'Roboto', sans-serif";
|
|
85
|
+
const monospace = "Menlo, Monaco, Consolas, 'Liberation Mono', 'Roboto Mono', 'Courier New', 'Microsoft YaHei', monospace";
|
|
86
|
+
let markedConfigured = false;
|
|
87
|
+
let configurePromise = null;
|
|
88
|
+
async function configureMarked() {
|
|
89
|
+
if (markedConfigured) return;
|
|
90
|
+
if (configurePromise) return configurePromise;
|
|
91
|
+
configurePromise = (async () => {
|
|
92
|
+
const highlightExtension = markedHighlight({
|
|
93
|
+
emptyLangClass: "hljs",
|
|
94
|
+
langPrefix: "hljs language-",
|
|
95
|
+
highlight: function(code, lang, info) {
|
|
96
|
+
const language = hljs.getLanguage(lang) ? lang : "plaintext";
|
|
97
|
+
return hljs.highlight(code, { language }).value;
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
marked.use(highlightExtension);
|
|
101
|
+
const attributeImageExtension = {
|
|
102
|
+
name: "attributeImage",
|
|
103
|
+
level: "inline",
|
|
104
|
+
start(src) {
|
|
105
|
+
return src.indexOf("![");
|
|
106
|
+
},
|
|
107
|
+
tokenizer(src) {
|
|
108
|
+
const rule = /^!\[([^\]]*)\]\(([^)]+)\)\{(.*?)\}/;
|
|
109
|
+
const match = rule.exec(src);
|
|
110
|
+
if (match) {
|
|
111
|
+
return {
|
|
112
|
+
type: "attributeImage",
|
|
113
|
+
raw: match[0],
|
|
114
|
+
alt: match[1],
|
|
115
|
+
href: match[2],
|
|
116
|
+
attrs: match[3]
|
|
117
|
+
};
|
|
100
118
|
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
119
|
+
},
|
|
120
|
+
renderer(token) {
|
|
121
|
+
const attrs = stringToMap(token.attrs);
|
|
122
|
+
const attrStr = Array.from(attrs).map(
|
|
123
|
+
([k, v]) => /^\d+$/.test(v) ? `${k}:${v}px` : `${k}:${v}`
|
|
124
|
+
).join("; ");
|
|
125
|
+
return `<img src="${token.href}" alt="${token.alt || ""}" title="${token.alt || ""}" style="${attrStr}">`;
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
marked.use({ extensions: [attributeImageExtension] });
|
|
129
|
+
const renderer = marked.Renderer;
|
|
130
|
+
const parser = marked.Parser;
|
|
131
|
+
renderer.heading = function(heading) {
|
|
132
|
+
const text = parser.parseInline(heading.tokens);
|
|
133
|
+
const level = heading.depth;
|
|
134
|
+
return `<h${level}><span>${text}</span></h${level}>
|
|
135
|
+
`;
|
|
136
|
+
};
|
|
137
|
+
renderer.paragraph = function(paragraph) {
|
|
138
|
+
const text = paragraph.text;
|
|
139
|
+
if (text.length > 4 && (/\$\$[\s\S]*?\$\$/g.test(text) || /\\\[[\s\S]*?\\\]/g.test(text))) {
|
|
140
|
+
return `${text}
|
|
107
141
|
`;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
return o.length > 4 && (/\$\$[\s\S]*?\$\$/g.test(o) || /\\\[[\s\S]*?\\\]/g.test(o)) ? `${o}
|
|
111
|
-
` : `<p>${n.parseInline(r.tokens)}</p>
|
|
142
|
+
} else {
|
|
143
|
+
return `<p>${parser.parseInline(paragraph.tokens)}</p>
|
|
112
144
|
`;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
renderer.image = function(token, title, text) {
|
|
148
|
+
const src = token.href;
|
|
149
|
+
return `<img src="${src}" alt="${token.text || ""}" title="${token.text || ""}">`;
|
|
150
|
+
};
|
|
151
|
+
marked.use({ renderer });
|
|
152
|
+
markedConfigured = true;
|
|
153
|
+
})();
|
|
154
|
+
return configurePromise;
|
|
117
155
|
}
|
|
118
|
-
function
|
|
119
|
-
const
|
|
120
|
-
|
|
121
|
-
const [
|
|
122
|
-
|
|
123
|
-
|
|
156
|
+
function stringToMap(str) {
|
|
157
|
+
const map = /* @__PURE__ */ new Map();
|
|
158
|
+
str.split(/\s+/).forEach((pair) => {
|
|
159
|
+
const [key, value] = pair.split("=");
|
|
160
|
+
if (key && value) {
|
|
161
|
+
map.set(key, value.replace(/^["']|["']$/g, ""));
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
return map;
|
|
124
165
|
}
|
|
125
|
-
async function
|
|
126
|
-
const { attributes
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
166
|
+
async function handleFrontMatter(markdown) {
|
|
167
|
+
const { attributes, body } = fm(markdown);
|
|
168
|
+
const result = {};
|
|
169
|
+
let head = "";
|
|
170
|
+
const { title, description, cover } = attributes;
|
|
171
|
+
if (title) {
|
|
172
|
+
result.title = title;
|
|
173
|
+
}
|
|
174
|
+
if (description) {
|
|
175
|
+
head += "> " + description + "\n\n";
|
|
176
|
+
result.description = description;
|
|
177
|
+
}
|
|
178
|
+
if (cover) {
|
|
179
|
+
result.cover = cover;
|
|
180
|
+
}
|
|
181
|
+
result.body = head + body;
|
|
182
|
+
return result;
|
|
132
183
|
}
|
|
133
|
-
async function
|
|
134
|
-
await
|
|
135
|
-
const
|
|
136
|
-
|
|
184
|
+
async function renderMarkdown(content) {
|
|
185
|
+
await configureMarked();
|
|
186
|
+
const html = marked.parse(content);
|
|
187
|
+
const htmlWithMath = await renderMathInHtml(html);
|
|
188
|
+
return htmlWithMath;
|
|
137
189
|
}
|
|
138
|
-
async function
|
|
139
|
-
let
|
|
140
|
-
if (
|
|
141
|
-
|
|
142
|
-
|
|
190
|
+
async function getContentForGzhBuiltinTheme(wenyanElement, themeId, hlThemeId, isMacStyle = true, isAddFootnote = true) {
|
|
191
|
+
let theme = themes["default"];
|
|
192
|
+
if (themeId) {
|
|
193
|
+
theme = themes[themeId];
|
|
194
|
+
if (!theme) {
|
|
195
|
+
theme = Object.values(themes).find(
|
|
196
|
+
(t) => t.name.toLowerCase() === themeId.toLowerCase()
|
|
197
|
+
);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
if (!theme) {
|
|
143
201
|
throw new Error("主题不存在");
|
|
144
|
-
|
|
202
|
+
}
|
|
203
|
+
if (!(hlThemeId in hlThemes)) {
|
|
145
204
|
throw new Error("代码块主题不存在");
|
|
146
|
-
|
|
147
|
-
|
|
205
|
+
}
|
|
206
|
+
const customCss = replaceCSSVariables(await theme.getCss());
|
|
207
|
+
const hlTheme = hlThemes[hlThemeId];
|
|
208
|
+
const highlightCss = await hlTheme.getCss();
|
|
209
|
+
return getContentForGzhCustomCss(wenyanElement, customCss, highlightCss, isMacStyle, isAddFootnote);
|
|
148
210
|
}
|
|
149
|
-
async function
|
|
150
|
-
|
|
211
|
+
async function getContentForGzhCustomCss(wenyanElement, customCss, highlightCss, isMacStyle = true, isAddFootnote = true) {
|
|
212
|
+
if (isAddFootnote) {
|
|
213
|
+
addFootnotes(false, wenyanElement);
|
|
214
|
+
}
|
|
215
|
+
customCss = modifyCss(customCss, {
|
|
151
216
|
"#wenyan pre code": [
|
|
152
217
|
{
|
|
153
218
|
property: "font-family",
|
|
154
|
-
value:
|
|
155
|
-
append:
|
|
219
|
+
value: monospace,
|
|
220
|
+
append: true
|
|
156
221
|
}
|
|
157
222
|
],
|
|
158
223
|
"#wenyan pre": [
|
|
159
224
|
{
|
|
160
225
|
property: "font-size",
|
|
161
226
|
value: "12px",
|
|
162
|
-
append:
|
|
227
|
+
append: true
|
|
163
228
|
}
|
|
164
229
|
]
|
|
165
230
|
});
|
|
166
|
-
const
|
|
231
|
+
const ast = csstree.parse(customCss, {
|
|
167
232
|
context: "stylesheet",
|
|
168
|
-
positions:
|
|
169
|
-
parseAtrulePrelude:
|
|
170
|
-
parseCustomProperty:
|
|
171
|
-
parseValue:
|
|
172
|
-
})
|
|
233
|
+
positions: false,
|
|
234
|
+
parseAtrulePrelude: false,
|
|
235
|
+
parseCustomProperty: false,
|
|
236
|
+
parseValue: false
|
|
237
|
+
});
|
|
238
|
+
const ast1 = csstree.parse(highlightCss, {
|
|
173
239
|
context: "stylesheet",
|
|
174
|
-
positions:
|
|
175
|
-
parseAtrulePrelude:
|
|
176
|
-
parseCustomProperty:
|
|
177
|
-
parseValue:
|
|
240
|
+
positions: false,
|
|
241
|
+
parseAtrulePrelude: false,
|
|
242
|
+
parseCustomProperty: false,
|
|
243
|
+
parseValue: false
|
|
178
244
|
});
|
|
179
|
-
|
|
180
|
-
|
|
245
|
+
ast.children.appendList(ast1.children);
|
|
246
|
+
if (isMacStyle) {
|
|
247
|
+
const ast2 = csstree.parse(macStyleCss, {
|
|
181
248
|
context: "stylesheet",
|
|
182
|
-
positions:
|
|
183
|
-
parseAtrulePrelude:
|
|
184
|
-
parseCustomProperty:
|
|
185
|
-
parseValue:
|
|
249
|
+
positions: false,
|
|
250
|
+
parseAtrulePrelude: false,
|
|
251
|
+
parseCustomProperty: false,
|
|
252
|
+
parseValue: false
|
|
186
253
|
});
|
|
187
|
-
|
|
254
|
+
ast.children.appendList(ast2.children);
|
|
188
255
|
}
|
|
189
|
-
|
|
256
|
+
csstree.walk(ast, {
|
|
190
257
|
visit: "Rule",
|
|
191
|
-
enter(
|
|
192
|
-
const
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
const
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
}
|
|
258
|
+
enter(node, item, list) {
|
|
259
|
+
const selectorList = node.prelude.children;
|
|
260
|
+
if (selectorList) {
|
|
261
|
+
selectorList.forEach((selectorNode) => {
|
|
262
|
+
const selector = csstree.generate(selectorNode);
|
|
263
|
+
const declarations = node.block.children.toArray();
|
|
264
|
+
if (selector === "#wenyan") {
|
|
265
|
+
declarations.forEach((decl) => {
|
|
266
|
+
const value = csstree.generate(decl.value);
|
|
267
|
+
wenyanElement.style[decl.property] = value;
|
|
268
|
+
});
|
|
269
|
+
} else {
|
|
270
|
+
const elements2 = wenyanElement.querySelectorAll(selector);
|
|
271
|
+
elements2.forEach((element) => {
|
|
272
|
+
declarations.forEach((decl) => {
|
|
273
|
+
const value = csstree.generate(decl.value);
|
|
274
|
+
element.style[decl.property] = value;
|
|
275
|
+
});
|
|
276
|
+
});
|
|
277
|
+
}
|
|
203
278
|
});
|
|
204
|
-
}
|
|
279
|
+
}
|
|
205
280
|
}
|
|
206
281
|
});
|
|
207
|
-
let
|
|
208
|
-
|
|
209
|
-
const
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
282
|
+
let elements = wenyanElement.querySelectorAll("mjx-container");
|
|
283
|
+
elements.forEach((element) => {
|
|
284
|
+
const svg2 = element.querySelector("svg");
|
|
285
|
+
svg2.style.width = svg2.getAttribute("width");
|
|
286
|
+
svg2.style.height = svg2.getAttribute("height");
|
|
287
|
+
svg2.removeAttribute("width");
|
|
288
|
+
svg2.removeAttribute("height");
|
|
289
|
+
const parent = element.parentElement;
|
|
290
|
+
element.remove();
|
|
291
|
+
parent.appendChild(svg2);
|
|
292
|
+
if (parent.classList.contains("block-equation")) {
|
|
293
|
+
parent.setAttribute("style", "text-align: center; margin-bottom: 1rem;");
|
|
294
|
+
}
|
|
295
|
+
});
|
|
296
|
+
elements = wenyanElement.querySelectorAll("pre code");
|
|
297
|
+
elements.forEach((element) => {
|
|
298
|
+
element.innerHTML = element.innerHTML.replace(/\n/g, "<br>").replace(/(>[^<]+)|(^[^<]+)/g, (str) => str.replace(/\s/g, " "));
|
|
299
|
+
});
|
|
300
|
+
elements = wenyanElement.querySelectorAll("h1, h2, h3, h4, h5, h6, blockquote, pre");
|
|
301
|
+
elements.forEach((element) => {
|
|
302
|
+
const afterResults = /* @__PURE__ */ new Map();
|
|
303
|
+
const beforeResults = /* @__PURE__ */ new Map();
|
|
304
|
+
csstree.walk(ast, {
|
|
218
305
|
visit: "Rule",
|
|
219
|
-
enter(
|
|
220
|
-
const
|
|
221
|
-
|
|
306
|
+
enter(node) {
|
|
307
|
+
const selector = csstree.generate(node.prelude);
|
|
308
|
+
const tagName = element.tagName.toLowerCase();
|
|
309
|
+
if (selector.includes(`${tagName}::after`)) {
|
|
310
|
+
extractDeclarations(node, afterResults);
|
|
311
|
+
} else if (selector.includes(`${tagName}::before`)) {
|
|
312
|
+
extractDeclarations(node, beforeResults);
|
|
313
|
+
}
|
|
222
314
|
}
|
|
223
|
-
})
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
315
|
+
});
|
|
316
|
+
if (afterResults.size > 0) {
|
|
317
|
+
element.appendChild(buildPseudoSpan(afterResults, wenyanElement.ownerDocument));
|
|
318
|
+
}
|
|
319
|
+
if (beforeResults.size > 0) {
|
|
320
|
+
element.insertBefore(buildPseudoSpan(beforeResults, wenyanElement.ownerDocument), element.firstChild);
|
|
321
|
+
}
|
|
322
|
+
});
|
|
323
|
+
elements = wenyanElement.querySelectorAll("li");
|
|
324
|
+
elements.forEach((li) => {
|
|
325
|
+
const section = wenyanElement.ownerDocument.createElement("section");
|
|
326
|
+
while (li.firstChild) {
|
|
327
|
+
section.appendChild(li.firstChild);
|
|
328
|
+
}
|
|
329
|
+
li.appendChild(section);
|
|
330
|
+
});
|
|
331
|
+
wenyanElement.setAttribute("data-provider", "WenYan");
|
|
332
|
+
return `${wenyanElement.outerHTML.replace(/class="mjx-solid"/g, 'fill="none" stroke-width="70"').replace(/\n<li/g, "<li").replace(/<\/li>\n/g, "</li>")}`;
|
|
230
333
|
}
|
|
231
|
-
function
|
|
232
|
-
const
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
334
|
+
function replaceCSSVariables(css) {
|
|
335
|
+
const variablePattern = /--([a-zA-Z0-9\-]+):\s*([^;()]*\((?:[^()]*|\([^()]*\))*\)[^;()]*|[^;]+);/g;
|
|
336
|
+
const varPattern = /var\(--([a-zA-Z0-9\-]+)\)/g;
|
|
337
|
+
const cssVariables = {};
|
|
338
|
+
let match;
|
|
339
|
+
while ((match = variablePattern.exec(css)) !== null) {
|
|
340
|
+
const variableName = match[1];
|
|
341
|
+
const variableValue = match[2].trim().replaceAll("\n", "");
|
|
342
|
+
cssVariables[variableName] = variableValue;
|
|
343
|
+
}
|
|
344
|
+
if (!cssVariables["sans-serif-font"]) {
|
|
345
|
+
cssVariables["sans-serif-font"] = sansSerif;
|
|
346
|
+
}
|
|
347
|
+
if (!cssVariables["monospace-font"]) {
|
|
348
|
+
cssVariables["monospace-font"] = monospace;
|
|
238
349
|
}
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
let
|
|
244
|
-
|
|
245
|
-
const
|
|
246
|
-
if (
|
|
247
|
-
const
|
|
248
|
-
|
|
350
|
+
function resolveVariable(value, variables, resolved = /* @__PURE__ */ new Set()) {
|
|
351
|
+
if (resolved.has(value)) return value;
|
|
352
|
+
resolved.add(value);
|
|
353
|
+
let resolvedValue = value;
|
|
354
|
+
let match2;
|
|
355
|
+
while ((match2 = varPattern.exec(resolvedValue)) !== null) {
|
|
356
|
+
const varName = match2[1];
|
|
357
|
+
if (variables[varName]) {
|
|
358
|
+
const resolvedVar = resolveVariable(variables[varName], variables, resolved);
|
|
359
|
+
resolvedValue = resolvedValue.replace(match2[0], resolvedVar);
|
|
249
360
|
}
|
|
250
361
|
}
|
|
251
|
-
return
|
|
362
|
+
return resolvedValue;
|
|
252
363
|
}
|
|
253
|
-
for (const
|
|
254
|
-
const
|
|
255
|
-
|
|
364
|
+
for (const key in cssVariables) {
|
|
365
|
+
const resolvedValue = resolveVariable(cssVariables[key], cssVariables);
|
|
366
|
+
cssVariables[key] = resolvedValue;
|
|
256
367
|
}
|
|
257
|
-
let
|
|
258
|
-
|
|
259
|
-
const
|
|
260
|
-
|
|
368
|
+
let modifiedCSS = css;
|
|
369
|
+
while ((match = varPattern.exec(css)) !== null) {
|
|
370
|
+
const varName = match[1];
|
|
371
|
+
if (cssVariables[varName]) {
|
|
372
|
+
modifiedCSS = modifiedCSS.replace(match[0], cssVariables[varName]);
|
|
373
|
+
}
|
|
261
374
|
}
|
|
262
|
-
return
|
|
375
|
+
return modifiedCSS.replace(/:root\s*\{[^}]*\}/g, "");
|
|
263
376
|
}
|
|
264
|
-
function
|
|
265
|
-
const
|
|
377
|
+
function modifyCss(customCss, updates) {
|
|
378
|
+
const ast = csstree.parse(customCss, {
|
|
266
379
|
context: "stylesheet",
|
|
267
|
-
positions:
|
|
268
|
-
parseAtrulePrelude:
|
|
269
|
-
parseCustomProperty:
|
|
270
|
-
parseValue:
|
|
380
|
+
positions: false,
|
|
381
|
+
parseAtrulePrelude: false,
|
|
382
|
+
parseCustomProperty: false,
|
|
383
|
+
parseValue: false
|
|
271
384
|
});
|
|
272
|
-
|
|
385
|
+
csstree.walk(ast, {
|
|
273
386
|
visit: "Rule",
|
|
274
|
-
leave: (
|
|
275
|
-
if (
|
|
276
|
-
const
|
|
277
|
-
if (
|
|
278
|
-
const
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
387
|
+
leave: (node, item, list) => {
|
|
388
|
+
if (node.prelude.type !== "SelectorList") return;
|
|
389
|
+
const selectors = node.prelude.children.toArray().map((sel) => csstree.generate(sel));
|
|
390
|
+
if (selectors) {
|
|
391
|
+
const selector = selectors[0];
|
|
392
|
+
const update = updates[selector];
|
|
393
|
+
if (!update) return;
|
|
394
|
+
for (const { property, value, append } of update) {
|
|
395
|
+
if (value) {
|
|
396
|
+
let found = false;
|
|
397
|
+
csstree.walk(node.block, (decl) => {
|
|
398
|
+
if (decl.type === "Declaration" && decl.property === property) {
|
|
399
|
+
decl.value = csstree.parse(value, { context: "value" });
|
|
400
|
+
found = true;
|
|
401
|
+
}
|
|
402
|
+
});
|
|
403
|
+
if (!found && append) {
|
|
404
|
+
node.block.children.prepend(
|
|
405
|
+
list.createItem({
|
|
406
|
+
type: "Declaration",
|
|
407
|
+
property,
|
|
408
|
+
value: csstree.parse(value, { context: "value" })
|
|
409
|
+
})
|
|
410
|
+
);
|
|
411
|
+
}
|
|
292
412
|
}
|
|
413
|
+
}
|
|
293
414
|
}
|
|
294
415
|
}
|
|
295
|
-
})
|
|
416
|
+
});
|
|
417
|
+
return csstree.generate(ast);
|
|
296
418
|
}
|
|
297
|
-
function
|
|
298
|
-
|
|
419
|
+
function extractDeclarations(ruleNode, resultMap) {
|
|
420
|
+
csstree.walk(ruleNode.block, {
|
|
299
421
|
visit: "Declaration",
|
|
300
|
-
enter(
|
|
301
|
-
const
|
|
302
|
-
|
|
422
|
+
enter(declNode) {
|
|
423
|
+
const property = declNode.property;
|
|
424
|
+
const value = csstree.generate(declNode.value);
|
|
425
|
+
resultMap.set(property, value);
|
|
303
426
|
}
|
|
304
427
|
});
|
|
305
428
|
}
|
|
306
|
-
function
|
|
307
|
-
const
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
429
|
+
function buildPseudoSpan(beforeRresults, document) {
|
|
430
|
+
const span = document.createElement("section");
|
|
431
|
+
if (beforeRresults.get("content")) {
|
|
432
|
+
span.textContent = beforeRresults.get("content").replace(/['"]/g, "");
|
|
433
|
+
beforeRresults.delete("content");
|
|
434
|
+
}
|
|
435
|
+
for (const [k, v] of beforeRresults) {
|
|
436
|
+
if (v.includes("url(")) {
|
|
437
|
+
const svgMatch = v.match(/data:image\/svg\+xml;utf8,(.*<\/svg>)/);
|
|
438
|
+
const base64SvgMatch = v.match(/data:image\/svg\+xml;base64,([^"'\)]*)["']?\)/);
|
|
439
|
+
const httpMatch = v.match(/(?:"|')?(https?[^"'\)]*)(?:"|')?\)/);
|
|
440
|
+
if (svgMatch) {
|
|
441
|
+
const svgCode = decodeURIComponent(svgMatch[1]);
|
|
442
|
+
span.innerHTML = svgCode;
|
|
443
|
+
} else if (base64SvgMatch) {
|
|
444
|
+
const decodedString = atob(base64SvgMatch[1]);
|
|
445
|
+
span.innerHTML = decodedString;
|
|
446
|
+
} else if (httpMatch) {
|
|
447
|
+
const img = document.createElement("img");
|
|
448
|
+
img.src = httpMatch[1];
|
|
449
|
+
img.setAttribute("style", "vertical-align: top;");
|
|
450
|
+
span.appendChild(img);
|
|
321
451
|
}
|
|
322
|
-
|
|
452
|
+
beforeRresults.delete(k);
|
|
323
453
|
}
|
|
324
|
-
|
|
325
|
-
|
|
454
|
+
}
|
|
455
|
+
const entries = Array.from(beforeRresults.entries());
|
|
456
|
+
const cssString = entries.map(([key, value]) => `${key}: ${value}`).join("; ");
|
|
457
|
+
span.style.cssText = cssString;
|
|
458
|
+
return span;
|
|
326
459
|
}
|
|
327
|
-
function
|
|
328
|
-
let
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
const
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
460
|
+
function addFootnotes(listStyle, element) {
|
|
461
|
+
let footnotes = [];
|
|
462
|
+
let footnoteIndex = 0;
|
|
463
|
+
const links = element.querySelectorAll("a[href]");
|
|
464
|
+
links.forEach((linkElement) => {
|
|
465
|
+
const title = linkElement.textContent || linkElement.innerText;
|
|
466
|
+
const href = linkElement.getAttribute("href");
|
|
467
|
+
footnotes.push([++footnoteIndex, title, href]);
|
|
468
|
+
const footnoteMarker = element.ownerDocument.createElement("sup");
|
|
469
|
+
footnoteMarker.setAttribute("class", "footnote");
|
|
470
|
+
footnoteMarker.innerHTML = `[${footnoteIndex}]`;
|
|
471
|
+
linkElement.after(footnoteMarker);
|
|
472
|
+
});
|
|
473
|
+
if (footnoteIndex > 0) {
|
|
474
|
+
if (!listStyle) {
|
|
475
|
+
let footnoteArray = footnotes.map((x) => {
|
|
476
|
+
if (x[1] === x[2]) {
|
|
477
|
+
return `<p><span class="footnote-num">[${x[0]}]</span><span class="footnote-txt"><i>${x[1]}</i></span></p>`;
|
|
478
|
+
}
|
|
479
|
+
return `<p><span class="footnote-num">[${x[0]}]</span><span class="footnote-txt">${x[1]}: <i>${x[2]}</i></span></p>`;
|
|
480
|
+
});
|
|
481
|
+
const footnotesHtml = `<h3>引用链接</h3><section id="footnotes">${footnoteArray.join("")}</section>`;
|
|
482
|
+
element.innerHTML += footnotesHtml;
|
|
338
483
|
} else {
|
|
339
|
-
|
|
340
|
-
|
|
484
|
+
let footnoteArray = footnotes.map((x) => {
|
|
485
|
+
if (x[1] === x[2]) {
|
|
486
|
+
return `<li id="#footnote-${x[0]}">[${x[0]}]: <i>${x[1]}</i></li>`;
|
|
487
|
+
}
|
|
488
|
+
return `<li id="#footnote-${x[0]}">[${x[0]}] ${x[1]}: <i>${x[2]}</i></li>`;
|
|
489
|
+
});
|
|
490
|
+
const footnotesHtml = `<h3>引用链接</h3><div id="footnotes"><ul>${footnoteArray.join("")}</ul></div>`;
|
|
491
|
+
element.innerHTML += footnotesHtml;
|
|
341
492
|
}
|
|
493
|
+
}
|
|
342
494
|
}
|
|
343
495
|
export {
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
496
|
+
addFootnotes,
|
|
497
|
+
buildPseudoSpan,
|
|
498
|
+
configureMarked,
|
|
499
|
+
extractDeclarations,
|
|
500
|
+
getContentForGzhBuiltinTheme,
|
|
501
|
+
getContentForGzhCustomCss,
|
|
502
|
+
handleFrontMatter,
|
|
503
|
+
modifyCss,
|
|
504
|
+
monospace,
|
|
505
|
+
renderMarkdown,
|
|
506
|
+
replaceCSSVariables,
|
|
507
|
+
sansSerif,
|
|
508
|
+
serif
|
|
357
509
|
};
|