让 luatex plain 输出 pdf
在“luatex plain 从零构建” 一文中,讲述了如何建立一个什么也干不了的 luatex plain 包。本文在 luatex plain 基础结构上,重新生成一份 Plain TeX 格式文件,使之可以支持 pdf 文件的输出,并添加一些西文字体。这样,我们便可以使用 luatex plain 进行一些西文文档的排版了。
注意,如无特殊说明,本文所言及的各 TeX 程序的运行,均是在使用 luatex-plain/setuptex 脚本开启 luatex plain 环境的前提下进行的。
格式
“luatex plain 从零构建”文中所讲的 Plain TeX 格式是基于 Knuth 的 plain.tex 文件产生的。为了产生可以输出 pdf 的 Plain TeX 格式,我们需要重新构造一个 tex 文件,在其中添加一些 luatex 原语(luatex 提供的 TeX 基本控制序列),并打开它的 pdf 输出功能。
首先,建立 luatex-plain/texmf/tex/generic/luatex 目录,然后在该目录中存放 luatex-plain.tex 文件,其内容如下:
\input plain \directlua { tex.enableprimitives('',tex.extraprimitives()) } \pdfoutput=1 \dump
luatex-plain.tex 文件的第 2 行代码用于开启对 luatex 提供的 TeX 原语的访问权限,这样我们方可使用像 \pdfoutput 这样的 luatex 原语。
然后,修改 texmf.cnf 文件,在 TEXINPUTS 变量中添加 luatex-plain.tex 的查找路径,如下:
TEXMFMAIN = $SELFAUTOPARENT/texmf TEXMFSYSVAR = $SELFAUTOPARENT/texmf-var TEXMF = {!!$TEXMFMAIN,!!$TEXMFSYSVAR} TEXMFDBS = $TEXMF TEXFORMATS = .;$TEXMF/web2c/luatex TEXINPUTS = .;$TEXMF/tex/{plain,generic}/{base,hyphen,luatex}// TFMFONTS = .;$TEXMF/fonts/tfm//
继而使用 mktexlsr 命令刷新 TeX 目录结构。
最后,使用 `luatex --ini --jobname=luatex luatex-plain` 命令重新生成 luatex.fmt 文件,并将其存储与 luatex-plain/texmf-var/web2c/luatex 目录。
测试
为了验证新的 Plain TeX 格式是否真的支持 pdf 输出,可对下面的 test.tex 文档进行编译。
Hello Lua\TeX! \bye
事实上是无法编译的,出错信息大致如下:
$ luatex test This is LuaTeX, Version beta-0.63.0-2010092018 (rev 3896) (./test.tex [1] kpathsea: Running mktexpk --mfmode / --bdpi 72 --mag 1+0/72 --dpi 72 cmr10 mktexpk: Cannot find mktex.opt; check your installation. kpathsea: Appending font creation commands to missfont.log. ) !LuaTeX error (file cmr10): Font cmr10 at 72 not found ==> Fatal error occurred, no output PDF file produced!
这个错误是因为我们没有对应的 CM 字体而导致的。回忆一下,在“luatex plain 从零构建”文中,我们只是安装了 CM 字体的字距文件,即 tfm 文件,而并未提供 CM 字体的字形文件。因此,在 luatex 生成 pdf 文件时企图嵌入字形,结果 kpathsea 库发现字形文件找不到,于是 kpathsea 库会自作聪明的去调用 mktexpk 程序去创建字形文件,结果却没有对应的 Metafont 源文件或者 Type1 字体文件,于是 kpathsea 只好沮丧的宣告它败了,继而 luatex 宣告它也败了。
字体与映射
虽然 luatex 的一大特色是直接支持 TrueType、OpenType 这样的矢量字体,但是本文所讲述的只是 luatex 比较传统的字体使用方法,这 luatex 从 pdftex 那里继承而来的。
CM 字体原本是 Knuth 使用 Metafont 设计的西文字体,它是位图字体(pk 格式)。我们可以使用 OpenType 格式 的 lm 字体去作为替代字体。如果仅仅是为了成功编译上述的 test.tex 文件,根据错误信息,那么我们只需要拥有 cmr10 的替代字体即可。
首先,我们可从 http://www.ctan.org/tex-archive/fonts/lm/fonts/opentype/public/lm/ 下载 lmroman10-regular.otf 文件,并构建 luatex-plain/texmf/fonts/opentype/lm 目录,将 lmroman10-regular.otf 字体文件置于其中。
然后,需要在 texmf.cnf 文件添加 OPENTYPEFONTS 变量的定义,使得 kpathsea 库可以找到 .otf 字体文件。更新后的 texmf.cnf 内容如下:
TEXMFMAIN = $SELFAUTOPARENT/texmf TEXMFSYSVAR = $SELFAUTOPARENT/texmf-var TEXMF = {!!$TEXMFMAIN,!!$TEXMFSYSVAR} TEXMFDBS = $TEXMF TEXFORMATS = .;$TEXMF/web2c/luatex TEXINPUTS = .;$TEXMF/tex/{plain,generic}/{base,hyphen,luatex}// TFMFONTS = .;$TEXMF/fonts/tfm// OPENTYPEFONTS = .;$TEXMF/fonts/opentype//
继而,需要构建 luatex-plain/texmf/fonts/map/pdftex/plain 目录,在其中建立 pdftex.map 文件。这个 .map 文件的作用是告诉 luatex 要使用一种字体去替换另一种字体。我们的目的是使用 lmroman10-regular.otf 替换 cmr10.pk,因此 pdftex.map 的内容如下:
cmr10 LMRoman10-Regular "enclmrepcmrm ReEncodeFont" <lm-rep-cmrm.enc <lmroman10-regular.otf
上述代码可以告诉 luatex:我要使用 lmroman10-regular.otf 字体,按照 lm-rep-cmrm.enc 文件定义的规则,替换 cmr10.pk 字体相应的字形。
为了让 luatex 在运行时通过 kpathsea 库发现 pdftex.map 文件的存在,需要在 texmf.cnf 文件中添加 TEXFONTMAPS 变量的定义。更新后的 texmf.cnf 文件内容如下:
TEXMFMAIN = $SELFAUTOPARENT/texmf TEXMFSYSVAR = $SELFAUTOPARENT/texmf-var TEXMF = {!!$TEXMFMAIN,!!$TEXMFSYSVAR} TEXMFDBS = $TEXMF TEXFORMATS = .;$TEXMF/web2c/luatex TEXINPUTS = .;$TEXMF/tex/{plain,generic}/{base,hyphen,luatex}// TEXFONTMAPS = .;$TEXMF/fonts/map/pdftex// TFMFONTS = .;$TEXMF/fonts/tfm// OPENTYPEFONTS = .;$TEXMF/fonts/opentype//
前面提到,在使用 lmroman10-regular.otf 替换 cmr10.pk 时,需要 lm-rep-cmrm.enc 文件的支持,该文件可从 http://www.ctan.org/tex-archive/fonts/lm/fonts/enc/dvips/lm/ 下载,并构建 luatex-plain/texmf/fonts/enc/dvips/lm 目录,将下载的 lm-rep-cmrm.enc 文件存于其中。为了可让 kpathsea 库能够搜索到这个文件,我们依然需要孜孜不倦的修改 texmf.cnf 文件,向其中添加 ENCFONTS 变量的定义。更新后的 texmf.cnf 文件内容如下:
TEXMFMAIN = $SELFAUTOPARENT/texmf TEXMFSYSVAR = $SELFAUTOPARENT/texmf-var TEXMF = {!!$TEXMFMAIN,!!$TEXMFSYSVAR} TEXMFDBS = $TEXMF TEXFORMATS = .;$TEXMF/web2c/luatex TEXINPUTS = .;$TEXMF/tex/{plain,generic}/{base,hyphen,luatex}// TEXFONTMAPS = .;$TEXMF/fonts/map/pdftex// ENCFONTS = .;$TEXMF/fonts/enc/dvips// TFMFONTS = .;$TEXMF/fonts/tfm// OPENTYPEFONTS = .;$TEXMF/fonts/opentype//
当做完上述准备工作后,使用 `mktexlsr` 命令刷新 TeX 目录结构。此后,便可以使用 luatex 成功编译 test.tex 文件了。
转载时,希望不要链接文中图片,另外请保留本文原始出处:http://garfileo.is-programmer.com