设为首页收藏本站

CTEX社区

 找回密码
 注册
搜索
查看: 34961|回复: 36

[中文处理] 中文直排文档的一些经验

[复制链接]

131

主题

0

好友

1万

积分

超级版主

圡人|无良吐槽水车

Rank: 8Rank: 8

发表于 2008-8-7 18:28:27 |显示全部楼层
用 TeX 做直排文档是一个相对繁杂的问题,以前的 TeXer 们也做出了不少努力,有很多漂亮的结果。这里并没有什么原创性的工作,但还是有一些以往较少提及的一些经验,供大家参考。请方家指正。

本页为目录页。

一、使用 CJK + CJKvert 宏包
二、使用 CJK + 直排字体
三、使用 XeTeX
四、其他相关

131

主题

0

好友

1万

积分

超级版主

圡人|无良吐槽水车

Rank: 8Rank: 8

发表于 2008-8-7 18:29:20 |显示全部楼层

一、使用 CJK + CJKvert 宏包

CJK 系统有一个 CJKvert 宏包,是专门设计用来排版直排文字的。

CJKvert 宏包的原理是利用 graphicx 宏包的盒子旋转功能,把所有的汉字逆时针旋转 90°,这样打印出来的文档就是直排的了。命令 \CJKvert(默认)和 \CJKhorz 用来切换直排和横排两种模式。如果需要把少量直排文字插入横排文字,则可以把直排的内容放进一个盒子,再顺时针旋转 90°。

为了适应直排习惯,纸张大小、页码形式都需要进一步调整。预览直排的 PDF 文档一般需要旋转 90 度。

一个利用 CJKvert 直排的简单例子如下:

  1. %# -*- coding: gbk -*-
  2. % cjk-gbsn.tex
  3. % 需要:cjk、cjk-fonts
  4. \documentclass[11pt,a5paper]{article}
  5. \usepackage[pdftex,landscape]{geometry}
  6. \usepackage{fancyhdr}
  7. \usepackage{CJK,CJKnumb,CJKvert}

  8. \pagestyle{fancy}
  9.   \cfoot{\begin{CJK}{GB}{gbsn}\CJKdigits{\value{page}}\end{CJK}}
  10.   \renewcommand{\headrulewidth}{0pt}
  11.   \renewcommand{\footrulewidth}{0pt}

  12. \begin{document}
  13. \begin{CJK}{GB}{gbsn}
  14. 屈原《离骚》:『朝发轫于苍梧兮,夕余至乎县圃。』

  15. 中英文混排 Chinese mix with English. 中英文 $\sin x^2$ 混排
  16. \end{CJK}
  17. \end{document}
复制代码



可以看到,使用 CJK-fonts 中的 gbsn,CJKvert 可以排出良好的直排文字。

不过,如果把上面的 gbsn 换成通常安装的 SimSun 字体,情况就变得惨不忍睹:标点错误、字距不准、中英文基线不齐。事实上,正如 CJK 文档 vertical.txt 中所说,利用 CJKvert 包得到的直排内容,在标点设置、盒子大小和基线位置都会有问题。


造成这两个字体的不同表现的原因,并非是字体的优劣不同,而是因为 CJK 宏包专门为 gbsn 字体做了直行排版的配置。直行排版的字体配置文件(.fdx 文件)是字体定义文件(.fd 文件)的一种扩充,它定义了 \CJKvdef、\CJKvlet 等命令对字符进行精调,其描述可见 CJK 的文档 fdxfiles.txt。

例如,为了解决盒子大小不准和基线不齐的问题,在 c10gbsn.fdx 文件中就有命令
  1. \CJKvdef{fullheight}{1em}
  2. \CJKvdef{height}{.88em}
  3. \CJKvdef{offset}{.5em}
  4. \CJKvdef{simpleoffset}{-.1em}
复制代码

进行设置。而中文逗号、句号的位置,以及不应旋转的括号、引号的设置,也在 c10gbsn.fdx 文件中逐一设置。

由于通常安装 CJK 的 SimSun 字体时,只编写了字体定义文件 gbksong.fd,而并没有编写相应的直行设置文件 gbksong.fdx,所以直行排版的质量不佳。

但是,编写 .fdx 文件必须对字体的特性有所了解,偏移的数值要进行细微的调整,尤其要对每个标点用内码设置,十分困难。即使对标点本身居中的字体(如 MingLiU),也有括号引号的问题。因而有必要寻找其他的解决方法。

[ 本帖最后由 milksea 于 2008-9-1 13:44 编辑 ]

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

131

主题

0

好友

1万

积分

超级版主

圡人|无良吐槽水车

Rank: 8Rank: 8

