使用 lstinputlisting 并以变量作为参数时未找到文件

使用 lstinputlisting 并以变量作为参数时未找到文件

尝试创建一个新环境,用于lstnewenvironment在文档中列出代码。有时此环境的内容直接在 tex 文件中输入,有时来自外部文件。我希望同一个环境能够处理这两种情况。这是环境:

\lstnewenvironment{output}[1][]
{
    \lstset{
        style=outputstyle,
        #1
    }
    \ifthenelse{\not\isempty{\fromfile}}
        {\lstinputlisting[style=outputstyle, #1]{example.cpp}\medskip}
        {NO FILE CONTENTS FOUND}
}{
    \endminipage
}

example.cpp如果我在环境定义中直接输入文件名(上面),环境就会按预期工作。

但是,我想ifthenelse使用自定义键将文件名作为可选参数(因此是)传递给环境。在序言中:

\makeatletter
\lst@Key{fromfile}{}{\def\fromfile{#1}}
\makeatother

并在文件中:

\begin{output}[fromfile={example.cpp}]
\end{pfaoutput}

并将环境定义更改为:

    \ifthenelse{\not\isempty{\fromfile}}
        {\lstinputlisting[style=outputstyle, #1]{\fromfile}\medskip}
        {NO FILE CONTENTS FOUND}

但这不起作用并会产生File not found错误:

! Package Listings Error: File `chapters/chapter_5/code/example.cpp(.tex)' not found.

我已经配置了\lstset{inputpath=chapters/chapter_5/code}选项,如果我直接输入文件名称,则可以找到文件并正确呈现,但如果我将文件作为参数传递给环境,则不会找到文件(尽管错误指示的路径是正确的)。我需要\fromfile以任何方式处理吗?

答案1

您需要\fromfile在 之前进行扩展\lstinputlisting。一种方法是定义一个宏,例如\myInputListing,如下所示:

\newcommand*{\myInputListing}[2]{%
  \lstinputlisting[style=outputstyle, #2]{#1}%
}

然后将其替换\lstinputlisting[style=outputstyle, #1]{\fromfile}\expandafter\myInputListing\expandafter{\fromfile}{#1}。另一种方法是,假设您使用的是 2019 或更高版本的 TeX 引擎,将同一部分替换为:

\expanded{%
  \unexpanded{\lstinputlisting[style=outputstyle, #1]}%
  \unexpanded\expandafter{\fromfile}%
}%

有了第二种解决方案,当然就不需要定义\myInputListing宏了。

相关内容