本着提问的精神像这样,我正在尝试构建一个 C 版本的TeX 程序;特别是 Taco 的CXTeX(部分元TeX)。
在 Ubuntu 14 上,我可以编译它,生成一个名为的二进制可执行文件cpdfetex
。如果你运行它(./cpedetex
),你会得到欢迎消息
这是 pdfeTeX,版本 3.141592-1.11b-2.1(Web2C 7.5.2,C 端口 0.5.1)
但是,如果你尝试执行任何超出此范围的操作(例如将文件编译.tex
为./cpdfetex foo.tex
,或\end
在终端中输入),则会收到错误消息
我找不到格式文件“cpdfetex.efm”!
知道该怎么办吗?
.efm
(首先,文件应该包含什么?)
编辑。 这动机是三重的。我想要一个 TeX 发行版
1)基本系统(只有 Knuth 的纯 TeX + Metafont),2)速度快(对于小文件,我4ms
使用 KerTeX、20ms
TeX Live 的 TeX、30ms
eTeX, 40ms
和 pdfTeX、120ms
LuaTex 开启dvi
模式编译时间都很快),并且3)可破解(最好是基于 C 的,但此时我会采取任何可以编译和运行的东西……)。
具体来说,我想访问包含输出的最终原始字节流.dvi
(就在写入磁盘之前),并将其传递给我正在编写的 C 程序(该程序可以理解格式.dvi
)。我目前正在将.dvi
输出写入磁盘(使用 TeX-the-program)并从磁盘读取(使用其他程序),但最好将其全部保存在内存中。
答案1
首先:LuaTeX 是 CXTeX 的后代。为什么这么说呢?我看不懂荷兰语,但我注意到 Taco Hoekwater 的这两篇论文有相似之处:CXTeX 发行版(MAPS 30,Voorjar(春季)2004)和LuaTEX 与 Pascal 告别(MAPS 39,EuroTeX 2009)。:-) 因此当后一篇论文说:
在 2008-2009 年的冬天,我们投入了大量时间将整个 LuaTeX 代码库手动转换为一组更接近当前编程实践的 C 源文件。大型 WEB 文件被拆分成大约五十对 C 源文件和包含头文件。
我认为这项工作受到了作者早期使用 CXTeX 的经验的影响/帮助。因此您可能只想使用 LuaTeX(它也是用 C 编写的)。它经过了更多的开发和测试,并且已知可以正常工作。
以下是我如何使用 TeX Live 发行版中的“数据”文件使 CXTeX 发挥作用(至少对于非数学而言)。(Ubuntu 17.04,gcc 6.3.3。)
为 cxtex 创建一个目录,获取源并解压:
mkdir cxtex && cd cxtex wget http://metatex.org/cxtex/cxtex-source-0.51.tar.gz tar xvfz cxtex-source-0.51.tar.gz cd cxtex-0.51/
在 中
cpdfetex/pdftex/writet1.c
,全局重命名cs_count
为其他名称(我使用了cs_count_here
)。原因:两者之间存在冲突EXTERN int cs_count; /* total number of known identifiers */
在第 29 行
cpdfetex/hash.h
,cpdfetex/pdftex/writet1.c
其中static int cs_count, cs_size, cs_size_pos;
在第 238 行,此外还有其他提及
cs_count
。在
texutil/perlemu.h
和texutil/perlemu.c
和中texutil/texexec.c
,全局strndup
一致地重命名为其他名称(我使用了strndup_here
)。原因:libc 中有一个标准函数strndup
。(注意:您也可以删除strndup
文件 中的定义texutil/perlemu.{h,c}
,以便texutil/texexec.c
使用标准 libc 函数。它可能会起作用,但我还没有尝试过。)編輯
cpdfetex/types.h
以變化typedef long int integer;
到
typedef int integer;
原因:转储格式文件时,该函数
dump_int
使用类型integer
,而undump_int
似乎经常使用类型调用int
。当我编译它时,对于我的编译器和机器架构的组合,我们有integer
8 个字节和int
4 个字节,这是不兼容的。可能还有其他更好的解决方案来解决这个问题,但这就是我所做的。在
Makefile
(顶层,内部cxtex/cxtex-0.51
)中,删除文件的提及.exe
:更改all: cd texk/kpathsea && $(MAKE) cd cpdfetex && $(MAKE) && cp cpdfetex.exe cpdfetex ../built cd texutil && $(MAKE) texutil && cp texutil.exe texutil ../built cd texutil && $(MAKE) texexec && cp texexec.exe texexec ../built
到
all: cd texk/kpathsea && $(MAKE) cd cpdfetex && $(MAKE) && cp cpdfetex ../built cd texutil && $(MAKE) texutil && cp texutil ../built cd texutil && $(MAKE) texexec && cp texexec ../built
原因:我们不是在 Windows 上构建,因此不会有任何
.exe
文件。
完成这些更改后,我们就可以进行编译了:
make
请注意,有很多警告,包括未定义行为和数组越界访问的警告。这表明代码库并不完善。完成后,将在、 和make
中创建三个二进制文件。在使用它们之前还有一些工作要做。built/
cpdfetex
texexec
texutil
移动到特定目录:我刚刚上升一级,到达我的
cxtex
目录:cd ..
创建一个 pdftex.cfg 文件:
touch pdftex.cfg
复制
plain.tex
:cp /usr/share/texlive/texmf-dist/tex/plain/base/plain.tex .
复制它引用的所有文件(字体和连字符):
cp /usr/share/texlive/texmf-dist/fonts/tfm/public/cm/{cmr{10,9,8,7,6,5},cmmi{10,9,8,7,6,5},cmsy{10,9,8,7,6,5},cmex10,cmss10,cmssq8,cmssi10,cmssqi8,cmbx{10,9,8,7,6,5},cmtt{10,9,8},cmsltt10,cmsl{10,9,8},cmti{10,9,8,7},cmu10,cmmib10,cmbsy10,cmcsc10,cmssbx10,cmdunh10}.tfm . cp /usr/share/texlive/texmf-dist/fonts/tfm/public/knuth-lib/manfnt.tfm . cp /usr/share/texlive/texmf-dist/tex/generic/hyphen/hyphen.tex .
转储格式文件:
./cxtex-0.51/built/cpdfetex -ini plain.tex '\dump'
这将创建一个名为的文件plain.efm
。现在 cxtex 就可以使用了!
创建测试文件:
echo "hello \bye" > hello.tex
并通过 TeX 运行它!
./cxtex-0.51/built/cpdfetex -efm=plain hello.tex
我用一些纯 TeX 文件(如“story.tex”甚至“xii.tex”)尝试过这种方法,效果不错。但当我尝试gentle.tex
,它只浏览了四页(其中一页恰好是空白页)就失败了:
! This can't happen (mlist4).
\Big ...eft #1\vbox to11.5\p@ {}\right .\n@space $
}}
l.477 \line{4.~$\Bigl\{
$Groups, $\bigl\{$Groups, $\{$and More%
因此,代码中存在一些错误(可能是我们在更改时引入的错误),仍需要进行调试。祝您黑客愉快!
很酷的是(与NTS不同)甚至 LaTeX 也可以:
从 TeX Live 源复制这些文件:
texmf-dist/tex/latex/base/*
和texmf-dist/fonts/tfm/public/latex-fonts/*.tfm
。跑步
./cxtex-0.51/built/cpdfetex -ini
并在
**
提示符下输入*
并按 Enter,然后\input latex.ltx
这会将格式转储到文件
texput.efm
(无法弄清楚如何更改它),您可以将其重命名为latex.efm
。
然后使用如下文件test.tex
:
\documentclass{article}
\begin{document}
This is a document.
Hello world.
This is math $x$ and $y$.
This is also math:
$$z$$
\end{document}
你可以运行:
./cxtex-0.51/built/cpdfetex -efm=texput test.tex
(或者efm=latex
如果你重命名了它)。
一旦数学模式中出现任何不平凡的东西(任何超过一个字母或数字的东西),它似乎就会出现错误,要么崩溃,要么给出奇怪的错误。现在你的 TeX 程序的源代码是可读的 C 语言,你可以尽情地调试它们了。:-)