You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
mail-yubao/scripts/patch-strip-subject-block.ts

115 lines
4.3 KiB

/**
* Fix subject-line stripping: optional colon + multi-line subject block
*/
import fs from "fs";
const SUBJECT_LINE_RE =
"/(?:\\u4e3b\\u9898|\\u4e3b\\u65e8|Subject)\\s*[\\uFF1A:]?/i";
const helper = `/** Drop subject / \\u4e3b\\u65e8 block (optional colon, multi-line wrap) */\nfunction stripSubjectLines(text: string): string {\n const lines = text.split(/\\n/);\n const out: string[] = [];\n let inSubject = false;\n for (const line of lines) {\n if (/(?:\\u4e3b\\u9898|\\u4e3b\\u65e8|Subject)\\s*[\\uFF1A:]?/i.test(line)) {\n inSubject = true;\n continue;\n }\n if (inSubject) {\n const t = line.trim();\n if (!t) {\n inSubject = false;\n continue;\n }\n if (\n /^(?:\\u5bc4\\u4ef6\\u4eba|\\u53d1\\u4ef6\\u4eba|\\u6536\\u4ef6\\u4eba|\\u6284\\u9001|\\u65e5\\u671f|\\u53d1\\u9001\\u65f6\\u95f4|From|To|Cc|Date|Sent|Dear|----)/i.test(\n t,\n ) ||\n /^date@/i.test(t) ||\n t === "date" ||\n /^[\\u5728\\\\s]*\\d{4}/.test(t)\n ) {\n inSubject = false;\n out.push(line);\n continue;\n }\n continue;\n }\n out.push(line);\n }\n return out.join("\\n");\n}\n`;
// Simpler: write file with real unicode via \u in the script string that becomes Chinese
const stripFn = `
function stripSubjectLines(text: string): string {
const lines = text.split(/\\n/);
const out: string[] = [];
let inSubject = false;
for (const line of lines) {
// "\\u4e3b\\u9898 Re:..." often has NO colon after \\u4e3b\\u9898
if (/(?:\u4e3b\u9898|\u4e3b\u65e8|Subject)\\s*[\uFF1A:]?/i.test(line)) {
inSubject = true;
continue;
}
if (inSubject) {
const t = line.trim();
if (!t) {
inSubject = false;
continue;
}
if (
/^(?:\u5bc4\u4ef6\u4eba|\u53d1\u4ef6\u4eba|\u6536\u4ef6\u4eba|\u6284\u9001|\u65e5\u671f|\u53d1\u9001\u65f6\u95f4|From|To|Cc|Date|Sent|Dear|----)/i.test(
t,
) ||
/^date@/i.test(t) ||
t === "date" ||
/^\u5728\\s*\\d{4}/.test(t)
) {
inSubject = false;
out.push(line);
continue;
}
continue;
}
out.push(line);
}
return out.join("\\n");
}
`.trimStart();
{
const path = "src/services/parse/instruction-lexicon.ts";
let src = fs.readFileSync(path, "utf8");
const a = src.indexOf("function stripSubjectLines");
const b = src.indexOf("export function isForwardShellSegment");
if (a < 0 || b < 0) throw new Error("markers");
// keep any comment before function - find from /** Drop or function
let start = src.lastIndexOf("/** Drop subject", a);
if (start < 0) start = a;
src =
src.slice(0, start) +
"/** Drop subject/\u4e3b\u65e8 block (optional colon; multi-line wrap) */\n" +
stripFn +
"\n" +
src.slice(b);
fs.writeFileSync(path, src);
console.log("lexicon stripSubjectLines updated");
}
{
const path = "src/services/parse/split-instructions.ts";
let src = fs.readFileSync(path, "utf8");
const neu = `function bodyForKindDetect(segBody: string): string {
// reuse same multi-line subject strip as lexicon (inline copy to avoid circular import)
const lines = segBody.split(/\\n/);
const out: string[] = [];
let inSubject = false;
for (const line of lines) {
if (/(?:\u4e3b\u9898|\u4e3b\u65e8|Subject)\\s*[\uFF1A:]?/i.test(line)) {
inSubject = true;
continue;
}
if (inSubject) {
const t = line.trim();
if (!t) {
inSubject = false;
continue;
}
if (
/^(?:\u5bc4\u4ef6\u4eba|\u53d1\u4ef6\u4eba|\u6536\u4ef6\u4eba|\u6284\u9001|\u65e5\u671f|\u53d1\u9001\u65f6\u95f4|From|To|Cc|Date|Sent|Dear|----)/i.test(
t,
) ||
/^date@/i.test(t) ||
t === "date" ||
/^\\u5728\\s*\\d{4}/.test(t) ||
/^\u5728\\s*\\d{4}/.test(t)
) {
inSubject = false;
out.push(line);
continue;
}
continue;
}
out.push(line);
}
return out.join("\\n");
}
`;
const a = src.indexOf("function bodyForKindDetect");
const b = src.indexOf("export function detectKindsForSegment");
if (a < 0 || b < 0) throw new Error("bounds");
src = src.slice(0, a) + neu + "\n" + src.slice(b);
fs.writeFileSync(path, src);
console.log("split bodyForKindDetect updated");
}