假设我有如下文档:
% !TEX TS-program = lualatex
\documentclass{scrartcl}
\newcommand{MyCommandForPrintingOnly}{...}
\newcommand{MyCommandForSpecifying}{...}
\MyCommandForPrintingOnly{A}
\begin{document}
\MyCommandForSpecifying{A}{Some A Text.}
\MyCommandForSpecifying{B}{Some B Text.}
\MyCommandForSpecifying{A}{Some A Text.}
\MyCommandForSpecifying{B}{Some B Text.}
\end{document}
我想要以下输出:
一些文本。
一些文本。
我怎样才能实现这个目标?
换句话说:我正在寻找一个将某物指定为“A”或“B”(或“C”...)的命令,以及另一个命令,然后仅打印指定为“A”的内容在输出中。有没有办法包含/排除某些内容?
或者,我可能只会想到我所寻找的是一种“动态注释掉”文档中某些行的方法,这样我就可以在序言中指定 A 或 B,并且指定为 B 的每一行都被视为被注释掉了%
。
(我想我以前在 tex.sx 上看到过类似的东西,但我找不到它。)
答案1
在普通的 TeX 中,你可以简单地定义
\def\switch#1#2{#1}
并在文档中使用
\switch{Some A text}{Some B text}
。
重新定义 \切换到
\def\switch#1#2{#2}
得到“B选项”。
如果我没记错的话,您可以将其扩展至最多 8 个选项。
答案2
另一个解决方案是使用\IfEq
来自字符串包裹。
定义
\newcommand{\MyCommandForSpecifying}[2]{}
\newcommand{\MyCommandForPrintingOnly}[1]{%
\renewcommand{\MyCommandForSpecifying}[2]{\IfEq{##1}{#1}{##2}{}}}
然后根据要打印的行数使用\MyCommandForPrintingOnly{A}
或。\MyCommandForPrintingOnly{B}
梅威瑟:
% !TEX TS-program = lualatex
\documentclass{scrartcl}
\usepackage{xstring}
\newcommand{\MyCommandForSpecifying}[2]{}
\newcommand{\MyCommandForPrintingOnly}[1]{%
\renewcommand{\MyCommandForSpecifying}[2]{\IfEq{##1}{#1}{##2}{}}}
\MyCommandForPrintingOnly{A}
\begin{document}
\MyCommandForSpecifying{A}{Some A Text.}
\MyCommandForSpecifying{B}{Some B Text.}
\MyCommandForSpecifying{A}{Some A Text.}
\MyCommandForSpecifying{B}{Some B Text.}
\end{document}
输出
答案3
有了expl3
它,就可以轻松实现多种选择。
\documentclass{scrartcl}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\MyCommandForPrintingOnly}{m}
{
\clist_gset:Nn \g_clint_printing_list_clist { #1 }
}
\clist_new:N \g_clint_printing_list_clist
\NewDocumentCommand{\MyCommandForSpecifying}{mm}
{
\clist_if_in:NnTF \g_clint_printing_list_clist { #1 }
{ #2 } % print the text
{ \__clint_ignore: } % do nothing but don't print two spaces
}
\makeatletter % we need \@bsphack and \@esphack
\cs_new_protected:Npn \__clint_ignore: { \@bsphack\@esphack }
\makeatother
\ExplSyntaxOff
\begin{document}
\section{Only A and C}
\MyCommandForPrintingOnly{A,C}
Some text \MyCommandForSpecifying{A}{Some A Text.} and other text
Some text \MyCommandForSpecifying{B}{Some B Text.} and other text
Some text \MyCommandForSpecifying{C}{Some C Text.} and other text
\section{Only B}
\MyCommandForPrintingOnly{B}
Some text \MyCommandForSpecifying{A}{Some A Text.} and other text
Some text \MyCommandForSpecifying{B}{Some B Text.} and other text
Some text \MyCommandForSpecifying{C}{Some C Text.} and other text
\end{document}
请注意,当段落中出现被忽略的文本时,此技巧\@bsphack\@esphack
可以避免打印两个空格。
答案4
由于您似乎正在使用 LuaLaTeX,因此这里有一个基于 Lua 的解决方案。有三个 TeX 宏:(\settotrue
将其参数 Lua 布尔值设置为“true”);\settofalse
(将其参数 Lua 布尔值设置为“false”);和\ConditionalPrint
(从您的 重命名\MyCommandForSpecifying
)。
对于手头的简单情况来说,代码有点“冗长”。不过,我相信,冗长的代码将使它能够直接适应更苛刻的设置。代码允许“A”和“B”同时为真;由用户决定将其中一个(或两个)设置为“真”。代码还允许在文档中间切换 A 为真和 B 为假(反之亦然)。
% !TEX TS-program = lualatex
\documentclass{scrartcl}
\usepackage{luacode} % for "luacode" environment and "\luastring" macro
%% Lua-side code: function "conditional_print"
\begin{luacode}
-- s1, s2: strings; A, B: booleans
function conditional_print (s1,s2)
if s1=="A" and A then tex.sprint (s2)
elseif s1=="B" and B then tex.sprint (s2)
end
end
\end{luacode}
%% TeX-side code: macros \settotrue, \settofalse, and \ConditionalPrint
\newcommand\settotrue[1]{ \directlua{ #1 = true } }
\newcommand\settofalse[1]{ \directlua{ #1 = false } }
\newcommand{\ConditionalPrint}[2]{%
\directlua{ conditional_print ( \luastring{#1}, \luastring{#2} ) }}
\begin{document}
\settotrue{A} % set A to "true"; B is still "nil" (and thus "false")
\ConditionalPrint{A}{Some A Text.}
\ConditionalPrint{B}{Some B Text.}
\ConditionalPrint{A}{Some Addtional A Text.}
\ConditionalPrint{B}{Some Addtional B Text.}
\dots
\settofalse{A} \settotrue{B} % set A to false & B to true
\ConditionalPrint{A}{Some A Text.}
\ConditionalPrint{B}{Some B Text.}
\ConditionalPrint{A}{Some Addtional A Text.}
\ConditionalPrint{B}{Some Addtional B Text.}
\end{document}