@jx3box/jx3box-editor 2.2.32 → 2.2.33
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/assets/css/katex-fix.css +20 -0
- package/assets/js/katex.js +183 -9
- package/package.json +1 -1
- package/src/Article.vue +2 -2
- package/src/ArticleMarkdown.vue +2 -2
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/* KaTeX 字体修复 */
|
|
2
|
+
.katex {
|
|
3
|
+
font-family: KaTeX_Main, "Times New Roman", serif !important;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
.katex .mord,
|
|
7
|
+
.katex .mop {
|
|
8
|
+
font-family: KaTeX_Main, "Times New Roman", serif !important;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/* 强制求和符号使用正确字体 */
|
|
12
|
+
.katex .mop.op-symbol.large-op {
|
|
13
|
+
font-family: KaTeX_Size2, KaTeX_Size1, KaTeX_Main, "Times New Roman", serif !important;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/* 确保数学符号显示 */
|
|
17
|
+
.katex .mop:before,
|
|
18
|
+
.katex .mop:after {
|
|
19
|
+
font-family: KaTeX_Main, "Times New Roman", serif !important;
|
|
20
|
+
}
|
package/assets/js/katex.js
CHANGED
|
@@ -1,17 +1,191 @@
|
|
|
1
|
-
import $ from 'jquery'
|
|
2
|
-
import katex from 'katex
|
|
3
|
-
import 'katex/dist/katex.css';
|
|
4
|
-
// katex.render("x=\\frac{-b\\pm\\sqrt{b^2-4ac}}{2a}", document.getElementById("math"));
|
|
1
|
+
import $ from 'jquery';
|
|
2
|
+
import katex from 'katex';
|
|
3
|
+
import 'katex/dist/katex.min.css';
|
|
5
4
|
|
|
6
|
-
function
|
|
5
|
+
function renderKatexBlock(selector = ".w-latex") {
|
|
7
6
|
try {
|
|
8
7
|
$(selector).each(function(i, ele) {
|
|
9
8
|
let $katex = $(this);
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
|
|
10
|
+
// 获取原始HTML内容
|
|
11
|
+
let raw = $katex.html();
|
|
12
|
+
|
|
13
|
+
// 处理各种换行组合:
|
|
14
|
+
// 1. \\<br /> 或 \\<br> -> \\
|
|
15
|
+
raw = raw.replace(/\\\\\s*<br\s*\/?>/gi, '\\\\');
|
|
16
|
+
// 2. \<br /> 或 \<br> -> \\
|
|
17
|
+
raw = raw.replace(/\\\s*<br\s*\/?>/gi, '\\\\');
|
|
18
|
+
// 3. 单独的 <br /> -> \\
|
|
19
|
+
raw = raw.replace(/<br\s*\/?>/gi, '\\\\');
|
|
20
|
+
|
|
21
|
+
// 移除其他HTML标签但保留内容
|
|
22
|
+
raw = raw.replace(/<[^>]+>/g, '');
|
|
23
|
+
|
|
24
|
+
// 解码HTML实体(如 -> 空格)
|
|
25
|
+
raw = $('<div>').html(raw).text();
|
|
26
|
+
|
|
27
|
+
// 清理多余的空白字符
|
|
28
|
+
raw = raw.trim();
|
|
29
|
+
|
|
30
|
+
console.log('Original HTML:', $katex.html());
|
|
31
|
+
console.log('Processed LaTeX:', raw);
|
|
32
|
+
|
|
33
|
+
katex.render(raw, $katex.get(0), { displayMode: true });
|
|
12
34
|
});
|
|
13
35
|
} catch (e) {
|
|
14
|
-
console.error(e);
|
|
36
|
+
console.error('KaTeX render error:', e);
|
|
37
|
+
console.error('Failed content:', $(this).html());
|
|
15
38
|
}
|
|
16
39
|
}
|
|
17
|
-
|
|
40
|
+
|
|
41
|
+
function renderKatexInline(container = document.body) {
|
|
42
|
+
// 支持 \(...\) 和 $...$ 两种行内语法
|
|
43
|
+
// 改进正则表达式,更好地匹配单美元符号
|
|
44
|
+
const inlineRegex = /(\\\((.+?)\\\)|\$([^$]+?)\$)/g;
|
|
45
|
+
|
|
46
|
+
const walker = document.createTreeWalker(
|
|
47
|
+
container,
|
|
48
|
+
NodeFilter.SHOW_TEXT,
|
|
49
|
+
{
|
|
50
|
+
acceptNode: function (node) {
|
|
51
|
+
if (
|
|
52
|
+
node.parentNode &&
|
|
53
|
+
!node.parentNode.closest("pre") &&
|
|
54
|
+
(node.nodeValue.includes("\\(") || node.nodeValue.includes("$"))
|
|
55
|
+
) {
|
|
56
|
+
return NodeFilter.FILTER_ACCEPT;
|
|
57
|
+
}
|
|
58
|
+
return NodeFilter.FILTER_REJECT;
|
|
59
|
+
},
|
|
60
|
+
}
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
const nodesToReplace = [];
|
|
64
|
+
while (walker.nextNode()) {
|
|
65
|
+
nodesToReplace.push(walker.currentNode);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
console.log('Inline processing nodes:', nodesToReplace.length);
|
|
69
|
+
|
|
70
|
+
nodesToReplace.forEach((node) => {
|
|
71
|
+
const text = node.nodeValue;
|
|
72
|
+
const frag = document.createDocumentFragment();
|
|
73
|
+
let lastIndex = 0;
|
|
74
|
+
let match;
|
|
75
|
+
|
|
76
|
+
console.log('Processing text:', text);
|
|
77
|
+
|
|
78
|
+
while ((match = inlineRegex.exec(text))) {
|
|
79
|
+
const fullMatch = match[0];
|
|
80
|
+
const parenContent = match[2]; // \(...\)的内容
|
|
81
|
+
const dollarContent = match[3]; // $...$的内容
|
|
82
|
+
const raw = parenContent || dollarContent;
|
|
83
|
+
const matchStart = match.index;
|
|
84
|
+
|
|
85
|
+
console.log('Found inline match:', fullMatch, 'Raw:', raw);
|
|
86
|
+
|
|
87
|
+
// 添加匹配前文本
|
|
88
|
+
frag.appendChild(document.createTextNode(text.slice(lastIndex, matchStart)));
|
|
89
|
+
|
|
90
|
+
try {
|
|
91
|
+
const span = document.createElement("span");
|
|
92
|
+
// 处理JavaScript字符串中的双反斜杠转义
|
|
93
|
+
const processedRaw = raw.replace(/\\\\/g, '\\');
|
|
94
|
+
console.log('Rendering inline:', processedRaw);
|
|
95
|
+
// 添加更多选项确保正确渲染
|
|
96
|
+
span.innerHTML = katex.renderToString(processedRaw, {
|
|
97
|
+
displayMode: false,
|
|
98
|
+
throwOnError: false,
|
|
99
|
+
strict: false,
|
|
100
|
+
trust: true
|
|
101
|
+
});
|
|
102
|
+
frag.appendChild(span);
|
|
103
|
+
} catch (e) {
|
|
104
|
+
frag.appendChild(document.createTextNode(fullMatch));
|
|
105
|
+
console.error("Inline render error:", raw, e);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
lastIndex = inlineRegex.lastIndex;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// 剩余文本
|
|
112
|
+
if (lastIndex < text.length) {
|
|
113
|
+
frag.appendChild(document.createTextNode(text.slice(lastIndex)));
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (frag.hasChildNodes()) {
|
|
117
|
+
node.parentNode.replaceChild(frag, node);
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function renderKatexDisplayBlock(container = document.body) {
|
|
123
|
+
// 支持 $$...$$ 和 \[...\] 两种块语法
|
|
124
|
+
const blockRegex = /(\$\$\s*([\s\S]+?)\s*\$\$|\\\[\s*([\s\S]+?)\s*\\\])/g;
|
|
125
|
+
|
|
126
|
+
const walker = document.createTreeWalker(
|
|
127
|
+
container,
|
|
128
|
+
NodeFilter.SHOW_TEXT,
|
|
129
|
+
{
|
|
130
|
+
acceptNode: function (node) {
|
|
131
|
+
if (
|
|
132
|
+
node.parentNode &&
|
|
133
|
+
!node.parentNode.closest("pre") &&
|
|
134
|
+
(node.nodeValue.includes("$$") || node.nodeValue.includes("\\["))
|
|
135
|
+
) {
|
|
136
|
+
return NodeFilter.FILTER_ACCEPT;
|
|
137
|
+
}
|
|
138
|
+
return NodeFilter.FILTER_REJECT;
|
|
139
|
+
},
|
|
140
|
+
}
|
|
141
|
+
);
|
|
142
|
+
|
|
143
|
+
const nodesToReplace = [];
|
|
144
|
+
while (walker.nextNode()) {
|
|
145
|
+
nodesToReplace.push(walker.currentNode);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
nodesToReplace.forEach((node) => {
|
|
149
|
+
const text = node.nodeValue;
|
|
150
|
+
const frag = document.createDocumentFragment();
|
|
151
|
+
let lastIndex = 0;
|
|
152
|
+
let match;
|
|
153
|
+
|
|
154
|
+
while ((match = blockRegex.exec(text))) {
|
|
155
|
+
const fullMatch = match[0];
|
|
156
|
+
const dollarContent = match[2]; // $$...$$的内容
|
|
157
|
+
const bracketContent = match[3]; // \[...\]的内容
|
|
158
|
+
const raw = dollarContent || bracketContent;
|
|
159
|
+
const matchStart = match.index;
|
|
160
|
+
|
|
161
|
+
// 添加匹配前文本
|
|
162
|
+
frag.appendChild(document.createTextNode(text.slice(lastIndex, matchStart)));
|
|
163
|
+
|
|
164
|
+
try {
|
|
165
|
+
const div = document.createElement("div");
|
|
166
|
+
// 处理JavaScript字符串中的双反斜杠转义
|
|
167
|
+
const processedRaw = raw.replace(/\\\\/g, '\\');
|
|
168
|
+
div.innerHTML = katex.renderToString(processedRaw, { displayMode: true });
|
|
169
|
+
frag.appendChild(div);
|
|
170
|
+
} catch (e) {
|
|
171
|
+
frag.appendChild(document.createTextNode(fullMatch));
|
|
172
|
+
console.error("Block render error:", raw, e);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
lastIndex = blockRegex.lastIndex;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// 添加剩余文本
|
|
179
|
+
if (lastIndex < text.length) {
|
|
180
|
+
frag.appendChild(document.createTextNode(text.slice(lastIndex)));
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
node.parentNode.replaceChild(frag, node);
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
export function renderKatexAll(container = document.body) {
|
|
188
|
+
renderKatexBlock(".w-latex");
|
|
189
|
+
renderKatexDisplayBlock(container);
|
|
190
|
+
renderKatexInline(container);
|
|
191
|
+
}
|
package/package.json
CHANGED
package/src/Article.vue
CHANGED
|
@@ -61,7 +61,7 @@ import renderDirectory from "../assets/js/directory";
|
|
|
61
61
|
import renderMacro from "../assets/js/macro";
|
|
62
62
|
import renderTalent from "../assets/js/qixue";
|
|
63
63
|
import renderTalent2 from "../assets/js/talent2";
|
|
64
|
-
import
|
|
64
|
+
import {renderKatexAll} from "../assets/js/katex";
|
|
65
65
|
import renderCode from "../assets/js/code";
|
|
66
66
|
import renderImgPreview from "../assets/js/renderImgPreview";
|
|
67
67
|
import renderPzIframe from "../assets/js/pz_iframe";
|
|
@@ -170,7 +170,7 @@ export default {
|
|
|
170
170
|
// 代码
|
|
171
171
|
renderCode(`code[class=^'language-']`);
|
|
172
172
|
// Tatex
|
|
173
|
-
|
|
173
|
+
renderKatexAll();
|
|
174
174
|
|
|
175
175
|
// 画廊(需要在宏、奇穴、物品等之前渲染以排除下方自动生成图片)
|
|
176
176
|
// renderGallery(this)
|
package/src/ArticleMarkdown.vue
CHANGED
|
@@ -28,7 +28,7 @@ import renderDirectory from "../assets/js/directory";
|
|
|
28
28
|
import renderMacro from "../assets/js/macro";
|
|
29
29
|
import renderTalent from "../assets/js/qixue";
|
|
30
30
|
import renderTalent2 from "../assets/js/talent2";
|
|
31
|
-
import
|
|
31
|
+
import {renderKatexAll} from "../assets/js/katex";
|
|
32
32
|
import renderCode from "../assets/js/code";
|
|
33
33
|
|
|
34
34
|
// 剑三
|
|
@@ -111,7 +111,7 @@ export default {
|
|
|
111
111
|
renderTalent();
|
|
112
112
|
renderTalent2();
|
|
113
113
|
// Tatex
|
|
114
|
-
|
|
114
|
+
renderKatexAll();
|
|
115
115
|
// 画廊
|
|
116
116
|
renderImgPreview(this);
|
|
117
117
|
// 语法高亮
|