我目前正在实现一个非平凡的软件组件(与排版无关),并希望将其与来自同一领域和其他领域的其他组件(包括 TeX)进行比较。我一直在尝试查找原始 TeX(不是 LaTeX)的源代码行数,但到目前为止还没有找到任何信息。
据我了解,TeX 已经以使用 WEB 的文学编程风格实现,因此源代码和代码级文档实际上是在同一个文件中。
显然 TeX 也是以结构化编程的风格实现的。我发现 Knuth 编写的一个结构化程序有 50,000 行代码(来源:http://www.literateprogramming.com/lpquotes.html) 但这可能不是 TeX。
我还发现了 Metafont 的行数,它似乎有 23,000 行代码(来源:http://walden-family.com/ieee/dtp-tex-part-1.pdf)
那么,标准 TeX 系统有多少行代码呢?如果能提供指向原始 WEB 源代码的参考资料就更好了;输入起来并不难wc -l
。
有关的:实现 TeX 需要多少人年?...尽管这与人年有关,而不是源代码。
答案1
这
tex.web
文件目前包含 24985 行。这是文学编程风格,因此有很多可以称为注释的内容。当通过时
tangle
(例如tangle tex.web
),您将获得 Pascal 代码,但这与 JavaScript 压缩器生成的代码相当:所有语句都挤在一行上,并且在本质上是临时的位置有换行符。(此文件中大约有 6115 行,但这实际上并不意味着什么。)如果您
tex.p
通过 Pascal 漂亮打印机运行此程序,则可能更能显示程序的大小:我运行后ptop -l 10000 tex.p tex.pretty.p
,生成的文件长度为 20619 行。当然,这取决于漂亮器等。相反,如果你
tex.web
跑过weave
,你会看到一个包含“注释”的程序排版列表;这是程序的阅读方式,也是它作为一本书出版的形式。在标准设置下,生成的 PDF有 1379 个模块和索引,打印在约 500 页上。从某种意义上说,这
tex.web
不是“完整”程序,而是一个假定的“公分母”程序,旨在轻松移植到当时(1982 年)存在的任何 Pascal 编译器。当移植到这样的计算机安装(操作系统、文件约定等)时,它将附带一个(希望很小的)“更改文件”。(事实上,即使在斯坦福的原始 TeX 安装中也使用了这样的更改文件,其中本地编辑器的文本文件包含页面,键盘包含相当多的非 ASCII 字符等。)因此,您可能也需要考虑这样的更改文件。
最后,下面的图片(通过这里),其中间区域(即如果忽略外面的四个大框)显示了程序不同部分的粗略相对大小(以代码行数/模块数计算):
编辑:以上只是我早上出门前发布的一个快速答案,但如果您有兴趣的话:
Knuth 1989 年的论文TeX 的错误(DOI 10.1002/spe.4380190702),其更新版本已转载至他的合集文学编程,对 TeX 的发展进行了权威而详细的描述。他自己在论文中统计道:
现在 TeX82 正处于第三阶段也是最后阶段。*它已经从 SAIL 中原来的 4600 条语句发展到 WEB 中的 1376 个模块,相当于 Pascal 中的约 14,000 条语句。
(* 1991 年添加的脚注(因此仅在书中)提到了(7 位→8 位)“1989 年的重大变化,可以说开启了 TeX82 的“第 4 阶段””。)
您想知道的更多信息:我已经开始编写(目前非常不完整)网页关于该程序和我阅读它的尝试。:-)
具体来说,为了了解程序的大小,你可能需要查看理查德·桑德伯格的将 tex.web 手动翻译成 C++,只保留代码,几乎没有注释:.cpp (17426 行 (16045 sloc)),.h(3068 行(2675 sloc))
如今,几乎所有 TeX 的使用都是通过在扩展的 TeX 程序上运行的大型宏包(如 LaTeX)进行的,因此(即使不计算宏包的大小,其行数也比 TeX 本身还要多!)您可能需要考虑 eTeX、pdfTeX 和 XeTeX,它们分别比 Knuth TeX 大约 15%、50-60% 和(严重依赖系统库)35%。
答案2
为了补充 ShreevatsaR 的优秀答案,这里是的开头tex.p
,即“纠结”形式的tex.web
{4:}{9:}{$C-,A+,D-}{[$C+,D+]}{:9}program TEX;label{6:}1,9998,9999;
{:6}const{11:}memmax=30000;memmin=0;bufsize=500;errorline=72;
halferrorline=42;maxprintline=79;stacksize=200;maxinopen=6;fontmax=75;
fontmemsize=20000;paramsize=60;nestsize=40;maxstrings=3000;
stringvacancies=8000;poolsize=32000;savesize=600;triesize=8000;
trieopsize=500;dvibufsize=800;filenamesize=40;
poolname='TeXformats:TEX.POOL ';
对应于的这一部分tex.dvi
,即的“编织形式” tex.web
:
列表tex.web
是
@ The program begins with a normal \PASCAL\ program heading, whose
components will be filled in later, using the conventions of \.{WEB}.
@.WEB@>
For example, the portion of the program called `\X\glob:Global
variables\X' below will be replaced by a sequence of variable declarations
that starts in $\section\glob$ of this documentation. In this way, we are able
to define each individual global variable when we are prepared to
understand what it means; we do not have to define all of the globals at
once. Cross references in $\section\glob$, where it says ``See also
sections \gglob, \dots,'' also make it possible to look at the set of
all global variables, if desired. Similar remarks apply to the other
portions of the program heading.
Actually the heading shown here is not quite normal: The |program| line
does not mention any |output| file, because \ph\ would ask the \TeX\ user
to specify a file name if |output| were specified here.
@:PASCAL H}{\ph@>
@^system dependencies@>
@d mtype==t@&y@&p@&e {this is a \.{WEB} coding trick:}
@f mtype==type {`\&{mtype}' will be equivalent to `\&{type}'}
@f type==true {but `|type|' will not be treated as a reserved word}
@p @t\4@>@<Compiler directives@>@/
program TEX; {all file names are defined dynamically}
label @<Labels in the outer block@>@/
const @<Constants in the outer block@>@/
mtype @<Types in the outer block@>@/
var @<Global variables@>@/
@#
procedure initialize; {this procedure gets things started properly}
var @<Local variables for initialization@>@/
begin @<Initialize whatever \TeX\ might access@>@;
end;@#
@t\4@>@<Basic printing procedures@>@/
@t\4@>@<Error handling procedures@>@/
显然,代码行数tex.p
非常粗略地表明了程序的复杂性。tangle
从 Web 文件中提取 Pascal 源代码的程序的名称准确地表达了它的作用:它将“文学程序”变成非常紧凑且不太人性化的东西。
检查 TeX Live 中用于编译 TeX 的 C 版本也没有定论,因为 C 源代码也相当复杂。