admin
|
c4e8c6cfd5
|
fix: 行內元素三分類(透明/隔離/整體)——jinze 下潛肢解 KaTeX 修復(下游問題六);v1 相容層移除
下游問題六:行內公式緊鄰禁則標點時,jinze 為綁鄰字透明下潛 .katex(全樹皆 SPAN,
僅憑標籤名判透明),把公式內側末字連同完整殼層逐層克隆切出(splitoff),上標漂移
錯位;pillSelector/skipAttribute/scope.avoid 三層防護全被刺穿。復現另揭兩向量:
相鄰 pill 時 descend 刺穿致 jz-hws 插入公式內部;pill 內部標點被 jiya charify。
確立三分類(§4.1,所有遍歷原語共用同一判定):
透明(styleInlines+jz-*)— 穿越/run 延續/可克隆切分;
隔離(isolateSelector,預設 "mark",新增選項)— 邊界斷 run/斷相鄰/不可切分、
兩端補隙(同 pill),內部照常處理(自成脈絡);
整體(pillSelector)— 內部對一切 pass 不可見(insidePill 過濾),禁則時作為
原子鄰字單位整體綁入 jz-jinze。
機制修復:
finder — transparentInline 改以元素判定(先排除 pill/isolate/avoid 再查標籤集);
avoidsSelf 自身判定(isAvoided 僅查祖先,自身命中 avoid 曾被穿越);descend 三態
(邊界字/無內容續找兄弟/blocked 終止——不可越界跳找更遠之字);eachTextNode
過濾 pill 內部;collectRuns 隔離元素內部自成 run。
core/split — canSplit 諮詢 finder(pill/isolate/avoid 不可切 → 退化整綁);
MARK 移出 SPLITTABLE(背景盒切分有可見接縫)。
jiyaAdjacency — pill/avoid(自身判定)斷相鄰不下探;isolate 斷而內部自成脈絡。
spacing Pass B — 邊界選擇器擴為 pill ∪ isolate;巢於 pill 內者跳過。
orphan — avoidsSelf 邊界;avoid 塊不綁(舊漏判:avoid 子樹內裸文本曾被計數包綁)。
v1 相容層移除(消費端已全數遷移 v2 API):src/compat/v1.ts、IIFE 全域別名
createCjkAutospace、死選項 autospaceClass(經查從未被任何 pass 讀取)一併刪;
I8 退役。dist/compat 殘留聲明清除、dist/core/split.d.ts 補入庫(前次遺漏)。
測試 112 全綠(問題六 ×7、isolate ×6、compat 移除 ×1);headless Chrome 實證
公式完整(splitoff=0、內部無 jz-hws/jz-char)、mark 與公式整體入 jz-jinze。
文檔:README 三分類節+選項示例+功能表(hanging 行補「已移除」);ARCHITECTURE
§4.1 三分類/§3.5 相容層移除/§6.1/§6.3/§6.4/I8 退役。
|
2026-06-12 17:15:24 +08:00 |
|
admin
|
04f2b25e4c
|
feat: lineedge 行端模式(squeeze);標點懸掛實作後全面停用(§6.5.2)
行端 lineedge 升級為可配模式(squeeze|hang|none),抽出共用行端標點偵測;
squeeze(現有行端半形)保留並修正「行歸屬判定」bug:jz-char 為 inline-block,其行盒
top 與相鄰純文本字形 top 因基線差約 5px、遠小於行高卻超舊容差(EPS=4px),致同行誤判
為下一行;改判「垂直區間」(下一行=b.top≥a.bottom、上一行=b.bottom≤a.top,容 2px)。
標點懸掛 hang 模式經 headless + 真實瀏覽器實測**確認不可行、全面停用**(純負 margin):
1. 句號墨色偏框左下,安全凸出量(<1em)只推出空白半框、墨色仍在版心內(視覺不懸掛);
2. 凸出滿 1em 釋放一整字寬、把下一字拉上本行致重疊;
3. 與 inline-block 對齊原子互斥(justifyAtoms:true 下 margin 被 justify 吸收);
4. ResizeObserver 重排時兩階段標記錯亂。
真正的解為原生 hanging-punctuation,惟 Chrome 不支援、且與本庫原子結構衝突。
**三重防逃逸**(下游以任何方式皆無法啟用):① index 鎖 lineEnd:"squeeze"(忽略 hanging
選項);② lineedge.modeForChar 無條件降 squeeze;③ applyEdge 之 HANG_ENABLED=false 總開關。
hang 之 lineedge 程式碼、CSS(jz-hang-*)、LineEndMode 型別保留休眠,俟原生支援再議。
hanging 選項仍被接受(API 相容)但無效果。
單元測試 90 通過,含防逃逸覆蓋(hanging:true/data-juzhen/blocks 各路徑皆不產生 jz-hang-*)。
|
2026-06-09 23:25:47 +08:00 |
|
admin
|
754b00da42
|
feat: 垂懸字避免(方案 C,斷行層無測量,order 70)(§6.5.1)
段末行 CJK 實義字數 ≥ N(預設 2;標點/符號不計)。standalone 段落級 pass:
自段末向前數 N 個實義字,把「第 N 字起至段末」(含其間/尾隨標點)包入
<jz-orphan>(white-space:nowrap)。該整體不可斷 → 末行恒含之 ⇒ 末行實義字 ≥ N,
任意寬度/字型/瀏覽器成立,無需量測 layout。
要點:
- 邊界字定位跨 jz-jinze/行內元素攀爬:實義字落於行內元素內時綁定整個塊級
直接子(不切割 nowrap 群、revert 乾淨);僅裸文本直接子才精確切分(最小綁定)。
- 僅處理葉段落(無塊級後代);段落實義字 < N 不綁;單行段方案 C 本就無害。
- 選項 orphan?: boolean | { chars? };**預設開 chars=2**(§6.5.6 建議);
下游可 orphan:false 關閉。段落級,data-jz-level=text 子樹自動跳過。
- order=70:jinze(40)/spacing(50)/longWord(60) 後、layout pass(90/92) 前。
新增 _orphan.css(jz-orphan{white-space:nowrap});JzTag 加 jz-orphan。
9 項單元測試(末 N+尾標點、chars 選項、標點不計、實義字<N 不綁、跨 jinze、
關閉、冪等、revert、段落級閘)。共 85 測試全綠。
窄容器拖動「末行恒 ≥N」之 layout 驗證留待 demo(Step 4-5,瀏覽器)。
|
2026-06-09 17:00:04 +08:00 |
|
admin
|
c1fbabf5b0
|
feat: 功能分級(文本級 vs 段落級)+ data-jz-level 標記(§6.5.0a)
整體計劃 §6.5 之前置基礎設施。把已實作功能切為兩級:
- 文本級(spacing 中西間隙、jiya 標點擠壓/鄰接):任意文本片段皆適用。
- 段落級(jinze 禁則、longWord 斷詞、lineEdge 行端、gapTrim):需行/段布局。
標記 API:
- 預設塊級元素 → 段落級(全功能)。
- 元素屬性 data-jz-level="text"|"paragraph"(最近祖先勝)。
- 選項 level:{ text: "選擇器" }(如標題/按鈕一鍵降為文本級)。
實作:
- 每個 pass 加 level 元數據;Finder.levelFor/levelAllows(含快取)。
- charify 段落級 pass(longWord)於共享走訪受閘;standalone 段落級 pass
(jinze/lineEdge/gapTrim)逐元素受閘。文本級不受限。
- spacing 補單元素 root 支援:root 為行內/單一非塊元素時亦處理(標題等
之中西間隙、標點半形生效)。
6 項新單元測試(text-level 跳段落級、選擇器標記、巢狀最近勝、單元素 spacing、
預設段落級回歸)。共 76 測試全綠。
|
2026-06-09 16:52:00 +08:00 |
|
admin
|
b821cd1134
|
feat: 字符分類規則集抽象(charClass,可配置;向下兼容)
把散落於各 pass 之硬編碼字符分類(中文 CJK/西文 ANS/全寬標點 BD_* 子類)統一抽象為
規則集 Ruleset:內置默認即現狀值,消費端經 options.charClass 擴充,以覆寫 spacing/
jiya/jinze 對特定字符之分類判定。
動機:英文全角句號 .(U+FF0E,異於中文句號 。U+3002)實證為**完全未分類**——不被
charify、不挤壓、與 CJK 間不補隙。與其每次硬編碼補字符(如先前 € 之西文集),不如給
消費端可配置之分類鉤子。
API(追加語義):
charClass?: {
cjk?: string; // 追加為中文
western?: string; // 追加為西文(半寬標點亦歸此)
biaodian?: { stop?, pause?, open?, close?, middle?, liga? }; // 追加為全寬標點,按子類
}
實作:
- core/unicode.ts:新增 Ruleset/CharClassOverride/BdSubclass 型別、DEFAULT_RULESET、
resolveRuleset(追加合併);classifyBiaodian(ch, biaodian) 改吃規則集(預設參數向下兼容)。
- types.ts:JuzhenOptions.charClass;ResolvedOptions.ruleset;index 再匯出公開型別。
- index.ts:resolveRuleset(opts.charClass) → ResolvedOptions.ruleset。
- typeset/spacing.ts:所有 CJK/ANS 依賴正則移入 makeRules(ruleset),per-instance 編譯
(非每 block);ALNUM/ALPHA/運算符等結構性 ASCII 仍為固定常數。
- typeset/jiya.ts:classifyBiaodian(ch, ruleset.biaodian)。
- typeset/jinze.ts:詞元邊界之 anyCjk 由 ruleset.cjk 建。
向下兼容:不傳 charClass 則 ruleset === DEFAULT_RULESET、行為與重構前完全一致。
v1 為追加語義,不支援重分類/移除內置字符(範圍式集合難挖洞、需求罕見,列後續)。
驗證:實 Chromium end-to-end——charClass.biaodian.stop="." → . charify 為 bd-stop
(开明式句末維持全角,比照 。);western="★"/cjk="〇" → 與對側正確補/不補中西間隙。
測試 66 通過(含 9 條 charClass 新測——默認未分類/各子類 charify/實例隔離不可變
(resolveRuleset 不污染 DEFAULT)/追加不破壞內置/多子類組合;57 既有不變)。
- README「自定義字符分類」節+ARCHITECTURE §4.2 規則集抽象。dist 重建。
|
2026-06-04 16:22:14 +08:00 |
|
admin
|
7b4a051a1f
|
feat: 標點半形 margin 後備模式+下游回饋修復
margin 後備(供缺 OpenType halt 之字型):
- jiya.halfWidth: "halt"(預設)|"margin"。margin 以 width:0.5em+字身依墨色
偏側溢出定位,於 CSS 盒模型重現 halt 之半形 advance(真 0.5em;相鄰標點各
0.5em、合佔 1em,無負 margin 之鄰接疊加/單側重疊)。模式由 data-jz-halfwidth
子樹屬性決定(可逐區塊/逐 lang,含 halt-island 反置)。
- 偏側 inkBias 依字身墨色中心給 left/center/right/full;參考表據方正書宋 GBK
實測,consumer 可經 jiya.bias 逐 lang 逐字覆寫。
- _lang.css 字型堆疊僅作後備(全包 :where 零特異度、只命中帶 lang 屬性之元素、
不直接覆寫 jz-inner)→ 消費端 font-family 恆優先,標點隨之以消費端字型渲染。
- 新增 tools/measure-bias.py(量 glyph ink 中心、產偏側建議表)+ README
「字型適配工作流」。demo/fallback.html:方正書宋 GBK 對照 halt 失效 vs margin。
下游回饋修復:
- 1a:adjacentLogicalChar 透明穿越 jz-jinze(同 jz-hws/樣式行內)→ pill 緊鄰
CJK 標點時,左緣間隙與作者空格剝除復原(jinze 先於 spacing 之交互)。
- 1b:CJK↔CJK 贅餘作者空格(含跨 inline 標籤)剝除、不留隙,與 CJK↔Latin 之
邊界正規化一致(DEL 哨符,全形空格 U+3000 不動)。
- 問題二:新增 justifyAtoms 選項;false → jz-char/jz-jinze 改 display:inline,
相容分頁器(Paged.js)對齊引擎(halt 半形與禁則 nowrap 保留)。
測試 43→49 全通過;dist 重建;README/ARCHITECTURE 同步更新契約。
|
2026-06-02 01:21:52 +08:00 |
|
admin
|
2d42c7ecf2
|
feat: 聚珍切片 1 — 中西間隙/標點擠壓/禁則 + v1 相容層
從零重寫之第一垂直切片(依 ARCHITECTURE.md 契約),涵蓋並超越 v1 全部功能。
核心基座(src/core):unicode 字元表+標點子類+字形側位;locale 語言與
全角/開明政策(全域 lang.style +逐 lang policy);dom(jz-* 工廠+可還原
標記);finder 遍歷引擎(avoid/scope.include/邏輯 run/pill 鄰字/分塊閘);
pass 聚合管線。
功能 pass(src/typeset):
- spacing:中西間隙採 margin 模型——包裹邊界左側字、以 margin-right 留隙,
不注入空白字元(textContent 完全不變、複製緊湊、justify 不暴增、不撐框、
行首乾淨)。含跨樣式邊界、pill、原檔空格移除。
- gapTrim(lineedge):layout pass,行末去隙,修正 justify 右緣內縮。
- longword:長英文詞 <span lang> + hyphens。
- jiya:標點 charify + 全角/開明/半角(全域 + 逐 lang);半形以字型 OpenType
halt 渲染(按字形正確定位、不重疊,居中字形 !? 與繁體 locl 句逗點號皆正確);
行內連續擠壓。
- jinze:行首行末避頭尾(閉類/點號綁前字、開類綁後字,以詞元為邊界、長引文
中段可斷);亦為 justify 綁定載體。
- lineedge:行端擠壓 layout pass(括號引號;ResizeObserver 重算,瀏覽器專用)。
§8 justify:jz-char inline-block 原子,句末標點單份間距。
v1 相容層(compat/v1):createCjkAutospace().apply 映射,IIFE 全域別名。
構建:esbuild → ESM/IIFE/CSS;tsc → d.ts。測試:39 個 jsdom 案例。
demo:簡繁並列+justify+強制繁體開明+標點寬度量測,載 Noto webfont 作參考
(擠壓依賴字型 halt)。間隔號 · 不觸發中西間隙;200% 等詞元不被禁則切斷。
|
2026-06-01 21:31:07 +08:00 |
|