(转载)laTEX 中文环境的架设

    技术2022-05-11  76

     转自http://www.soforge.com/emacs/teTeX-chinese.html

     

    本文的目的是说明如何在 Unix/Linux 下搭建一个 TEX 环境,并作配置和调整, 可以用来编辑和处理中文,最终生成高质量的 pdf 文档。

    文中示例都是在 NetBSD 操作系统下,结合 pkgsrc 软件包管理系统进行的。在 不同的 Unix/Linux 发行版中,teTEX 的软件包封装形式各不相同,但基本原理 和设置是一样的,因此参照本文也可以在其他系统下架设出 TEX 中文环境。

    下面表格是搭建这个 TEX 环境所需软件包,在 pkgsrc 中对应的名称和版本:

    软件包版本备注print/teTeX3-bin3.0 print/teTeX3-texmf3.0 print/teTeX3-texmfsrc3.0可选fonts/arphic-ttf2.11文鼎字体fonts/ttf2pk1.3.1 wip/tex-arphic-ttf2.11 wip/cjk-latex4.6.0 fonts/adobe-cmaps20051109 print/dvipdfmx0.0.0.20050831 fonts/t1utils1.32 fonts/ttf2pt13.44 

    这些软件包,既可以采用 pkgsrc 的源码编译机制使用 make install 进行安装, 也可以直接使用预编译的二进制软件包。但 wip 下的软件包,由于没有提供二进 制软件包,还需自己动手进行编译。

    teTEX

    TEX 在 Unix/Linux 下的分发套件是 teTEX。首先我们需要安装软件 包 print/teTeX3-bin,该软件包主要内容是 TEX 的可执行文件,包 括 latex、pdflatex、xdvi 这些命令,以及这些命令的配置文件,还有对应 的 man 和 info 等帮助信息。

    接着安装 print/teTeX3-texmf,它里面是 TEX 所使用的宏包和各种字体定义, 以及大量的帮助和示例文档。该软件包安装的目录,在 TEX 中称为 TEXMFMAIN, 对于 pkgsrc,默认是安装到 /usr/pkg/share/texmf 目录。另外一个软件 包 print/teTeX3-texmfsrc 是这些宏包的源码文件,也建议安装,它对于学习使 用这些宏包很有帮助。

    teTEX 软件包中各项功能的配置文件,位于 TEXMFMAIN 目录下。我们可以直接 编辑该目录下的文件调整配置信息,但修改后影响的是整个系统的配 置。Unix/Linux 本身是多用户的系统,其下的应用软件,都支持用户设置各自的 配置信息。teTEX 也支持这种特性,它默认使用用户 HOME 目录下的 texmf 目 录,该目录在 TEX  中称为 TEXMFHOME,修改该目录下的文件,与修 改 TEXMFMAIN 中的文件有同样的效果。另外,在用户目录中修改配置文件,最大 的好处就是当 teTeX 软件升级时,更新的软件包只会修改 TEXMFMAIN 里面的内 容,而不会覆盖用户自己定义的配置文件。

    teTEX 软件包中的 dvips 工具,默认配置输出指向的是打印机,为了生成 ps 文件,需要对配置文件进行调整。它的配置文件是 TEXMFMAIN 目录下 的 dvips/config/config.ps,为了修改 dvips 的配置,我们先复制一份配置文 件到 TEXMFHOME:

    $ mkdir -p ~/texmf/dvips/config$ cd ~/texmf/dvips/config$ cp /usr/pkg/share/texmf/dvips/config/config.ps .

    然后将 config.ps 中的

    o |lpr

    一行注释掉即可。为了让这次修改生效,还必须执行 texhash 命令。

    安装完上述软件包就可以编辑和处理英文的 TEX 文档。例如,将下面这 段 TEX 文字保存为 russell_en.tex:

    /documentclass[12pt]{article}/begin{document}/section*{What I Have Lived For}/normalsize /small The Prologue to /textit{Bertrand Russell}'sAutobiography/normalsize/bigskipThree passions, simple but overwhelmingly strong, have governed mylife: the longing for love, the search for knowledge, and unbearablepity for the suffering of mankind. These passions, like great winds,have blown me hither and thither, in a wayward course, over a greatocean of anguish, reaching to the very verge of despair./end{document}

    然后执行 LATEX 命令生成 dvi 格式文件:

    $ latex russell_en

    这个 dvi 文件,我们可以使用 TEX 中的 xdvi 工具进行查看:

    $ xdvi russell_en.dvi

    如果满意,使用 dvips 和 dvipdf 命令将 dvi 文件转换成 ps 和 pdf 格式的文 档。

    $ dvips russell_en.dvi$ dvipdf russell_en.dvi

    如果不想使用 dvi 格式作为中介,我们还可以直接用 pdflatex 命令生成 pdf 格式的文件:

    $ pdflatex russell_en

    使用 CJK

    TEX 中处理中文现在有很多种解决方案,其中最常见的是用于 LATEX 的 CJK 宏包,虽然它并不是按中文用户的习惯设计开发的,但是因为与其他 的 LATEX 宏包兼容性最好,所以最受欢迎。

    CJK 宏包的软件发布包中并不附带 TEX 格式的字体,这需要用户自己另行安装。 在 pkgsrc 中提供了 fonts/arphic-ttf,它是文鼎捐助的中文 TrueType 字体。 另外还有 fonts/ttf2pk 软件包,其中的工具可以将 TrueType 字体转换 成 TEX 可以使用的格式。wip/tex-arphic-ttf 软件包就是使用文鼎的字体 和 ttf2pk 中的工具生成可供 TEX 使用的中文字体。准备好中文字体,就可以 安装 wip/cjk-latex 这个宏包。

    下面我们就用 CJK 宏包来处理中文:

    /documentclass[12pt]{article}/usepackage{CJK}/begin{document}/begin{CJK*}{GB}{song}/section*{What I Have Lived For}/section*{我为何而生}/normalsize /small The Prologue to /textit{Bertrand Russell}'sAutobiography/noindent 伯兰特罗素自传序言/normalsize/bigskipThree passions, simple but overwhelmingly strong, have governed mylife: the longing for love, the search for knowledge, and unbearablepity for the suffering of mankind. These passions, like great winds,have blown me hither and thither, in a wayward course, over a greatocean of anguish, reaching to the very verge of despair./bigskip对爱情的渴望,对知识的追求,对人类苦难不可遏制的同情,是支配我一生的单纯而强烈的三种感情。这些感情如阵阵巨风,吹拂在我动荡不定的生涯中,有时甚至吹过深沉痛苦的海洋,直抵绝望的边缘。/end{CJK*}/end{document}

    这段文字在前面 russell_en.tex 的基础上增加了中文译文,文档的导言部分加 入使用 CJK 宏包的声明

    /usepackage{CJK}

    并在使用中文的段落前后增加 CJK 环境

    /begin{CJK}{GB}{song}.../end{CJK}

    现在将它另存为 russell_gb.tex 文件,保存时选择存为 GB2312 编码。处 理 TEX 中文文档生成 dvi 和 pdf 文件的过程与英文文档没有区别,同样是 用 latex 和 pdflatex 命令。

    汉字的复制与剪切

    上一节里面生成的中文 pdf 文档,浏览和打印都正常,但是在 Adobe Reader 中 无法实现中文段落的复制与剪切。为了使 TEX 生成的中文 pdf 文档支持这一功 能,还需要使用 print/dvipdfmx 这一软件包。

    dvipdfmx 实现中文字句的复制与剪切,需要用到 Adobe 的 CMap,因此在安 装 dvipdfmx 前要先安装 fonts/adobe-cmaps 这一软件包。

    安装完 dvipdfmx,在使用之前,还需将系统中所使用的中文字体告诉它。前面我 们安装的是文鼎的字体,因此在 /texmf/dvipdfm/config/cid-x.map 中添加:

    % Arphic GB TrueType fontsgbsn00lp@UGB@ UniGB-UCS2-H :0:gbsn00lp.ttfgkai00mp@UGB@ UniGB-UCS2-H :0:gkai00mp.ttf

    然后执行 texhash 命令更新。

    为了生成支持复制和剪切的中文 pdf 文档,就不能使用 pdflatex 命令,而必须 分两步操作,第一步生成 dvi 文件,再用 dvipdfmx 转换成 pdf 文件。例如:

    $ latex russell_gb$ dvipdfmx russell_gb.dvi

    Unicode

    文鼎的字体只支持 GB2312 字符集,当前已经不能满足中文处理的要求。要使用 较大的字符集,我们可以选择 GBK 或者 Unicode。由于 Unicode 有更广泛的应 用面,下面就介绍在 TEX 中使用 Unicode 的方法。

    teTEX 软件包中有一个 Omega 程序,它是为了更好地支持 Unicode 等多字节的 文档用来替代 TEX。现在虽然已经可以处理中文,但仍处于开发阶段,并与已有 宏包的兼容性不是很好,所以实用性不高。因此,当前的解决方案还是 在 TEX 的基础上进行扩充,来支持 Unicode 文档的处理。

    CJK 宏包内包含了对 UTF8 编码的支持,由于没有对应的字体,还需要另外生成。 与使用 GB2312 编码的字体一样,需要先准备好字体,再用 ttf2pk 里面的工具 进行转换。

    这里有一个 shell 脚本 cvtfont.sh 可以辅助生成 TEX 字体和配置文件:

    #!/bin/sh## Origin By Edward G.J. Lee 2001.11.25# http://www.study-area.org/tips/latex/pdftex.html# This code is Public Domain.## Enhanced by intron@intron.ac, 2006.1.9# Modified for NetBSD by jungle@soforge.com, 2006.1.14# Italic support added by robert.zhangle@gmail.com, 2006.5.19#if [ $# -ne 3 ]then cat << EOFUsage: `basename $0` font.ttf <TeX_Internal_Font_Name> <Tex_Font_Name> <TeX_Internal_Font_Name>: Used to name *.enc, *.afm, *.pfb, *.tfm & *.map <Tex_Font_Name>: Used in TeX source: /CJKencfamily{UTF8}{Tex_Font_Name} An example: `basename $0` gbsn00lp.ttf gbsn00lp songpt1EOF exit 1fiif ! which ttf2pt1; then echo "Please install pkgsrc fonts/ttf2pt1 before you can run me." exit 1fiif ! which t1asm; then echo "Please install pkgsrc fonts/t1utils before you can run me." exit 1fiif ! which extconv; then echo "Please install pkgsrc chinese/CJK before you can run me." exit 1ficat <<EOF**************************************************************************** Please confirm that current working directory is EMPTY except scripts ** and HAS ENOUGH SPACE to contain so many intermediate files. ** If it is not empty, this script may DAMAGE INNOCENT FILES!!! ****************************************************************************EOFread -p "Go ahead?[n]" aif [ "$a" != "y" ] && [ "$a" != "Y" ]; then exit 0 fiFONTFILENAME="$1"FONTNAME="$2"FONTTEXNAME="$3"TEXMFHOME=`kpsexpand '$TEXMFHOME'`ENCDIR=${TEXMFHOME}/fonts/enc/dvips/local/${FONTNAME}AFMDIR=${TEXMFHOME}/fonts/afm/local/${FONTNAME}TFMDIR=${TEXMFHOME}/fonts/tfm/local/${FONTNAME}PFBDIR=${TEXMFHOME}/fonts/type1/local/${FONTNAME}MAPDIR=${TEXMFHOME}/fonts/map/dvips/localUPDMAPCFG=${TEXMFHOME}/web2c/updmap.cfgif [ ! -f $UPDMAPCFG ]then SYSUPDMAPCFG=`kpsewhich -format 'web2c files' updmap.cfg` cp $SYSUPDMAPCFG $UPDMAPCFGfiCIDXMAP=${TEXMFHOME}/dvipdfm/config/cid-x.mapif [ ! -f $CIDXMAP ]then touch $CIDXMAPfiCJKDIR=${TEXMFHOME}/tex/latex/CJK/UTF8INSTALLDIRMODE="-m 0755"INSTALLMODE="-m 0644"FONTFILEBASENAME=`basename "$FONTFILENAME"`FDNAME=c70${FONTTEXNAME}.fd#MAPFILE=/usr/local/share/ttf2pt1/maps/cugb.mapPLANENUM=255# Initialize ${FONTNAME}.mapecho -n "" > ${FONTNAME}.mapn=0echo "Generating subfonts from plane $n to plane $PLANENUM ..."while [ $n -le $PLANENUM ]do m=`printf x $n` echo -n "[$n]" SUBFONTNAME=${FONTNAME}${m} # Generate *.t1a *.afm *.enc ttf2pt1 -GAE -pft -OHUBs -W0 -l plane+pid=3,eid=1,0x$m / "$FONTFILENAME" ${SUBFONTNAME} # avoid dvips(k)(before v5.86) t1part module bug. perl -pi -e 's/_/Z/g' ${SUBFONTNAME}.t1a ${SUBFONTNAME}.afm # Generate *.pfb t1asm -b ${SUBFONTNAME}.t1a > ${SUBFONTNAME}.pfb 2>/dev/null # Generate *.tfm afm2tfm ${FONTNAME}$m.afm ${FONTNAME}$m.tfm >/dev/null afm2tfm ${FONTNAME}$m.afm -s .167 ${FONTNAME}sl$m.tfm >/dev/null # Generate ${FONTNAME}.map AFMNAME=`grep -m 1 -i fontname ${SUBFONTNAME}.afm | cut -d ' ' -f 2` echo "${FONTNAME}$m ${AFMNAME} <${FONTNAME}$m.pfb" >> ${FONTNAME}.map echo "${FONTNAME}sl$m ${AFMNAME} /" .167 SlantFont /" <${FONTNAME}$m.pfb" / >> ${FONTNAME}.map n=`expr $n + 1`doneechocat > ${FDNAME} << EOF% This file is automatically generated by `basename $0`//def//fileversion{0.0.1}//def//filedate{`date +%Y/%m/%d`}//ProvidesFile{${FDNAME}}[//filedate//space//fileversion]//DeclareFontFamily{C70}{${FONTTEXNAME}}{//hyphenchar //font//m@ne}//DeclareFontShape{C70}{${FONTTEXNAME}}{m}{n}{<-> CJK * ${FONTNAME}}{}//DeclareFontShape{C70}{${FONTTEXNAME}}{bx}{n}{<-> CJKb * ${FONTNAME}}{//CJKbold}//DeclareFontShape{C70}{${FONTTEXNAME}}{m}{it}{<-> CJK * ${FONTNAME}sl}{}//DeclareFontShape{C70}{${FONTTEXNAME}}{bx}{it}{<-> CJKb * ${FONTNAME}sl}{//CJKbold}//DeclareFontShape{C70}{${FONTTEXNAME}}{m}{sl}{<-> CJK * ${FONTNAME}sl}{}//DeclareFontShape{C70}{${FONTTEXNAME}}{bx}{sl}{<-> CJKb * ${FONTNAME}sl}{//CJKbold}//endinputEOF#exit 0;echoecho "Installing ..."install -d $INSTALLDIRMODE $ENCDIR $AFMDIR $TFMDIR $PFBDIR $MAPDIR $CJKDIRn=0while [ $n -le $PLANENUM ]do m=`printf x $n` echo -n "[$n]" install $INSTALLMODE ${FONTNAME}${m}.enc $ENCDIR install $INSTALLMODE ${FONTNAME}${m}.afm $AFMDIR install $INSTALLMODE ${FONTNAME}${m}.tfm $TFMDIR install $INSTALLMODE ${FONTNAME}sl${m}.tfm $TFMDIR install $INSTALLMODE ${FONTNAME}${m}.pfb $PFBDIR n=`expr $n + 1`doneechoinstall $INSTALLMODE ${FONTNAME}.map $MAPDIRinstall $INSTALLMODE $FDNAME $CJKDIRecho >> $UPDMAPCFGecho "Map ${FONTNAME}.map" >> $UPDMAPCFG# update cid-x.mapecho "${FONTNAME}@Unicode@ unicode :0:${FONTFILENAME}" >> $CIDXMAPecho "${FONTNAME}sl@Unicode@ unicode :0:${FONTFILENAME}" >> $CIDXMAPmktexlsr#updmap-sysupdmapread -p "Do you want remove all intermediate files?[n]" aif [ "$a" = "y" ] || [ "$a" = "Y" ]; then n=0 while [ $n -le $PLANENUM ] do m=`printf x $n` echo -n "[$n]" rm -f ${FONTNAME}${m}.enc ${FONTNAME}${m}.afm ${FONTNAME}${m}.t1a / ${FONTNAME}${m}.pfb ${FONTNAME}sl${m}.tfm ${FONTNAME}${m}.tfm n=`expr $n + 1` done echo rm -fv $FDNAME ${FONTNAME}.mapfiechoecho "OK, all done. :-)"echo

    这个脚本将 TrueType 生成 Type1 字体,过程中使用 了 t1asm 和 ttf2pt1 工具,因此使用前要先安装 fonts/t1utils 和 fonts/ttf2pt1 软 件包。

    下面示例用的是 Solaris 10 里面的方正中文字体。TEX  要求 TrueType字体放 在 fonts/truetype 目录下,为了与其他字体区分开来,这里再建一个 local 子 目录,然后放入将要处理的几款字体,包 括 fangsongti.ttf、heiti.ttf、kaiti.ttf 和 songti.ttf。

    接着,就用上面的脚本处理这些字体:

    $ ./cvtfont.sh fangsongti.ttf fzfs fzfs$ ./cvtfont.sh heiti.ttf fzhei fzhei$ ./cvtfont.sh kaiti.ttf fzkai fzkai$ ./cvtfont.sh songti.ttf fzsong fzsong

    文档中使用 UTF8 字体的时候,需要将文件中的

    /begin{CJK}{GB}{song}

    替换为

    /begin{CJK}{UTF8}{fzsong}

    用 TEX 命令处理该文档时,文件本身必须是 UTF8 编码的。现将前面示例  russell_gb.tex 另存为 russell_utf.tex,保存时编码选成 UTF8。TEX  命令的使用方法与处理 GB2312 编码的文档相同。

    中文 bookmarks

    pdf 格式的文档有一个特性 -- bookmarks,让用户可以打开一个树状的索引浏 览文章的各个章节,这在阅读较大的文档时非常方便。TEX 中可以使 用 hyperref 宏包实现这一功能。

    pdf 的 bookmarks 对文字的编码要求比较特殊,它可以使用两种编码:ISO Latin 1 或 Unicode UTF16 Big Endian。TEX 处理像中文这种多字节语言,即 使文档采用 UTF8 编码保存,仍然无法得到正确的 bookmarks,这需要在文档中 使用特殊的命令。

    下面是常用的 hyperref 宏包的调用方法:

    /usepackage[dvipdfm,CJKbookmarks,bookmarks=true,%bookmarksnumbered=true]{hyperref}

    对于 GB2312 编码的文件,我们可以在其后加上一行特殊指令:

    /AtBeginDvi{/special{pdf:tounicode GBpc-EUC-UCS2}}

    而 UTF8 编码的文件,则使用:

    /AtBeginDvi{/special{pdf:tounicode UTF8-UCS2}}

    其中 UTF8-UCS2 的 CMap,需要到 这里下载一个文件包,然后将 UTF8-UCS2 文件复制到 TEXMFHOME/dvipdfm/CMap 目录下

    Emacs 下的 TEX 编辑环境

    由于 TEX 文档是纯文本文件,我们可以使用任何一款自己熟悉的编辑器进行编 写。编辑完后,再转到命令行下,调用相应的 TEX 命令进行处理。虽然这种经 典的操作步骤也可以完成日常工作,但现在有很多对 TEX 支持良好的编辑器, 可以大幅提高工作效率。在 Unix/Linux 的世界,Emacs 是一个强大的编辑器, 它有很多的模式对 TEX提供支持。这一节就 Emacs 和 AUCTeX 模式下编辑和处 理 TEX 文档进行简单的介绍。

    安装

    Emacs 最新的稳定版本是 21.4,但它不支持 Unicode,如果要编辑 UTF8 编码 的文件,还需要安装 mule-ucs 包进行转换。Emacs 和 mule-ucs 软件包 在 pkgsrc 中的位置是 editors/emacs 和 editors/mule-ucs。Emacs 的当前开 发版本 22.0.50 已经内含了 Unicode 的支持,而且稳定性也不错,建议使用。 这个版本可以使用 cvs 从 GNU savannah 获取:

    $ cvs -d :pserver:anonymous@cvs.savannah.gnu.org:/cvsroot/emacs co emacs

    编译安装的步骤为:

    $ ./configure$ make bootstrap# make install

    AUCTeX 可以从 这里下载,然后使用下面命令进行编译安装:

    $ ./configure$ make# make install

    设置

    为了在 Emacs 运行时加载 AUCTeX,需要在 HOME 目录的 .emacs 配置文件中加 入下面语句:

    (load "auctex.el" nil t t)

    如果需要 preview 功能,可以加上

    (load "preview-latex.el" nil t t)

    AUCTeX 还可以和 RefTeX 模式配合使用

    (autoload 'reftex-mode "reftex" "RefTeX Minor Mode" t)(autoload 'turn-on-reftex "reftex" "RefTeX Minor Mode" nil)(autoload 'reftex-citation "reftex-cite" "Make citation" nil)(autoload 'reftex-index-phrase-mode "reftex-index" "Phrase mode" t)(add-hook 'LaTeX-mode-hook 'turn-on-reftex);(add-hook 'latex-mode-hook 'turn-on-reftex);

    其中 LaTeX-mode 指的是 AUCTeX 提供的模式, latex 是 Emacs 内含的模式。

    我们还可以给 TEX 模式加入 Emacs 里面常用的自动换行、拼写检查、outline 等常用功能:

    (add-hook 'LaTeX-mode-hook (function (lambda () (auto-fill-mode) (outline-minor-mode) (flyspell-mode))))(add-hook 'latex-mode-hook (function (lambda () (auto-fill-mode) (outline-minor-mode) (flyspell-mode))))

    如果要让 AUCTeX 正确处理多个文件组成的文档,还需加入

    (setq TeX-auto-save t)(setq TeX-parse-self t)(setq-default TeX-master nil)

    CJK 宏包也有两个工具配合 AUCTeX 使用,它们位于 cjk 发布包的 utils/lisp 目 录下:cjkspace.el 和 emacs/cjk-enc.el。将它们复制到 Emacs 搜索加载的路 径,然后在 .emacs 中加入

    (load-library "cjk-enc")(autoload 'CJK-insert-space "cjkspace" "Insert tildes appropriately in CJK document." t)(defun cjk-LaTeX-mode-hook () "CJK key definitions for LaTeX mode." (define-key LaTeX-mode-map " " 'CJK-insert-space))(add-hook 'LaTeX-mode-hook 'cjk-LaTeX-mode-hook)

    在 AUCTeX 模式下编辑一个 TEX 文档,不再需要切换到命令行下,可以 用 Emacs 的快捷键调用 TEX 命令。

    Ctrl+c Ctrl+c 这是使用最频繁的快捷键。首次键入时,它通 常调用 latex 命令处理当前 buffer 中的文件。再次键入时,它默认会调 用 xdvi 程序查看上一命令生成的 .dvi 文件。如果不想使用 AUCTeX 建议 使用的命令,可以按下 TAB 键浏览和选择所需的命令。

    对于 AUCTeX 没有提供的命令,我们自己可以进行扩充。比如,加入 dvipdfmx 命令,只需在 .emacs 中加入:

    (require 'tex)(add-to-list 'TeX-command-list (list "dvipdfmx" "dvipdfmx %s.dvi" 'TeX-run-command nil t))

    Ctrl+c ` 执行 LATEX 命令如果遇到了错误,用此快捷键可 以定位错误信息。

    Ctrl+c Ctrl+r 如果想只查看文件中的某一部分内容的输出 效果,比如一个数学公式,可以先用 mark 将其设置到一个区域内,然后此 快捷键,可以像理整个文档一样处理该区域。对于大型文档,这种方法可以 节约不少时间。

    Ctrl+c Ctrl+t Ctrl+p 如果想直接生成 pdf 文件而跳 过 dvi 文件这一步骤,可以用它在 dvi 和 pdf 之间切换,也就是选择调 用 latex 或 pdflatex 命令。

    除了能很方便地调用 TEX 命令,AUCTeX 还提供了键入 TEX 文档中宏和环境 的快捷方法。

    Ctrl+c Ctrl+e 输入环境,像 quote、verbatim,甚 至 documentclass 和 CJK 也可以用它来输入。 Ctrl+c Ctrl+s 输入段落的章节。 Ctrl+c Enter 输入宏,比如 usepackage、ref 等等。 Ctrl+c Ctrl+f 插入特殊的字体,插入黑体为 Ctrl+b,斜体 为 Ctrl+i 等等。 Ctrl+c Ctrl+j 插入 itemize 等环境的下一个 item。

    如果这些快捷键记不住,通过 AUCTeX 提供的菜单上也能选择所需的命令。

        

    最新回复(0)