我希望能够在主标志(比如说output
)的开头设置一个标志,告诉我是否要生成纸质文档或电子文档。
然后我应该检查这个标志来定义是否为空页面,hypperref,oneside或twosides等。
我怎能这样做?
答案1
方法有很多。
普通 LaTeX
也许最经典的是:
\newif\ifpaper
然后要么
\papertrue % or
\paperfalse
这些设置\ifpaper
为分别等于\iftrue
和\iffalse
。因此要使用它:
\ifpaper
% using paper
\else
% electronic
\fi
然而,使用这些原始条件可能会导致意想不到的问题如果您不完全熟悉 TeX 处理它们的方式,建议采用以下解决方案。
电子工具箱
采用了一种更加用户友好和现代的方法etoolbox
,你可以这样写
\newtoggle{paper}
设置为
\toggletrue{paper}
\togglefalse{paper}
如何使用它:
\iftoggle{paper}{%
% using paper
}{%
% electronic
}
为什么我说这更友好?因为你永远不会遇到嵌套问题,而 LaTeX 的\newif
条件有时会让嵌套问题有点难以处理。
etoolbox 还支持布尔表达式,例如
\ifboolexpr { togl {paper} and togl {pdf} } {true} {false}
它还可以与该包(和其他包)提供的各种测试功能相结合:
\ifboolexpr { togl {paper} or test {\ifdef{\foo}} } {true} {false}
解释3
最后,对于软件包编写者(不是真正的文档作者):作为 LaTeX3 的一部分,expl3 提供了可以以各种有趣的方式使用的布尔值。对于基本用法,它们看起来像这样:
\bool_new:N \l_tmpa_bool
\bool_set_true:N \l_tmpa_bool
\bool_set_false:N \l_tmpa_bool
\bool_if:NTF \l_tmpa_bool {true} {false}
\bool_if:NT \l_tmpa_bool {true}
\bool_if:NF \l_tmpa_bool {false}
您可以使用布尔逻辑,如下所示:
\bool_if:nTF { ( \l_tmpa_bool || \l_tmpb_bool ) && !( \l_tmpc_bool ) } {true} {false}
一切都是可扩展的,并使用惰性求值来避免执行不需要检查的测试。
您还可以将上面的布尔变量与条件函数(如\cs_if_eq_p:NN
(“两个控制序列是否相等?”)结合起来,可以用完全相同的方式进行测试:
\bool_if:nTF { \l_tmpa_bool && \cs_if_eq_p:NN \foo \bar } {true} {false}
etoolbox 和 expl3 之间的重叠相当明显;我认为两者之间的区别在于文档作者(对于 etoolbox)和软件包编写者(对于 expl3)之间的区别。但归根结底,这纯粹是一个品味问题。
答案2
另一种方法是使用optional
包,我将其用于多种用途,以及boolexpr
具有良好\switch
和\case
命令的包。
这里举一个简单的例子来说明。
%%%my-varient-for-different-output.tex
%%%This is the file that you actually call with pdftex/lualatex/etc.
\documentclass{minimal}
%\usepackage{xifthen}
\usepackage[foo]{optional}
%\input{themain-file.tex}
%%%EOF my-varient-for-different-output.tex
%%%%START OF themain-file.tex
\usepackage{boolexpr}
\makeatletter
%Check if optional is loaded. Otherwise, you don't
%want to define these commands.
\@ifpackageloaded{optional}{%
%%Don't do anything here because you've got it covered.
}{%
%%%What are the defaults if no optional class was loaded?
\usepackage[bar]{optional}
}
%%%Let's make an ifthenelse version of the \opt command that's
%%%provided by the optional package
\newcommand\ifopt[3]{%
\ifboolexpr{%
0 = \pdfstrcmp{true}{%
\opt{#1}{true}%
}%
}{#2}{#3}%
}%
%%%This command is a wrapper around the \switch command that's
%%%provided by boolexpr. It lets you quickly create a switch
%%%that checks if an option is set.
\newcommand*\switchopt[1]{%
\switch[\pdfstrcmp{\opt{#1}{#1}}]%
}
%%%I'm sure there is a way to embed the \switch
%%%command in here, but I'm not that smart. Is
%%%there some application of \noexpand?
%%%
%%%Anyway, this is more common to use than \switchopt
%%%You'll use \switch (with no optional argument)
%%%and \case[\caseopt{myoption}] Do stuff...
%%%
\newcommand*\caseopt[1]{%
\pdfstrcmp{#1}{\opt{#1}{#1}}% = 0%
}
\makeatother
\begin{document}
I'm writing some text but \opt{foo}{don't want this
unless foo is there.} If I want an else as part of
the deal, then \ifopt{bar}{bar must be there}{bar
is out to lunch} and it's time to go.
Nesting ifopt commands can be tedious. Best to use
a case if we've got a ton of definitions\ldots
%%%NOTICE THE {{ and }}. They are required when using
%%% an optional argument in \switch.
\switchopt{bar}
\case{{foo}} Foo stuff here!
\case{{bar}} Bar stuff here!
\case{{third}} Some other thingy-dingy!
\otherwise Nothing I know of was set.
\endswitch%
\switch
\case{\caseopt{foo}} Foo stuff here!
\case{\caseopt{bar}} Bar stuff here!
\otherwise Nothing I know of was set.
\endswitch%
\end{document}
尽管选定的答案可能更好,但这可能会带来更多的想法。
答案3
ifthen
也可以成为你的朋友
http://texdoc.net/texmf-dist/doc/latex/base/ifthen.pdf
但 Will R 的解决方案更低级,可能更接近您的要求。
我将 ifthen 用于我的简历,因为我必须有一个内部版本和一个外部版本。更不用说它还具有“长”和“短”版本。
答案4
在命令行中,您可以执行\def\MYFLAG{}
,然后使用 测试是否\MYFLAG
在您的文档(或包含的样式文件)中定义\ifdefined\MYFLAG ... \else ... \fi
。
这使您可以以不同的方式运行文档而无需修改它,就像程序的命令行选项一样。
这并不是确切提出的问题,但与您给出的用例密切相关。