Chen Yufei's Blog

Programming Language, Apple, Linux

重装TeX的笔记

Some notes on (La)TeX

<!-- Page published by Emacs Wiki begins here -->

kpathsea 和 texmf.cnf,TDS(TeX Directory Structure) 内文件如何搜索

我对 kpathsea 只了解基本的一些知识,这里所写可能是错误的,当心误导!主要是根据 TeXLive 2005 和 teTeX 3.0 来写的。以前用 teTeX,现在 Thomas Esser 不维护以后我就使用 TeXLive 了,所以对 teTeX 的说明可能有些错误。

先介绍一些 texmf.cnf 里的变量。texmf.cnf 一般应该在系统 /usr/share/texmf/web2c 目录下,对 TeXLive 是在 /usr/share/local/texlive/2005/texmf/web2c下。(根据你的版本有一些不同)

  • TEXMFHOME
  • 默认是$HOME/texmf。主目录下的 TDS,这里用户可以自己创建他的自己的 TDS,对系统的其他人没有影响。当然如果你修改了这个变量的话可能就不是主目录下了。
  • TEXMFLOCAL
  • 这个变量 teTeX 里应该是 /usr/local/share/texmf,TeXLive 是 /usr/local/texlive/texmf-local。这里也是一个 TDS,在这里创建的 TDS 对所有使用系统的人都有效。 如果是一个人使用的话我推荐使用 TEXMFHOME 来创建自己的 TDS,这样的话不需要超级用户的权限,而且备份主目录的时候就把你的 TeX 配置也备份进去了。(这个利用到了对目录的搜索顺序,下面会提到)
  • TEXMFVAR
  • 这个变量 teTeX 里默认是 .texmf-var,TeXLive 是 .texlive2005/texmf-var)。这个文件夹下面存放的是 texconfig 运行时时生成的文件。比如 updmap 生成的字体 map file 一般是放在这个目录的 fonts 目录下。( updmap-sys 生成的 map file 则是放在 VARTEXFONTS 下。)
  • TEXCONFIG
  • texconfig 生成的配置信息都保存在这个变量定义的目录下。(另外还有一个texconfig-sys,修改系统配置的。)
  • VARTEXFONTS
  • 运行时生成的字体文件会放在这里。这个变量在以下两个条件中的一个满足时使用
  1. 源字体文件在系统目录下找到但是那个目录不可写
  2. mktex.cnf 里面启用了 varfonts

  • TEXMFDBS 和 ls-R
  • TEXMFDBS 默认和 TEXMF 相等。

    更新目录树的命令有 texhash 或者 mktexlsr。这两个命令运行以后会在所有 TEXMFDBS 目录下生成一个名为 ls-R 的文件。这个文件出去第一行

    % ls-R -- filename database for kpathsea; do not change this line.
    

    以外,剩下的就是命令“ls -1LRA”的输出。kpathsea 搜索文件的时候先搜索是否有 ls-R 这个文件,如果有就直接在这个文件里面找需要的文件而不会在去搜索文件系统。如果没有它才会去搜索文件系统。但是如果目录变量之前有2个感叹号的话,即使找不到 ls-R 文件也不会去搜索文件系统。所以当你的目录下有 ls-R 文件,当你对目录做出修改以后如果不运行 texhash 或 mktexlsr 的话 kpathsea 是不会看到你的更改的。

  • 其他变量
  • 其他变量主要都是于系统相关TDS相关的变量,有 TEXMFMAIN(系统 TDS 目录,一般是 /usr/share/texmf,TeXLive 为 texlive/2005/texmf 下), TEXMFSYSCONFIG(定义 texconfig-sys 读写配置文件的目录), TEXMFSYSVAR(texconfig-sys 的 runtime 文件保存的地方), TEXMFDIST。TEXMF 是所有目录有关变量的一个集合,注意里面各个变量的顺序决定了搜索文件时的顺序。

    kpathsea 就是根据 texmf.cnf 里面定义的这些变量来搜索需要的文件。另外这些变量也可以从环境变量中来定义,环境变量中定义的变量会覆盖掉 texmf.cnf 里面定义的变量。默认的 TEXMF 中目录的先后决定了搜索的顺序是 TEXMFCONFIG –> TEXMFVAR –> TEXMFHOME –> TEXMFSYSCONFIG –> TEXMFSYSVAR –> TEXMFMAIN –> TEXLOCAL –> TEXMFDIST利用这一点我把自己的所有配置都放在主目录下,这样的话我自己的配置一定会被使用到,也不会和系统的 TDS 混起来。这样升级和备份都方便,到其他系统上去使用的话也只要拷贝一下主目录下的 texmf 文件夹就可以。

    Type 1 和 True Type 字体生成的 PDF 文件视觉上的区别(针对中文)

    在Adobe Reader 中如果选择 Fit Width,使用Type 1 的字笔画比较细,而 True Type 的相对比较粗。个人感觉Type 1 的看起来觉得干净一点,不过似乎有点发虚,而 True Type 的因为粗所以看起来不会感觉发虚,但是却有点觉得脏。

    让dvipdfmx 生成可以搜索中文的 PDF 文档

    在 texmf/dvipdfm/dvipdfmx.cfg 中添加 map file 时要使用类似 cid-x.map 里面内容的文件。用 gbkfonts 生成的 cid-x.map 如下,使用这样的 map file 是可以的。

    gbksong@UGBK@  UniGB-UCS2-H    :0:simsun.ttf
    gbksongsl@UGBK@ UniGB-UCS2-H    :0:simsun.ttf
    gbkkai@UGBK@    UniGB-UCS2-H    :0:simkai.ttf
    

    另外如果在 dvipdfmx.cfg 中指定 gbkfonts 生成的 dvipdfm 目录下的 gbk*.map 文件的话,生成的 PDF 文件是无法搜索中文的。

    除了要注意指定 map file 以外,还需要几个 CMap 文件,文件如下:

    Adobe-GB1-UCS2 UniGB-UCS2-H UniGB-UTF16-H GBK-EUC-UCS2 UniGB-UCS2-V UniGB-UTF16-V

    这个是在何勃亮的网页里看到的,具体文件也可以在他的网页里可以下载到。

    现在不知道 CMap file 究竟是干什么用的,以后搞明白了再补上。

    dvipdfmx 生成中文书签

    \usepackage{CJKbookmarks,dvipdfm]{hyperref}
    \usepackage{CJK}
    \AtBeginDvi{\special{pdf:tounicode GBK-EUC-UCS2}}%GBK->unicode得到中文目录书签
    

    CJK 宏包与字体

    关于中文字体安装网上有不少文章的,我的Blog的LaTeX分类下也有一篇,不过是在使用wordpress.com的blog时用英文写的。

    更多的关于 CJK 和 LaTeX 是如何工作的可以去看王垠的文章,在这里。我这里只是几个自己遇到的问题。

    安装和使用中我遇到过的问题

    CJK 宏包的安装只要拷贝 texinput 目录下的文件到某个 TDS 树下的 latex 目录下。关于字体的安装可以看另外的文章,我有写过一篇,不过是英文的。不过光有这些的话还是不够的,对 CJK 宏包你还得告诉它你有哪些字体可以用,这一点如果忘了的话还是不能使用 CJK宏包。1如果你使用 gbkfonts 来安装字体的话那么会自动生成这样的文件,在 tex/latex/CJK/GB目录下。这里是一个例子,文件名是 c19song.fd:

    % This is the file c19song.fd of the CJK package
    % for using Asian logographs (Chinese/Japanese/Korean) with LaTeX2e
    % created by Werner Lemberg 
    % Version 4.3.0 (20-Jun-1999)
    
    \def\fileversion{4.3.0}
    \def\filedate{1999/06/20}
    
    % \ProvidesFile{c19song.fd}[\filedate\space\fileversion]
    % Chinese characters (extension of GB 2312)
    % character set: GBK
    % font encoding: CJK (extended)
    
    \DeclareFontFamily{C19}{song}{}
    \DeclareFontShape{C19}{song}{m}{n}{<-> CJK * gbksong}{}
    \DeclareFontShape{C19}{song}{bx}{n}{<-> CJKb * gbkhei}{}
    \DeclareFontShape{C19}{song}{m}{it}{<-> CJK * gbkkaisl}{}
    \DeclareFontShape{C19}{song}{bx}{it}{<-> CJKb * gbkheisl}{}
    \DeclareFontShape{C19}{song}{m}{sl}{<-> CJK * gbksongsl}{}
    \DeclareFontShape{C19}{song}{bx}{sl}{<-> CJKb * gbksongsl}{}
    
    \endinput
    

    如果你没有这样的文件或者文件里面指定的字体不对,可能会遇到这样的出错信息:

    (/usr/local/texlive/2005/texmf-dist/tex/latex/CJK/GB/c19song.fd)kpathsea: Running mktextfm gbk37
    mktextfm: Running mf-nowin -progname=mf \mode:=ljfour; mag:=1; nonstopmode; input gbk37
    This is METAFONT, Version 2.71828 (Web2C 7.5.5)
    
    kpathsea: Running mktexmf gbk37
    ! I can't find file `gbk37'.
    <*> ...e:=ljfour; mag:=1; nonstopmode; input gbk37
    

    看到这样的信息应该检查一下你的 CJK 宏包里面是否有c19song.fd这个文件了。其实看一下 CJK 宏包里面本来的 c19song.fd 的话对这个出错信息会稍微明白一些。

    \DeclareFontFamily{C19}{song}{\hyphenchar \font\m@ne}
    
    \DeclareFontShape{C19}{song}{m}{n}{<-> CJK * gbk}{}
    \DeclareFontShape{C19}{song}{bx}{n}{<-> CJKb * gbk}{\CJKbold}
    

    注意到这里是 CJK * gbk 而不是 CJK * gbksong,gbkfonts 生成的字体文件名字都是 gbk*,相信如果改成 gbk 的话应该就可以使用 CJK 宏包提供的 c19song.fg 了。

    使用 GBK 还是 GB

    你的 TeX 文档里面如果是 \begin{CJK*}{GBK}{song} 的话会加载 c19song.fd。如果用GB的话 TeX 这时加载的是 tex/latex/CJK/GB/c10song.fd ,然后就是下面的输出(如果你修改过 c10song.fd 的话应该就不一样了,甚至也可以通过吧)

    LaTeX Font Warning: Font shape `C10/song/m/n'
    (Font)              in size <12> not available.
    (Font)              Font shape `C10/fs/m/n'
    (Font)              tried instead on input line 16.
    

    再就是字体不能创建之类的信息了。

    指定 GB 的话会使用 c10song.fd,而使用 GBK 的话会使用 c19song.fd。关于字符集和使用编码在 fd 文件的 character set 和 font encoding 里面都有说明。另外还有 c11, c20, c21 等分别对应其他的字符集和编码。(不过这里的编码不是很明白,有的指明 font encoding 是 CJK(standard), 还有的是 CJK(extended),而 Bg5 下 c00song.fg 里是 CJK(Bg5),这个 CJK 究竟算是什么编码呢?还有就是这些数字是怎么来的,为什么偏偏是他们?)

    另外再看一下 CJK 宏包里面的 c10gbsn.fd 吧,它使用的字体是 AR PL SungtiL GB (台湾的 Arphic 公司出的,安装 TeXLive 的时候),只支持 GB 编码,所以 \begin 里面要使用 GB。(可惜的是这个字体生成的 PDF 文件字体粗细不均)

    % This is the file c10gbsn.fd of the CJK package
    %   for using Asian logographs (Chinese/Japanese/Korean) with LaTeX2e
    %
    % created by Werner Lemberg 
    %
    % Version 4.6.0 (11-Aug-2005)
    
    \def\fileversion{4.6.0}
    \def\filedate{2005/08/11}
    \ProvidesFile{c10gbsn.fd}[\filedate\space\fileversion]
    
    
    % simplified Chinese characters
    %
    % character set: GB 2312-80
    % font encoding: CJK (standard)
    
    % Arphic PL TrueType font AR PL SungtiL GB / BousungEG-Light-GB (SongTi)
    
    \DeclareFontFamily{C10}{gbsn}{\hyphenchar \font\m@ne}
    
    \DeclareFontShape{C10}{gbsn}{m}{n}{<-> CJK * gbsnlp}{}
    \DeclareFontShape{C10}{gbsn}{bx}{n}{<-> CJKb * gbsnlp}{\CJKbold}
    
    \endinput
    

    TeXLive 相对 teTeX 的好处

    1. TeXLive 跨平台,Windows, Linux, UNIX 下都可以使用。
    2. TeXLive 更统一。teTeX 在不同的 Linux 发行版里面配置文件等目录都不同,在不同的发行版里面使用 teTeX 还要先熟悉那些目录的位置。
    3. TeXLive 安装宏包方便,运行 CD 里的 install-pkg.pl 就可以了,CD 里面的宏包非常全。teTeX 要额外安装的话要看你的 Linux 发行版里面是否提供了,如果没有的话就得手工安装。
    4. teTeX 的作者 Thomas Esser 目前已经不再维护 teTeX 了,他本人建议对 teTeX 有兴趣的开发者转向 TeXLive project 去。

    [1] 我在 Arch 上装 teTeX 时因为 Arch 的 repository 里面没有 cjk-latex 所以要自己安装,因为我喜欢装在 主目录的 texmf 下面,然后看到那里有 texmf/tex/latex/CJK/GB,但是不全,就直接删掉然后把解压后的 CJK/texinput 拷贝到 texmf/tex/latex/CJK 下了,texhash 以后中文文件怎么都不能编译,一开始老是以为是字体文件找不到,就是这个时候开始看 texmf.cnf,研究 kpathsea 对文件的搜索。然后怎么都想不通为什么字体文件会找不到。就因为这个才换了 TeXLive,当然正好这时 teTeX 已经没人维护了,所以换也是值得的。但是换了以后还是不行,这次的 CJK 宏包是 TeXLive 里面提供的,所以宏包安装肯定没有为题。最后从字体安装开始重来,结果一运行完 go 那个脚本我就发现了生成的那个 tex/latex/CJK/GB/*.fd,马上意识到问题出在哪里了!

    我发现问题那天用了一个下午加一个晚上的时间到凌晨2点都没有找到问题所在,重来是第二天的事情了。发现自己有问题不解决的话就不想睡觉,其实应该放一放的,过了一段时间看问题眼光就变了,更容易找到问题所在!

    还差点错怪 teTeX 了……

    Comments