Files
mindfulness/spec_kit/Text Wrap/modules/overflow-fallback/plan.md
2026-02-10 11:39:33 +08:00

3.9 KiB
Raw Blame History

overflow-fallback技术计划

1. 计划目标

实现统一的“溢出与兜底”策略模块,用于在以下情况给出确定性且可解释的返回:

  • 搜索器无法在 <=maxLines 覆盖到结束边界 N
  • lineMode=FIXED 需要刚好 maxLines 但无解
  • 测量不可用或失败导致无法执行宽度派约束(尤其 Widget

支持三种模式:

  • ELLIPSIS:最后一行加省略号并保证不超宽(必要时回退移除 token 再加)
  • CLIP:截断到 maxLines(不加省略号)
  • SYSTEM_DEFAULT:算法层不插入换行,交给系统排版(仅在 meta 标记)

2. 对外输入/输出(与 spec 对齐)

2.1 输入

  • tokens: Token[]
  • partialLayout?: { breaks: number[]; lines: Array<{ start; end; text? }> }
    • 若提供:表示搜索器的 best-effort可能未覆盖到 N
  • overflowMode: 'ELLIPSIS' | 'CLIP' | 'SYSTEM_DEFAULT'
  • availableWidth: number
  • maxLines: number
  • lang: 'TC' | 'EN'
  • context: 'APP' | 'WIDGET'
  • ellipsisToken: string(推荐 "…",配置化)
  • measure?: { contextProfile; fontSpec; measureWidthImpl; widgetEnableMeasure? }(用于“加省略号后再测量”)
  • reason: 'NO_CANDIDATE' | 'WIDTH_UNKNOWN' | 'TOO_LONG' | 'WIDOW' | 'PARTICLE' | string

2.2 输出

统一返回:

  • result: { lines: string[]; wrappedText: string; meta: { fallback_type; overflow_type; reason } }

其中:

  • fallback_type: NONE | RELAX_RULES | SYSTEM_DEFAULT
  • overflow_type: NONE | ELLIPSIS | CLIP

3. 核心行为细则(对应文档 12.x

3.1 overflow 判定

在本模块内不重新跑搜索,仅基于输入判断:

  • partialLayout 覆盖到 N(即最后一行 end==N),则 overflow_type=NONE
  • 否则为 overflow按 overflowMode 执行

3.2 SYSTEM_DEFAULT12.4A

  • 返回 lines=[原文单行]wrappedText=原文
  • meta.fallback_type='SYSTEM_DEFAULT'
  • meta.overflow_type='NONE'(因为不再输出算法换行;由 UI 决定是否完全交给系统)
  • meta.reason=输入 reason

3.3 CLIP

  • partialLayout 有 lines取前 maxLines 行,重组 wrappedText=lines.join('\n')
  • 若无:返回单行原文
  • meta.overflow_type='CLIP'fallback_type='NONE'reason=输入 reason

3.4 ELLIPSIS12.3/12.5

仅处理最后一行:

  1. 选取 baseLines
    • 优先使用 partialLayout.lines(若为空则把全文当单行)
    • 截断到 maxLines(只在最后一行做 ellipsis
  2. 清理规则(固定,确定性):
    • 不输出 " …":最后一行末尾空白先 trim
    • 不输出 ",…"/"。…":若最后一行末尾是常见 TC 标点(,。!?;:、),则移除该标点再加 ellipsis
  3. 宽度检查12.3
    • 若提供测量能力且启用:
      • 重新测量 lastLine+ellipsisToken
      • 若超宽:按语言回退单位移除 token 再加省略号并重测
        • EN按整词token
        • TC按 graphemetoken
    • 若测量不可用不做重测直接输出meta.reason 仍保留)

说明:首版不做“避免截断 emotionPhrase 的整段前移/整段省略”,该策略可在后续结合 scoring 决策升级,但必须保持确定性。

4. 代码落位(客户端)

  • client/src/features/textWrap/overflow/
    • types.ts
    • ellipsis.ts
    • fallback.ts入口applyOverflowFallback
    • index.ts
    • __tests__/overflowFallback.test.ts

5. 测试计划Vitest

  • SYSTEM_DEFAULTlines 单行meta.fallback_type=SYSTEM_DEFAULT
  • CLIP超过 maxLines 时截断行数
  • ELLIPSIS
    • 末尾空白去除,不输出 " …"
    • 末尾 TC 标点去除,不输出 ",…"
    • 测量超宽时按 token 回退直到不超宽(用 mock measureWidthImpl

6. 完成定义DoD

  • 三种 overflowMode 行为稳定且可解释
  • ELLIPSIS 的清理与回退测量实现完毕(可测)
  • 输出 meta 字段满足文档 12/14 的治理需求