Files
cjk-autospace/README.md
T
admin a0c66ecadc feat: Pass C —— 長英文段 lang 包裝(預設啟用)
把 [A-Za-z]{N,} 之長英文段包進 <span lang="en">,配合消費端 CSS
[lang|="en"] { hyphens: auto; ... } 用瀏覽器原生 en 字典斷詞 + 渲
染連字符。連字符純由 CSS 渲染,DOM 內不存在 → 選取 / 複製返回原文
無污染。冪等:parent 為 <span lang> 直接跳過。

skip 鏈共用 Pass A / B 之 isSkipped(CODE / KBD / PRE / SAMP / TT
/ VAR / SCRIPT / STYLE / TEXTAREA / INPUT / SVG / contentEditable
/ data-md-key)。

預設啟用以解 CJK 兩端對齊正文中行末長英文詞之斷行問題;消費端可傳
longWordWrap: false 顯式關閉,或 { minLength, lang } 自訂粒度與標
語。

README + .d.ts 同步說明,含字型陷阱(CJK serif 把 U+2010 設為全形)
與消費端 CSS 範本(含 hyphenate-character: "-")。
2026-05-26 16:54:23 +08:00

77 lines
4.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# cjk-autospace
CJK ↔ Latin / 數字 / 標點 / 引號 / 括號 / 運算子等邊界之自動間距 shim。Pangu.js v7.2.1 規則之 ES5 端口,加上「跨樣式標籤透明 + 行內塊邊界」兩 pass 架構,再加 Pass C 長英文段 `<span lang>` 包裝(讓瀏覽器原生連字斷詞)。工廠模式,由消費端注入配置。
> **詳細文檔 + Changelog 位於 `docs` 分支**:架構解析、雙 pass 流程、整合範例見 [`index.html`](https://git.commilitia.net/admin/cjk-autospace/src/branch/docs/index.html);變更記錄見 [`CHANGELOG.html`](https://git.commilitia.net/admin/cjk-autospace/src/branch/docs/CHANGELOG.html)。本機並列檢出:`git worktree add ../cjk-autospace-docs docs`。
## API
```js
const autospace = createCjkAutospace({
pillSelector: "code, kbd, .your-pill-class",
});
autospace.apply(document.body);
```
回傳 `{ apply(root?) }`。冪等:在已注入 marker 之 DOM 上重跑會跳過既有 `.cjk-autospace`。完整選項見 `cjk-autospace.d.ts`
## CSS 需求
```css
.cjk-autospace {
-webkit-user-select: none;
user-select: none;
/* 視覺寬度由消費端決定,例如 0.25em via inline-block + width */
}
```
`user-select: none` 讓選取與剪貼板跳過 markermarker 內含真實 ASCII spacelayout 視為 whitespace:行末 collapse、容許換行、justify 可拉伸)。
## 標籤三分類
- **STYLE_INLINES**`<strong>` / `<em>` / `<a>` / `<b>` / `<i>` / `<u>` / `<s>` / `<mark>` / `<ins>` / `<del>` / `<sub>` / `<sup>` / `<small>` / `<abbr>` / `<cite>` / `<dfn>` / `<q>` / `<span>` / `<var>` / `<samp>` / `<time>` / `<bdo>` / `<bdi>` / `<ruby>` / `<rb>` / `<rt>` / `<rp>` / `<wbr>`)— shim 透明走過。跨樣式之 Pangu 邊界(如 `<strong>是</strong> Neovim`)由 Pass A 在剝離後識別。
- **PILL**(由 `pillSelector` 指定,預設 `code, kbd`)— 行內塊。邊界由 Pass B 處理,與內容鄰接(CJK / 字母數字)即插 marker。
- **BLOCK**`<p>` / `<div>` / `<h1>``<h6>` / `<li>` / `<pre>` / `<table>` / `<br>` / `<hr>` / …)— 段落級。Pass A 把它們當作 run 邊界,子 block 各自一次。
## 三 pass
- **Pass A — per-block Pangu on tag-stripped text**:對每個 BLOCK 走 DFS 收集邏輯文本(STYLE 透明、PILL 與子 BLOCK 中斷 run、既有 marker 也中斷),整段套 `panguSpace`,把 MARK 反映射回 textNode/offset。MARK 對應原文若是單 ASCII space 則 strip 後插 marker,否則純插。actions 倒序執行確保前面偏移不被後面動作影響。
- **Pass B — pill boundary**:對每個 PILL 透過 STYLE 鏈遞迴找邏輯鄰字(`adjacentLogicalChar`),鄰字若是 CJK / 字母數字直接插 marker;若是 1 個 ASCII space 且另一側為內容字則 strip 後插 marker;其餘(標點 / 多空格 / 換行 / 既有 marker)跳過。
- **Pass C — long English word wrap****預設啟用**`longWordWrap: false` 顯式關閉):將文本節點內所有 `[A-Za-z]{N,}`(預設 `N=6`)之長英文段包進 `<span lang="en">`。冪等:parent 已為 `<span lang>` 直接跳過。**連字符不在 DOM**,由瀏覽器 `hyphens: auto` 在斷行時純視覺渲染 → 選取 / 複製返回原文無污染。需消費端加 CSS:
```css
[lang|="en"] {
hyphens: auto;
-webkit-hyphens: auto;
hyphenate-limit-chars: 6 3 3; /* 詞長 / 斷點前 / 斷點後最少字符 */
}
```
不加 CSS 則 span 為惰性(DOM 變更但無視覺效果)。
## 配置選項
| 選項 | 預設 | 說明 |
|---|---|---|
| `pillSelector` | `"code, kbd"` | 行內塊 CSS 選擇器 |
| `styleInlines` | 預設樣式標籤集 | tagName 大寫之陣列 |
| `blockTags` | 預設段落標籤集 | tagName 大寫之陣列 |
| `skipTags` | mono / form / script / style | tagName 大寫之陣列;整 subtree skip |
| `autospaceClass` | `"cjk-autospace"` | marker span class 名 |
| `skipAttribute` | `"data-md-key"` | 任一祖先帶此屬性即整 subtree skip |
| `isSkipped` | (無) | 自訂 skip callback;先於內建判定檢查 |
| `longWordWrap` | `true`(預設啟用) | Pass C 開關。傳 `false` 顯式關閉;`{minLength, lang}` 自訂;`true` / 省略等同 `{minLength: 6, lang: "en"}` |
## 模組形式
UMD-ish
- **ES module / TypeScript**:直接 `import { createCjkAutospace } from "./cjk-autospace.js"`(搭配 `cjk-autospace.d.ts`
- **CommonJS / Node**`module.exports.createCjkAutospace`
- **Browser global**`globalThis.createCjkAutospace`
- **Inline `<script>`**:函式宣告即註冊於 enclosing scope
## 授權
基於 Pangu.js v7.2.1 的規則表 port[原始項目](https://github.com/vinta/pangu.js) MIT)。