From 3e57c2c2cf9167a47f744f233baed8210365050d Mon Sep 17 00:00:00 2001 From: commilitia Date: Tue, 7 Jul 2026 21:16:05 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20README=EF=BC=8FARCHITECTURE=20=E5=90=8C?= =?UTF-8?q?=E6=AD=A5=E9=9A=8E=E6=AE=B5=E4=B8=80=EF=BC=8F=E4=BA=8C=E2=80=94?= =?UTF-8?q?=E2=80=94=E8=A8=AD=E7=BD=AE=E9=80=9F=E6=9F=A5=E8=A1=A8=EF=BC=8B?= =?UTF-8?q?=E4=B8=89=E5=88=86=E9=A1=9E=E5=88=86=E5=B1=A4=EF=BC=8Bavoid=20?= =?UTF-8?q?=E4=B8=83=E6=BA=90=EF=BC=8B=E4=BF=AE=E6=AD=A3=E9=81=8E=E6=99=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit goal 2 文檔重整(main 部分)。反映階段一/二之行為與契約變更,並修審計發現之過時內容。 README: ・新增「全部選項速查」表——突出被埋沒之強力設置(lang.style/styleInlines/blockTags/ skipTags 之標籤名陣列、skipAttribute/isSkipped 函數鉤子)+ HTML 屬性一覽;標明「標籤名 陣列」與「CSS 選擇器」兩機制之別。 ・選項示例補 lang.style;三分類「共用同一判定」改分層表述(邏輯流共用 isTransparent、未知 行內=嚴格白名單邊界、canSplit/lineedge 為獨立層);avoid 要點改七源+isAvoided 組合入口+ skipTags 不含 CODE/KBD 之三分類互斥說明。 ARCHITECTURE: ・§3.1 scope.avoid 過時示例修正(無默認、與內建 skipTags 並存,非「追加於內建 avoid」)。 ・§4.1 avoid 內建名單去 code/kbd、改七源表述;「共用同一判定」改分層(isTransparent 為邏輯流 單一真相源+嚴格白名單;canSplit/lineedge 兩層正當不同、不硬併,含 lineedge 須跨 isolate 之 物理測量理由);transparentInline→isTransparent、avoidsSelf/isAvoided 組合入口。 ・§4.2 標點六子類修正(bd-stop/pause/open/close/middle/liga——舊列 bd-cop/bd-sep/quote 與實作不符)。 --- ARCHITECTURE.md | 71 +++++++++++++++++++++++++------------------ README.md | 81 +++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 116 insertions(+), 36 deletions(-) diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index a732f37..5e70b32 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -86,7 +86,7 @@ jz.revert(root?); // 還原 root: document.body, // 預設處理根;render(root) 可逐次覆寫 include: null, // 啟用選擇器;設則僅處理命中子樹(opt-in) // 如 ".juzhen, [data-juzhen]" - avoid: "code, kbd, pre, samp, textarea, [contenteditable]", // 追加於內建 avoid + avoid: null, // 追加排除子樹之選擇器(預設 null,與內建 skipTags 名單並存;見 §4.1) }, // 全域逐功能開關(true/false 或細部物件),預設見各 pass @@ -219,8 +219,10 @@ Nvim peek/Claude 模板等 v1 消費端之過渡期。**最後一批 v1 消費 職責(所有 pass 的共同地基): - **遍歷**:`TreeWalker(SHOW_TEXT)` 走 `root` 下文本節點。 -- **avoid**:跳過 avoid 名單之子樹(內建:`code/kbd/pre/samp/textarea/script/ - style/SVG/[contenteditable]/[data-jz-skip]`,可由 `scope.avoid` 追加)。 +- **avoid**:avoid 之**七源**(`isSkipped`/`skipTags` 名單/SVG/`contentEditable`/ + `data-jz-skip`/`skipAttribute`/`scope.avoid`)任一命中即跳過其子樹。內建 `skipTags`: + `pre/samp/tt/var/script/style/textarea/input`(**不含 code/kbd**——二者由 `pillSelector` + 以 pill 涵蓋,三分類互斥)。自身判定用 `avoidsSelf`、自身或祖先之組合用 `isAvoided`。 - **scope.include**:若設啟用選擇器,僅走訪命中之子樹(opt-in,§3.6)。 - **featureEnabledFor(node, name)**:解析該節點之有效功能集(§3.6),供各 pass 之 `collect` per-node 閘用;結果以元素為鍵快取。 @@ -234,9 +236,11 @@ Nvim peek/Claude 模板等 v1 消費端之過渡期。**最後一批 v1 消費 設計要點:finder 不知道任何具體排版規則;它只提供「在何處、跨何種邊界、對哪些 字元」的遍歷與安全變更原語。規則由各 pass 以 unicode 表 + 回呼注入。 -**行內元素三分類(下游問題六後確立)**:行內元素對排版有且僅有三種口徑,所有遍歷 -原語(`collectRuns`/`adjacentLogicalChar`/`eachTextNode`、`jiyaAdjacency` 之相鄰 -掃描、`core/split` 之可切判定、orphan 之實義字收集)共用同一判定: +**行內元素三分類(下游問題六後確立)**:行內元素對排版有且僅有三種口徑。**邏輯文本流**之 +遍歷原語(`collectRuns`/`adjacentLogicalChar`、`jiyaAdjacency` 之相鄰掃描、orphan 之實義字 +收集)共用單一判定 `isTransparent`。**未在 `styleInlines` 之未知行內標籤採嚴格白名單、一律 +當隔離式邊界**(斷 run/相鄰、內部自成脈絡),透明須顯式登記 `styleInlines`(另兩層見下)。 +三口徑: - **透明**(`styleInlines` + wrap 類 `jz-*`)——穿越、run 延續、禁則可克隆切分。 - **隔離**(`isolateSelector`,預設 `mark`)——邊界斷 run/斷相鄰/不可切分、兩端 @@ -246,25 +250,33 @@ Nvim peek/Claude 模板等 v1 消費端之過渡期。**最後一批 v1 消費 過濾 `insidePill`,不 charify/不插間隙/不切分/不下潛),禁則時作為原子鄰字 單位**整體綁入** `jz-jinze`。典型:`code`/`kbd`、行內公式 `.katex`。 -判定**以元素為準、非標籤名**(`transparentInline(el)`,先排除 pill/isolate/ -avoid 再查標籤集):KaTeX 全樹皆 ``,舊版按標籤名判透明曾令 `canSplit`/ -`descend` 整棵下潛——禁則把公式內側末字連同完整殼層逐層克隆切出(`splitoff`), -上標漂移錯位(下游問題六);`pillSelector`/`skipAttribute`/`scope.avoid` 三層 -防護全被刺穿。同根修復:**avoid 以自身判定**(`avoidsSelf(el)`——`isAvoided` 僅查 -祖先鏈,元素自身命中 avoid 時曾被穿越);`adjacentLogicalChar` 之 `descend` 改三態 +判定**以元素為準、非標籤名**(`isTransparent(el)`,先排除 pill/isolate/avoid +再查標籤集):KaTeX 全樹皆 ``,舊版按標籤名判透明曾令 `canSplit`/`descend` +整棵下潛——禁則把公式內側末字連同完整殼層逐層克隆切出(`splitoff`),上標漂移錯位 +(下游問題六);`pillSelector`/`skipAttribute`/`scope.avoid` 三層防護全被刺穿。 +同根修復:**avoid 自身判定** `avoidsSelf(el)` 供遍歷原語逐元素下探自判;一次性「是否 +avoid」用組合入口 `isAvoided`(=自身或祖先,階段二歸一,免「avoidsSelf ‖ isAvoided」 +漏一半致自身命中 avoid 時仍被穿越)。`adjacentLogicalChar` 之 `descend` 改三態 (邊界字/無內容續找兄弟/**blocked** 終止——遇 pill/isolate/avoid 不可跳過續找 更遠之字,否則重蹈「越過 `jz-char` 取更前字 → 誤隙」之同型錯誤);`core/split` 之 `canSplit` 諮詢 finder(pill/isolate/avoid 一律不可切、退化整綁)。 -**「行內透明」原則之一致性(下游 Bug 修復)**:「邏輯文本應透明穿越之行內元素」一語 -須在所有遍歷原語中**口徑一致**,否則同一段文本在不同原語下被切成不同邏輯串、生成相 -互矛盾之結果。`transparentInline` 為單一真相源,列入:樣式行內標籤、`jz-hws`/ -`jz-jinze`(wrap 群組)、**`jz-char`/`jz-inner`(標點原子)**。後者必須透明,否則 -`adjacentLogicalChar` 之 `descend` 遇標點原子既不進入亦不終止、而是**跳過**它續找更前 -之兄弟——`漢字。` 經禁則綁定後,pill 之左鄰字應為「。」(標點,非 pill 鄰字、不 -補間隙),舊邏輯卻越過 `jz-char` 取到「字」誤補 `jz-hws`。修復後與 `collectRuns` 之既 -有透明遞迴對齊。同理 `lineedge` 之 `edgeRect` 攀爬集由 `options.finder.styleInlines` -**派生**(非硬編碼子集),免遺漏 `ins`/`del`/`sub` 等致行端誤判(T4)。 +**「行內透明」判定之分層(階段二確立)**:「透明穿越」曾有兩套口徑散落——`collectRuns` +默認透明、`isTransparent`/`adjacentLogicalChar` 默認邊界——同一未登記行內標籤(如 `