Skip to content

xeCJK: 关于重构的一些要点 #511

Description

@RuixiZhang42

目的

开这条 issue 的目的是为了统一整合 xeCJK 未来重构需要注意的要点。个人能力有限,会有总结不到位之处,欢迎大家补充。

本 issue 的结构

这条评论里提出第一个要点,未来的要点在下面依次提出。每个要点关注某些具体方面,会提供 MWE、截取相关 log、指出目前的不足、提出「理想的效果」。

单个标点符号的处理

通过如下 MWE 可以看出 xeCJK 其实对待标点符号也是「加法模式」,但是「过于激进」。

\documentclass{article}
\usepackage{xeCJK}
\newcommand\sampletext{逗,句。号}
\begin{document}

\showboxbreadth=\maxdimen
\showboxdepth=\maxdimen

\CJKfontspec{SimSun.ttc}%
\sampletext

\CJKfontspec{SourceHanSerifSC-Regular.otf}[Language=Chinese Simplified]%
\sampletext

\CJKfontspec{SourceHanSerifSC-Regular.otf}[Language=Chinese Traditional]%
\sampletext

\showlists

\end{document}

log 里相关的部分如下:

...
.\TU/SimSun.ttc(0)/m/n/10 逗
.\penalty 10000
.\TU/SimSun.ttc(0)/m/n/10 ,
.\rule(0.0+0.0)x-7.22656
.\glue 7.22656 minus 6.01563
.\glue 0.0 plus 0.96002
.\TU/SimSun.ttc(0)/m/n/10 句
.\penalty 10000
.\TU/SimSun.ttc(0)/m/n/10 。
.\rule(0.0+0.0)x-6.44531
.\glue 6.44531 minus 5.07813
.\glue 0.0 plus 0.96002
.\TU/SimSun.ttc(0)/m/n/10 号
...
.\TU/SourceHanSerifSC-Regular.otf(0)/m/n/10 逗
.\penalty 10000
.\TU/SourceHanSerifSC-Regular.otf(0)/m/n/10 ,
.\rule(0.0+0.0)x-7.71
.\glue 7.71 minus 6.95001
.\glue 0.0 plus 0.96002
.\TU/SourceHanSerifSC-Regular.otf(0)/m/n/10 句
.\penalty 10000
.\TU/SourceHanSerifSC-Regular.otf(0)/m/n/10 。
.\rule(0.0+0.0)x-6.77
.\glue 6.77 minus 6.35
.\glue 0.0 plus 0.96002
.\TU/SourceHanSerifSC-Regular.otf(0)/m/n/10 号
...
.\TU/SourceHanSerifSC-Regular.otf(1)/m/n/10 逗
.\penalty 10000
.\TU/SourceHanSerifSC-Regular.otf(1)/m/n/10 ,
.\rule(0.0+0.0)x-7.71
.\glue 7.71 minus 6.95001
.\glue 0.0 plus 0.96002
.\TU/SourceHanSerifSC-Regular.otf(1)/m/n/10 句
.\penalty 10000
.\TU/SourceHanSerifSC-Regular.otf(1)/m/n/10 。
.\rule(0.0+0.0)x-6.77
.\glue 6.77 minus 6.35
.\glue 0.0 plus 0.96002
.\TU/SourceHanSerifSC-Regular.otf(1)/m/n/10 号
...

问题分析

以全角句号 U+3002 为例,目前的效果是

<字> <penalty> <句号> <rule> <glue> <CJKglue> <字>

通过 log 可见两大不足:

  1. \rule 的宽度随字体而变,例如中易宋体的句号后面紧跟 -64.453125% 宽的 rule,而思源宋体(简体)的句号后面紧跟 -67.7% 宽的 rule;
  2. 思源宋体切换成繁体之后,句号已经居中,但其后的 rule 仍然是 -67.7% 宽。

重构要点

我们从铅字排印入手,提出如下两条要点:

  1. 我们应该摒弃目前的「测量标点字面」的做法,对那些占据字面小于 50% 的标点,不应该「抹掉全部空白」,而应该「统一抹掉 50%」;
  2. 我们应该分离「避头尾禁则」与「字面位置」这两个属性。例如「全角句号」是 closing 标点,不可以出现在行首,这是「禁则」属性;与之独立的应该还有「偏左半边」、「偏右半边」、「居中一半」、「居中占满」这些「字面位置」属性,其中「偏左半边」、「偏右半边」可以直接对应到直排/竖排的「偏上半边」、「偏下半边」,而保持代码实现不变。

组合:closing + 偏左半边

例如

  • 横竖排皆适用:简体中文跟日文用到的逗号 U+FF0C、句号 U+3002、顿号 U+3001、点号 U+FF0E
  • 仅限横排适用:简体中文用到的冒号 U+FF1A、分号 U+FF1B、叹号 U+FF01、问号 U+FF1F

理想效果应该是

<字>
<nobreak CJKglue> % 支持疏排,标点、汉字一起被拉开
% <nobreak penalty> 此处不再需要 penalty 了,因为已经不是合法的断行点了
<这种标点>
<rule: -50%> % 抹掉二分空白
<glue: 50% minus 50%> % 这里是可断行的位置
<CJKglue>
<字>

组合:closing + 偏右半边

这种组合不可能。

组合:closing + 居中一半

例如

  • 横竖排皆适用:繁体中文用到的逗号 U+FF0C、句号 U+3002、顿号 U+3001、点号 U+FF0E,日文用到的冒号 U+FF1A
  • 仅限横排适用:繁体中文用到的冒号 U+FF1A、分号 U+FF1B,日文用到的分号 U+FF1B

理想效果应该是

<字>
<nobreak CJKglue> % 支持疏排,标点、汉字一起被拉开
% <nobreak penalty> 此处不再需要 penalty 了,因为已经不是合法的断行点了
<nobreak glue: 25% minus 25%> % 这里不可断行
<rule: -25%> % 抹掉四分空白
<这种标点>
<rule: -25%> % 抹掉四分空白
<glue: 25% minus 25%> % 这里是可断行的位置
<CJKglue>
<字>

组合:closing + 居中占满

例如

  • 横竖排皆适用:繁体中文跟日文用到的叹号 U+FF01、问号 U+FF1F
  • 仅限竖排适用:简体中文、繁体中文跟日文用到的分号 U+FF1B,简体中文用到的叹号 U+FF01、问号 U+FF1F,等等。

理想效果应该是

<字>
<nobreak CJKglue> % 支持疏排,标点、汉字一起被拉开
% <nobreak penalty> 此处不再需要 penalty 了,因为已经不是合法的断行点了
<这种标点> % 没有空间可以挤压的标点
<CJKglue>
<字>

其余组合:opening + XXXX

如上分析,可以依次给出理想的效果。

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions