我正在使用子文件包来处理大型项目。
我将主文件放在主目录中,将子文件放在子目录中。为了在主文件中编译时在子文件中使用 \input 命令,我需要在 \subfile 命令之前手动更改输入路径,然后在之后恢复。
示例代码如下(复制自此处回答),
\makeatletter
\providecommand*{\input@path}{}
\edef\input@path{{subfile_path/}\input@path}% subfolder path
\makeatother
\subfile{subfile_path/subfile}
\makeatletter
\providecommand*{\input@path}{}
\edef\input@path{{./}\input@path}% restore
\makeatother
我想问一下是否可以将“makeatletter”代码封装到命令中。我尝试定义一个新命令
\newcommand{\autosubfile}[2]{
\makeatletter
\providecommand*{\input@path}{}
\edef\input@path{{#1/}\input@path}% subfolder path
\makeatother
\subfile{#1/#2}
\makeatletter
\providecommand*{\input@path}{}
\edef\input@path{{./}\input@path}% restore
\makeatother
}
但如果失败了。以下是错误消息:
ERROR: LaTeX Error: Command \input already defined.
--- TeX said ---
Or name \end... illegal, see p.192 of the manual.
See the LaTeX manual or LaTeX Companion for explanation.
Type H <return> for immediate help.
...
本文提到的 etoolbox 包回答可能会有帮助,但我不知道如何更改 \subfile 的参数数量,或者定义一个新命令来执行“makeatletter”代码片段。
谢谢你的帮助。
答案1
你应该有\makeatletter
前@
任何使用名称中的命令的定义。
您还含糊其辞地给出了您所指的答案。
\providecommand{\input@path}{}
只需做一次。- 您不断地添加内容
\input@path
而不是恢复内容。
您可以这样做:
\makeatletter
\providecommand*{\input@path}{} % in case it's undefined
\newcommand{\autosubfile}[2]{% <- don't forget
% save the current \input@path
\let\saved@input@path\input@path
\edef\input@path{{#1/}\input@path}% subfolder path
\subfile{#1/#2}%
% restore \input@path to its previous value
\let\input@path\saved@input@path
}
\makeatother
答案2
你的错误(在用户开始了解 TeX 功能时很常见)是基于对 TeX 中 tokenizer 和扩展处理器的协作的误解。Tokenizer\foo
总是像一个 token一样创建控制序列当数据第一次从输入文件读取时。宏被保存在 TeX 内存中,作为 tokenizer 创建的 token 序列,而不是字符串。当宏被展开时,展开处理器会将 token 序列更改为另一个 token 序列。
举例来说:
\def\yourmacro{
\makeatletter %... instruction for tokenizer in your example
% this is not processed when macro body is read,
% this is saved only to TeX memory
\foo@bar %... tokenizer creates \foo and @ and b and a and r
% and this is saved to TeX memory in macro body
\makeaother %... instruction for tokenizer without effect
}
... usage of \yourmacro % expand processor replaces it by \makeatletter
% followed by \foo, @, b, a, r and \makeatother.
% Now, \makeatletter is instruction for tokenizer without
% effect because \foo, @, b, a, r are tokenized already.
另一方面正确的用法:
\makeatletter %... instrution for tokenizer, all new read data are
% tokenized differently now.
\def\yourmacro{
...
\foo@bar % one token \foo@bar is saved to TeX memory in macro body
...
}
\makeatother % instruction for tokenizer to behave normally
... usage of \yourmacro % expand processor replaces it by ... \foo@bar ...