docs: §6.5 功能分級/垂懸字落地;標點懸掛停用記錄(ARCHITECTURE/README)

ARCHITECTURE §6.5:功能分級、垂懸字(方案 C,預設開)標為已落地工作良好;標點懸掛標為
實作後停用,記錄四項不可行原因、三重防逃逸、未來原生 hanging-punctuation 路徑(§6.5.6)。
README:功能表加功能分級 level、垂懸字 orphan;標點懸掛列改為「已評估停用」說明;選項示例
與「標點懸掛」一節同步為停用。
This commit is contained in:
2026-06-09 23:26:06 +08:00
parent 04f2b25e4c
commit 89d1008755
2 changed files with 134 additions and 39 deletions
+46 -1
View File
@@ -69,9 +69,12 @@ jz.render(document.querySelector("main"));
| **長英文詞** `longWord` | `[A-Za-z]{6,}` 包入 `<span lang="en">`,配合 CSS `hyphens:auto` 原生斷詞(DOM 無連字符 → 複製不污染)。 |
| **標點擠壓** `jiya` | 標點 charify 為 `jz-char``bd-*` class。三機制:①baseline 政策(全角式不擠/開明式擠句內點號+括號引號/半角式全擠);②行內連續擠壓(相鄰標點**雙側獨立**收——各標點若其有空白之側緊鄰另一標點即收半,故 `,「` 全角式與開明式皆 1em、`。」` 全角式 1.5em/開明式 1em;透明穿越 `strong``em` 等行內邊界);③行端擠壓(`lineedge` layout pass)。半形預設以字型 `halt` 渲染(按字形正確定位,居中字形如 `!?`/繁體 `。,` 不重疊;不依賴 `text-spacing-trim`)。**字型缺 `halt` 時可切 `margin` 後備模式**(見下節)。 |
| **禁則** `jinze` | 行首行末避頭尾:閉類/點號綁前一字(不置行首)、開類綁後一字(不置行末),只隔離邊界字故長引文中段仍可斷。亦為 `justify` 綁定載體。 |
| **垂懸字避免** `orphan` | 段末行 CJK 實義字 ≥ N(預設 2;標點/符號不計)。方案 C(斷行層、無測量):把段末「第 N 個實義字起至段末」包入 `jz-orphan``white-space:nowrap`),整體不可斷 → 末行恒含之 ⇒ 末行實義字 ≥ N,任意寬度/字型成立。單行段無害。**預設開**(`orphan:false` 關,`{chars:n}` 調)。段落級功能。 |
| ~~**標點懸掛** `hanging`~~ | **已評估停用**(§6.5.6):純負 margin 機制不可行(墨色不出版心/滿凸拉升後字重疊/resize 重排錯亂),原生 `hanging-punctuation` 為正解但 Chrome 不支援。`hanging` 選項仍被接受但**無任何效果**;程式碼休眠待原生支援成熟。 |
| **功能分級** `level` | 功能分文本級(中西間隙、標點擠壓——任意文本片段適用)與段落級(禁則、垂懸字、懸掛、長詞——需行/段布局)。塊級元素預設全功能;`data-jz-level="text"` 子樹或選項 `level:{text:"選擇器"}`(如標題/按鈕)僅跑文本級。 |
| **justify 單份間距** | 每個 `jz-char``inline-block` 原子項,句末標點只貢獻一份對齊伸縮量。 |
後續(架構已預留,不返工):標點懸掛、標點修正(簡↔繁)、著重號、注音/Ruby。
後續(架構已預留,不返工):標點修正(簡↔繁)、著重號、注音/Ruby。
---
@@ -92,6 +95,9 @@ createJuzhen({
longWord: { minLength: 6, lang: "en" },
jiya: true, // 或物件:{ halfWidth: "halt" | "margin", bias }
jinze: true,
orphan: true, // 垂懸字避免(預設開);或 { chars: 2 }false 關
// hanging:已停用、無效果(見「標點懸掛」一節)
level: { text: "h1,h2,h3,button,.ui" }, // 此選擇器子樹僅跑文本級功能(見下)
justifyAtoms: true, // jz-char/jz-jinze 以 inline-block 作對齊原子;
// 分頁器(Paged.js)下設 false 改 inline(見下)
blocks: [ // 分塊功能選擇
@@ -119,6 +125,45 @@ createJuzhen({
<div lang="zh-Hans"></div> <!-- lang 驅動全角/開明 -->
```
### 功能分級:文本級 vs 段落級(`level``data-jz-level`
功能分兩級:
- **文本級**(中西間隙 `spacing`、標點擠壓 `jiya`):僅依字符鄰接,**任意文本片段**(單行
標題、按鈕、單一行內元素)皆適用且想要。
- **段落級**(禁則 `jinze`、垂懸字 `orphan`、標點懸掛 `hanging`、長詞 `longWord`):依賴
行/段布局(換行、行端、段末),對單行/非段落文本無意義甚至有害。
塊級元素(`p``div``li``h1`…)**預設段落級(全功能)**。把標題/按鈕/UI 文字標為
**文本級**(要間隙與標點半形、不要懸掛/避孤字/避頭尾):
```html
<h1 data-jz-level="text">標題:只跑中西間隙與標點擠壓</h1>
<p data-jz-level="paragraph"></p> <!-- 顯式全功能(巢狀於 text 子樹內可覆寫,最近祖先勝) -->
```
```ts
createJuzhen({ level: { text: "h1,h2,h3,button,.ui" } }); // 選擇器一鍵標記
```
### 標點懸掛(`hanging`)— 已評估停用
原計劃之標點懸掛(行端標點凸出版心)經 headless + 真實瀏覽器實測**確認不可行、已全面停用**。
`hanging` 選項仍被接受(API 相容)但**無任何效果**——縱使下游以 `hanging:true``data-juzhen`
`blocks` 等任何方式要求,亦不會啟用(行端恒 squeeze;三重防逃逸:`lineEnd` 鎖死、`modeForChar`
降級、`applyEdge` 總開關)。
**為何不可行**(純負 `margin` 機制):
1. 句號等標點墨色偏字框左下角;安全凸出量(&lt; 1 個 CJK 字寬 1em)只把空白半框推出版心、
**墨色仍在版心內**(視覺不懸掛)。
2. 凸出滿 1em 又**釋放一整字寬**、把下一字拉上本行、與懸掛標點**重疊**。
3. `ResizeObserver` 重排時,「自然佈局標記→施加 margin→佈局再變」致標記**錯亂**。
真正的解是原生 CSS `hanging-punctuation`,惟 **Chrome 至今不支援**(僅 Safari 較全),且與本庫
`inline-block` 對齊原子結構衝突。故 hang 之程式碼與 CSS **保留休眠**,俟原生支援成熟再議。
詳見 `ARCHITECTURE.md §6.5.6`
---
## 標點半形:`halt` 預設與 `margin` 後備