我有一个文档,它使用一些命令并通过外部文件\input
创建了参考书目。.bib
bibtex
现在我必须内联\input
命令(即\input
用相应文件的内容替换每个命令)并内联参考书目(即用 bibtex 生成的 .tex 代码替换参考书目命令)。内联是编辑器所必需的。
我怎样才能自动完成此操作?
答案1
在你的 之前\documentclass
添加以下内容:
\begin{filecontents}{file1}
Contents of file 1
\end{filecontents}
\begin{filecontents}{file2}
Contents of file 2
\end{filecontents}
等等。无需\input
更换
答案2
将生成的程序重命名file.bbl
为mybib.bbl
,然后将\bibliography
命令替换为\input{mybib.bbl}
。如果您确定不会bibtex
再次运行该程序,则只需将其替换为\input{file.bbl}
。
http://texnik.dante.de/misc/buildFile.pl是一个 Perl 脚本,它创建一个独立的文件。所有 \input 和 \include 都将被其内容替换
答案3
类似的问题时常出现,比如(本质上)让 TeX 输出 .tex 文件。到目前为止,我发现最实用的方法是激活所有字符(或本质上等同于同一事物的变体),并定义它们以将自身存储到缓冲区,然后将其输出到文件。
然后,我们希望执行的命令不仅仅是逐字复制,而是重新定义这些命令来执行我们想要的操作(请参阅\RLK@input
下面的定义)。当然,还有一些子项(控制序列名称中只能出现字母,而不能出现活动字符)。
更改InFile.tex
为您想要“内联”的文件,然后更改OutFile.tex
为输出。
\def\RLKinputfile{InFile.tex}
\def\RLKoutputfile{OutFile.tex}
\catcode`\@=11\relax
\long\gdef\RLKgobble#1{}
\long\gdef\RLKfirstoftwo#1#2{#1}
\long\gdef\RLKsecondoftwo#1#2{#2}
\gdef\RLK{%
\begingroup%
\count0=1\relax%
\loop%
\catcode\count0=\active%
\lccode`~\count0\relax%
\lowercase{\protected\edef~{\RLKbuffer@append{\string~}}}%
\ifnum\count0<255%
\advance\count0 by 1\relax%
\repeat%
\lccode`\~`\\%
\lowercase{\let~\RLKcatchcs}%
%
\input \RLKinputfile %
\endgroup%
}
\gdef\RLKbuffer{}
\protected\def\RLKbuffer@append#1{\xdef\RLKbuffer{\RLKbuffer#1}}
\newif\if@catchcs@
\protected\def\RLKcatchcs{%
% catches the control word, naively stopping at the first non A-Za-z
\def\RLKcatchcs@csname{}%
\RLKcatchcs@aux}
\def\RLKcatchcs@aux#1{%
\@catchcs@false% We have reached the end...
\unless\ifnum`#1>`z\relax%
\unless\ifnum`#1<`A\relax%
\@catchcs@true% ...except if we are in the range A-z...
\fi\fi%
\ifnum`#1>`Z\relax%
\ifnum`#1<`a\relax%
\@catchcs@false% ...and not in the range Z-a.
\fi\fi%
\if@catchcs@%
\expandafter\RLKfirstoftwo%
\else%
\expandafter\RLKsecondoftwo%
\fi%
% If we haven't reached the end, catch one more.
{\edef\RLKcatchcs@csname{\RLKcatchcs@csname\string#1}%
\RLKcatchcs@aux}%
% If we have, stop, do the relevant \RLK@... if it exists, otherwise
% just output to the buffer. And don't forget to put #1 back in the stream.
{\ifcsname RLK@\RLKcatchcs@csname\endcsname%
\csname RLK@\RLKcatchcs@csname\expandafter\endcsname%
\else%
\RLKbuffer@append{\expandafter\RLKgobble\string\\\RLKcatchcs@csname}%
\fi%
#1%
}%
}
% Define \input{...} to have the desired behaviour: actually input the file.
% We could do the same for other commands (\usepackage, etc.)
\begingroup
\catcode`\{=\active
\catcode`\}=\active
\catcode`\(=1\relax
\catcode`\)=2\relax
\gdef\RLK@input{#1}(\RLKaux@input(#1))
\endgroup
\gdef\RLKaux@input#1{\expandafter\input \detokenize{#1} }
% Here it goes, we act.
\RLK
% Then output the \RLKbuffer to a file.
\newwrite\RLKwrite
\immediate\openout\RLKwrite \RLKoutputfile\relax
\newlinechar\endlinechar
\immediate\write\RLKwrite{\RLKbuffer}
\immediate\closeout\RLKwrite
% tex, pdftex will be stopped there,
% but latex, pdflatex will only see \relax.
\csname bye\endcsname
% this makes latex, pdflatex happy.
\documentclass{minimal}
\begin{document}
\end{document}
这应该适用于tex
、latex
和,并且扩展到其他变体应该不难。另外,在人们问之前,RLK 只是一串随机的字母pdftex
。pdflatex
答案4
跳出固有的思维模式,我会尝试使用文本编辑器(或sed您可以使用 C 脚本将指令更改\input
为合适的指令#include
,然后将结果传递给 C 预处理器。
\input
使用 Perl 脚本实现该效果也很简单。
我确信使用纯 TeX 可以做到这一点,但如果没有现有的机制要求 TeX 在处理过程中的正确时刻将标记流转储回文件,那么纯度可能不值得付出努力。
请注意,无论选择哪种实施方式,我都会确保不会因为这种替换而意外破坏原始文档。