我正在尝试制作一个宏,根据其参数创建一个文件路径,然后从该文件加载列表。这很快就失败了。
下面是我正在尝试做的事情的示意图:
\documentclass{article}%
\RequirePackage{filecontents}% for creating dummy contents for now
%
\edef\@dummyPath{\jobname.latexgit.dummy}% the dummy file path
\begin{filecontents*}{\@dummyPath}
blabla
\end{filecontents*}
%
\def\getFilePath#1#2#3{%
\edef\@argA{#1}% <-- if I have this line, it fails
%% do more complicated stuff, return \@dummyPath as fallback if complicated stuff fails
\@dummyPath%
}%
%
\usepackage{listings}%
\begin{document}%
\lstinputlisting{\getFilePath{a}{b}{c}}%
\end{document}%
现在,上面只是稍微 MWE 展示了我的问题。我的宏有三个参数。它应该尽可能地扩展参数(将来,它们也可能是宏或其他东西)并对它们执行某些操作。然后它应该“返回”一个表示文件路径的字符串。(有时,它可能只返回虚拟路径,如示例中所示。)
如果我pdflatex example_1.tex
,那么我得到:
This is pdfTeX, Version 3.141592653-2.6-1.40.22 (TeX Live 2022/dev/Debian) (preloaded format=pdflatex)
restricted \write18 enabled.
entering extended mode
(./example_1.tex
LaTeX2e <2021-11-15> patch level 1
L3 programming layer <2022-01-21>
(/usr/share/texlive/texmf-dist/tex/latex/base/article.cls
Document Class: article 2021/10/04 v1.4n Standard LaTeX document class
(/usr/share/texlive/texmf-dist/tex/latex/base/size10.clo))
(/usr/share/texlive/texmf-dist/tex/latex/filecontents/filecontents.sty
Package filecontents Warning: This package is obsolete. Disabling it and
(filecontents) passing control to the filecontents environment
(filecontents) defined by the LaTeX kernel.
)
LaTeX Info: File `example_1.latexgit.dummy' already exists on the system.
Not generating it from this source.
(/usr/share/texlive/texmf-dist/tex/latex/listings/listings.sty
(/usr/share/texlive/texmf-dist/tex/latex/graphics/keyval.sty)
(/usr/share/texlive/texmf-dist/tex/latex/listings/lstmisc.sty)
(/usr/share/texlive/texmf-dist/tex/latex/listings/listings.cfg))
(/usr/share/texlive/texmf-dist/tex/latex/l3backend/l3backend-pdftex.def)
No file example_1.aux.
! Missing endcsname inserted.
<to be read again>
edef
l.17 \lstinputlisting{\getFilePath{a}{b}{c}}
总体思路:我正在制作一个与 BibTeX 有点类似的工具,但用于外部文件。换句话说,如果一切顺利:
- 第一次
pdflatex
运行时,\getFilePath
会将一些内容写入辅助文件并始终返回虚拟文件的路径。 - aux 文件将被外部工具处理并向其中添加一些内容。
- 然后在下一次
pdflatex
运行中,\getFilePath
将返回实际文件的路径。
现在,我可以让所有这些步骤都起作用,即我可以\getFilePath
输出实际的文件路径。但它们不能与任何实际的东西一起工作用途路径,例如类似listings
或类似的东西。当我尝试访问 MWE 中的参数值时,这已经失败了…… :-(
答案1
您的问题源于\getFilePath
不可扩展的事实,但您只能在 (La)TeX 需要文件名的地方使用可扩展宏。
不幸的是,您无法以可扩展的方式写入 AUX 文件,因此您的宏在设计上无法扩展。如果您无法摆脱这种 AUX 依赖性(我猜这不太可能),您将不得不将您的方法更改为两步解决方案。您的第一步应该处理您的宏参数并执行不可扩展的操作,最后设置一个扩展到所选名称的辅助宏。然后,您可以将该辅助宏用于文件访问。
另外:您不应该\def
直接在或多或少通用的宏名称上使用。\def
如果您使用 检查名称是否可用,您仍然可以使用\@ifdefinable
。
\documentclass{article}%
\RequirePackage{filecontents}% for creating dummy contents for now
%
\makeatletter
\edef\@dummyPath{\jobname.latexgit.dummy}% the dummy file path
\begin{filecontents*}{\@dummyPath}
blabla
\end{filecontents*}
%
\newcommand*\theFilePath{}% initialising the auxiliary macro
\@ifdefinable\getFilePath{\protected\def\getFilePath#1#2#3{%
\edef\@argA{#1}% <-- if I have this line, it fails
%% do more complicated stuff, return \@dummyPath as fallback if complicated stuff fails
\let\theFilePath\@dummyPath%
}}
\makeatother
%
\usepackage{listings}%
\begin{document}%
\getFilePath{a}{b}{c}%
\lstinputlisting{\theFilePath}%
\end{document}%