具有多个条件的条件,其中一个是字符串搜索

具有多个条件的条件,其中一个是字符串搜索

目的

我想要一个命令来根据需要写入“其中#1是任意常数”、“其中#1是任意常数”、“其中#1是任意函数#2”或“其中#1是任意函数”。#2

背景

通常,让单复数检测依赖于 中逗号的存在与否就足够了#1。为此,以下函数可以正常工作。

\documentclass{article}
\usepackage{xstring,xargs,xifthen,amsmath}
\newcommandx{\arbitrary}[3][1=\text{ where }, 3=]{%
    #1#2%
    \IfSubStr{#2}{,}{\text{ are}}{\text{ is an}}%
    \text{ arbitrary}%
    \ifthenelse{\equal{#3}{}}{\text{ constant}}{\text{ function}}%
    \IfSubStr{#2}{,}{\text{s}}{}%
    \ifthenelse{\equal{#3}{}}{}{\text{ of }#3}
}
\begin{document}
    \begin{align*}
        & \arbitrary{a} \\ % where a is an arbitrary constant
        & \arbitrary{a,b} \\ % where a,b are arbitrary constants
        & \arbitrary{f}[x] \\ % where f is an arbitrary function of x
        & \arbitrary{f,g}[x] % where f,g are arbitrary functions of x
    \end{align*}
\end{document}

但有时我想将一个单数参数复数化,例如

2a_n+1, \text{ where $a_n$ are arbitrary constants, } n \in \{1,2,\dots\}

为此,我尝试使用可选参数实现备份检测机制。这涉及定义两个条件,函数将根据这两个条件将其视为#1复数:如果#1包含逗号,或者如果#4=p为复数。

\documentclass{article}
\usepackage{xstring,xargs,xifthen}
\newcommandx{\arbitrary}[4][1=\text{ where }, 3=, 4=]{%
    #1#2%
    \ifthenelse{%
        1=\IfSubStr{#2}{,}{1}{0}\OR%
        \equal{#4}{p}%
    }{\text{ are}}{\text{ is}}%
    \text{ arbitrary}%
    \ifthenelse{\equal{#3}{}}{\text{ constant}}{\text{ function}}%
    \ifthenelse{%
        1=\IfSubStr{#2}{,}{1}{0}\OR%
        \equal{#4}{p}%
    }{\text{s}}{}%
    \ifthenelse{\equal{#3}{}}{}{\text{ of }#3}
}
\begin{document}
    I wish this function worked.
\end{document}

问题

LaTeX 似乎不喜欢这种语法\ifthenelse{1=\IfSubStr{ab}{a}{1}{0}}{1}{0}

\documentclass{article}
\usepackage{xstring,xifthen}
\begin{document}
    \IfSubStr{ab}{a}{1}{0} % returns 1
    \ifthenelse{1=1}{1}{0} % returns 1
    \ifthenelse{1=\IfSubStr{ab}{a}{1}{0}}{1}{0} % returns error
\end{document}

答案1

扩展版本还处理多变量函数。* 版本强制使用复数。

\documentclass{article}
\usepackage{amsmath}

\ExplSyntaxOn

\NewDocumentCommand{\arbitrary}{smo}
 {% #1 = boolean for forcing plural
  % #2 = mandatory argument
  % #3 = optional argument for the variable
  \IfBooleanTF{#1}
   { \bool_set_true:N \l_mjc_arbitrary_plural_bool }
   { \bool_set_false:N \l_mjc_arbitrary_plural_bool }
  \IfNoValueTF{#3}
   { \mjc_arbitrary_constant:n { #2 } }
   { \mjc_arbitrary_function:nn { #2 } { #3 } }
 }

\bool_new:N \l_mjc_arbitrary_plural_bool
\seq_new:N \l__mjc_arbitrary_variables_seq
\seq_new:N \l__mjc_arbitrary_variables_out_seq

\cs_new_protected:Nn \mjc_arbitrary_constant:n
 {
  \bool_lazy_or:nnTF
   { \l_mjc_arbitrary_plural_bool }
   { \int_compare_p:n { \clist_count:n { #1 } > 1 } }
   { \mjc_arbitrary_phrases:nnnn { #1 } { are } { constants } { } }
   { \mjc_arbitrary_phrases:nnnn { #1 } { is~an } { constant } { } }
 }

\cs_new_protected:Nn \mjc_arbitrary_function:nn
 {
  \bool_lazy_or:nnTF
   { \l_mjc_arbitrary_plural_bool }
   { \int_compare_p:n { \clist_count:n { #1 } > 1 } }
   { \mjc_arbitrary_phrases:nnnn { #1 } { are } { functions } { #2 } }
   { \mjc_arbitrary_phrases:nnnn { #1 } { is~an } { functions } { #2 } }
 }

\cs_new_protected:Nn \mjc_arbitrary_phrases:nnnn
 {% #1 = object, #2 = verb, #3 = type, #4 = optional variable
  \mode_if_math:TF 
   { \text { \__mjc_arbitrary_phrases:nnnn { #1 } { #2 } { #3 } { #4 } } }
   { \__mjc_arbitrary_phrases:nnnn { #1 } { #2 } { #3 } { #4 } }
 }
\cs_new_protected:Nn \__mjc_arbitrary_phrases:nnnn
 {
  where~$#1$~#2~arbitrary~#3
  \tl_if_blank:nF { #4 }
   {
    \seq_set_from_clist:Nn \l__mjc_arbitrary_variables_seq { #4 }
    \c_space_tl of~the~variable
    \int_compare:nT { \seq_count:N \l__mjc_arbitrary_variables_seq > 1 } { s }
    \nobreakspace
    \__mjc_arbitrary_variables:
   }
 }
\cs_new_protected:Nn \__mjc_arbitrary_variables:
 {
  \seq_set_map:NNn \l__mjc_arbitrary_variables_out_seq \l__mjc_arbitrary_variables_seq { $##1$ }
  \seq_use:Nnnn \l__mjc_arbitrary_variables_out_seq { ~and~ } { ,~ } { ,~and\nobreakspace }
 }
\ExplSyntaxOff

\begin{document}

\begin{align*}
& \arbitrary{a} \\ % where a is an arbitrary constant
& \arbitrary*{a_n} \\ % where a_n are arbitrary constants
& \arbitrary{a,b} \\ % where a,b are arbitrary constants
& \arbitrary{f}[x] \\ % where f is an arbitrary function of x
& \arbitrary{f,g}[x] \\% where f,g are arbitrary functions of x
& \arbitrary{f}[x,y] \\ % where f is an arbitrary function of x and y
& \arbitrary{f,g}[x,y] \\% where f,g are arbitrary functions of x, y, and z
& \arbitrary*{f_n}[x] \\ % where f is an arbitrary function of x
& \arbitrary*{f_n}[x,y] % where f is an arbitrary function of x and y
\end{align*}

\arbitrary{a},
\arbitrary*{a_n},
\arbitrary{a,b},
\arbitrary{f}[x],
\arbitrary{f,g}[x],
\arbitrary*{f_n}[x].

\end{document}

我仅当在数学模式下找到该命令时才使用\text;在文本模式下,您不希望使东西跨行牢不可破。

稍微复杂一点的是使用~您想要的空间,但它只需要一点练习。

在此处输入图片描述

答案2

我用etoolbox,以第一个参数中的 为条件(通过\patchcmd{<cmd>}{<search>}{<replace>}{<success>}{<failure>})。这提供了第一个条件分支。然后我使用 来以结束可选参数的存在为条件xparse\IfValueTF{<arg>}{<true>}{<false>}

在此处输入图片描述

\documentclass{article}

% \usepackage{xparse}% Only if you have LaTeX < 2020-10
\usepackage{etoolbox,amsmath}

\NewDocumentCommand{\arbitrary}{m o}{
  \def\firstarg{#1}% Store mandatory argument
  \text{ where }
  \firstarg
  \IfValueTF{#2}
    {\patchcmd{\firstarg}{,}{,}
      {\text{ are arbitrary functions of } #2}% Contains a comma , => plural
      {\text{ is an arbitrary function of } #2}}% Does not contain a comma , => singular
    {\patchcmd{\firstarg}{,}{,}
      {\text{ are arbitrary constants}}% Contains a comma , => plural
      {\text{ is an arbitrary constant}}}% Does not contain a comma , => singular
}
\begin{document}

\begin{align*}
  & \arbitrary{a} \\ % where a is an arbitrary constant
  & \arbitrary{a,b} \\ % where a,b are arbitrary constants
  & \arbitrary{f}[x] \\ % where f is an arbitrary function of x
  & \arbitrary{f,g}[x] % where f,g are arbitrary functions of x
\end{align*}

\end{document}

如果你想力量为单数项输出复数,您可以\arbitrary采用星号 - \arbitrary*。这是您使用该条件的方式:

\documentclass{article}

% \usepackage{xparse}% Only if you have LaTeX < 2020-10
\usepackage{etoolbox,amsmath}

\NewDocumentCommand{\arbitrary}{s m o}{
  \def\firstarg{#2}% Store mandatory argument
  \text{ where }
  \firstarg
  \IfBooleanTF{#1}
    {\text{ are arbitrary constants}}% Starred version => plural
    {
    \IfValueTF{#3}
      {\patchcmd{\firstarg}{,}{,}
        {\text{ are arbitrary functions of } #3}% Contains a comma , => plural
        {\text{ is an arbitrary function of } #3}}% Does not contain a comma , => singular
      {\patchcmd{\firstarg}{,}{,}
        {\text{ are arbitrary constants}}% Contains a comma , => plural
        {\text{ is an arbitrary constant}}}% Does not contain a comma , => singular
    }
}
\begin{document}

\begin{align*}
  & \arbitrary{a} \\ % where a is an arbitrary constant
  & \arbitrary*{a_n} \\ % where a_n are arbitrary constants
  & \arbitrary{a,b} \\ % where a,b are arbitrary constants
  & \arbitrary{f}[x] \\ % where f is an arbitrary function of x
  & \arbitrary{f,g}[x] % where f,g are arbitrary functions of x
\end{align*}

\end{document}

相关内容