\input 真的只包含文件吗?

\input 真的只包含文件吗?

我对这个命令有疑问\input

因为在此处说明,“这相当于将 filename.tex 中的所有命令直接输入到 \input 行所在的当前文件中。”

我觉得事实并非如此,至少在某些情况下,我希望得到一些澄清。

考虑这个 MVCE (例如,在文件中main.tex):

\documentclass{article}
\usepackage{mypackage}
\begin{document}
\begin{myenvir}{Hello}
\mycommand{World}
\end{myenvir}
\end{document}

现在mypackage.sty文件(存储在同一文件夹中):

\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{mypackage}[version 0.1]

\newenvironment{myenvir}[1]
{%
    \newcommand{\mycommand}[1]
    { test:command arg=##1 environment arg=#1}
    \begin{center}
}
{\end{center}} 
\endinput

编译时main.tex,它运行正常,并能产生结果。

test:command arg=World environment arg=Hello

但是现在,假设出于某种原因(*),我想将命令定义存储在单独的文件中。所以我只需将 sty 文件更改为:

\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{mypackage}[version 0.1]

\newenvironment{myenvir}[1]
{%
    \input{fcommand}
    \begin{center}
}
{\end{center}} 
\endinput

fcommand.tex并将这两行存储到文件中:

\newcommand{\mycommand}[1]
{ test:command arg=##1 environment arg=#1}

这难道不应该完全相同的结果

但在编译时main.tex出现此错误:

你不能在水平模式下使用宏参数字符#

输出(pdf)文件包含:

test:command arg=1 environment arg=World

问题:发生了什么事?据我所知,当代码在单独的文件中时,参数替换似乎存在问题。因此,我的假设并不真正\input等同于将代码放在同一个文件中。

我也检查过了这个相关问题,其中答案指出要添加\unskip。所以我尝试了这个:

\input{fcommand}\unskip%

并改变了命令文件的内容:

\newcommand{\mycommand}[1]
{ test:command arg=##1 environment arg=#1}\endinput

但仍然出现同样的错误。

其他相关问题:https://tex.stackexchange.com/a/319512/11083

(*)关于尝试这个的原因,这个问题实际上是一个后续问题关于另一个问题我目前正在处理。

答案1

问题是,当 TeX 读取环境命令时,它会检测所有 的位置#1,但\input不会被处理。当执行环境时(即\myenvir展开底层命令),所有#1之前看到的 都会被参数 替换Hello。因此使用

\begin{myenvir}{Hello}
\mycommand{World}
\end{myenvir}

与(减去注释)相同

% \begin{myenvir}{Hello}
\input{fcommand}
\begin{center}
% environment contents
\mycommand{World}
% \end{myenvir}
\end{center}

Hello由于没有在任何地方使用,所以它丢失了。现在扩展\input为:

% \begin{myenvir}{Hello}
\newcommand{\mycommand}[1]
{ test:command arg=##1 environment arg=#1}
\begin{center}
% environment contents
\mycommand{World}
% \end{myenvir}
\end{center}

然后,定义完成后,展开得到\mycommand

% \begin{myenvir}{Hello}
% \newcommand{\mycommand}[1] %%% Already defined
% { test:command arg=##1 environment arg=#1}
\begin{center}
% environment contents
test:command arg=#1 environment arg=World
% \end{myenvir}
\end{center}

现在您尝试#1在文本中间写入内容,这会引发错误:

! You can't use `macro parameter character #' in horizontal mode.
l.40 test:command arg=#
                       1 environment arg=World

相关内容