# Text Wrap（大需求总览）

> 本文件只保留高层背景、总览与模块拆分；各子模块可独立实现与验收。
> 详细算法口径以 `设计说明文档/文档换行算法.md`（v1.2.1）为准。

## 1. Overview（背景/目标/非目标）

Home 页面与 iOS 桌面小组件（Widget）都会展示“情绪文案/正念短句”。若依赖系统默认换行，会出现不可控、不可解释、跨端不一致的问题。

本需求要求把“文案换行算法”从 UI 组件中**独立成一个可复用模块**，用于：

- Home 页面文案渲染
- Widget 文案渲染（允许测量能力不同，但规则与决策必须一致）

### 目标

- **确定性**：同输入（含配置版本）必定同输出
- **跨端一致口径**：索引体系、断点定义、关键词命中与 tie-break 规则完全一致
- **可治理**：支持 debug meta、线上打点、Golden Case 回归
- **可复用**：算法作为纯函数核心，UI 仅消费 `lines[]/wrappedText/meta`

### 非目标

- 不做语义理解/情绪识别/机器学习
- 不做通用排版引擎
- 不承诺 Widget 场景做到像 App 一样的像素级测量（Widget 可使用估算/常量）

## 2. 对外接口（统一口径）

模块对外暴露 `wrapText()`（纯函数）：

```ts
wrapText({
  text: string,
  lang: 'TC' | 'EN',
  availableWidth: number,
  maxLines: number,
  context: 'APP' | 'WIDGET',
  fontSpec?: { fontSize: number; fontWeight?: string; fontFamily?: string },
  overflowMode?: 'ELLIPSIS' | 'CLIP' | 'SYSTEM_DEFAULT',
  lineMode?: 'AUTO' | 'FIXED',
  constraints?: {
    protectedPhrases?: string[];
    forbiddenBreakRanges?: Array<{ start: number; end: number }>;
  },
  configVersion?: string,
  debug?: boolean
}) => {
  lines: string[];
  wrappedText: string;
  meta?: {
    configVersion?: string;
    fallback_type?: 'NONE' | 'RELAX_RULES' | 'SYSTEM_DEFAULT';
    overflow_type?: 'NONE' | 'ELLIPSIS' | 'CLIP';
    reason?: 'NO_CANDIDATE' | 'WIDTH_UNKNOWN' | 'WIDOW' | 'PARTICLE' | 'TOO_LONG';
    breaks?: number[];
    scoreTopTerms?: Array<{ key: string; delta: number; detail?: any }>;
  }
}
```

## 3. 模块拆分（modules）与依赖关系

### 3.1 `modules/` 目录结构

```text
spec_kit/Text Wrap/
├ spec.md
└ modules/
   ├ core-contract/spec.md
   ├ grapheme-segmentation/spec.md
   ├ width-measurement/spec.md
   ├ breakpoint-candidates/spec.md
   ├ scoring-tiebreak/spec.md
   ├ search-engine-app/spec.md
   ├ search-engine-widget/spec.md
   ├ overflow-fallback/spec.md
   ├ golden-tests/spec.md
   └ integration/spec.md
```

### 3.2 模块职责概览

- **`core-contract`**：EN/TC token 索引体系、文本重组、EN 关键词命中“全词等值”、配置/版本化与确定性比较口径 ✅
- **`grapheme-segmentation`**：TC 字符簇分割的推荐实现与无库兜底 + 回归样例 ✅
- **`width-measurement`**：测量接口、缓存、宽度不可用降级（approx mode）与打点  ✅
- **`breakpoint-candidates`**：候选断点生成（PUNCT/SPACE/BALANCE）、去重排序、约束过滤与规模上限 ✅
- **`scoring-tiebreak`**：评分项顺序、可解释 breakdown、tieKey/tie-break 规则与整数分/EPS ✅
- **`search-engine-app`**：APP 场景 DP + TopK 的确定性实现
- **`search-engine-widget`**：WIDGET 场景 Beam Search 的确定性实现
- **`overflow-fallback`**：ELLIPSIS/CLIP/SYSTEM_DEFAULT 语义、ellipsis 细则与兜底链路
- **`golden-tests`**：Golden Cases 与性质测试（确定性、近似单调性、maxLines 不变差）
- **`integration`**：Home/Widget 接入约定（参数映射、渲染策略、fallback 语义对齐）

## 4. 实现顺序（推荐）

> 目标是“先锁口径，再做搜索与评分，再做溢出与回归”，避免后期重构。

1. `core-contract`
2. `grapheme-segmentation`
3. `width-measurement`
4. `breakpoint-candidates`
5. `scoring-tiebreak`
6. `search-engine-app`
7. `search-engine-widget`
8. `overflow-fallback`
9. `golden-tests`
10. `integration`

