Files
cjk-autospace/README.md
T
admin a5faec5abf feat: 補 ESM export { createCjkAutospace }
下游 Vite / Rollup / TypeScript 靜態 ESM 解析需要真正之 `export`
關鍵字;原 UMD-ish(module.exports + globalThis)對 ESM 消費端
仍須走副作用導入 + globalThis 取值之 workaround。

於檔尾既有 CJS / globalThis 兩塊後再加 `export { createCjkAutospace };
順序刻意如此,讓串接端(IIFE 函式體內不能有 module-level export)
只需以 `sed '/^export {/d'` 剝最後一行即安全。

four-form export 同時支援:ESM named import / CommonJS require /
globalThis / IIFE 串接(後者需剝 export 行)。README 同步補上。
2026-05-26 17:25:34 +08:00

83 lines
5.1 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"}` |
## 模組形式
四種消費場景並存:
- **ES module / TypeScript**`import { createCjkAutospace } from "./cjk-autospace.js"`(檔尾 `export { createCjkAutospace }`,配 `cjk-autospace.d.ts`
- **CommonJS / Node**`require("./cjk-autospace.js").createCjkAutospace`(檔尾 `module.exports`
- **Browser global**:載入後可 `globalThis.createCjkAutospace`
- **IIFE 串接**:把本檔內容 `cat` 進單一閉包(如 Claude 模板 `build.sh` / Nvim peek build hook)— `export {…}` 為 ESM module-level 語法,串入函式體內會語法錯誤,串接端須剝掉那行:
```sh
sed '/^export[[:space:]]*{/d' cjk-autospace.js
```
其餘 `module.exports` / `globalThis` 兩塊在閉包內安全(`typeof` 檢查不會 throw、globalThis 賦值無副作用)。
## 授權
基於 Pangu.js v7.2.1 的規則表 port[原始項目](https://github.com/vinta/pangu.js) MIT)。