对于我的课程,我会编写练习;我还会提供解决方案(供我和助教使用)。我喜欢处理单个文档,但设置一个“标志”来指示是否提供解决方案。这答案帮助我完成了这项工作。但是当我在可选材料中包含“lstlisting”时,事情就不再正常工作了:
\documentclass{article}
\RequirePackage{listings}
\RequirePackage{etoolbox}
\newcommand{\solflag}{}
\newcommand{\version}[2]
{\ifcsdef{#1flag}{#2}{}}
\begin{document}
Before.
\version{sol}{
\begin{lstlisting}[language=C]
// An example of a C comment.
\end{lstlisting}
}
After.
\end{document}
在我的 Linux 机器上使用 pdflatex 处理这个问题会产生一个警告(Package Listings Warning: Text dropped after begin of listing on input line 18.
),后面跟着“星号等待输入”状态。
从这个答案,我看到后面的内容\begin{lstlisting}
(在同一行)被吞没并忽略,并引发该警告。宏参数的处理是否会吞没所有行尾标记或类似的东西?如果是这样,我可以做些什么来让它工作?
(一个答案:我可以使用\lstincludelisting
,它似乎工作正常......但很高兴看到小(10 行?)列表就在正确的位置而不是通过引用。并且切换还涉及编辑数十个文档。)
答案1
你不能通过listings
环境(lstlisting
或类似)作为宏的参数(\version
在您的例子中),以及lstlisting
许多类别代码更改,所有这些都会在作为参数吞噬时导致问题。这在本质上非常类似于提供verbatim
类似内容作为参数非常相似,因此请参阅为什么不在verbatim
...内工作?
不要使用“标志”作为布尔值,而是定义一个comment
类似环境,区分您的“解决方案”和“非解决方案”版本:
\documentclass{article}
\usepackage{listings,comment}
\includecomment{solution}% Include solution environment
%\excludecomment{solution}% Exclude solution environment
\setlength{\parindent}{0pt}% Just for this example
\begin{document}
Before.
\begin{solution}
\begin{lstlisting}[language=C,basicstyle=\ttfamily]
#include <iostream.h>
main()
{
cout << "Hello World!";
return 0;
}
\end{lstlisting}
\end{solution}
After.
\end{document}
按原样编译上述内容可获得
取消注释\excludecomment{solution}
并编译以获得