release: 发布 v0.6.2 DOCX 真实文档修复
新增能力:将 DOCX 发布验收拆分为四套独立 140,支持真实语料冻结、指纹复用、失败与基础设施错误独立统计,并为表格换行、全 JSON 围栏、代码连续性和长文档分页建立通用门禁。 问题修复:冻结 Paged.js 分片前的逻辑表格列轨并传递打印几何,统一 Markdown 表格换行、代码、段落与 OOXML 翻译;改进 PDF 文本流排序、语义块映射、颜色与栅格比较,消除窄字符重叠和跨行范围符号误报。 兼容与部署:版本统一为 0.6.2;正式 Docker 镜像内置固定 Chromium、Pandoc 3.9.0.2 和 Serif/Sans/Mono 字体;Desktop NSIS 与 ZIP 继续直接内置字体,无需系统字体安装。 验证结果:合成基线与长庆严格 280/280,M4N 140/140;健康数据残余误报 6/115(5.22%),均核查为重复表头自动对齐/取样误报且基础设施错误为 0。全项目测试、类型检查、生产构建和 git diff --check 通过;正式 Docker、NSIS、ZIP、离线镜像、部署包、清单及 SHA-256 均已生成并校验。
This commit is contained in:
@@ -40,9 +40,88 @@ describe("PDF 文本行聚合", () => {
|
||||
]);
|
||||
});
|
||||
|
||||
it("合并 Office 同一视觉行内小于字体高度两成的基线漂移", () => {
|
||||
const left = item("源系统", 10, 100, 30, 10);
|
||||
const middle = item("nut_pickup_order.meal_type", 42, 101.8, 140, 10);
|
||||
const right = item("原值", 184, 100, 20, 10);
|
||||
const lines = aggregatePdfTextLines([left, middle, right], 842);
|
||||
|
||||
expect(lines).toHaveLength(1);
|
||||
expect(lines[0]?.normalizedText).toBe(
|
||||
"源系统nut_pickup_order.meal_type原值",
|
||||
);
|
||||
});
|
||||
|
||||
it("将同行公式的上标片段按横坐标并回正文", () => {
|
||||
const lines = aggregatePdfTextLines(
|
||||
[
|
||||
item("减因子", 10, 100, 42, 12),
|
||||
item("e", 53, 97, 8, 15),
|
||||
item("−λΔt", 62, 96, 24, 10),
|
||||
item("的动态权重", 87, 100, 70, 12),
|
||||
],
|
||||
842,
|
||||
);
|
||||
|
||||
expect(lines).toHaveLength(1);
|
||||
expect(lines[0]?.normalizedText).toBe("减因子e−λΔt的动态权重");
|
||||
});
|
||||
|
||||
it("将超出正文右缘但紧邻行末的公式片段并回正文", () => {
|
||||
const lines = aggregatePdfTextLines(
|
||||
[
|
||||
item("性、记忆重要程度、时效性衰减权重(须支持基于时间衰减因子 e", 150, 469.5, 346, 12),
|
||||
item("−λΔt", 495.7, 466.1, 26, 10.2),
|
||||
item("下一视觉行", 150, 489.7, 60, 12),
|
||||
],
|
||||
842,
|
||||
);
|
||||
|
||||
expect(lines.map((line) => line.normalizedText)).toEqual([
|
||||
"性、记忆重要程度、时效性衰减权重(须支持基于时间衰减因子 e−λΔt",
|
||||
"下一视觉行",
|
||||
]);
|
||||
});
|
||||
|
||||
it("将字体 ToUnicode 中的传统户部件归一为简体字符", () => {
|
||||
expect(normalizePdfText("戶⼾")).toBe("户户");
|
||||
expect(normalizePdfText("⻅⻆⻓⻔⻚⻛")).toBe("见角长门页风");
|
||||
expect(normalizePdfText("⻅⻆⻓⻔⻚⻛⻝⻣⻋⻬")).toBe(
|
||||
"见角长门页风食骨车齐",
|
||||
);
|
||||
});
|
||||
|
||||
it("统一 Chromium 与 Office PDF 文本层的中英文弯引号", () => {
|
||||
expect(normalizePdfText("“记录”与‘计算’")).toBe('"记录"与\'计算\'');
|
||||
});
|
||||
|
||||
it("保留与全角括号重叠的窄引号文本流顺序", () => {
|
||||
const lines = aggregatePdfTextLines(
|
||||
[
|
||||
item("主观定性判断", 532.3, 151.5, 58.5),
|
||||
item("”", 590.8, 151.5, 3.4),
|
||||
item("(如", 589.3, 151.5, 19.5),
|
||||
item("“", 608.8, 151.5, 3.4),
|
||||
item("高心率占比", 612.2, 151.5, 48.8),
|
||||
],
|
||||
595,
|
||||
);
|
||||
|
||||
expect(lines).toHaveLength(1);
|
||||
expect(lines[0]?.normalizedText).toBe('主观定性判断"(如"高心率占比');
|
||||
});
|
||||
|
||||
it("忽略 Emoji 文本层可选的变体选择符", () => {
|
||||
expect(normalizePdfText("⚠️ 提示")).toBe("⚠ 提示");
|
||||
});
|
||||
|
||||
it("统一 CJK 字体文本层的 em dash 与 horizontal bar", () => {
|
||||
expect(normalizePdfText("仓库―仓区")).toBe("仓库—仓区");
|
||||
});
|
||||
|
||||
it("统一数字区间中被 Chromium 提取为双连字符的 en dash", () => {
|
||||
expect(normalizePdfText("10% -- 20%")).toBe("10%–20%");
|
||||
expect(normalizePdfText("10% --")).toBe("10%–");
|
||||
expect(normalizePdfText("命令 --flag")).toBe("命令 --flag");
|
||||
});
|
||||
|
||||
it("从可编辑正文契约中移除 Word 自动列表装饰符", () => {
|
||||
|
||||
Reference in New Issue
Block a user