宏工厂,传递明星论据

宏工厂,传递明星论据

我想定义一组具有类似行为但应用于不同符号的宏。为了避免重复,我认为从模板以编程方式生成它们是一个好主意。

我有很多数量

  1. \idx运用一般指标( ),
  2. 但我偶尔需要这个索引的变体(例如,用于定义递归关系);
  3. 或者完全废除自动索引并用其他索引代替。

我考虑过使用O{\idx}参数类型,但我不喜欢这种解决方案,因为我想特别重申\idx2.似乎星号参数在这里很有用。

这就是为什么我想出这个主意:

\documentclass[12pt]{article}

\usepackage{amsmath}

\NewDocumentCommand\idx{}{j}
\NewDocumentCommand\pmatstar{mm}{#1_{#2}}
\NewDocumentCommand\pmatnostar{mm}{#1_{\idx#2}}
\NewDocumentCommand\matnum{smO{}}{
    \IfBooleanTF{#1}{
        \pmatstar{#2}{#3}
    }{
        \pmatnostar{#2}{#3}
    }
}

%%%%%
% What I do not know how to do
%
% \NewDocumentCommand\specmatnum{mm}{...}
% \spectmatnum{mlow}{L}
% \spectmatnum{mupp}{U}
% ...
%
%%%%%

%%%%%
% This is what I want to avoid
%
% \NewDocumentCommand\mlow{sO{}}{
%     \IfBooleanTF{#1}{
%         \pmatstar{L}{#2}
%     }{
%         \pmatnostar{L}{#2}
%     }
% }
% \NewDocumentCommand\mupp{sO{}}{
%     \IfBooleanTF{#1}{
%         \pmatstar{U}{#2}
%     }{
%         \pmatnostar{U}{#2}
%     }
% }
% ...
%
%%%%%
\begin{document}

\begin{align*}
\text{Default: } &\matnum{L}\\
\text{No star, modified default: } &\matnum{L}[+1]\\
\text{Star, no optional argument: } &\matnum*{L}\\
\text{Star, optional '2': } &\matnum*{L}[2]
\end{align*}

%%%%%
% How I would like to be able to replicate the above example without calling \matnum directly
%
% \mlow
% \mlow[+1]
% \mlow*
% \mlow*[2]
%
%%%%%

\end{document}

示例输出

我的问题是,如何不重复所有符号的定义\matnum?对我来说,主要的困难是传递*,而不重写;这首先就\IfBooleanTF{}{}{}使拥有的意义变得毫无意义。我认为剩下的很简单。\matnum

答案1

在此处输入图片描述

\documentclass[12pt]{article}

\usepackage{amsmath}

\NewDocumentCommand\idx{}{j}
\NewDocumentCommand\matnum{msO{}}{#1_{\IfBooleanF{#2}{\idx}#3}}

\NewDocumentCommand\specmatnum{mm}{%
 \ExpandArgs{c}\NewDocumentCommand{#1}{}{\matnum{#2}}}

\specmatnum{mlow}{L}
\specmatnum{mupp}{U}

\begin{document}

\begin{align*}
\text{Default: } &\mlow\\
\text{No star, modified default: } &\mlow[+1]\\
\text{Star, no optional argument: } &\mlow*\\
\text{Star, optional '2': } &\mlow*[2]
\end{align*}


\end{document}

答案2

写下你想要抽象的内容,它会变得更简单:

\documentclass{article}
\usepackage{amsmath}

% we want that
% \spectmatnum{\mlow}{L}
% defines \mlow so
% \mlow -> L_{j}
% \mlow[+1] -> L_{j+1}
% \mlow* -> L
% \mlow*[2] -> L_{2}
%
% \NewDocumentCommand{\mlow}{so}{%
%   L%
%   \IfBooleanTF{#1}{%
%     \IfValueT{#2}{_{#2}}%
%   }{%
%     _{\idx\IfValueT{#2}{#2}}%
%   }%
% }

\NewDocumentCommand{\spectmatnum}{mm}{%
  % #1 = command name
  % #2 = letter
  \NewDocumentCommand{#1}{so}{%
    #2%
    \IfBooleanTF{##1}{%
      \IfValueT{##2}{_{##2}}%
    }{%
      _{\idx\IfValueT{##2}{##2}}%
    }%
  }%
}

\NewDocumentCommand{\idx}{}{j}

\spectmatnum{\mlow}{L}
\spectmatnum{\mupp}{U}



\begin{document}

$\mlow\quad\mlow[+1]\quad\mlow*\quad\mlow*[2]$

$\mupp\quad\mupp[+1]\quad\mupp*\quad\mupp*[2]$

%%% comparison with \matnum
\NewDocumentCommand\matnum{msO{}}{#1_{\IfBooleanF{#2}{\idx}#3}}
\NewDocumentCommand{\MLOW}{}{\matnum{L}}

$\mlow*|$

$\MLOW*|$

\end{document}

内部的参数\NewDocumentCommand变成##1##2,而#1#2指的是外部的参数。

因为\spectmatnum定义了一个命令,所以只需将该命令作为参数,而不仅仅是名称。

为什么不sO{\idx}作为参数说明符?您可以在底部看到原因,其中显示了不需要的空格。

在此处输入图片描述

相关内容