Skip to content

de 的 approvalsInbox 三个值用 ASCII 直引号双侧成对,同族兄弟 approveOneTitle 却是正确的 „…“ —— 审批收件箱一屏两种引号 #3919

Description

@yinlianghui

#3876(de 包 20 个值把德语开引号 与 ASCII 直引号配成一对)落地时,全量扫 packages/i18n/src/locales/de.ts 的直引号残余,发现修完那 20 处之后还剩 6 个 U+0022,全在 approvalsInbox 一个命名空间里。

这是另一种缺陷形态,不是 #3876 的错配对:它们双侧都是 ASCII 直引号、自身是"配平"的,所以 #3876 落的持久不变量(每个 之后第一个引号字符必须是 )按设计扫不到它们 —— 这三个值里根本没有

实测(main@2937bcf7d,packages/i18n/src/locales/de.ts)

3180:    approveOneTitle: '„{{title}}“ genehmigen?',     ← 正确的德语引号
3279:    rejectOneTitle: '"{{title}}" ablehnen?',         ← ASCII 双侧
3285:    inlineApproved: '"{{title}}" genehmigt',         ← ASCII 双侧
3286:    inlineRejected: '"{{title}}" abgelehnt',         ← ASCII 双侧

同一个审批收件箱里,批准的确认标题用 „…“驳回的确认标题用 "…",而 inlineApproved / inlineRejected 这对孪生 toast 也是 ASCII。德语用户在同一屏、同一个操作对里看到两种引号排印。

en 侧两个兄弟是对称的(approveOneTitle: 'Approve "{{title}}"?' / rejectOneTitle: 'Reject "{{title}}"?',en 行 3401 / 3500),所以这不是 en 的形状差异带过来的,是 de 侧单侧翻译时的笔误。

#3876 修完后 de 包的计数: 45、 47、 2、" 6 —— 这 6 个就是上面三个值(每值 2 个)。

修法

把这三个值的引号改成 „…“(U+201E … U+201C),与 3180 行的兄弟以及 de 包的多数派(45 处配对)一致。

改完 de 包的 U+0022 应为 0,届时可以把 #3876 的钉子升级成更强的形态(de 包零直引号),那比现在的显式清单更省事。

为什么门禁看不见

#3876 同一族的值域盲区:all-locales-key-parity 比键名与占位符形状、check-i18n-call-site-keys.mjs 只判 key 能否解析、check-i18n-en-drift.mjs 只在 en 值变化时要求九包跟随 —— 这三个值从落地起就是这样,不存在「变化」事件。

已有的钉子会拦住静默漂移

PR #3918(#3876)已在 packages/i18n/src/__tests__/de-quote-pairing-3876.test.ts 里把这 3 个 key 钉成显式清单:

const straight = DE.filter(([, v]) => v.includes(STRAIGHT)).map(([k]) => k);
expect(straight).toEqual([
  'approvalsInbox.rejectOneTitle',
  'approvalsInbox.inlineApproved',
  'approvalsInbox.inlineRejected',
]);

所以数目再漂会红;修本单的人必须回来更新这份清单(或按上面说的直接换成「零直引号」断言)。

关联:#3876(错配对,PR #3918)、#3866(取证方法本身出错的先例)。

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions