@2kog/pkg-editor 0.0.2 → 0.0.3
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/package.json +1 -1
- package/src/assets/js/katex.js +87 -68
package/package.json
CHANGED
package/src/assets/js/katex.js
CHANGED
|
@@ -4,56 +4,60 @@ import 'katex/dist/katex.min.css';
|
|
|
4
4
|
|
|
5
5
|
function renderKatexBlock(selector = ".w-latex") {
|
|
6
6
|
try {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
let $katex = $(this);
|
|
7
|
+
$(selector).each(function() {
|
|
8
|
+
const $katex = $(this);
|
|
10
9
|
|
|
11
|
-
//
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
// 处理各种换行组合:
|
|
15
|
-
// 1. \\<br /> 或 \\<br> -> \\
|
|
16
|
-
raw = raw.replace(/\\\\\s*<br\s*\/?>/gi, '\\\\');
|
|
17
|
-
// 2. \<br /> 或 \<br> -> \\
|
|
18
|
-
raw = raw.replace(/\\\s*<br\s*\/?>/gi, '\\\\');
|
|
19
|
-
// 3. 单独的 <br /> -> \\
|
|
20
|
-
raw = raw.replace(/<br\s*\/?>/gi, '\\\\');
|
|
10
|
+
// 避免重复渲染
|
|
11
|
+
if ($katex.data('katex-rendered')) return;
|
|
21
12
|
|
|
22
|
-
|
|
23
|
-
raw = raw.replace(/<[^>]+>/g, '');
|
|
24
|
-
|
|
25
|
-
// 解码HTML实体(如 -> 空格)
|
|
26
|
-
raw = $('<div>').html(raw).text();
|
|
13
|
+
let raw = $katex.html();
|
|
27
14
|
|
|
28
|
-
//
|
|
29
|
-
raw = raw
|
|
15
|
+
// 统一处理换行符
|
|
16
|
+
raw = raw
|
|
17
|
+
.replace(/\\\\\s*<br\s*\/?>/gi, '\\\\')
|
|
18
|
+
.replace(/\\\s*<br\s*\/?>/gi, '\\\\')
|
|
19
|
+
.replace(/<br\s*\/?>/gi, '\\\\')
|
|
20
|
+
.replace(/<[^>]+>/g, '');
|
|
30
21
|
|
|
31
|
-
|
|
32
|
-
|
|
22
|
+
// 解码HTML实体
|
|
23
|
+
raw = $('<div>').html(raw).text().trim();
|
|
33
24
|
|
|
34
|
-
|
|
25
|
+
try {
|
|
26
|
+
katex.render(raw, $katex.get(0), {
|
|
27
|
+
displayMode: true,
|
|
28
|
+
throwOnError: false,
|
|
29
|
+
strict: false
|
|
30
|
+
});
|
|
31
|
+
$katex.data('katex-rendered', true);
|
|
32
|
+
} catch (e) {
|
|
33
|
+
console.error('KaTeX render error:', e.message, raw);
|
|
34
|
+
}
|
|
35
35
|
});
|
|
36
36
|
} catch (e) {
|
|
37
|
-
console.error('KaTeX render error:', e);
|
|
38
|
-
console.error('Failed content:', $(this).html());
|
|
37
|
+
console.error('KaTeX block render error:', e);
|
|
39
38
|
}
|
|
40
39
|
}
|
|
41
40
|
|
|
42
41
|
function renderKatexInline(container = document.body) {
|
|
43
|
-
//
|
|
44
|
-
|
|
45
|
-
const inlineRegex = /(\\\((.+?)\\\)|\$([^$]+?)\$)/g;
|
|
42
|
+
// 改进的正则:不匹配换行符,支持转义
|
|
43
|
+
const inlineRegex = /(?<!\\)(\\\((.+?)\\\)|(?<!\\)\$([^\n$]+?)(?<!\\)\$)/g;
|
|
46
44
|
|
|
47
45
|
const walker = document.createTreeWalker(
|
|
48
46
|
container,
|
|
49
47
|
NodeFilter.SHOW_TEXT,
|
|
50
48
|
{
|
|
51
49
|
acceptNode: function (node) {
|
|
50
|
+
// 跳过已渲染的节点
|
|
52
51
|
if (
|
|
53
52
|
node.parentNode &&
|
|
54
|
-
|
|
55
|
-
|
|
53
|
+
(node.parentNode.classList?.contains('katex') ||
|
|
54
|
+
node.parentNode.closest("pre, code, .katex"))
|
|
56
55
|
) {
|
|
56
|
+
return NodeFilter.FILTER_REJECT;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const value = node.nodeValue || '';
|
|
60
|
+
if (value.includes("\\(") || value.includes("$")) {
|
|
57
61
|
return NodeFilter.FILTER_ACCEPT;
|
|
58
62
|
}
|
|
59
63
|
return NodeFilter.FILTER_REJECT;
|
|
@@ -66,35 +70,32 @@ function renderKatexInline(container = document.body) {
|
|
|
66
70
|
nodesToReplace.push(walker.currentNode);
|
|
67
71
|
}
|
|
68
72
|
|
|
69
|
-
console.log('Inline processing nodes:', nodesToReplace.length);
|
|
70
|
-
|
|
71
73
|
nodesToReplace.forEach((node) => {
|
|
72
74
|
const text = node.nodeValue;
|
|
73
75
|
const frag = document.createDocumentFragment();
|
|
74
76
|
let lastIndex = 0;
|
|
75
|
-
let match;
|
|
76
77
|
|
|
77
|
-
|
|
78
|
+
// 重置正则状态
|
|
79
|
+
inlineRegex.lastIndex = 0;
|
|
78
80
|
|
|
79
|
-
|
|
81
|
+
const matches = [...text.matchAll(inlineRegex)];
|
|
82
|
+
|
|
83
|
+
matches.forEach((match) => {
|
|
80
84
|
const fullMatch = match[0];
|
|
81
|
-
const parenContent = match[2];
|
|
82
|
-
const dollarContent = match[3];
|
|
85
|
+
const parenContent = match[2];
|
|
86
|
+
const dollarContent = match[3];
|
|
83
87
|
const raw = parenContent || dollarContent;
|
|
84
88
|
const matchStart = match.index;
|
|
85
89
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
+
// 添加匹配前的文本
|
|
91
|
+
if (matchStart > lastIndex) {
|
|
92
|
+
frag.appendChild(document.createTextNode(text.slice(lastIndex, matchStart)));
|
|
93
|
+
}
|
|
90
94
|
|
|
91
95
|
try {
|
|
92
96
|
const span = document.createElement("span");
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
console.log('Rendering inline:', processedRaw);
|
|
96
|
-
// 添加更多选项确保正确渲染
|
|
97
|
-
span.innerHTML = katex.renderToString(processedRaw, {
|
|
97
|
+
span.className = "katex-inline";
|
|
98
|
+
span.innerHTML = katex.renderToString(raw, {
|
|
98
99
|
displayMode: false,
|
|
99
100
|
throwOnError: false,
|
|
100
101
|
strict: false,
|
|
@@ -103,13 +104,13 @@ function renderKatexInline(container = document.body) {
|
|
|
103
104
|
frag.appendChild(span);
|
|
104
105
|
} catch (e) {
|
|
105
106
|
frag.appendChild(document.createTextNode(fullMatch));
|
|
106
|
-
console.error("Inline render error:", raw, e);
|
|
107
|
+
console.error("Inline render error:", raw, e.message);
|
|
107
108
|
}
|
|
108
109
|
|
|
109
|
-
lastIndex =
|
|
110
|
-
}
|
|
110
|
+
lastIndex = matchStart + fullMatch.length;
|
|
111
|
+
});
|
|
111
112
|
|
|
112
|
-
//
|
|
113
|
+
// 添加剩余文本
|
|
113
114
|
if (lastIndex < text.length) {
|
|
114
115
|
frag.appendChild(document.createTextNode(text.slice(lastIndex)));
|
|
115
116
|
}
|
|
@@ -121,19 +122,25 @@ function renderKatexInline(container = document.body) {
|
|
|
121
122
|
}
|
|
122
123
|
|
|
123
124
|
function renderKatexDisplayBlock(container = document.body) {
|
|
124
|
-
//
|
|
125
|
-
const blockRegex = /(
|
|
125
|
+
// 使用非贪婪匹配,允许多行但不跨过多段落
|
|
126
|
+
const blockRegex = /(?<!\\)(\$\$([\s\S]+?)\$\$|(?<!\\)\\\[([\s\S]+?)\\\])/g;
|
|
126
127
|
|
|
127
128
|
const walker = document.createTreeWalker(
|
|
128
129
|
container,
|
|
129
130
|
NodeFilter.SHOW_TEXT,
|
|
130
131
|
{
|
|
131
132
|
acceptNode: function (node) {
|
|
133
|
+
// 跳过已渲染的节点
|
|
132
134
|
if (
|
|
133
135
|
node.parentNode &&
|
|
134
|
-
|
|
135
|
-
|
|
136
|
+
(node.parentNode.classList?.contains('katex') ||
|
|
137
|
+
node.parentNode.closest("pre, code, .katex"))
|
|
136
138
|
) {
|
|
139
|
+
return NodeFilter.FILTER_REJECT;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const value = node.nodeValue || '';
|
|
143
|
+
if (value.includes("$$") || value.includes("\\[")) {
|
|
137
144
|
return NodeFilter.FILTER_ACCEPT;
|
|
138
145
|
}
|
|
139
146
|
return NodeFilter.FILTER_REJECT;
|
|
@@ -150,38 +157,50 @@ function renderKatexDisplayBlock(container = document.body) {
|
|
|
150
157
|
const text = node.nodeValue;
|
|
151
158
|
const frag = document.createDocumentFragment();
|
|
152
159
|
let lastIndex = 0;
|
|
153
|
-
let match;
|
|
154
160
|
|
|
155
|
-
|
|
161
|
+
// 重置正则状态
|
|
162
|
+
blockRegex.lastIndex = 0;
|
|
163
|
+
|
|
164
|
+
const matches = [...text.matchAll(blockRegex)];
|
|
165
|
+
|
|
166
|
+
matches.forEach((match) => {
|
|
156
167
|
const fullMatch = match[0];
|
|
157
|
-
const dollarContent = match[2];
|
|
158
|
-
const bracketContent = match[3];
|
|
159
|
-
const raw = dollarContent || bracketContent;
|
|
168
|
+
const dollarContent = match[2];
|
|
169
|
+
const bracketContent = match[3];
|
|
170
|
+
const raw = (dollarContent || bracketContent).trim();
|
|
160
171
|
const matchStart = match.index;
|
|
161
172
|
|
|
162
|
-
//
|
|
163
|
-
|
|
173
|
+
// 添加匹配前的文本
|
|
174
|
+
if (matchStart > lastIndex) {
|
|
175
|
+
frag.appendChild(document.createTextNode(text.slice(lastIndex, matchStart)));
|
|
176
|
+
}
|
|
164
177
|
|
|
165
178
|
try {
|
|
166
179
|
const div = document.createElement("div");
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
180
|
+
div.className = "katex-block";
|
|
181
|
+
div.innerHTML = katex.renderToString(raw, {
|
|
182
|
+
displayMode: true,
|
|
183
|
+
throwOnError: false,
|
|
184
|
+
strict: false,
|
|
185
|
+
trust: true
|
|
186
|
+
});
|
|
170
187
|
frag.appendChild(div);
|
|
171
188
|
} catch (e) {
|
|
172
189
|
frag.appendChild(document.createTextNode(fullMatch));
|
|
173
|
-
console.error("Block render error:", raw, e);
|
|
190
|
+
console.error("Block render error:", raw, e.message);
|
|
174
191
|
}
|
|
175
192
|
|
|
176
|
-
lastIndex =
|
|
177
|
-
}
|
|
193
|
+
lastIndex = matchStart + fullMatch.length;
|
|
194
|
+
});
|
|
178
195
|
|
|
179
196
|
// 添加剩余文本
|
|
180
197
|
if (lastIndex < text.length) {
|
|
181
198
|
frag.appendChild(document.createTextNode(text.slice(lastIndex)));
|
|
182
199
|
}
|
|
183
200
|
|
|
184
|
-
|
|
201
|
+
if (frag.hasChildNodes()) {
|
|
202
|
+
node.parentNode.replaceChild(frag, node);
|
|
203
|
+
}
|
|
185
204
|
});
|
|
186
205
|
}
|
|
187
206
|
|