使用逐字命令的安全方法

使用逐字命令的安全方法

我关于如何利用代码示例和列表来做一些聪明的事情的所有想法最终都会导致“紧急停止”错误。

让我简要回顾一下我现在正在做的事情以及我真正想要实现的目标:我已经提供了一个 LaTeX 模板,其中包含一个,demo.tex显示了模板的所有可能性。对我来说,它主要用于测试目的(我发现许多它是一种非常实用的“操作手册”,可以帮您轻松找到使用它的软件包中的错误。对于用户来说,它是随模板提供的很棒的“操作手册”。

目前,用户必须查看代码才能了解示例的工作原理。对于即将发布的版本,我想通过在 pdf 中提供源代码来改变这种情况。此外,如果可以将所有内容作为样式文件而不是文件提供,那就太好了.tex。我们的想法是提供\AddDemo\PrintDemo,以便可以在任何地方定义它们并根据要求打印。特别是这不仅允许我,还允许包编写者提供他们自己的示例代码。然而,从最近几天在这里发布的相关问题的答案来看,我已经放弃了这个想法。

仍然有并排(或顶部/底部)显示代码和结果的想法。这里showexpl包提供了一些有用的东西。

但是:如果放在命令中,它会失败。这使得它无法使用,因为我必须测试示例是否可以执行。下面的代码演示了这一点:

\documentclass{scrbook}

\usepackage{showexpl}
\usepackage{soul}

\providecommand{\IfDefined}[2]{%
\ifcsname #1\endcsname
   #2 %
\else
     % do nothing
\fi
}
\begin{document}
\IfDefined{so}{
\begin{LTXexample}
\so{letterspacing}, \ul{underlining} 
\st{overstriking} and \hl{highlighting}. 
\end{LTXexample}
}
\end{document}

任何其他\ifdef命令都可能会导致相同的错误。

如果无法在任何类型的命令中使用逐字材料,我将不得不回到简单的lstlisting环境并将每个代码放置两次。

欢迎对我的代码进行任何与提供通用示例代码的想法相关的改进。

答案1

值得一提的是,ConTeXt 提供了一个buffer对此类情况非常有用的环境。在 ConTeXt MkII(pdftex 和 xetex 引擎)中,缓冲区的内容存储在外部文件中,而在 MkIV(luatex 引擎)中,缓冲区的内容存储在内存中。因此,你可以在 ConTeXt 中执行如下操作

\startbuffer[so-example]
\so{letterspacing}, \ul{underlining} 
\st{overstriking} and \hl{highlighting}
\stopbuffer

\doifdefined\so{\typebuffer[so-example]}

LaTeX 实际上没有与缓冲区等效的东西。最接近的是包filecontents(见此问题)因此你可以尝试(未经测试)

\begin{filecontents}{\jobname-so-example}
\begin{LTXexample}
\so{letterspacing}, \ul{underlining} 
\st{overstriking} and \hl{highlighting}. 
\end{LTXexample}
\end{filecontents}

\IfDefined\so{\input{\jobname-so-example}}

您还可以将最后一位包装在宏后面:

\def\ShowExample#1
   {\IfDefined{\csname#1\endcsame}{\input{\jobname-#1-example}}

答案2

这并不能完全或直接地回答这个问题,但也许这项技术可以根据您的目的进行调整。这里有一个小的示例文件,它“完成它的事情”,然后在演示之后将自己打印出来。

\documentclass{article}
\usepackage{wasysym}
\usepackage{verbatim}
\nofiles

\newcommand{\opluslhrim}{\mathbin{\rlap{$\Leftcircle$}{+}}}
\newcommand{\oplusrhrim}{\mathbin{{+}\llap{$\Rightcircle$}}}

\begin{document}

\section*{Semidirect sums}
Constructed using \texttt{wasy}'s left and right half circles:\\
$\Leftcircle \quad + \quad A \opluslhrim B \quad
+ \quad \Rightcircle \quad C \oplusrhrim D$

In display:
\[
\Leftcircle \quad + \quad A \opluslhrim B \quad
+ \quad \Rightcircle \quad C \oplusrhrim D
\]

\vspace{3\baselineskip}
\verbatiminput{\jobname.tex}

\end{document}

我用这个技巧积累了一系列“howto”文件,为已经解决的问题提供解决方案,供 ams 生产人员参考。当然,这种技术假设测试代码中没有任何内容会导致作业因错误而停止。

答案3

如果您不介意在输出周围添加一个额外的组,那么您可以使用:

\makeatletter
\newcommand\IdDefined[1]
    {\ifcsname #1\endcsname
      \else
        \expandafter\@gobble
      \fi}
\makeatother

相关内容