我尝试使用 listings 包来排版 C 代码,这样 C 注释就可以被解释为 \LaTeX 的输入。使用texcl
选项,一行注释很容易,
\begin{lstlisting}[texcl]
main(){main();}//\LaTeX
\end{lstlisting}
但此选项仅适用于行注释
\begin{lstlisting}[texcl]
main(){main();}/*\LaTeX*/
\end{lstlisting}
escapeinside
可以使用以下选项来代替,
\begin{LTXexample}
\begin{lstlisting}[escapeinside={/*}{*/}]
main(){main();}/*\LaTeX*/
\end{lstlisting}
使用escapebegin
和,escapeend
我们甚至可以让输出看起来非常像输入,只需稍加润色
\begin{lstlisting}[
escapeinside={/*}{*/},
escapebegin={\texttt{/*}},
escapeend={\texttt{*/}}]
main(){main();}/*\LaTeX*/
\end{lstlisting}
車輛改道我为什么要让输出看起来像输入?我设想了一个简易版的 web/tangle/weave,其中在 listings 环境版本中编写的代码不仅在呈现的文档中很好地呈现,而且还保存在名为 的文件中\jobname.c
,该文件可以由 C 编译器编译。对于对 \LaTeX 了解甚少的人来说,这个文件也应该有意义。类似
\lstnewenvironment{code}{
\lstset{frame=single,
escapeinside={/*}{*/},
escapebegin={\texttt{/*}\itshape},
escapeend={\texttt{*/}}}}{\footnote
{Should be saved in \jobname.c}}
\begin{code}
main(){main();}/*\LaTeX*/
\end{code}
问题是转义到 \LaTeX 不能正常工作,输入中的换行符会消失
\begin{code}
/* The shortest legal (but not warnings free) C
program.*/
main(){for(;;);}
\end{code}
我认为转义机制还有另外一个小问题;它似乎添加了一个空格。
\begin{lstlisting}[escapeinside={/*}{*/}]
/* This is the time for all good men to come to the */
main(){main();}/*\LaTeX*/
\end{lstlisting}
以下是一个 latex 文档来演示这个问题
\documentclass{article}
\usepackage{listings,showexpl}
\begin{document}
I try to use the listings package to typeset C code, such that C comments
are interpreted as input to \LaTeX.
\begin{LTXexample}
\lstset{language=C}
\end{LTXexample}
One line comments are easy with \verb/texcl/
option,
\begin{LTXexample}
\begin{lstlisting}[texcl]
main(){main();}//\LaTeX
\end{lstlisting}
\end{LTXexample}
But, this option applies only to line comments
\begin{LTXexample}
\begin{lstlisting}[texcl]
main(){main();}/*\LaTeX*/
\end{lstlisting}
\end{LTXexample}
The \verb/escapeinside/ option can be used instead,
\begin{LTXexample}
\begin{lstlisting}[escapeinside={/*}{*/}]
main(){main();}/*\LaTeX*/
\end{lstlisting}
\end{LTXexample}
With \verb/escapebegin/ and \verb/escapeend/ we can even make the output look
very much like the input, with a bit of polishing
\begin{LTXexample}
\begin{lstlisting}[
escapeinside={/*}{*/},
escapebegin={\texttt{/*}},
escapeend={\texttt{*/}}]
main(){main();}/*\LaTeX*/
\end{lstlisting}
\end{LTXexample}
\paragraph{Detour} Why would I want to make the output look like the input? I envision a poor man's version of web/tangle/weave in which code written within a version of a listings
environment is not only presented nicely on the rendered document, it is also saved in a file named \verb/\jobname.c/, which can be compiled by a C compiler.
This file should also make sense to a person who has very little understanding of \LaTeX. Something like
\begin{LTXexample}
\lstnewenvironment{code}{
\lstset{frame=single,
escapeinside={/*}{*/},
escapebegin={\texttt{/*}\itshape},
escapeend={\texttt{*/}}}}{\footnote
{Should be saved in \jobname.c}}
\begin{code}
main(){main();}/*\LaTeX*/
\end{code}
\end{LTXexample}
The problem is that escaping to \LaTeX does not work quite right, and new line
characters in the input disappear
\begin{code}
/* The shortest legal (but not warnings free) C
program.*/
main(){for(;;);}
\end{code}
There is yet another small glitch I think with the escaping mechanism; it seems to
be adding a space.
\begin{LTXexample}
\begin{lstlisting}[escapeinside={/*}{*/}]
/* This is the time for all good men to come to the */
main(){main();}/*\LaTeX*/
\end{lstlisting}
\end{LTXexample}
答案1
在多行转义环境中尊重换行符的一种方法是明确定义换行符应该做什么。以下是一个例子
\documentclass{article}
\usepackage{listings}
\begin{document}
\lstset{language=C}
{%
\makeatletter
\catcode13=13\relax% Make ASCII 13 active to define it later
\gdef\newlinewillbreakandindent{%
\lst@CalcColumn% Record the column position of slash-star
\xdef\slashstarposition{\the\numexpr\@tempcnta+2}
\itshape% Apply some formatting here, not relevant.
\def^^M{% What should I do whenever I see ASCII 13?
\\% first, break the line
\hbox{}\hskip\slashstarposition\lst@width% then, indent to proper column
}%
}%
}
\lstnewenvironment{Ccode}{
\lstset{
frame=single,
escapeinside={/*}{*/},
escapebegin={\texttt{/*}\bgroup\newlinewillbreakandindent},
escapeend={\egroup\texttt{*/}}
}
}{\footnote{Should be saved in \jobname.c}}
\begin{Ccode}
/* The shortest legal
(but not warnings free)
C program. */
main(){for(;;);}
\end{Ccode}
\end{document}
正如您所见,我无法让框架正常工作(没有双关语)。我在这里放弃了。