6834029c31785aa2647bab22b0acb079235ca39f
文檔正本只存於 docs 分支;main 留一份未追蹤副本於 .docs/(唯讀)。 舊 docs 分支更名為 docs-legacy。
聚珍(Juzhen)
現代簡/繁中文網頁排版套件。Han.css 之現代化重寫,沿其功能版圖,並針對 數種情況作調整:複製乾淨(中西間隙不入剪貼板)、依
lang全角/開明 自動切換、justify下句末標點只佔一份間距、跨瀏覽器一致 (Chrome/Edge/Safari/WebKit/Firefox)。
倉庫名仍為 cjk-autospace;公開 API 為 createJuzhen / 全域 Juzhen;注入之
自訂元素前綴 jz-。完整設計見 ARCHITECTURE.md。
本版(2.x)為從零重寫。v1 之
createCjkAutospaceAPI 由相容層保留(見下), 既有消費端不需改碼即可運行;v1 原始碼保存於v1-autospace分支。
安裝與構建
npm install
npm run build # esbuild → dist/juzhen.{mjs,iife.js,css};tsc → dist/index.d.ts
npm test # jsdom DOM 正確性測試
產物(dist/,已入庫):
| 檔 | 用途 |
|---|---|
dist/juzhen.mjs |
ESM,供打包器/TypeScript |
dist/juzhen.iife.js |
IIFE,全域 Juzhen,原生 <script> 直跑 |
dist/juzhen.css |
合併樣式(必須引入,視覺尺寸全在此) |
dist/index.d.ts |
TypeScript 型別宣告 |
用法
原生 <script>
<link rel="stylesheet" href="dist/juzhen.css">
<script src="dist/juzhen.iife.js"></script>
<script>
const jz = Juzhen.createJuzhen({ scope: { include: ".prose" } });
jz.render(); // 對 document.body 套用(僅命中 .prose 子樹)
// jz.revert(); // 還原
</script>
ESM/TypeScript
import { createJuzhen } from "cjk-autospace";
import "cjk-autospace/css";
const jz = createJuzhen({ lang: { default: "zh-Hant" } });
jz.render(document.querySelector("main"));
JS 與 CSS 缺一不可:JS 只注入 jz-* 結構,所有視覺尺寸(間隙寬度、擠壓量、
justify 原子化、字體堆疊)都在 juzhen.css。
切片 1 已實作功能
| 功能 | 說明 |
|---|---|
中西間隙 spacing |
CJK↔西文邊界插入 copy-clean 之 jz-hws(user-select:none,剪貼板跳過)。含跨樣式行內邊界與 code/kbd pill 邊界。 |
長英文詞 longWord |
[A-Za-z]{6,} 包入 <span lang="en">,配合 CSS hyphens:auto 原生斷詞(DOM 無連字符 → 複製不污染)。 |
標點擠壓 jiya |
標點 charify 為 jz-char+bd-* class。三機制:①baseline 政策(全角式不擠/開明式擠句內點號+括號引號/半角式全擠);②行內連續擠壓(相鄰標點對向側收);③行端擠壓(lineedge layout pass)。半形以字型 halt 渲染(按字形正確定位,居中字形如 !?/繁體 。, 不重疊;不依賴 text-spacing-trim)。 |
禁則 jinze |
行首行末避頭尾:閉類/點號綁前一字(不置行首)、開類綁後一字(不置行末),只隔離邊界字故長引文中段仍可斷。亦為 justify 綁定載體。 |
| justify 單份間距 | 每個 jz-char 為 inline-block 原子項,句末標點只貢獻一份對齊伸縮量。 |
後續(架構已預留,不返工):標點懸掛、標點修正(簡↔繁)、著重號、注音/Ruby。
選項
createJuzhen({
lang: {
default: "zh-Hant", // 無 lang 祖先時之預設
policy: { "zh-Hant": "quanjiao", "zh-Hans": "kaiming" }, // 全角/開明/半角
},
scope: {
root: document.body, // 處理根;render(root) 可逐次覆寫
include: ".prose", // 啟用選擇器(opt-in):僅處理命中子樹
avoid: "blockquote.raw", // 追加排除選擇器
},
spacing: true,
longWord: { minLength: 6, lang: "en" },
jiya: true,
jinze: true,
blocks: [ // 分塊功能選擇
{ selector: ".code-comment", features: [ "spacing" ] },
],
});
分塊功能選擇(HTML 屬性,就近繼承)
<p data-juzhen="spacing jiya">…</p> <!-- 白名單:僅此二功能 -->
<p data-juzhen-off="jiya">…</p> <!-- 黑名單:停用 jiya,其餘繼承 -->
<div lang="zh-Hans">…</div> <!-- lang 驅動全角/開明 -->
v1 向下相容
// 既有消費端零改動:
const cjk = createCjkAutospace({ pillSelector: "code, kbd" });
cjk.apply(document.body);
IIFE 構建另掛 globalThis.createCjkAutospace 別名。與 v1 之差異(行為等價、
不要求逐位一致):
- 間隙標記由
<span class="cjk-autospace">變為<jz-hws class="cjk-autospace">(仍帶原 class,既有.cjk-autospace{user-select:none}CSS 仍命中)。 - 標點擠壓由消費端
font-feature-settings:"halt"改為juzhen.css之負margin(需改用juzhen.css;機制不同,同為開明式「句內點號半形」之效果)。
目視驗證
demo/index.html 載入 dist/ 產物,簡繁並列、可切 justify、附 copy-clean 測試區。
版面相關結論(justify 單份間距、擠壓視覺量、行端、inline-block 基線)須於
Chrome/Safari/Firefox 三引擎目視核對——jsdom 僅驗證 DOM 結構正確性。
授權
MIT。借鑑 Han.css/Heti 之思路與分類表(MIT),成品自含、不依賴其執行期程式碼。
Description
Languages
TypeScript
55.6%
JavaScript
37.4%
CSS
4.8%
Python
1.2%
HTML
1%