我对这个命令有疑问\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