@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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@2kog/pkg-editor",
3
- "version": "0.0.2",
3
+ "version": "0.0.3",
4
4
  "description": "Custom Tinymce、Article Renderer",
5
5
  "scripts": {
6
6
  "serve": "npm run dev",
@@ -4,56 +4,60 @@ import 'katex/dist/katex.min.css';
4
4
 
5
5
  function renderKatexBlock(selector = ".w-latex") {
6
6
  try {
7
- // eslint-disable-next-line no-unused-vars
8
- $(selector).each(function(i, ele) {
9
- let $katex = $(this);
7
+ $(selector).each(function() {
8
+ const $katex = $(this);
10
9
 
11
- // 获取原始HTML内容
12
- let raw = $katex.html();
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
- // 移除其他HTML标签但保留内容
23
- raw = raw.replace(/<[^>]+>/g, '');
24
-
25
- // 解码HTML实体(如 &nbsp; -> 空格)
26
- raw = $('<div>').html(raw).text();
13
+ let raw = $katex.html();
27
14
 
28
- // 清理多余的空白字符
29
- raw = raw.trim();
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
- console.log('Original HTML:', $katex.html());
32
- console.log('Processed LaTeX:', raw);
22
+ // 解码HTML实体
23
+ raw = $('<div>').html(raw).text().trim();
33
24
 
34
- katex.render(raw, $katex.get(0), { displayMode: true });
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
- !node.parentNode.closest("pre") &&
55
- (node.nodeValue.includes("\\(") || node.nodeValue.includes("$"))
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
- console.log('Processing text:', text);
78
+ // 重置正则状态
79
+ inlineRegex.lastIndex = 0;
78
80
 
79
- while ((match = inlineRegex.exec(text))) {
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
- console.log('Found inline match:', fullMatch, 'Raw:', raw);
87
-
88
- // 添加匹配前文本
89
- frag.appendChild(document.createTextNode(text.slice(lastIndex, matchStart)));
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
- // 处理JavaScript字符串中的双反斜杠转义
94
- const processedRaw = raw.replace(/\\\\/g, '\\');
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 = inlineRegex.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 = /(\$\$\s*([\s\S]+?)\s*\$\$|\\\[\s*([\s\S]+?)\s*\\\])/g;
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
- !node.parentNode.closest("pre") &&
135
- (node.nodeValue.includes("$$") || node.nodeValue.includes("\\["))
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
- while ((match = blockRegex.exec(text))) {
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
- frag.appendChild(document.createTextNode(text.slice(lastIndex, matchStart)));
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
- // 处理JavaScript字符串中的双反斜杠转义
168
- const processedRaw = raw.replace(/\\\\/g, '\\');
169
- div.innerHTML = katex.renderToString(processedRaw, { displayMode: true });
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 = blockRegex.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
- node.parentNode.replaceChild(frag, node);
201
+ if (frag.hasChildNodes()) {
202
+ node.parentNode.replaceChild(frag, node);
203
+ }
185
204
  });
186
205
  }
187
206