处理和隐藏文本的宏?

处理和隐藏文本的宏?

我正在为一篇课文写解决方案手册。有些解决方案只对讲师可见,所以我写了一个宏

\newcommand{\instructor}[1]{}

它隐藏了它的参数。我在学生版手册中使用了这个宏,而在教师版手册中使用了不同的定义。

使用 knitr 排版 R 代码时会出现问题。(knitr 是一个预处理器,它运行代码并将输出插入文本。)如果 R 代码包含百分号,knitr 会输出类似

\begin{knitrout}
\definecolor{shadecolor}{rgb}{0.969, 0.969, 0.969}\color{fgcolor}  
\begin{kframe}
\begin{alltt}
\hlnum{1} \hlopt{%%} \hlnum{2}
\end{alltt}
\end{kframe}
\end{knitrout}

(这表明1 %% 2。)当它作为我的 \instructor宏的参数出现时,百分号被视为注释标记,并且括号不匹配,从而导致错误。

所以,我的问题是:有没有一种方法可以做到这一点而不会失败?我猜它需要排版内容(因此 % 暂时转换为常规字符),然后丢弃输出。

编辑后补充:Ulrike 的解决方案适用于上述问题,但事情实际上更复杂,因为我有一些枚举,我想跳过学生版中的项目。例如,

\documentclass{article}
\begin{document}

% This pair of macros is what I'm using now, but the
% student version (the first one) fails.

% \newcommand{\instructor[#1]{\addtocounter{enumi}{1}}
\newcommand{\instructor}{}

\begin{enumerate}

\item This is for everyone:
\catcode`\%=11
{ 12 %% 13 }
\catcode`\%=5

\instructor{
\item This is just for the instructor:
\catcode`\%=11
{ 12 %% 13 }
\catcode`\%=5
}

\end{enumerate}
\end{document}

我不认为该comment软件包提供了用完全不同的东西替换注释文本的解决方案,比如\addtocounter。还是有?

答案1

不要使用带参数的命令——如果涉及到 catcode 更改,这将始终很困难。最好使用注释包:

\documentclass{article}

\usepackage{comment}
\includecomment{instructor}
%\excludecomment{instructor}
\begin{document}

bllb

\begin{instructor}
some text
\catcode`\%=11
12 %% 13
\catcode`\%=5
\begin{verbatim}
\section
\end{verbatim}

\end{instructor}

\end{document}

注意:来自文档的引用:

开始和结束命令应单独成行。起始命令和结束命令之间不应有任何空格,后面也不应有任何内容。

答案2

这不是一个很好的解决方案,但它确实有效。下面有一个更好但更复杂的解决方案。

将每次使用\instructor{}包含文字%字符的宏的\catcode修改包装起来,例如在原始 knitr 代码中:

\catcode`\%=11
\instructor{
<<>>=
1 %% 2
@
}
\catcode`\%=5

TeX 向导可能知道如何将其构建到\instructor宏定义中,但我不知道。

这适用于以下定义\instructor

% For the student version:
\newcommand{\instructor}[1]{}

% For the instructor version:
\newcommand{\instructor}{}

我仍然欣赏更优雅的解决方案!

编辑后添加:

根据 Ulrike 的回答,我认为我现在有一个相当优雅的解决方案。它使用该comment包,并添加此宏定义:

\long\def\specialexclude
#1#2{\message{Excluding comment '#1'}%
\csarg\def{#1}{\endgroup \message{Excluding '#1' comment.}%
    \begingroup%
       \DefaultCutFileName #2\relax\def\ProcessCutFile{}%
       \def\ThisComment####1{}\ProcessComment{#1}}%
\csarg\def{After#1Comment}{\CloseAndInputCutFile \endgroup}
\CommentEndDef{#1}}

这将添加一个新环境,并用任意命令替换其内容。你可以像这样使用它:

\documentclass{article}
\usepackage{comment}

\long\def\specialexclude
#1#2{\message{Excluding comment '#1'}%
\csarg\def{#1}{\endgroup \message{Excluding '#1' comment.}%
    \begingroup%
       \DefaultCutFileName #2\relax\def\ProcessCutFile{}%
       \def\ThisComment####1{}\ProcessComment{#1}}%
\csarg\def{After#1Comment}{\CloseAndInputCutFile \endgroup}
\CommentEndDef{#1}}

% For the student version:
\excludecomment{instructor}
\specialexclude{instructori}{\addtocounter{enumi}{1}}

% For the instructor version:
% \includecomment{instructor}
% \includecomment{instructori}

\begin{document}
\begin{enumerate}

\item This is for everyone:
\catcode`\%=11
{ 12 %% 13 }
\catcode`\%=5

\begin{instructori}
\item This is just for the instructor:
\catcode`\%=11
{ 12 %% 13 }
\catcode`\%=5
\end{instructori}

\item This is also for everyone.

\end{enumerate}
\end{document}

答案3

将其分成两个标志可能更容易:一个用于 LaTeX,一个用于knitr。将第三行更改为true并将第一个块中的逻辑更改为TRUE应该会计算出您想要的结果。

\documentclass{article}
\usepackage{ifthen}
\newcommand{\isinstructor}{false} %change to false/true
\newcommand{\instructor}[1]{\ifthenelse{\equal{\isinstructor}{true}}{#1}{}}
<<include = FALSE>>=
instructor <- FALSE #change to FALSE/TRUE
@

\begin{document}
Everyone sees this:
<<eval = FALSE>>=
1 %% 2
@

\instructor{Only the instructor can see this}

<<include = instructor>>=
1 %% 2  # 1 + 2 would be okay
@

\end{document}

包含的要求enumerate也将按如下方式工作(请注意,讲师计数器减少以使其与前一个学生问题相同):

\documentclass{article}
\usepackage{ifthen}
\newcommand{\isinstructor}{false} %change to false/true
\newcommand{\instructor}[1]{\ifthenelse{\equal{\isinstructor}{true}}{\addtocounter{enumi}{-1} #1}{}}
<<include = FALSE>>=
instructor <- FALSE #change to FALSE/TRUE
@

\begin{document}

\begin{enumerate}
\item Everyone sees this:
<<eval = FALSE>>=
1 %% 2
@

\instructor{\item Only the instructor can see this}

<<include = instructor>>=
1 %% 2  # 1 + 2 would be okay
@
\end{enumerate}

\end{document}

相关内容