import type { FeatureLevel, ResolvedOptions } from "../types.js"; /** 邏輯 run 中之單一字元來源位置。 */ export interface CharPos { textNode: Text; offset: number; } /** 一段邏輯文本:剝離樣式後之連續字元,及其逐字回映射。 */ export interface LogicalRun { text: string; map: CharPos[]; } /** pill 鄰接之邏輯鄰字。 */ export interface AdjacentChar { textNode: Text; offset: number; ch: string; } export declare class Finder { private readonly opts; private readonly styleSet; private readonly blockSet; private readonly skipSet; private readonly pillSelector; private readonly isolateSelector; private readonly avoidSelector; private readonly includeSelector; private readonly skipAttr; private readonly userIsSkipped; private readonly levelTextSelector; private readonly featureCache; private readonly levelCache; constructor(opts: ResolvedOptions); /** 該元素是否匹配 pill 選擇器(三分類之「整體」:code/kbd/行內公式等)。 */ pillMatches(el: Element): boolean; /** 該元素是否匹配 isolate 選擇器(三分類之「隔離」:帶盒樣式之行內,如背景色 * )。邊界口徑同 pill(斷 run/斷相鄰/不可切分/兩端補隙),內部照常處理。 */ isolateMatches(el: Element): boolean; /** 節點是否位於 pill **內部**(僅查祖先,不含自身)。pill 為整體元素:內部對 * 一切 pass 不可見——不 charify、不收 run、不切分、不於其內插間隙(下游問題六: * .katex 內部曾被 jiya/spacing 直接變更)。 */ insidePill(node: Node): boolean; /** 邏輯文本應**透明穿越**之行內元素:樣式行內標籤,以及聚珍自身之 wrap 類 * jz-*(jz-hws 間隙、jz-jinze 禁則群組、jz-char/jz-inner 標點原子)。穿越這些 * 才能正確找到跨包裝之邏輯鄰字(如 jinze 已把 pill 納入 jz-jinze 後,pill 之左 * 鄰字仍須可達;I7)。 * ⚠ 以**元素**而非標籤名判定:pill/isolate/avoid 縱使標籤名在樣式集亦為邊界、 * 不可穿越(下游問題六:KaTeX 全樹皆 SPAN,名字判定令整棵公式被當透明下潛而 * 肢解;scope.avoid/skipAttribute 命中自身者同理)。 * ⚠ jz-char/jz-inner 必須透明:否則 adjacentLogicalChar 之 descend 遇標點原子既 * 不進入亦不終止、而是**跳過**它續找更前之兄弟(下游 Bug:`汉字。` 經 jinze * 綁定為 `汉`,pill 之左鄰字應 * 為「。」、不補間隙;舊邏輯卻越過 jz-char 取到「字」→ 誤包 jz-hws 於「字。」之間)。 * jz-char 僅含標點(jiya 只 charify biaodian),標點非 pillNeighbor,故透明後 descend * 回傳標點 → 不補隙,與 collectRuns 之既有透明遞迴一致。jz-inner 亦須列入,否則 * descend 進入 jz-char 後因 jz-inner 不透明而跳過其內標點。 */ private transparentInline; /** 該元素**自身**是否為 avoid 邊界(內建 skip 名單 / SVG / contentEditable / * data-jz-skip / skipAttribute / avoid 選擇器 / isSkipped)。isAvoided 沿祖先 * 鏈逐層呼叫本判定;遍歷原語另須對「正要進入」之元素直接判自身——舊版僅查 * 祖先,元素自身命中 avoid 時被當透明穿越(下游問題六:scope.avoid 對 .katex * 形同虛設)。 */ avoidsSelf(el: Element): boolean; /** 節點是否處於 avoid 子樹(祖先鏈上任一元素 avoidsSelf;自身不計——元素 * 自身之邊界判定由遍歷原語以 avoidsSelf 執行)。 */ isAvoided(node: Node): boolean; /** scope.include 啟用判定:未設則恆 true;設則須有命中祖先(opt-in)。 */ inScope(node: Node): boolean; /** 走訪 root 下所有「可處理」文本節點(已過濾 avoid / pill 內部 / 非作用域)。 */ eachTextNode(root: Element, cb: (node: Text) => void): void; /** 走訪 root 下所有 block 元素(含 root 本身若為 block)。 */ eachBlock(root: Element, cb: (block: Element) => void): void; /** * 收集 block 之邏輯文本 run(架構 §4.1,I7):樣式行內元素與 wrap 類 * jz-* 透明穿越;block/pill/avoid/間隙 marker(jz-hws)中斷 run。 * 回傳 text.length >= 2 之 run(短於 2 無間隙可言)。 */ collectRuns(block: Element): LogicalRun[]; /** * pill 之邏輯鄰字(架構 §4.1):經樣式鏈遞迴,遇 pill/block/avoid/間隙 * marker 即止。direction = -1 取前鄰字,+1 取後鄰字。 */ adjacentLogicalChar(el: Element, direction: -1 | 1): AdjacentChar | null; /** * 節點之功能級別(§6.5.0a)。自 node 向上找**最近**之顯式信號:元素屬性 * `data-jz-level="text|paragraph"`(最優先),或命中 `level.text` 選擇器(→ text); * 皆無則預設 paragraph(全功能)。結果以解析後之元素為鍵快取。 */ levelFor(node: Node): FeatureLevel; /** * 某級別之 pass 是否可作用於該節點(§6.5.0a gate)。文本級 pass 不受限(恆 true); * 段落級 pass 僅作用於段落級元素(text-level 子樹跳過)。與 featureEnabledFor 疊加: * level 為粗粒度語義組(先判),blocks/屬性為細粒度逐功能(後調)。 */ levelAllows(node: Node, passLevel: FeatureLevel): boolean; /** * 解析節點對某功能之有效啟用狀態(§3.6,per-node 閘)。向上找最近帶 * 功能指令之祖先(data-juzhen 白名單 / data-juzhen-off 黑名單 / 命中 * blocks 選擇器),無則回退全域 features。結果以元素為鍵快取。 */ featureEnabledFor(node: Node, name: string): boolean; private globalFeature; private resolveFeature; }