Skip to content

Commit c77ff12

Browse files
authored
zh-format:0.1.0 (#3455)
1 parent a5944be commit c77ff12

File tree

5 files changed

+349
-0
lines changed

5 files changed

+349
-0
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2025 KercyDing
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# zh-format
2+
3+
[![Typst Universe](https://img.shields.io/badge/Typst-Universe-239DAD.svg)](https://typst.app/universe/package/zh-format) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
4+
5+
zh-format is a Chinese formatting package for Typst, providing better solutions for bold, italic, and underline styles tailored for Chinese typography.
6+
7+
zh-format 是一个用于 Typst 的中文格式包,提供更适合中文排版的粗体、斜体和下划线处理方案。
8+
9+
## 用法
10+
11+
```typst
12+
// 从 Typst Universe 导入 (推荐)
13+
// #import "@preview/zh-kit:0.1.0": *
14+
15+
// 如果是本地开发或直接使用仓库代码
16+
#import "../lib.typ": * // 假设 lib.typ 在上一级目录
17+
18+
#show: zh-format
19+
20+
这是*粗体*、_斜体_和#underline[下划线]的效果。
21+
22+
这是#u(width: 8em, offset: 0.4em)[自定义下划线]
23+
```
24+
25+
### 主要功能
26+
27+
#### 1. 粗体 (Bold)
28+
- 中文使用描边方式 (`stroke: 0.02857em`)
29+
- 英文使用原生字体加粗
30+
- 自动识别中英文并分别处理
31+
32+
#### 2. 斜体 (Italic)
33+
- 中文使用 `skew(ax: -18deg)` 倾斜变换
34+
- 英文使用原生 `style: "italic"`
35+
- 智能处理中英文混排
36+
37+
#### 3. 下划线 (Underline)
38+
- 基本下划线: `#underline[文本]`
39+
- 自定义宽度下划线: `#u(width: 8em)[文本]`
40+
41+
### 完整示例
42+
43+
查看 [example.typ](example/example.typ) 获取详细使用示例。
44+
45+
## 更新日志
46+
47+
### 0.1.0
48+
- 初始版本
49+
- 实现基础的粗体、斜体、下划线功能
50+
- 支持中英文混排智能识别
51+
- 添加自定义宽度下划线函数 `#u()`
52+
53+
## 许可证
54+
55+
[MIT License](LICENSE)
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
#import "@preview/zh-kit:0.1.0": *
2+
// #import "../lib.typ": *
3+
4+
#show: zh-format
5+
6+
#set page(paper: "a4", margin: 2cm)
7+
#set text(font: ("Times New Roman", "SimSun"), size: 12pt)
8+
#set par(justify: true, first-line-indent: 0em)
9+
#set heading(numbering: "1.1.1")
10+
11+
= zh-format 库功能测试文档
12+
13+
本文档用于测试 zh-format 库的各项中文格式化功能。
14+
15+
== 粗体效果测试
16+
17+
=== 纯中文粗体
18+
这是*普通中文粗体文本*的效果展示。通过描边实现更好的视觉效果。
19+
20+
*完整段落的中文粗体测试:中文字体的粗体处理采用描边方式,能够在不改变字形结构的前提下,实现更加清晰的加粗效果。这种方法特别适合宋体等衬线字体。*
21+
22+
=== 纯英文粗体
23+
This is *bold English text* for testing purposes.
24+
25+
*Complete paragraph in bold English: The bold formatting for English text uses native font weight, which provides optimal rendering for Latin characters.*
26+
27+
=== 中英文混合粗体
28+
*中英文混合 Mixed Chinese and English 粗体效果测试 bold text rendering*
29+
30+
== 下划线效果测试
31+
32+
=== 基本下划线
33+
这是#underline[中文下划线]的效果。
34+
35+
This is #underline[English underline] effect.
36+
37+
#underline[中英文混合下划线 Mixed underline test 测试]
38+
39+
=== 自定义下划线函数 #u
40+
基本效果(需提供 width 参数):#u(width: 8em)[居中文本]
41+
42+
调整偏移量:#u(width: 8em, offset: 0.4em)[较低的下划线]
43+
44+
+ 填空题示例:
45+
46+
+ 中国的首都是 #u(width: 4em)[]。
47+
48+
+ 1 + 1 = #u(width: 2em)[]。
49+
50+
+ Typst 是一个现代的 #u(width: 6em)[] 系统。
51+
52+
+ 签名栏:#h(1fr) #u(width: 8em)[签名] #h(2em) 日期:#u(width: 6em)[]
53+
54+
== 斜体效果测试
55+
56+
=== 纯中文斜体
57+
这是_中文斜体文本_的效果,使用倾斜变换实现。
58+
59+
_完整段落的中文斜体测试:中文斜体采用 skew 变换,倾斜角度为 -18 度,这样可以在保持字形清晰的同时实现倾斜效果。_
60+
61+
=== 纯英文斜体
62+
This is _italic English text_ using native font style.
63+
64+
_Complete paragraph in italic English: The italic formatting for English text uses the native italic font variant for optimal typography._
65+
66+
=== 中英文混合斜体
67+
_中文倾斜 and English italic 混合效果 mixed rendering test 测试_
68+
69+
== 组合效果测试
70+
71+
=== 粗体 + 下划线
72+
*#underline[中文粗体下划线]*
73+
74+
*#underline[English bold underline]*
75+
76+
=== 粗体 + 斜体
77+
*_中文粗斜体组合_*
78+
79+
*_English bold italic combination_*
80+
81+
=== 斜体 + 下划线
82+
_#underline[中文斜体下划线]_
83+
84+
_#underline[English italic underline]_
85+
86+
=== 三重组合
87+
*_#underline[中文粗斜体下划线]_*
88+
89+
*_#underline[English bold italic underline]_*
90+
91+
== 实际应用场景
92+
93+
=== 文章摘要
94+
*摘要:*本文介绍了一个用于 Typst 的中文格式化库 _zh-format_,该库提供了#underline[更适合中文排版]的粗体、斜体和下划线处理方案。传统的 LaTeX 或其他排版系统往往*直接套用西文规则*,导致中文显示效果不佳。
95+
96+
=== 强调重点
97+
在学习过程中,我们需要特别注意以下几点:
98+
- *重点内容*使用粗体标注
99+
- _次要强调_使用斜体表示
100+
- #underline[关键术语]使用下划线突出
101+
102+
=== 表格中的格式化
103+
104+
#table(
105+
columns: (1fr, 2fr),
106+
[*功能*], [*说明*],
107+
[粗体], [使用 `*text*``#strong[]` 实现],
108+
[斜体], [使用 `_text_``#emph[]` 实现],
109+
[下划线], [使用 `#underline[]``#u[]` 实现],
110+
[自定义宽度], [使用 `#u(width: )[]` 指定固定宽度],
111+
)
112+
113+
== 特殊符号与标点
114+
115+
=== 中文标点符号
116+
*中文标点:,。!?;:""''《》【】()*
117+
118+
_中文标点:、…—·「」『』〈〉_
119+
120+
=== 混合标点
121+
*Mixed punctuation test: 中文,English, 混合! What? 测试。*
122+
123+
== 总结
124+
125+
zh-format 库提供了三个主要功能:
126+
+ *setup-bold*:优化中文粗体显示
127+
+ *setup-underline*:改进下划线渲染
128+
+ *setup-emph*:智能处理中英文斜体
129+
130+
通过 `#show: zh-format` 可以一次性应用所有格式化规则,让您的中文文档排版更加美观专业。
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
// ===========================
2+
// 格式化工具库
3+
// ===========================
4+
5+
6+
// 粗体处理逻辑
7+
#let setup-bold(body) = {
8+
show text.where(weight: "bold").or(strong): it => {
9+
show regex("[\p{script=Han}!-・〇-〰—]+"): cn => {
10+
set text(weight: "regular")
11+
context {
12+
set text(stroke: 0.02857em + text.fill)
13+
cn
14+
}
15+
}
16+
it
17+
}
18+
body
19+
}
20+
21+
// 下划线处理逻辑
22+
#let setup-underline(body) = {
23+
show underline: it => context {
24+
let line_width = measure(it.body).width
25+
box[
26+
#it.body
27+
#place(
28+
bottom + left,
29+
dy: 0.15em,
30+
line(length: line_width, stroke: 0.05em)
31+
)
32+
]
33+
}
34+
body
35+
}
36+
37+
// 自定义下划线函数(#u):
38+
// width 参数为必填命名参数,指定固定宽度,内容自动居中
39+
// 使用: #u(width: )[]
40+
#let u(width: none, offset: 0.2em, body) = {
41+
assert(width != none, message: "参数 width 是必填的")
42+
context {
43+
let line_width = width
44+
45+
box(width: line_width)[
46+
#align(center, body)
47+
#place(
48+
bottom + left,
49+
dy: offset,
50+
line(length: line_width, stroke: 0.05em)
51+
)
52+
]
53+
}
54+
}
55+
56+
// 中文检测
57+
#let has-chinese(content) = {
58+
let text-content = if type(content) == str {
59+
content
60+
} else if content.has("text") {
61+
content.text
62+
} else if content.has("body") {
63+
return has-chinese(content.body)
64+
} else if content.has("children") {
65+
return content.children.any(has-chinese)
66+
} else {
67+
return false
68+
}
69+
if type(text-content) == str {
70+
text-content.codepoints().any(c => {
71+
let code = str.to-unicode(c)
72+
code >= 0x4E00 and code <= 0x9FFF
73+
})
74+
} else {
75+
false
76+
}
77+
}
78+
79+
// 斜体处理逻辑:
80+
// - 英文:使用原生 italic
81+
// - 空格:保持原样
82+
// - 其他(中文、数字、符号等):使用 skew(-18deg)倾斜
83+
#let setup-emph(body) = {
84+
show emph: it => {
85+
let process-content(content) = {
86+
if type(content) == str {
87+
let pattern = regex("( +)|([a-zA-Z]+)|([^ a-zA-Z]+)")
88+
let matches = content.matches(pattern)
89+
90+
matches.map(m => {
91+
let str = m.text
92+
let first-char = str.at(0)
93+
if first-char >= "A" and first-char <= "Z" or first-char >= "a" and first-char <= "z" {
94+
box(inset: 0pt, outset: 0pt, text(style: "italic")[#str])
95+
} else if first-char == " " {
96+
box(inset: 0pt, outset: 0pt, str)
97+
} else {
98+
box(skew(ax: -18deg)[#str])
99+
}
100+
}).join()
101+
} else if content.has("text") {
102+
process-content(content.text)
103+
} else if content.has("body") {
104+
process-content(content.body)
105+
} else if content.has("children") {
106+
content.children.map(process-content).join()
107+
} else {
108+
let repr-str = repr(content)
109+
if repr-str == "[ ]" {
110+
box(inset: 0pt, outset: 0pt, content)
111+
} else {
112+
content
113+
}
114+
}
115+
}
116+
117+
if has-chinese(it.body) {
118+
process-content(it.body)
119+
} else {
120+
it
121+
}
122+
}
123+
body
124+
}
125+
126+
// 统一格式化函数
127+
#let zh-format(body) = {
128+
show: setup-bold
129+
show: setup-underline
130+
show: setup-emph
131+
body
132+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
[package]
2+
name = "zh-format"
3+
version = "0.1.0"
4+
compiler = "0.13.1"
5+
repository = "https://github.com/KercyDing/zh-format"
6+
entrypoint = "lib.typ"
7+
authors = ["KercyDing <[email protected]>"]
8+
license = "MIT"
9+
description = "更好的Typst中文文本格式包(粗体、斜体、下划线)。A Typst package for better Chinese text formatting (bold, italic, underline)"
10+
keywords = ["chinese", "cn", "format", "中文", "格式", "粗体", "斜体", "下划线"]
11+
exclude = ["example/"]

0 commit comments

Comments
 (0)