发表于 2008-8-7 20:09:05 |显示全部楼层

二、使用 CJK + 直排字体

使用 CJKvert 宏包旋转的字体,最大的症结在于标点的设置复杂。事实上,CJKvert 是在用横排模式模拟直排模式。在 Windows 下的许多其他软件(如 Windows 画图),也有直排模式,其中的标点排版就很正确。事实上直排是汉字字体的一种属性(在 Windows 中往往在字体名前加符号“@”表示,也是旋转过 90° 的文字,但标点被正确设置。因此我们希望直接安装直排属性的字体。

安装直排字体的方法和为 LaTeX 安装一般的 TTF 字体没有大的区别,但目前的中文字体安装工具如 (x)GBKfonts、FontsGen 都没有安装直排属性字体的选项。因此我们需要手工安装。为方便计,这里只为 DVIPDFMx 驱动安装字体。

仍以 Windows 的 SimSun.ttf/ttc 为例。

1、生成 .tfm 文件。
TFM(TeX Font Matrix)文件描述了在 TeX 中字符盒子的数据。使用 ttf2tfm 工具生成 TFM 文件。ttf2tfm 有两个关于直排的选项:
    -x        字符旋转 90°
    -y <实数> 对旋转的字符,竖直向下平移实数个字符位置
其中 -y 选项是因为旋转过的字符通常都会偏离原来的位置,因此需要将盒子也进行调整。生成 SimSun 的 TFM 的命令如下(Windows 下)

  1. ttf2tfm %SystemRoot%\fonts\SimSun.ttc -f 0 -q -x -y 0.5 gbksongvert@UGBK@
复制代码

注:Windows XP 使用 SimSun.ttc,需要用 -f 0 选择第一种字体;而老版本 Windows 则使用 SimSun.ttf,不需要此选项。
注:有的版本的 ttf2tfm 工具在生成旋转的字体时会出错,如 MiKTeX 2.7 中的就是如此,但 FontsGen 中附带的版本就可以工作。这只在使用 GBK 编码时会如此,如果用 Unicode 编码则一切正常。原因不明。

生成好一大堆 .tfm 文件后,则可以将它们复制到 local-texmf/fonts/tfm/chinese-vert/gbksongvert/ 目录下。

2、编写 .fd 文件。
FD(Font Definition)文件描述了 LaTeX 字体的 NFSS 信息,CJK 字体还有一些特殊的命令。关于 FD 文件的写法可参考 LaTeX 标准文档 fntguide 和 CJK 的文档 fonts.txt。下面的例子是最简单的,假定使用的字体族名为 songvert,没有粗、斜体:

  1. \ProvidesFile{C19songvert.fd}
  2. \DeclareFontFamily{C19}{songvert}{\hyphenchar \font\m@ne}
  3. \DeclareFontShape{C19}{songvert}{m}{n}{<-> CJK * gbksongvert}{}
  4. \endinput
复制代码


将此文件复制到 local-texmf/fonts/fd/songvert/ 或 local-texmf/tex/latex/CJK/GBK 目录下。

3、为 DVIPDFMx 编辑 cid-x.map 文件。
修改 local-texmf 目录下的 cid-x.map 文件。它通常在 local-texmf/fonts/map/dvipmdfx/ 目录下(也可能在其他目录)。

在 cid-x.map 的末尾加上一行:

  1. gbksongvert@UGBK@ Identity-V :0:SimSun.ttc -v 50
复制代码

这里 gbksongvert 是 TFM 文件名前缀,@UGBK@ 是子字体编码,Identity-V 表示不转换编码,用直行(V)模式,:0:SimSun.ttc 表示在 SimSun.ttc 中选择第一个字体,而 -v 50 选项是 DVIPDFMx 是最新版本新加入用来调整 StemV 值的选项。对较老版本的 DVIPDFMx,应去掉 -v 50。

4、刷新文件名数据库。
执行

  1. texhash
复制代码


完成以上的工作,就可以测试我们的新字体了。这次我们采用横、直混排的方式,用如下的测试文件:

  1. %# -*- coding: gbk -*-
  2. % CJKvertfont.tex

  3. \documentclass{ctexart}
  4. \usepackage{graphicx}

  5. \begin{document}

  6. 屈原《离骚》曰:
  7. \begin{center}
  8. \rotatebox{-90}{\fbox{\begin{minipage}{9\ccwd}
  9. \CJKfamily{songvert}
  10. 『朝发轫于苍梧兮,\\
  11. 夕余至乎县圃。\\
  12. 欲少留此灵琐兮,\\
  13. 日忽忽其将暮。\\
  14. 吾令羲和弭节兮,\\
  15. 望崦嵫而勿迫。』
  16. \end{minipage}}}
  17. \end{center}
  18. 这里羲和便等于一名马车夫,因为
  19. 他是御日的,诗人生怕太阳赶快落了,就叫羲和慢一点走。不过话经我
  20. 一翻译,显得淘气一点,原文只是一个高贵的身分,另外不表现着什么
  21. 个性了。

  22. \vspace{1em}
  23. {\Huge\fbox{永}\fbox{\CJKfamily{songvert}永}\fbox{永}}

  24. \end{document}
复制代码


从结果可以看到,新字体的直行标点显示十分正确,调整过的盒子位置也与字符实际位置合适。唯一的缺点是基线不齐,如果要进行中英文混排,还需要调整。

调整基线最简单的办法还是利用 CJKvert 包的功能。当 CJKvert 包调入时,字体的 .fdx 配置文件则被读入,可以调整基线。唯一不同的是这里我们是对竖直字体的“横排”(H)模式调整基线:

  1. \ProvidesFile{C19songvert.fdx}
  2. \CJKhdef{offset}{0.3em}
  3. \endinput
复制代码

代码见附件,效果如图(由于 CJKvert 包与 CJKpunct 包的冲突,禁用了 CJKpunct):


[ 本帖最后由 milksea 于 2008-8-7 20:13 编辑 ]

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

144

主题

0

好友

3250

积分

论坛元老

Rank: 8Rank: 8

发表于 2008-8-7 20:40:20 |显示全部楼层
有意思。请把制作直排字体配置的要点总结一下发给我,我看看能不能把FontsGen改一下。

131

主题

0

好友

1万

积分

超级版主

圡人|无良吐槽水车

Rank: 8Rank: 8

发表于 2008-8-7 20:51:35 |显示全部楼层

回复 #4 instanton 的帖子

其实因为各种原因,几种方法的结果都不算完美。安装 CJK 直排字体和使用 XeTeX 是相对好些的。

我只测试了为 DVIPDFMx 安装直排字体,PDFTeX 还不知道是否支持这个字体属性。

要点很简单:
1、调用 ttf2tfm 时增加 -x -y <real> 选项。我只试了个别字体,取值都是 0.5 比较合适。
2、写入 cid-x.map 时使用 Identity-V 的 map。(XXX-V 都是直排的,不过我查了 DVIPDFMx 的源文件,并不存在一个 unicode-V)

生成字体的过程有时是很郁闷的,因为对 GBK 编码,经常出现 ttf2tfm 不能正确运行的问题,有时换一个版本的 sfd 就可以正常,有时还要换一个 ttf2tfm。但换 Unicode 编码就没有这个问题。

还有已知的不可解决的问题是,部分字体旋转后(如方正书宋),不仅竖直方向偏移了(这可以用 ttf2tfm 的 -y 选项纠正),水平方向实际字体位置和盒子边界也偏移了(没有工具可以纠正)。——这让我又对方正痛恨不已。

131

主题

0

好友

1万

积分

超级版主

圡人|无良吐槽水车

Rank: 8Rank: 8

发表于 2008-8-7 23:18:12 |显示全部楼层

三、使用 XeTeX

XeTeX 大大简化了字体的使用。对 Unicode 的直接支持也使中文的处理大为简化。旋转是 XeTeX 的一个字体选项(vertical),而直排符号是中文字体的一个属性(vert),利用 XeTeX 直接使用这个属性就可以实现直排。

网上常见的使用 XeTeX 直排往往都是使用 Adobe Song Std 字体,而使用 SimSun 字体的都不能得到正确的直排标点。zhspacing 宏包专门为中文标点设置字体,做直排例子时使用两种字体。这不能不说是一种误区。

我们首先介绍一个 XeTeX 的工具:xetexfontinfo(http://www.ctan.org/tex-archive/ ... /xetexfontinfo.html)。它就是一个 xetex 文档,可以列举一个字体的所有属性(字体属性的介绍可以参考 XeTeX Companion 或 Adobe/Microsoft 的相关网页)。

利用这个工具,我们可以看到,Adobe Song Std 字体支持的特性包括:
'aalt'    Access All Alternates
'dlig'    Discretionary Ligatures
'fwid'    Full Widths
'hwid'    Half Widths
'nalt'    Alternate Annotation Forms
'pwid'    Proportional Widths
'trad'    Traditional Forms
'vert'    Vertical Writing
'vrt2'    Vertical Alternates and Rotation
'cpct'    Centered CJK Punctuation
'halt'    Alternate Half Widths
'vhal'    Alternate Vertical Half Metrics
而这些属性都是对包括默认(DFLT)的六种 script 的所有默认语言可用的:
script = 'DFLT'
language = <default>

我们再来看 SimSun,它只支持 script=hani(CJK 表意)、language=CHN(中文)和默认(<default>)之下的一种属性,即 vert。

是的,如果论支持的属性的全面性,那么无疑 Adobe 的字体更强大(居中和不居中的标点、不同的间距)。但 SimSun 也是支持直排的,只不过它要求明确指定 script 为 'hani'。

我们不难由此得到测试文件。

plain TeX:

  1. %# -*-coding:utf-8 -*-
  2. % xeplain.tex
  3. \def\fbox#1{\hbox{\vrule\vbox{\hrule\hbox{#1}\hrule}\vrule}}

  4. \font\song="SimSun"
  5. \font\songv="SimSun:script=hani:language=CHN:vertical:+vert"

  6. \def\zhs{\fbox{这}\fbox{是}\fbox{一}\fbox{段}\fbox{中}\fbox{文}\fbox{。}}

  7. \song 这是一段中文。{\songv 这是一段中文。}这是一段中文。

  8. \vskip 1cm
  9. boxed: \song\zhs\songv\zhs\song\zhs

  10. \bye
复制代码



XeLaTeX 加 fontsepc/xeCJK/zhspacing 的方法,只要注意加上合适的 RawFeature 即可。不再举例。

必须指出,XeTeX 虽然可以直接得到正确的直排字形,但直排文字的盒子位置与实际字符仍然是偏离的。这里,我们既不能像使用 ttf2tfm 的 -y 选项一样修正这些盒子,也不能使用 CJKvert 包的位置修正功能。因此,在 XeTeX 下直排的中英文混排依然会很难看。

[ 本帖最后由 milksea 于 2008-8-9 16:31 编辑 ]

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

34

主题

0

好友

612

积分

高级会员

My Iron Cross

Rank: 4

发表于 2008-8-8 07:42:33 |显示全部楼层
用gezhu宏包也是很不错的。
http://code.google.com/p/gezhu/

[ 本帖最后由 fntty 于 2008-8-8 07:46 编辑 ]

62

主题

0

好友

1995

积分

金牌会员

Rank: 6Rank: 6

发表于 2008-8-8 09:54:37 |显示全部楼层
试了一下:
  1. %-*- coding: utf-8 -*-
  2. \documentclass[oneside]{article}
  3. \usepackage[boldfont,slantfont,CJKnumber]{xeCJK}
  4. \setCJKmainfont{AR PL SungtiL GB}
  5. \setCJKfamilyfont{vert}[RawFeature={vertical}]{AR PL SungtiL GB}

  6. \textwidth 180mm
  7. \textheight 220mm
  8. \oddsidemargin 0pt
  9. \begin{document}

  10. \leftskip -50pt
  11. \parindent 0pt
  12. \let\hCJKsymbol\CJKsymbol
  13. \def\vCJKsymbol#1{\lower 0.12em\vbox to 1em{\vskip -.37em\hbox{\hCJKsymbol{#1}}\vfil}}
  14. \fontsize{100pt}{140pt}\selectfont

  15. \XeTeXuseglyphmetrics=0

  16. 这\fbox{是}\CJKfamily{vert}\let\CJKsymbol\vCJKsymbol
  17. \let\CJKpunctsymbol\CJKsymbol
  18. \fbox{竖}排\fbox{。}
  19. \end{document}
复制代码

[ 本帖最后由 mytex 于 2008-8-8 12:51 编辑 ]

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

131

主题

0

好友

1万

积分

超级版主

圡人|无良吐槽水车

Rank: 8Rank: 8

发表于 2008-8-8 14:08:10 |显示全部楼层

回复 #7 fntty 的帖子

第四部分打算要提及的,还没来得及写。

131

主题

0

好友

1万

积分

超级版主

圡人|无良吐槽水车

Rank: 8Rank: 8

发表于 2008-8-8 14:09:54 |显示全部楼层

回复 #8 mytex 的帖子

谢谢孙老师指点,我对 CJK 的源码还是没办法看下去,一时也没想到改法。这个改法似乎和 .fdx 文件的配置差不多。
现在我想把这种设置移植到 CJK 中,并不依赖 CJKvert,把相关代码都放进 .fd 文件中。

[ 本帖最后由 milksea 于 2008-8-8 14:22 编辑 ]
您需要登录后才可以回帖 登录 | 注册

手机版|Archiver|CTEX.ORG ( 京ICP备05002166号  

GMT+8, 2014-12-21 18:37 , Processed in 0.014985 second(s), 6 queries , Gzip On, Apc On.

Powered by Discuz! X2.5

© 2001-2012 Comsenz Inc.

回顶部