我想定义一组具有类似行为但应用于不同符号的宏。为了避免重复,我认为从模板以编程方式生成它们是一个好主意。
我有很多数量
\idx
运用一般指标( ),- 但我偶尔需要这个索引的变体(例如,用于定义递归关系);
- 或者完全废除自动索引并用其他索引代替。
我考虑过使用O{\idx}
参数类型,但我不喜欢这种解决方案,因为我想特别重申\idx
。2.
似乎星号参数在这里很有用。
这就是为什么我想出这个主意:
\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}
作为参数说明符?您可以在底部看到原因,其中显示了不需要的空格。