@tencent-weixin/openclaw-weixin 2.1.4 → 2.1.5
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/openclaw.plugin.json +1 -1
- package/package.json +1 -1
- package/src/messaging/markdown-filter.ts +62 -92
package/openclaw.plugin.json
CHANGED
package/package.json
CHANGED
|
@@ -6,9 +6,22 @@
|
|
|
6
6
|
* holding back the minimum characters needed for pattern disambiguation
|
|
7
7
|
* (e.g. a trailing `*` that might become `***`).
|
|
8
8
|
*
|
|
9
|
+
* Constructs passed through (not filtered):
|
|
10
|
+
* - Code fences (```)
|
|
11
|
+
* - Inline code (`)
|
|
12
|
+
* - Tables (|...|)
|
|
13
|
+
* - Horizontal rules (---, ***, ___)
|
|
14
|
+
* - Bold (**)
|
|
15
|
+
* - Italic/bold-italic wrapping non-CJK content
|
|
16
|
+
*
|
|
17
|
+
* Constructs filtered (markers stripped, content kept):
|
|
18
|
+
* - Italic/bold-italic wrapping CJK content
|
|
19
|
+
* - Headings H5/H6 (#####, ######)
|
|
20
|
+
* - Images () — removed entirely
|
|
21
|
+
*
|
|
9
22
|
* States:
|
|
10
23
|
* - **sol** (start-of-line): checks for line-start patterns (```, >, #####, indent)
|
|
11
|
-
* - **body**: scans for inline patterns (
|
|
24
|
+
* - **body**: scans for inline patterns (![, ~~, ***) and outputs safe chars
|
|
12
25
|
* - **fence**: inside a fenced code block, passes through until closing ```
|
|
13
26
|
* - **inline**: accumulating content inside an inline marker pair
|
|
14
27
|
*/
|
|
@@ -16,7 +29,7 @@ export class StreamingMarkdownFilter {
|
|
|
16
29
|
private buf = "";
|
|
17
30
|
private fence = false;
|
|
18
31
|
private sol = true;
|
|
19
|
-
private inl: { type: "
|
|
32
|
+
private inl: { type: "image" | "bold3" | "italic" | "ubold3" | "uitalic"; acc: string } | null = null;
|
|
20
33
|
|
|
21
34
|
feed(delta: string): string {
|
|
22
35
|
this.buf += delta;
|
|
@@ -45,26 +58,32 @@ export class StreamingMarkdownFilter {
|
|
|
45
58
|
}
|
|
46
59
|
|
|
47
60
|
if (eof && this.inl) {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
} else {
|
|
51
|
-
const markers: Record<string, string> = { code: "`", image: "![", strike: "~~", bold3: "***", italic: "*", ubold3: "___", uitalic: "_" };
|
|
52
|
-
out += (markers[this.inl.type] ?? "") + this.inl.acc;
|
|
53
|
-
}
|
|
61
|
+
const markers: Record<string, string> = { image: "![", bold3: "***", italic: "*", ubold3: "___", uitalic: "_" };
|
|
62
|
+
out += (markers[this.inl.type] ?? "") + this.inl.acc;
|
|
54
63
|
this.inl = null;
|
|
55
64
|
}
|
|
56
65
|
return out;
|
|
57
66
|
}
|
|
58
67
|
|
|
59
|
-
/** Inside a code fence: pass content
|
|
68
|
+
/** Inside a code fence: pass content and markers through verbatim. */
|
|
60
69
|
private pumpFence(eof: boolean): string {
|
|
61
70
|
if (this.sol) {
|
|
62
71
|
if (this.buf.length < 3 && !eof) return "";
|
|
63
72
|
if (this.buf.startsWith("```")) {
|
|
64
|
-
this.fence = false;
|
|
65
73
|
const nl = this.buf.indexOf("\n", 3);
|
|
66
|
-
|
|
67
|
-
|
|
74
|
+
if (nl !== -1) {
|
|
75
|
+
this.fence = false;
|
|
76
|
+
const line = this.buf.slice(0, nl + 1);
|
|
77
|
+
this.buf = this.buf.slice(nl + 1);
|
|
78
|
+
this.sol = true;
|
|
79
|
+
return line;
|
|
80
|
+
}
|
|
81
|
+
if (eof) {
|
|
82
|
+
this.fence = false;
|
|
83
|
+
const line = this.buf;
|
|
84
|
+
this.buf = "";
|
|
85
|
+
return line;
|
|
86
|
+
}
|
|
68
87
|
return "";
|
|
69
88
|
}
|
|
70
89
|
this.sol = false;
|
|
@@ -93,10 +112,18 @@ export class StreamingMarkdownFilter {
|
|
|
93
112
|
if (b[0] === "`") {
|
|
94
113
|
if (b.length < 3 && !eof) return "";
|
|
95
114
|
if (b.startsWith("```")) {
|
|
96
|
-
this.fence = true;
|
|
97
115
|
const nl = b.indexOf("\n", 3);
|
|
98
|
-
|
|
99
|
-
|
|
116
|
+
if (nl !== -1) {
|
|
117
|
+
this.fence = true;
|
|
118
|
+
const line = b.slice(0, nl + 1);
|
|
119
|
+
this.buf = b.slice(nl + 1);
|
|
120
|
+
this.sol = true;
|
|
121
|
+
return line;
|
|
122
|
+
}
|
|
123
|
+
if (eof) {
|
|
124
|
+
this.buf = "";
|
|
125
|
+
return b;
|
|
126
|
+
}
|
|
100
127
|
return "";
|
|
101
128
|
}
|
|
102
129
|
this.sol = false;
|
|
@@ -104,8 +131,6 @@ export class StreamingMarkdownFilter {
|
|
|
104
131
|
}
|
|
105
132
|
|
|
106
133
|
if (b[0] === ">") {
|
|
107
|
-
if (b.length < 2 && !eof) return "";
|
|
108
|
-
this.buf = b.length >= 2 && b[1] === " " ? b.slice(2) : b.slice(1);
|
|
109
134
|
this.sol = false;
|
|
110
135
|
return "";
|
|
111
136
|
}
|
|
@@ -123,13 +148,6 @@ export class StreamingMarkdownFilter {
|
|
|
123
148
|
return "";
|
|
124
149
|
}
|
|
125
150
|
|
|
126
|
-
if (b[0] === "|") {
|
|
127
|
-
this.buf = b.slice(1);
|
|
128
|
-
this.inl = { type: "table", acc: "" };
|
|
129
|
-
this.sol = false;
|
|
130
|
-
return "";
|
|
131
|
-
}
|
|
132
|
-
|
|
133
151
|
if (b[0] === " " || b[0] === "\t") {
|
|
134
152
|
if (b.search(/[^ \t]/) === -1 && !eof) return "";
|
|
135
153
|
this.sol = false;
|
|
@@ -145,9 +163,13 @@ export class StreamingMarkdownFilter {
|
|
|
145
163
|
let count = 0;
|
|
146
164
|
for (let k = 0; k < j; k++) if (b[k] === ch) count++;
|
|
147
165
|
if (count >= 3) {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
166
|
+
if (j < b.length) {
|
|
167
|
+
this.buf = b.slice(j + 1);
|
|
168
|
+
this.sol = true;
|
|
169
|
+
return b.slice(0, j + 1);
|
|
170
|
+
}
|
|
171
|
+
this.buf = "";
|
|
172
|
+
return b;
|
|
151
173
|
}
|
|
152
174
|
}
|
|
153
175
|
this.sol = false;
|
|
@@ -170,23 +192,15 @@ export class StreamingMarkdownFilter {
|
|
|
170
192
|
this.sol = true;
|
|
171
193
|
return out;
|
|
172
194
|
}
|
|
173
|
-
if (c === "`") {
|
|
174
|
-
out += this.buf.slice(0, i);
|
|
175
|
-
this.buf = this.buf.slice(i + 1);
|
|
176
|
-
this.inl = { type: "code", acc: "" };
|
|
177
|
-
return out;
|
|
178
|
-
}
|
|
179
195
|
if (c === "!" && i + 1 < this.buf.length && this.buf[i + 1] === "[") {
|
|
180
196
|
out += this.buf.slice(0, i);
|
|
181
197
|
this.buf = this.buf.slice(i + 2);
|
|
182
198
|
this.inl = { type: "image", acc: "" };
|
|
183
199
|
return out;
|
|
184
200
|
}
|
|
185
|
-
if (c === "~"
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
this.inl = { type: "strike", acc: "" };
|
|
189
|
-
return out;
|
|
201
|
+
if (c === "~") {
|
|
202
|
+
i++;
|
|
203
|
+
continue;
|
|
190
204
|
}
|
|
191
205
|
if (c === "*") {
|
|
192
206
|
if (i + 2 < this.buf.length && this.buf[i + 1] === "*" && this.buf[i + 2] === "*") {
|
|
@@ -237,7 +251,6 @@ export class StreamingMarkdownFilter {
|
|
|
237
251
|
else if (this.buf.endsWith("__")) hold = 2;
|
|
238
252
|
else if (this.buf.endsWith("*")) hold = 1;
|
|
239
253
|
else if (this.buf.endsWith("_")) hold = 1;
|
|
240
|
-
else if (this.buf.endsWith("~")) hold = 1;
|
|
241
254
|
else if (this.buf.endsWith("!")) hold = 1;
|
|
242
255
|
}
|
|
243
256
|
out += this.buf.slice(0, this.buf.length - hold);
|
|
@@ -252,41 +265,14 @@ export class StreamingMarkdownFilter {
|
|
|
252
265
|
this.buf = "";
|
|
253
266
|
|
|
254
267
|
switch (this.inl.type) {
|
|
255
|
-
case "code": {
|
|
256
|
-
const idx = this.inl.acc.indexOf("`");
|
|
257
|
-
if (idx !== -1) {
|
|
258
|
-
const content = this.inl.acc.slice(0, idx);
|
|
259
|
-
this.buf = this.inl.acc.slice(idx + 1);
|
|
260
|
-
this.inl = null;
|
|
261
|
-
return content;
|
|
262
|
-
}
|
|
263
|
-
const nl = this.inl.acc.indexOf("\n");
|
|
264
|
-
if (nl !== -1) {
|
|
265
|
-
const r = "`" + this.inl.acc.slice(0, nl + 1);
|
|
266
|
-
this.buf = this.inl.acc.slice(nl + 1);
|
|
267
|
-
this.inl = null;
|
|
268
|
-
this.sol = true;
|
|
269
|
-
return r;
|
|
270
|
-
}
|
|
271
|
-
return "";
|
|
272
|
-
}
|
|
273
|
-
case "strike": {
|
|
274
|
-
const idx = this.inl.acc.indexOf("~~");
|
|
275
|
-
if (idx !== -1) {
|
|
276
|
-
const content = this.inl.acc.slice(0, idx);
|
|
277
|
-
this.buf = this.inl.acc.slice(idx + 2);
|
|
278
|
-
this.inl = null;
|
|
279
|
-
return content;
|
|
280
|
-
}
|
|
281
|
-
return "";
|
|
282
|
-
}
|
|
283
268
|
case "bold3": {
|
|
284
269
|
const idx = this.inl.acc.indexOf("***");
|
|
285
270
|
if (idx !== -1) {
|
|
286
271
|
const content = this.inl.acc.slice(0, idx);
|
|
287
272
|
this.buf = this.inl.acc.slice(idx + 3);
|
|
288
273
|
this.inl = null;
|
|
289
|
-
return content;
|
|
274
|
+
if (StreamingMarkdownFilter.containsCJK(content)) return content;
|
|
275
|
+
return `***${content}***`;
|
|
290
276
|
}
|
|
291
277
|
return "";
|
|
292
278
|
}
|
|
@@ -296,7 +282,8 @@ export class StreamingMarkdownFilter {
|
|
|
296
282
|
const content = this.inl.acc.slice(0, idx);
|
|
297
283
|
this.buf = this.inl.acc.slice(idx + 3);
|
|
298
284
|
this.inl = null;
|
|
299
|
-
return content;
|
|
285
|
+
if (StreamingMarkdownFilter.containsCJK(content)) return content;
|
|
286
|
+
return `___${content}___`;
|
|
300
287
|
}
|
|
301
288
|
return "";
|
|
302
289
|
}
|
|
@@ -317,7 +304,8 @@ export class StreamingMarkdownFilter {
|
|
|
317
304
|
const content = this.inl.acc.slice(0, j);
|
|
318
305
|
this.buf = this.inl.acc.slice(j + 1);
|
|
319
306
|
this.inl = null;
|
|
320
|
-
return content;
|
|
307
|
+
if (StreamingMarkdownFilter.containsCJK(content)) return content;
|
|
308
|
+
return `*${content}*`;
|
|
321
309
|
}
|
|
322
310
|
}
|
|
323
311
|
return "";
|
|
@@ -339,7 +327,8 @@ export class StreamingMarkdownFilter {
|
|
|
339
327
|
const content = this.inl.acc.slice(0, j);
|
|
340
328
|
this.buf = this.inl.acc.slice(j + 1);
|
|
341
329
|
this.inl = null;
|
|
342
|
-
return content;
|
|
330
|
+
if (StreamingMarkdownFilter.containsCJK(content)) return content;
|
|
331
|
+
return `_${content}_`;
|
|
343
332
|
}
|
|
344
333
|
}
|
|
345
334
|
return "";
|
|
@@ -362,30 +351,11 @@ export class StreamingMarkdownFilter {
|
|
|
362
351
|
}
|
|
363
352
|
return "";
|
|
364
353
|
}
|
|
365
|
-
case "table": {
|
|
366
|
-
const nl = this.inl.acc.indexOf("\n");
|
|
367
|
-
if (nl !== -1) {
|
|
368
|
-
const line = this.inl.acc.slice(0, nl);
|
|
369
|
-
this.buf = this.inl.acc.slice(nl + 1);
|
|
370
|
-
this.inl = null;
|
|
371
|
-
this.sol = true;
|
|
372
|
-
const row = StreamingMarkdownFilter.extractTableRow(line);
|
|
373
|
-
return row ? row + "\n" : "";
|
|
374
|
-
}
|
|
375
|
-
return "";
|
|
376
|
-
}
|
|
377
354
|
}
|
|
378
355
|
return "";
|
|
379
356
|
}
|
|
380
357
|
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
if (/^[\s|:\-]+$/.test(line) && line.includes("-")) return "";
|
|
384
|
-
const parts = line.split("|").map(c => c.trim());
|
|
385
|
-
const cells = parts.slice(
|
|
386
|
-
parts[0] === "" ? 1 : 0,
|
|
387
|
-
parts[parts.length - 1] === "" ? parts.length - 1 : parts.length,
|
|
388
|
-
);
|
|
389
|
-
return cells.join("\t");
|
|
358
|
+
private static containsCJK(text: string): boolean {
|
|
359
|
+
return /[\u2E80-\u9FFF\uAC00-\uD7AF\uF900-\uFAFF]/.test(text);
|
|
390
360
|
}
|
|
391
361
|
}
|