在编写软件文档时,需要一条命令来自动将大写字母中的 camelCase 单词连字符连接起来,例如 camel-Case。此外,这些 camelCase 单词会排版为特定颜色。@David Carlisle 提供了解决方案这里通过命令\zzz{camelCase}
。
但是,有些 camelCase 变量仅供内部使用。为此,有一个标志定义为
\newboolean{\internal}
\setboolean{internal}{true}
在配置文件中。在另一篇帖子@Steven B. Segletes 引入了一个新命令\zzzconditional
,当为假时,变量就会消失\internal
。
现在到了压轴戏 =) 我的文档中有很多段落包含\zzzconditional
命令,但也仅供内部使用,例如
\ifthenelse{\boolean{internal}}{%
Here is a paragraph for internal use which will only appear when the \textbackslash internal flag is set to TRUE. But I also refer to a camelCase variable \zzzconditional{InpShaftActTrqSpdRndVar} using the aforementioned command.%
}{}%
不幸的是,~ 中定义的自定义连字符\zzzconditional
在此上下文中不起作用。更准确地说,~ 连字符会完全断开,从而导致行过满(参见 MWE)。
\zzzconditional
是否有任何实现允许在命令内部使用\ifthenelse
?
下列平均能量损失由一个主文件组成,该文件通过命令加载另一个文件 codeInput.tex \input
。以下是 MWE 主文件的代码:
\documentclass{scrartcl}
\usepackage{xcolor}
\usepackage{ifthen}
\def\zzcolor{\color{red}}
% --------------------------------------------
% Definition of \zzz for text formatting and hyphenation
% --------------------------------------------
\makeatletter
\def\zzz{\leavevmode\begingroup
\def\zzelt##1{%
\catcode`##1\active\uccode`\~`##1\uppercase{%
\def~{\egroup\egroup\-\hbox\bgroup\bgroup\zzcolor\string##1}}}%
\zz@Alph{}%
\@zzz}
\def\zz@Alph#1{%
\zzelt A\zzelt B\zzelt C\zzelt D\zzelt E\zzelt F\zzelt G\zzelt H\zzelt I\zzelt J\zzelt
K\zzelt L\zzelt M\zzelt N\zzelt O\zzelt P\zzelt Q\zzelt R\zzelt S\zzelt T\zzelt U\zzelt V\zzelt W\zzelt X\zzelt
Y\zzelt Z}
\def\@zzz#1{\textbf{\texttt{\hbox\bgroup\bgroup\zzcolor#1\egroup\egroup}}\endgroup}
\makeatother
% --------------------------------------------
% Flag to set internal version of document
% --------------------------------------------
\newboolean{internal}
\setboolean{internal}{true}
% --------------------------------------------
% Definition of \zzzconditional which should work like \zzz, but only print to document if interal flag is TRUE
% --------------------------------------------
% helper command
\newcommand\removetheargument[1]{\leavevmode\unskip}
% command
\newcommand{\zzzconditional}{%
\ifthenelse{\boolean{internal}}{%
\zzz%
}{
\removetheargument%
}%
}
\begin{document}
\section{Test}
Here is an example of how \textbackslash zzz\{\} hyphenates camelCase words. A variable \zzz{InpShaftActTrqSpdRndVar} is hyphenated at capital letters thanks to the amazing support here on StackExchange.
Now here is an example of \textbackslash zzzconditional\{\}'s hyphenation. A variable \zzzconditional{InpShaftActTrqSpdRndVar} is hyphenated at capital letters. %
% +++++ internal flag set to false +++++
\setboolean{internal}{false}%
% ++++++++++++++++++++++++++++++++++++++
Having set the \textbackslash internal flag to false, the variable \zzzconditional{InpShaftActTrqSpdRndVar} will disappear. Look at the tex code of this example to see that \textbackslash zzzconditional\{InpShaftActTrqSpdRndVar\} was used in the previous sentence.
% +++++ internal flag set to true +++++
\setboolean{internal}{true}%
% +++++++++++++++++++++++++++++++++++++
\ifthenelse{\boolean{internal}}{%
Here is a paragraph which appears only when the \textbackslash internal flag is true. However, inside this \textbackslash ifthenelse\{\}\{\}\{\} construct the hypenation in \textbackslash zzzconditional\{\} is broken. Instead it will result in an overfull line. This is shown in the following example \zzzconditional{InpShaftActTrqSpdRndVar}.%
}{}%
\ifthenelse{\boolean{internal}}{%
The issue issue also persists if I use the command \textbackslash zzz\{\}, for example \zzz{InpShaftActTrqSpdRndVar}. So the core issue does not seem to be with \textbackslash zzzconditional\{\}.%
}{}%
\ifthenelse{\boolean{internal}}{%
\input{codeInput}%
}{}%
\end{document}
以下是外部文件 codeInput.tex 的代码:
However,~if I use \textbackslash ifthenelse in the main document to \textbackslash input the text from an external file codeInput.tex,~\textbackslash zzzconditional will work. Look at this variable \zzzconditional{InpShaftActTrqSpdRndVar} for example. Unfortunately this workaround is not feasible in the scope of my document\footnote{Large software documentation with so many internal paragraphs that is not practical to create an individual file for loading each one.}.
答案1
如果您只是寻找有条件输入的内容,我会使用以下方法之一:
普通风格的布尔值:
\newif\ifFoo% initializing
\Footrue% set it true
\Foofalse% set it false
\ifFoo
<True case>
\else
<False case>
\fi
%% Usage with a primitive wrapper (no catcode changes in arguments possible)
\makeatletter
\newcommand\myif[1]
{%
\csname if#1\endcsname
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi
}
\makeatother
\myif{Foo}{<True case>}{<False case>}
etoolbox
布尔值(这与上面使用包装器基本相同):
\usepackage{etoolbox}
\newbool{Foo}
\booltrue{Foo}
\boolfalse{Foo}
\ifbool{Foo}{<True case>}{<False case>}
etoolbox
谷歌搜索:
\usepackage{etoolbox}
\newtoggle{Foo}
\toggletrue{Foo}
\togglefalse{Foo}
\iftoggle{Foo}{<True case>}{<False case>}
\newtoggle
和之间有细微的差别\newbool
。后者\newif
在内部使用,并且实际上每个 bool 需要三个宏:\ifFoo
、\Footrue
和\Foofalse
。切换方法在内部是不同的。我不知道一种方法是否比另一种方法有明显的优势。
如果你需要非常高级的东西,你也可以使用expl3
。它有一个很好的布尔接口,允许&&
和||
构造。在我看来,这对你的用途来说有点过度了。
如果任何输入需要更改 catcode(如逐字读取内容),您实际上只能使用第一种方法,即使用普通样式,因为参数是读取的,因此任何类别更改都不适用于已经标记化的输入。使用 可能是一种可能的解决方案\scantokens
,但在我看来,这又过于复杂了。
答案2
正如在接受的答案下方的评论中所承诺的那样,这是我在 MWE 中实现的解决方案。我基本上引入了一个自定义条件,如下所述此链接。然后我\ifthenelse
用constructs替换了文档主体中的constructs \ifflagInternal
。
我也尝试\ifthenelse
在 的定义中替换\zzzconditional
,但出于某种原因,它无法与 一起使用\ifflagInternal
。这只是供您参考,无需解决方案。现在一切都按预期运行 =)
@Skillmon 发布的 MWE 代码及解决方案的实现:
\documentclass{scrartcl}
\usepackage{xcolor}
\usepackage{ifthen}
\def\zzcolor{\color{red}}
% --------------------------------------------
% Definition of \zzz for text formatting and hyphenation
% --------------------------------------------
\makeatletter
\def\zzz{\leavevmode\begingroup
\def\zzelt##1{%
\catcode`##1\active\uccode`\~`##1\uppercase{%
\def~{\egroup\egroup\-\hbox\bgroup\bgroup\zzcolor\string##1}}}%
\zz@Alph{}%
\@zzz}
\def\zz@Alph#1{%
\zzelt A\zzelt B\zzelt C\zzelt D\zzelt E\zzelt F\zzelt G\zzelt H\zzelt I\zzelt J\zzelt
K\zzelt L\zzelt M\zzelt N\zzelt O\zzelt P\zzelt Q\zzelt R\zzelt S\zzelt T\zzelt U\zzelt V\zzelt W\zzelt X\zzelt
Y\zzelt Z}
\def\@zzz#1{\textbf{\texttt{\hbox\bgroup\bgroup\zzcolor#1\egroup\egroup}}\endgroup}
\makeatother
% --------------------------------------------
% Flags to set internal version of document
% --------------------------------------------
% flag for \zzzconditional
\newboolean{internal}
\setboolean{internal}{true}
% flag for use in document
\newif\ifflagInternal
\flagInternaltrue
% --------------------------------------------
% Definition of \zzzconditional which should work like \zzz, but only print to document if interal flag is TRUE
% --------------------------------------------
% helper command
\newcommand\removetheargument[1]{\leavevmode\unskip}
% command
\newcommand{\zzzconditional}{%
\ifthenelse{\boolean{internal}}{%
\zzz%
}{
\removetheargument%
}%
}
\begin{document}
\section{Test}
Here is an example of how \textbackslash zzz\{\} hyphenates camelCase words. A variable \zzz{InpShaftActTrqSpdRndVar} is hyphenated at capital letters thanks to the amazing support here on StackExchange.
Now here is an example of \textbackslash zzzconditional\{\}'s hyphenation. A variable \zzzconditional{InpShaftActTrqSpdRndVar} is hyphenated at capital letters. %
% +++++ internal flag set to false +++++
\setboolean{internal}{false}%
% ++++++++++++++++++++++++++++++++++++++
Having set the \textbackslash internal flag to false, the variable \zzzconditional{InpShaftActTrqSpdRndVar} will disappear. Look at the tex code of this example to see that \textbackslash zzzconditional\{InpShaftActTrqSpdRndVar\} was used in the previous sentence.
% +++++ internal flag set to true +++++
\setboolean{internal}{true}%
% +++++++++++++++++++++++++++++++++++++
\ifflagInternal%
Here is a paragraph which appears only when the \textbackslash internal flag is true. However, inside this \textbackslash ifthenelse\{\}\{\}\{\} construct the hypenation in \textbackslash zzzconditional\{\} is broken. Instead it will result in an overfull line. This is shown in the following example \zzzconditional{InpShaftActTrqSpdRndVar}.%
\fi%
\ifflagInternal%
The issue issue also persists if I use the command \textbackslash zzz\{\}, for example \zzz{InpShaftActTrqSpdRndVar}. So the core issue does not seem to be with \textbackslash zzzconditional\{\}.%
\fi%
\ifflagInternal%
\input{codeInput}%
\fi%
\end{document}
编译后的MWE: