简洁版本:
TeX Live 2017 和 2018 之间\openin
文件打开 ( )的一些细微行为似乎在不同环境中有所不同。只有 Overleaf 的行为不同。我没有看到任何关于此的通知,但为什么呢?
考虑以下代码:
\openin1 \read1 to \X \closein1 \show\X
通常\openin
后面应该跟一个文件,但这里省略了。TeX/e-TeX/e-(u)pTeX/XeTeX/LuaTeX 的背页(TL2017)显示\par
,但我的本地安装(TL2018)和云 LaTeX(TL2017),网络上的日语 TeX(TL2016;仅 e-pTeX 可用)不显示任何内容(空)。
与e-TeX类似的区别:
\openin1 \readline1 to\X\show\X\readline1 to\X\show\X\readline1 to\X\show\X\closein1 \bye
Overleaf 的 e-TeX 只返回^^M
并停止,但我的本地安装的 e-TeX 显示:
> \X=macro:
->%%^^M.
<*> \openin1 \readline1 to\X\show\X
\readline1 to\X\show\X\readline1 to\X\sho...
?
> \X=macro:
->%% This is file `.tex',^^M.
<*> ...readline1 to\X\show\X\readline1 to\X\show\X
\readline1 to\X\show\X\clo...
?
> \X=macro:
->%% generated with the docstrip utility.^^M.
<*> ...readline1 to\X\show\X\readline1 to\X\show\X
\closein1 \bye
?
No pages of output.
以下是我根据这些行为做出的猜测:
- ??? 在 Overleaf 中被阅读,
tools/.tex
正在我的本地安装 Cloud LaTeX 中读取
我不认为这是一个问题;只是出于好奇。
答案1
一些观察:
到目前为止,这种异常行为似乎只能在背页尽管该问题的早期版本提到了 OP 对 TL 2017 和网络上的日语 TeX。
在 Overleaf 上,这种行为(其中
\X
设置为\par
)不仅可以通过\openin1 \read1 to \X
(如问题中所示)重现,甚至可以通过\openin1= \read1 to \X
和重现\openin1="" \read1 to \X
,但是不是with\openin1=".tex" \read1 to \X
(在这种情况下\X
设置为空宏,与其他环境相同)。事实上,使用\verbatiminput{.tex}
(使用 LaTeX 和 进行编译\usepackage{verbatim}
),可以看到即使在 Overleaf 上,也.tex
存在相同的文件,我们在其他环境中看到它已加载(texmf-dist/tex/latex/tools/.tex
)。(这很有趣,从 读取""
与从 读取不同".tex"
。)因此,排除该解释后,让我们坚持使用这种\openin1="" \read1 to \X
形式,因为它可能最清楚。有时
\read
会尝试从终端读取,所以这是另一种可能的解释。但如果我们\openin1="nonexistent.tex" \read1 to \X
在 Overleaf 上尝试,我们会收到一条来自 TeX 的消息cannot \read from terminal in nonstop modes
,提示 TeX 正在使用\batchmode
或运行\nonstopmode
。即使我们尝试通过先\errorstopmode
在文件中执行来强制解决问题,我们也会得到“End of file on the terminal!
”。所以这个解释也被排除了,这只会加深谜团:如果 TeX 没有从文件读取.tex
,也没有从终端读取,那么它从哪里读取?
基于这些观察,我们可以按如下方式进行调试:创建一个latexmkrc
包含
$latex = 'tex -recorder %O %S';
记录此情况,并准备以下输入文件:
\openin 1=".tex"
\read 1 to \X
\message{... With full filename, \meaning\X ...}
\closein 1
\openin 2=""
\read 2 to \X
\message{... With blank filename, \meaning\X ...}
\closein 2
\openin 3=".tex"
\read 3 to \X
\message{... With full filename, \meaning\X ...}
\closein 3
\obeylines
\input \jobname.fls
\bye
(3 与 1 相同,只是重复以使顺序更清晰)。日志文件包含:
This is TeX, Version 3.14159265 (TeX Live 2017) (preloaded format=tex 2017.7.12) 29 DEC 2018 10:20
**main.tex
(/compile/main.tex ... With full filename, macro:->... ... With blank filename,
macro:->\par ... ... With full filename, macro:->... (/compile/output.fls) [1]
)
Output written on /compile/output.dvi (1 page, 716 bytes).
这说明了奇怪的事情,但更有趣的是排版输出:
PWD /compile
INPUT /usr/local/texlive/2017/texmf.cnf
INPUT /usr/local/texlive/2017/texmf-dist/web2c/texmf.cnf
INPUT /usr/local/texlive/2017/texmf-var/web2c/tex/tex.fmt
INPUT /compile/main.tex
OUTPUT /compile/output.log
INPUT /usr/local/texlive/2017/texmf-dist/tex/latex/tools/.tex
INPUT /compile/
INPUT /usr/local/texlive/2017/texmf-dist/tex/latex/tools/.tex
INPUT /compile/output.fls
—— 注意INPUT /compile/
两次 INPUTing 之间的区别.tex
。
这似乎解答了一些谜题,但又引发了新的问题:为什么TeX(在 Overleaf 上,当给定一个空文件名时)是否输入(看起来像)包含输入文件的目录?(输入目录到底是什么意思 / 为什么效果与读取一个空文件相同?)
不幸的是,这一切都与 TeX 的系统相关(即,在这种情况下,它完全是 kpathsea 库的内部),因此如果无法在本地重现,进一步调试似乎很困难。(也许这与 chroot 或 Overleaf 所做的某种沙盒有关。)不过,我要指出的是kpathsea
2017-11-03有一次提交(所以不是 TL2017 的一部分)这与空文件名有关。也许有关系。