| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103 |
- /**
- * 验证「markdown → 纯文本」(回答的复制按钮用的那份实现)。
- *
- * 用户 2026-09-22 反馈:复制出来的内容还带着 `###`、`**`、`[文字](链接)` 这些语法符号。
- *
- * 怎么跑(先打包):
- * npx esbuild harness/tools/_entry-plain-text.ts --bundle --format=esm \
- * --outfile=harness/tools/_plain-text.mjs --alias:@=./src --define:import.meta.env='{}'
- * node harness/tools/verify-markdown-plain-text.mjs
- */
- import { readFileSync } from 'node:fs';
- const { markdownToPlainText } = await import('./_plain-text.mjs');
- let pass = 0;
- let fail = 0;
- const check = (name, ok, extra = '') => {
- if (ok) {
- pass++;
- console.log(' ok ' + name);
- } else {
- fail++;
- console.log(' FAIL ' + name + ' ' + extra);
- }
- };
- /** markdown 语法符号:这些出现在复制结果里就是没剥干净 */
- const MD_SYNTAX = [/^#{1,6}\s/m, /\*\*[^*]+\*\*/, /\[[^\]]+\]\([^)]+\)/, /^\s*[-*+]\s/m, /`[^`]+`/];
- const hasMdSyntax = (text) => MD_SYNTAX.find((re) => re.test(text));
- console.log('\n【1】用户实际复制到的那份内容的形态');
- {
- const md = `### 一、市级通用查询与申兑
- **办理渠道**
- - “随申兑”惠企政策平台:https://zwdt.sh.gov.cn/qykj
- - “上海企业登记在线”的“中小企业公共资助项目”栏目
- **办理流程**
- 1. 登录上述平台,按行业、规模等条件匹配可申报项目。
- 2. 按项目要求在线提交申请。
- ### 四、ESG惠利贷(江苏银行上海青浦支行)
- - 额度与期限:0-10000万元,6-12个月。
- [查看产品详情](https://csjsfqeqr.yddeltazwh.org.cn/financeProduct_detail?id=317)`;
- const text = markdownToPlainText(md);
- if (process.env.DBG) console.log(JSON.stringify(text));
- check('不含任何 markdown 语法符号', !hasMdSyntax(text), JSON.stringify(text).slice(0, 160));
- check('标题只留文字(去掉 ###)', text.includes('一、市级通用查询与申兑') && !text.includes('###'));
- check('加粗只留文字(去掉 **)', text.includes('办理渠道') && !text.includes('**'));
- check('无序列表去掉 `- `,各项各占一行', text.includes('\n“随申兑”惠企政策平台:https://zwdt.sh.gov.cn/qykj\n'), JSON.stringify(text.slice(0, 120)));
- check('**有序列表保留序号**(顺序是内容,不是装饰)', text.includes('1. 登录上述平台') && text.includes('2. 按项目要求在线提交申请'));
- check(
- '链接写成「文字(地址)」——**地址不能丢**',
- text.includes('查看产品详情(https://csjsfqeqr.yddeltazwh.org.cn/financeProduct_detail?id=317)'),
- JSON.stringify(text.slice(-120))
- );
- check('纯文字链接保持原样', text.includes('“随申兑”惠企政策平台:https://zwdt.sh.gov.cn/qykj'));
- check('段落之间空一行', text.includes('一、市级通用查询与申兑\n\n办理渠道'));
- }
- console.log('\n【2】边界');
- {
- check('空串 → 空串', markdownToPlainText('') === '' && markdownToPlainText(' ') === '');
- check('纯文本原样返回', markdownToPlainText('就是一句话。') === '就是一句话。');
- check('行内代码去掉反引号', markdownToPlainText('用 `npm run dev` 启动') === '用 npm run dev 启动');
- check('斜体去掉星号', markdownToPlainText('这是 *重点* 内容') === '这是 重点 内容');
- check('引用去掉 > 符号', markdownToPlainText('> 引用一句') === '引用一句');
- check('分隔线不留下垃圾', markdownToPlainText('甲\n\n---\n\n乙') === '甲\n\n乙', JSON.stringify(markdownToPlainText('甲\n\n---\n\n乙')));
- check('data URL 图片不复制出去', !markdownToPlainText('看图 ').includes('base64'));
- check('链接文字与地址相同时不重复', markdownToPlainText('[https://a.cn](https://a.cn)') === 'https://a.cn');
- check('多余空行被收敛', markdownToPlainText('甲\n\n\n\n乙') === '甲\n\n乙');
- }
- console.log('\n【3】拿真实回答跑一遍(DMS 里存的那一份)');
- {
- // 真实内容:前面几轮从 DMS 读回来过的那类长回答(含标题/加粗/列表/链接)
- const file = 'harness/tools/_real-answer.txt';
- let md = '';
- try {
- md = readFileSync(file, 'utf8');
- } catch {
- /* 没有就跳过 */
- }
- if (!md.trim()) {
- console.log(` ⏭ 没有 ${file}(把 DMS 里的 c_answer 落盘到这里即可跑这条)`);
- } else {
- const text = markdownToPlainText(md);
- const hit = hasMdSyntax(text);
- check('真实回答里没有残留的 md 语法符号', !hit, hit ? String(hit) : '');
- check('真实回答的文字没被吃掉(长度接近)', text.length > md.length * 0.5, `${md.length} → ${text.length}`);
- }
- }
- console.log(`\n===== 通过 ${pass} 项,失败 ${fail} 项 =====`);
- process.exit(fail ? 1 : 0);
|