如何扩展使用 SplitArgument 定义的命令以允许 4 个参数而不仅仅是 2 个?

如何扩展使用 SplitArgument 定义的命令以允许 4 个参数而不仅仅是 2 个?

我有一个命令\cont主要以 的形式使用\cont{X, Y},并使用 进行定义\SplitArgument,如下面的源代码所示。我如何重新定义(即扩展 的定义)\cont以允许 4 个参数而不是 2 个参数,这些参数成对分组,如 outout 等式 (2) 所示?

请注意,当只有 2 个参数时,我想继续使用逗号作为分隔符,例如\cont{X, Y}。但是当有 4 个参数时,我想将(主)分隔符更改为分号,同时保留逗号作为辅助分隔符,例如\cont{X, x; Y, y}

\documentclass[fleqn]{memoir}
\usepackage{xparse}

\NewDocumentCommand{\cont}{ >{\SplitArgument{1}{,}} m }{\printcont#1}
\NewDocumentCommand{\printcont}{mm}{{\mathcal{C}}({#1}\IfValueT{#2}{, {#2}})}

\begin{document}

\noindent Equation~(\ref{one}) shows use of \verb!\cont! with 2 arguments, as in \verb!\cont{X, Y}!, with comma as separator:
\begin{equation}\label{one}
\cont{X, Y}
\end{equation}
 
\noindent How can we \emph{extend} the definition of \verb!\cont! so that\dots\\[6pt]
\mbox{}\qquad\verb!\cont{X, x; Y, y}! \\[6pt]
---with commas and a single semicolon as separators----gives the same result as equation~(\ref{two}), below?
\begin{equation}\label{two}
\mathcal{C}[(X, x), (Y, y)]
\end{equation}

\end{document}

扩展 def 以允许 4 个参数而不仅仅是 2 个

答案1

我会立即发出\mathcal{C},然后将控制权传递给另一个检查分号并采取适当操作的命令。

\documentclass[fleqn]{memoir}
\usepackage{amsmath}

\NewDocumentCommand{\cont}{>{\SplitArgument{1}{;}}m}{%
  \mathcal{C}%
  \printcont#1%
}
\NewDocumentCommand{\printcont}{mm}{%
  \IfNoValueTF{#2}{%
    \conttwo{#1}%
  }{%
    [\conttwo{#1},\conttwo{#2}]%
  }%
}
\NewDocumentCommand{\conttwo}{>{\SplitArgument{1}{,}}m}{%
  \printconttwo#1%
}
\NewDocumentCommand{\printconttwo}{mm}{%
  (#1\IfValueT{#2}{,#2})%
}

\begin{document}

\begin{gather*}
\cont{X} \\
\cont{X, Y} \\
\cont{X;Y} \\
\cont{X,x;Y} \\
\cont{X, x;Y, y}
\end{gather*}

\end{document}

在此处输入图片描述

如果您想在括号中添加\bigl和,则传递整个参数。\bigr\cont*

\documentclass[fleqn]{memoir}
\usepackage{amsmath}

\NewDocumentCommand{\cont}{s>{\SplitArgument{1}{;}}m}{%
  \mathcal{C}%
  \printcont{#1}#2%
}
\NewDocumentCommand{\printcont}{mmm}{%
  \IfNoValueTF{#3}{%
    \conttwo{#2}%
  }{%
    \IfBooleanT{#1}{\bigl}[%
    \conttwo{#2},\conttwo{#3}
    \IfBooleanT{#1}{\bigr}]%
  }%
}
\NewDocumentCommand{\conttwo}{>{\SplitArgument{1}{,}}m}{%
  \printconttwo#1%
}
\NewDocumentCommand{\printconttwo}{mm}{%
  ({#1}\IfValueT{#2}{, {#2}})
}

\begin{document}

\begin{gather*}
\cont{X} \\
\cont{X, Y} \\
\cont{X;Y} \\
\cont{X,x;Y} \\
\cont{X, x;Y, y} \\
\cont*{X,x;Y} \\
\cont*{X, x;Y, y}
\end{gather*}

\end{document}

在此处输入图片描述

答案2

\cont仅使用 TeX 原语定义的宏:

\def\cont#1{\contA#1;\end}
\def\contA#1;#2\end{\ifx;#2;{\cal C}(#1)\else\contB#1;#2\fi}
\def\contB#1;#2;{{\cal C}\bigl[(#1),(#2)\bigr]}

%% test:

$$\displaylines{
  \cont{X} \cr
  \cont{X, Y} \cr
  \cont{X;Y} \cr
  \cont{X,x;Y} \cr
  \cont{X, x;Y, y}
}$$

\bye

答案3

以下方法使用etoolbox的列表处理功能来设置提供的参数\cont,用分隔参数(列表);,然后有条件地设置列表:单个项目的设置与项目列表不同。

在此处输入图片描述

\documentclass{article}

\usepackage{etoolbox}

\DeclareListParser{\contlist}{;}% Processes a list using ; as separator
\newcounter{contcount}
\newcommand{\cont}[1]{%
  \setcounter{contcount}{0}% Reset counter
  \renewcommand*{\do}[1]{\stepcounter{contcount}}% Count items in list
  \contlist{#1}% Count elements in list
  \ifnum\value{contcount}<2
    \mathcal{C}(#1)% Singular element
  \else % \value{contcount}>1
    \mathcal{C}[
      % https://tex.stackexchange.com/a/89187/5764
      \newcommand{\contitemsep}{\renewcommand{\contitemsep}{,}}% Delayed definition of \contitemsep
      \renewcommand*{\do}[1]{\contitemsep(##1)}% How each item in list should be printed
      \contlist{#1}% Print entire list
    ]
  \fi
}

\begin{document}

\noindent Equation~(\ref{one}) shows use of \verb!\cont! with 2 arguments, as in \verb!\cont{X, Y}!, with comma as separator:
\begin{equation}\label{one}
  \cont{X, Y}
\end{equation}
 
\noindent How can we \emph{extend} the definition of \verb!\cont! so that\dots

\qquad\verb!\cont{X, x; Y, y}!

---with commas and a single semicolon as separators----gives the same result as equation~(\ref{two}), below?
\begin{equation}\label{two}
  \cont{X, x; Y, y}
\end{equation}

\end{document}

答案4

此变体不愿意添加括号,并且此变体与\cont{X,Y}相同, \cont{X;Y}并且\cont*{X,Y}与 相同 ,即,仅当 的非星号参数\cont*{X;Y}中同时出现逗号和分号时,才会得到方括号。\cont

\documentclass[fleqn]{memoir}
\usepackage{amsmath}

\NewDocumentCommand{\cont}{s>{\SplitArgument{1}{;}}m}{%
  % #1  - \BooleanTrue/\BooleanFalse - flag / control-word-token
  %       denoting the presence/non-presence of star.
  % #2  - user-provided argument, split in two brace-nested arguments, one holding
  %       "things before first semicolon", the other holding "things behind first semicolon".
  \conttwo#2{#1}%
}
\NewDocumentCommand{\conttwo}{>{\SplitArgument{1}{,}}mm}{%
  % #1 - things before first semicolon, split in two brace-nested arguments at first comma.
  % #2 - things behind first semicolon
  % You need to check if #2 is the NoValue-marker as 
  % xparse-argument-processors like \SplitArgument do not work on
  % the NoValue-Marker
  \IfNoValueTF{#2}{\printcont{#2}}{\contthree}{#2}#1%
}
\NewDocumentCommand{\contthree}{>{\SplitArgument{1}{,}}m}{%
  % #1 - things behind first semicolon, split in two brace-nested arguments at first comma.
  \printcont#1%
}
\NewDocumentCommand\printcont{mmmmm}{%
  % #1 - first component of things behind first semicolon after splitting these things at first comma.
  % #2 - second component of things behind first semicolon after splitting these things at first comma.
  % #3 - first component of things before first semicolon after splitting these things at first comma.
  % #4 - second component of things before first semicolon after splitting these things at first comma.
  % #5 - \BooleanTrue/\BooleanFalse - flag denoting presence of star.
  \mathcal{C}%
  \IfNoValueTF{#1}{%
    (#3\IfNoValueF{#4}{,#4})% <-only commas
  }{%
    \IfNoValueTF{#4}{%
                      \IfNoValueTF{#2}{(#3,#1)}% <-only semicolons
                                      {\IfBooleanT{#5}{\bigl}[#3,(#1,#2)\IfBooleanT{#5}{\bigr}]}%
                    }%
                    {\IfBooleanT{#5}{\bigl}[(#3,#4),\IfNoValueTF{#2}{#1}{(#1,#2)}\IfBooleanT{#5}{\bigr}]}%
  }%
}%

\begin{document}

\Huge

\begin{tabular}{|l|l|}
\hline
\(\cont{X}\)&\(\cont*{X}\) \\
\hline
\(\cont{X, Y}\)&\(\cont*{X, Y}\) \\
\hline
\(\cont{X;Y}\)&\(\cont*{X;Y}\) \\
\hline
\(\cont{X,x;Y}\)&\(\cont*{X,x;Y}\) \\
\hline
\(\cont{X;Y, y}\)&\(\cont*{X;Y, y}\) \\
\hline
\(\cont{X, x;Y, y}\)&\(\cont*{X, x;Y, y}\)\\
\hline
\end{tabular}

\end{document}

在此处输入图片描述

相关内容