zh-smart-typeset
v1.0.0
Published
Chinese typography with word-aware line breaking based on Pretext
Downloads
14
Maintainers
Readme
zh-smart-typeset
智能中文词组排版库 + 浏览器扩展
解决中文排版的核心问题:防止词组在行尾被截断,同时保持自然的阅读体验。
痛点对比
浏览器默认断行逻辑按字符而非词语,导致以下问题:
| ❌ 未使用 zh-smart-typeset | ✅ 使用 zh-smart-typeset | |---|---| | 我们在这个时代... →我们在这个时代**...</** | 我们在这个时代...(完整保护) | | 人工智能正在深**......刻改变生活 | 人工智能正在完整保留**改变生活 |
本库使用 Pretext 精确测量字体宽度,结合中文 2-gram 分词,实现智能词组保护。
核心特性
- 精确测量:基于 Pretext 的字体宽度计算,不依赖 DOM 测量
- 智能分词:Intl.Segmenter + 常见词组库(50+ 高频 bigram)
- 零依赖:核心库零生产依赖,仅需
pretext(开发) - 极小体积:生产包 7.7 kB(gzip 3.2 kB)
- 多模式:
word-aware(默认)、word-aware-justify、plain-left、plain-justify - SSR 兼容:纯计算库,可在 Node.js 环境中运行
快速开始
安装
npm install zh-smart-typeset基础用法
import { layout, createTypography } from 'zh-smart-typeset';
// 方式一:直接计算布局
const result = layout('人工智能正在改变世界', {
containerWidth: 400,
fontSize: 16,
lineHeight: 1.8,
mode: 'word-aware', // 智能词组保护
wordBreakThreshold: 0.3, // 阈值 0~1
});
// result.lines → LayoutLine[]
// result.totalHeight → number
// result.lineCount → number
// 方式二:绑定 DOM 容器(自动响应 resize)
const instance = createTypography(document.getElementById('article'), {
containerWidth: 600,
fontSize: 16,
lineHeight: 1.8,
});
// 更新内容
instance.setText('新的文本内容');
// 更新选项并重新排版
instance.updateOptions({ wordBreakThreshold: 0.5 });
// 销毁实例
instance.destroy();渲染 HTML
import { render } from 'zh-smart-typeset';
const html = render('人工智能正在改变世界', {
containerWidth: 400,
fontSize: 16,
lineHeight: 1.8,
});
// → '<span style="display:block">人工智能正在</span><span style="display:block">改变世界</span>'API 文档
layout(text, options)
对文本进行排版计算,不修改 DOM。
参数:
text: string— 输入文本options: TypographyOptions— 排版选项
返回值: LayoutResult
interface LayoutResult {
lines: LayoutLine[];
totalHeight: number;
lineCount: number;
}
interface LayoutLine {
text: string; // 该行的完整文本
width: number; // 该行宽度(像素)
words: WordInfo[]; // 该行的词信息
}createTypography(container, options)
创建交互式排版实例,绑定 DOM 容器并自动响应容器宽度变化。
参数:
container: HTMLElement— 目标容器元素options: TypographyOptions— 排版选项
返回值: TypographyInstance
interface TypographyInstance {
setText(text: string): void;
updateOptions(options: Partial<TypographyOptions>): void;
render(): void;
destroy(): void;
}render(text, options)
快捷函数,直接返回 HTML 字符串。
配置选项
| 选项 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| fontSize | number | 16 | 字号(px) |
| lineHeight | number | 1.5 | 行高倍数 |
| containerWidth | number | 400 | 容器宽度(px) |
| wordBreakThreshold | number | 3 | 词组保护阈值(字符数) |
| mode | TypographyMode | 'word-aware' | 排版模式 |
排版模式:
word-aware— 智能词组保护(推荐)word-aware-justify— 智能词组 + 两端对齐plain-left— 无保护,左对齐plain-justify— 无保护,两端对齐
工作原理
1. 文本分词
"人工智能正在改变世界"
↓ Intl.Segmenter + 2-gram 规则
["人工智能", "正在", "改变", "世界"]2. 宽度测量
使用 Pretext 计算每个词的实际像素宽度:
import { measureWord } from 'zh-smart-typeset';
const width = measureWord('人工智能', 'sans-serif', 16);
// → 64 px(根据实际字体计算)3. 行布局
贪心算法装箱,超出容器宽度时智能断行:
Container width: 400px
[人工智能(64px)][正在(48px)][改变(48px)][世界(32px)]
→ 检测到总宽度 192px < 400px,全部在一行4. Pretext 集成
Pretext 负责精确的字体测量:
import { prepareWithSegments } from 'pretext';
const font = prepareWithSegments('sans-serif', '16px');
const metrics = font.measure('人工智能');
// → { advance: 64, ascent: 14, ... }浏览器扩展
除了库,本项目还提供 Chrome / Edge / Firefox 浏览器扩展:
- 自动检测:扫描页面中文本段落
- 一键开关:Popup 快速启用/禁用
- 智能分词:复用库的分词能力
- 动态内容:支持无限滚动、SPA 页面
- 白名单/黑名单:按域名配置
- 导入/导出:JSON 格式备份设置
与其他方案对比
| 方案 | 词组保护 | 测量方式 | 体积 | 动态内容 |
|------|---------|---------|------|---------|
| zh-smart-typeset | ✅ 智能 | Pretext 精确 | 7.7 kB | ✅ MutationObserver |
| CSS word-break: keep-all | ⚠️ 机械 | 无 | 0 | ❌ |
| pangu.js | ❌ 仅加空格 | 无 | 15 kB | ✅ |
| heti | ⚠️ 半自动 | CSS 估算 | 8 kB | ❌ |
浏览器兼容性
| 浏览器 | 版本要求 | |--------|---------| | Chrome | ≥ 80 | | Edge | ≥ 80 | | Firefox | ≥ 75 | | Safari | ≥ 14 | | Node.js | ≥ 14 |
依赖说明:
Intl.Segmenter(用于智能分词):Chrome/Edge/Firefox/Safari 14+ 支持,Node.js 16+ 支持- 不支持时自动降级到手动 2-gram 分词
已知限制
- SSR 场景:需要服务器返回已计算好的宽度,使用前需确保
containerWidth准确 - 字体变化:当容器内文本字体不统一时,测量可能略有偏差
- 超长文本:单次处理文本超过 50,000 字符时自动截断
- 框架集成:React/Vue SSR 场景建议在客户端 hydration 后调用
开发
# 安装依赖
npm install
# 开发模式
npm run dev # 库 + demo
cd extension && npm run dev # 扩展(Chrome Ext)
# 构建
npm run build # 库
cd extension && npm run build # 扩展
# 测试
npm test # vitest 单元测试
# 打包
cd extension && npm run zip # 生成 zh-smart-typeset.zip项目结构
zh-smart-typeset/
├── src/ # 核心库源码
│ ├── index.ts # 主入口
│ ├── segmenter.ts # 中文分词(Intl.Segmenter + 2-gram)
│ ├── measurer.ts # Pretext 宽度测量
│ ├── linebreaker.ts # 换行算法
│ ├── renderer.ts # HTML 渲染
│ └── types.ts # TypeScript 类型
├── dist/ # 构建产物(npm 发布)
├── extension/ # 浏览器扩展
│ ├── src/
│ │ ├── content.ts # Content Script
│ │ └── popup/ # Popup UI
│ └── dist/ # 扩展构建产物
├── examples/ # 集成示例
└── tests/ # 单元测试License
MIT © 李轶凡
