使用自定义连字命令时,\ifthenelse 中的 camelCase 连字

使用自定义连字命令时,\ifthenelse 中的 camelCase 连字

在编写软件文档时,需要一条命令来自动将大写字母中的 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.}.

这是编译后的MWE: 在此处输入图片描述

答案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:

在此处输入图片描述

相关内容