我正在进一步编写 LaTeX 示例代码。我想使用 showexpl 包同时打印代码和结果。不幸的是,我得到了“!紧急停止。”
\documentclass{scrbook}
\makeatletter
\providecommand{\packagename}{templatedemo}
\RequirePackage{etoolbox}
\RequirePackage{showexpl}
\providecommand\AddDemo[3][]{%
\expandafter\providecommand\csname demo@content@#2\endcsname{#3}%
\expandafter\providecommand\csname demo@options@#2\endcsname{#1}%
}
\providecommand\demo@printhis{}
\providecommand\PrintDemo[1]{%
\ifcsdef{demo@content@#1}%
{ % print
\renewcommand{\demo@printhis}{\expandafter\csname demo@content@#1\endcsname}
\begin{LTXexample}
\demo@printhis
\end{LTXexample}
}%
{}
}
\AddDemo{text}{Sample Text}% end: \AddDemo
\makeatother
\listfiles
\begin{document}
\PrintDemo{text}
\end{document}
如果这个方法可行,那么下一个问题就是列表将只显示扩展版本。因此,如果我这样写:
\begin{document}
\begin{LTXexample}
\PrintDemo{text}
\end{LTXexample}
\end{document}
列表包将输出“\PrintDemo{text}”而不是其内容。
答案1
您的代码中存在许多问题。主要问题是,它LTXexample
是一种非常类似的环境verbatim
,无法在命令的参数中使用。
在某些情况下,可以通过 来规避这个问题\scantokens
。但是,你继续的方法不会考虑输入中的换行符;至少在不对类别代码进行大修的情况下不会,因为代码会被读取多次,所以无论如何都会中断;一旦字符标记进入 TeX,其类别代码就会固定。\scantokens
可以重新读取它并重新分配类别代码,但一旦将其传递给LTXexample
该问题就会再次出现。
为了展示一种可能性,这里有一个尝试:
\newcommand\AddDemo[3][]{%
\expandafter\newcommand\csname demo@content@#2\endcsname{#3}%
\expandafter\newcommand\csname demo@options@#2\endcsname{#1}%
}
\newcommand\PrintDemo[1]{%
\ifcsdef{demo@content@#1}%
{ % print
\letcs\next{demo@content@#1}%
\toks@=\expandafter{\next}%
\edef\next{\unexpanded{\begin{LTXexample}}^^J%
\the\toks@^^J%
\unexpanded{\end{LTXexample}}}%
\scantokens{\next}%
}%
{}
}
\makeatother
\AddDemo{text}{Sample Text}% end: \AddDemo
你可以尝试一下,看看它是否按预期工作。但是
\AddDemo{text}{Sample
Text}
将以完全相同的方式打印(这在代码示例中通常不是故意的)。然而,主要问题是
\AddDemo{text}{Sample Text \today}
将会打破列表(由 所使用LTXexample
)。尝试一下。
一些评论
您对 的使用\providecommand
是错误的;\providecommand\AddDemo
如果 已经定义,它将被默默忽略\AddDemo
。假设某个包定义了它:您将对结果感到非常困惑。
在 的定义中也是错误的\AddDemo
;说
\AddDemo{text}{demo1}
...
\AddDemo{text}{demo2}
被错误地使用:\PrintDemo{text}
总是会使用demo1
,并且您不会收到有关双重定义的通知。
也是\expandafter\csname demo@content@#1\endcsname
值得怀疑的:\expandafter
会试图扩张d
(当然是不可扩张的);其效果与 完全相同\csname demo@content@#1\endcsname
。在其他情况下,放错\expandafter
可能会造成灾难。
我可以理解您希望将所有代码示例放在一个地方,但是排版 TeX 代码需要微妙之处,这使得这个目标很难(如果不是不可能)实现。