如何自动内联 \input 命令和参考书目?

如何自动内联 \input 命令和参考书目?

我有一个文档,它使用一些命令并通过外部文件\input创建了参考书目。.bibbibtex

现在我必须内联\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.bblmybib.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}

这应该适用于texlatex和,并且扩展到其他变体应该不难。另外,在人们问之前,RLK 只是一串随机的字母pdftexpdflatex

答案4

跳出固有的思维模式,我会尝试使用文本编辑器(或sed您可以使用 C 脚本将指令更改\input为合适的指令#include,然后将结果传递给 C 预处理器。

\input使用 Perl 脚本实现该效果也很简单。

我确信使用纯 TeX 可以做到这一点,但如果没有现有的机制要求 TeX 在处理过程中的正确时刻将标记流转储回文件,那么纯度可能不值得付出努力。

请注意,无论选择哪种实施方式,我都会确保不会因为这种替换而意外破坏原始文档。

相关内容