Wir möchten ein Makro definieren \ellipsis
, das vier Argumente annimmt und das folgende Verhalten hat:
\ellipsis{x^{#DUMMY#}}{0}{5}{+}
und Ausgänge:
Der Musterstring #DUMMY#
(der nicht exakt dieser String sein muss) muss durch das zweite und dritte Argument ersetzt werden. Das erste Argument ist also die Definition eines Makros für sich.
Wir haben ein paar Dinge ausprobiert, aber am Ende verwenden wir immer zwei verschiedene Makros, um das gewünschte Verhalten zu erzielen. Zum Beispiel
\newcommand{\ellipMacro}[1]{x^{#1}}
\newcommand{\ellip}[4]{\csuse{#1}{#2}#4\ldots #4 \csuse{#1}{#3}}
Dabei wird die Steuersequenz \csuse
aus dem Paket verwendet.Abonnieren(wir können problemlos beliebige Pakete verwenden).
Wir möchten dies in nureinsBefehl, daher muss die Definition des inneren Makros ( x^{#DUMMY}
) innerhalb der Definition des größeren Makros platziert werden.
Bitte geben Sie alle Ideen an, die Sie hierzu haben.
Antwort1
Dies ist eine Anpassung meiner Antwort unterWie erstellt man einen Befehl zur automatischen Erstellung von Produkten ähnlich der Primfaktorzerlegung?
\documentclass{article}
\usepackage{amsmath}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\elliptic}{O{i}mmmm}
{% #1 = item to substitute
% #2 = main term
% #3 = first index
% #4 = last index
% #5 = operation
\group_begin:
\lucas_elliptic:nnnnn { #1 } { #2 } { #3 } { #4 } { #5 }
\group_end:
}
\tl_new:N \l__lucas_elliptic_term_tl
\cs_generate_variant:Nn \cs_set:Nn { NV }
\cs_new:Nn \lucas_elliptic:nnnnn
{
\tl_set:Nn \l__lucas_elliptic_term_tl { #2 }
\regex_replace_all:nnN
{ #1 } % search
{ \cB\{\cP\#1\cE\} } % replace
\l__lucas_elliptic_term_tl % what to act on
\cs_set:NV \__lucas_elliptic_term:n \l__lucas_elliptic_term_tl
\__lucas_elliptic_term:n { #3 }
#5 \dots #5
\__lucas_elliptic_term:n { #4 }
}
\ExplSyntaxOff
\begin{document}
$\elliptic{x^{i}}{0}{5}{+}$
$\elliptic{x_{i}}{0}{5}{+}$
$\elliptic[k]{(x_{k}+y_{k}i)}{1}{n}{}$
\end{document}
Wenn Sie mit der Verwendung #1
als Platzhalter einverstanden sind, kann dies vereinfacht werden:
\documentclass{article}
\usepackage{amsmath}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\elliptic}{mmmm}
{% #1 = main term
% #2 = first index
% #3 = last index
% #4 = operation
\group_begin:
\lucas_elliptic:nnnn { #1 } { #2 } { #3 } { #4 }
\group_end:
}
\cs_new:Nn \lucas_elliptic:nnnn
{
\cs_set:Nn \__lucas_elliptic_term:n { #1 }
\__lucas_elliptic_term:n { #2 }
#4 \dots #4
\__lucas_elliptic_term:n { #3 }
}
\ExplSyntaxOff
\begin{document}
$\elliptic{x^{#1}}{0}{5}{+}$
$\elliptic{x_{#1}}{0}{5}{+}$
$\elliptic{(x_{#1}+y_{#1}i)}{1}{n}{}$
\end{document}
Antwort2
Für das angegebene Beispiel, bei dem das Argument am Ende des Platzhalters steht, müssen Sie keinen internen Befehl definieren, aber im allgemeinen Fall \ellipsisb
verwendet das Formular als erstes Argument den Hauptteil einer beliebigen Befehlsdefinition mit einem Argument. Dies ermöglicht das am Ende gezeigte 0^2...5^2-Formular.
\documentclass{article}
\begin{document}
\newcommand\ellipsis[4]{#1{#2}#4\cdots#4#1{#3}}
$\ellipsis{x^}{0}{5}{+}$
\newcommand\ellipsisb[4]{%
\def\tmp##1{#1}\tmp{#2}#4\cdots#4\tmp{#3}}
$\ellipsisb{x^{#1}}{0}{5}{+}$
$\ellipsisb{{#1}^2}{0}{5}{+}$
\end{document}
Antwort3
Vielleicht verstehe ich nicht, was Sie wollen, aber soweit ich sehe, brauchen Sie das \csuse
hier nicht und können Folgendes definieren:
\newcommand\ellip[4]{{#1}^{#3}#2\dots#2{#1}^{#4}}
Auf diese Weise ergeben $\ellip x+04$ bzw. $\ellip y-{-1}2$
Wenn Sie wirklich eine ausgefallenere Version brauchen, die ein Makro unterstützt, dann schlage ich vor, das Makro nicht in den Exponenten einzufügen, sondern es stattdessen einfach x^
durch Folgendes zu ersetzen \csuse{#1}
:
\newcommand\fancyellip[4]{\csuse{#1}{#3}#2\dots#2\csuse{#1}{#4}}
so dass nun $\fancyellip{xint}-{1}2$ ergibt
für eine angemessene Definition von \xint
.
Hier ist der vollständige Code:
\documentclass{article}
\newcommand\ellip[4]{{#1}^{#3}#2\dots#2{#1}^{#4}}
\usepackage{etoolbox}
\newcommand\fancyellip[4]{\csuse{#1}{#3}#2\dots#2\csuse{#1}{#4}}
\newcommand\xint[1]{\int_{0}^{#1}x\,dx}
\begin{document}
$\ellip x+04$
$\ellip y-{-1}2$
\bigskip
$\fancyellip{xint}-{1}2$
\end{document}
Antwort4
Mein Makro
\replaceiandreplicate{<term with i>}%
{<loop-start-index>}%
{<loop-end-index>}%
{<separator>}%
{<end index>}
in der Diskussion vorgestelltSchleifencode für wiederholte Summenund in der DiskussionWie erstellt man einen Befehl zur automatischen Erstellung von Produkten ähnlich der Primfaktorzerlegung?könnte für Sie von Interesse sein:
\documentclass{article}
\makeatletter
%%=============================================================================
%% Paraphernalia:
%% \UD@firstoftwo, \UD@secondoftwo,
%% \UD@PassFirstToSecond, \UD@Exchange, \UD@removespace
%% \UD@CheckWhetherNull, \UD@CheckWhetherBrace,
%% \UD@CheckWhetherLeadingSpace, \UD@ExtractFirstArg
%%=============================================================================
\newcommand\UD@firstoftwo[2]{#1}%
\newcommand\UD@secondoftwo[2]{#2}%
\newcommand\UD@PassFirstToSecond[2]{#2{#1}}%
\newcommand\UD@Exchange[2]{#2#1}%
\newcommand\UD@removespace{}\UD@firstoftwo{\def\UD@removespace}{} {}%
%%-----------------------------------------------------------------------------
%% Check whether argument is empty:
%%.............................................................................
%% \UD@CheckWhetherNull{<Argument which is to be checked>}%
%% {<Tokens to be delivered in case that argument
%% which is to be checked is empty>}%
%% {<Tokens to be delivered in case that argument
%% which is to be checked is not empty>}%
%%
%% The gist of this macro comes from Robert R. Schneck's \ifempty-macro:
%% <https://groups.google.com/forum/#!original/comp.text.tex/kuOEIQIrElc/lUg37FmhA74J>
\newcommand\UD@CheckWhetherNull[1]{%
\romannumeral0\expandafter\UD@secondoftwo\string{\expandafter
\UD@secondoftwo\expandafter{\expandafter{\string#1}\expandafter
\UD@secondoftwo\string}\expandafter\UD@firstoftwo\expandafter{\expandafter
\UD@secondoftwo\string}\expandafter\expandafter\UD@firstoftwo{ }{}%
\UD@secondoftwo}{\expandafter\expandafter\UD@firstoftwo{ }{}\UD@firstoftwo}%
}%
%%-----------------------------------------------------------------------------
%% Check whether argument's first token is a catcode-1-character
%%.............................................................................
%% \UD@CheckWhetherBrace{<Argument which is to be checked>}%
%% {<Tokens to be delivered in case that argument
%% which is to be checked has leading
%% catcode-1-token>}%
%% {<Tokens to be delivered in case that argument
%% which is to be checked has no leading
%% catcode-1-token>}%
\newcommand\UD@CheckWhetherBrace[1]{%
\romannumeral0\expandafter\UD@secondoftwo\expandafter{\expandafter{%
\string#1.}\expandafter\UD@firstoftwo\expandafter{\expandafter
\UD@secondoftwo\string}\expandafter\expandafter\UD@firstoftwo{ }{}%
\UD@firstoftwo}{\expandafter\expandafter\UD@firstoftwo{ }{}\UD@secondoftwo}%
}%
%%-----------------------------------------------------------------------------
%% Check whether brace-balanced argument starts with a space-token
%%.............................................................................
%% \UD@CheckWhetherLeadingSpace{<Argument which is to be checked>}%
%% {<Tokens to be delivered in case <argument
%% which is to be checked>'s 1st token is a
%% space-token>}%
%% {<Tokens to be delivered in case <argument
%% which is to be checked>'s 1st token is not
%% a space-token>}%
\newcommand\UD@CheckWhetherLeadingSpace[1]{%
\romannumeral0\UD@CheckWhetherNull{#1}%
{\expandafter\expandafter\UD@firstoftwo{ }{}\UD@secondoftwo}%
{\expandafter\UD@secondoftwo\string{\UD@CheckWhetherLeadingSpaceB.#1 }{}}%
}%
\newcommand\UD@CheckWhetherLeadingSpaceB{}%
\long\def\UD@CheckWhetherLeadingSpaceB#1 {%
\expandafter\UD@CheckWhetherNull\expandafter{\UD@secondoftwo#1{}}%
{\UD@Exchange{\UD@firstoftwo}}{\UD@Exchange{\UD@secondoftwo}}%
{\UD@Exchange{ }{\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter}\expandafter\expandafter
\expandafter}\expandafter\UD@secondoftwo\expandafter{\string}%
}%
%%-----------------------------------------------------------------------------
%% Extract first inner undelimited argument:
%%
%% \UD@ExtractFirstArg{ABCDE} yields {A}
%%
%% \UD@ExtractFirstArg{{AB}CDE} yields {AB}
%%.............................................................................
\newcommand\UD@RemoveTillUD@SelDOm{}%
\long\def\UD@RemoveTillUD@SelDOm#1#2\UD@SelDOm{{#1}}%
\newcommand\UD@ExtractFirstArg[1]{%
\romannumeral0%
\UD@ExtractFirstArgLoop{#1\UD@SelDOm}%
}%
\newcommand\UD@ExtractFirstArgLoop[1]{%
\expandafter\UD@CheckWhetherNull\expandafter{\UD@firstoftwo{}#1}%
{ #1}%
{\expandafter\UD@ExtractFirstArgLoop\expandafter{\UD@RemoveTillUD@SelDOm#1}}%
}%
%%=============================================================================
%% \DefineReplacementMacro{<replacement-macro>}%
%% {<internal helper-macro>}%
%% {<single non-explicit-space/non-explicit-brace-token to replace>}%
%%
%% defines <replacement-macro> to fetch two arguments,
%% #1 = <replacement for item to replace>
%% #2 = <token sequence with item to replace>
%% , and to deliver after two expansion-steps:
%% <token sequence with all instances of
%% <single non-explicit-space/non-explicit-brace-token to replace> replaced
%% by <replacement for item to replace>. >
%%
%% Internally an <internal helper-macro> is needed.
%%
%% (!!! <replacement-macro> does also replace all pairs of matching
%% explicit character tokens of catcode 1/2 by matching brace-tokens!!!
%% Under normal circumstances this is not a problem as under normal
%% circumstances { and } are the only characters of catcode 1 respective 2.)
%%-----------------------------------------------------------------------------
\newcommand\DefineReplacementMacro[3]{%
\newcommand#2{}\long\def#2##1#3{}%
\newcommand#1[2]{%
\romannumeral0\UD@ReplaceAllLoop{##2}{##1}{}{#2}{#3}%
}%
}%
\newcommand\UD@ReplaceAllLoop[5]{%
\UD@CheckWhetherNull{#1}{ #3}{%
\UD@CheckWhetherLeadingSpace{#1}{%
\expandafter\UD@ReplaceAllLoop
\expandafter{\UD@removespace#1}{#2}{#3 }{#4}{#5}%
}{%
\UD@CheckWhetherBrace{#1}{%
\expandafter\expandafter\expandafter\UD@PassFirstToSecond
\expandafter\expandafter\expandafter{%
\expandafter\UD@PassFirstToSecond\expandafter{%
\romannumeral0\expandafter\UD@ReplaceAllLoop
\romannumeral0\UD@ExtractFirstArgLoop{#1\UD@SelDOm}{#2}{}{#4}{#5}%
}{#3}}%
{\expandafter\UD@ReplaceAllLoop\expandafter{\UD@firstoftwo{}#1}{#2}}%
{#4}{#5}%
}{%
\expandafter\UD@CheckWhetherNoReplacement
\romannumeral0\UD@ExtractFirstArgLoop{#1\UD@SelDOm}{#1}{#2}{#3}{#4}{#5}%
}%
}%
}%
}%
\newcommand\UD@CheckWhetherNoReplacement[6]{%
\expandafter\UD@CheckWhetherNull\expandafter{#5#1#6}%
{%
\expandafter\UD@ReplaceAllLoop
\expandafter{\UD@firstoftwo{}#2}{#3}{#4#1}{#5}{#6}%
}{%
\expandafter\UD@ReplaceAllLoop
\expandafter{\UD@firstoftwo{}#2}{#3}{#4#3}{#5}{#6}%
}%
}%
%%=============================================================================
%% \UD@ReplaceAlli -- Replace all "i" in undelimited Argument:
%%
%% \UD@ReplaceAlli{<replacement for i>}{<token sequence with i>}
%% yields <token sequence with all i replaced by replacement for i>
%%
%% <replacement for i> may contain i.
%%
%% (This routine does also replace all pairs of matching explicit
%% character tokens of catcode 1/2 by matching braces!!!)
%%
%% The letter "i" as item to replace is hard-coded.
%% You cannot replace öetters other than I with this macro.
%%.............................................................................
\DefineReplacementMacro{\UD@ReplaceAlli}{\UD@gobbletoi}{i}%
%%
%%=============================================================================
%% \replaceiandreplicate{<term with i>}%
%% {<loop-start-index>}%
%% {<loop-end-index>}%
%% {<separator>}%
%% {<end index>}
%%
%% e.g.,
%%
%% \replaceiandreplicate{p_i^{\epsilon_i}}{1}{3}{\cdots}{n}
%%.............................................................................
\newcommand\replaceiandreplicate[5]{%
\romannumeral0\expandafter\expandafter
\expandafter \UD@Exchange
\expandafter\expandafter
\expandafter{%
\UD@ReplaceAlli{#5}{#1}%
}{%
\replaceiandreplicateloop{#3}{#2}{#1}#4%
}%
}%
\newcommand\replaceiandreplicateloop[3]{%
\ifnum#1<#2 %
\expandafter\UD@firstoftwo
\else
\expandafter\UD@secondoftwo
\fi
{ }{%
\expandafter\expandafter
\expandafter \UD@Exchange
\expandafter\expandafter
\expandafter{%
\UD@ReplaceAlli{#1}{#3}%
}{%
\expandafter\replaceiandreplicateloop
\expandafter{\number\numexpr\number#1-1\relax}{#2}{#3}%
}%
}%
}%
\makeatother
\parindent=0ex
\begin{document}
\begin{verbatim}
$\replaceiandreplicate{x^{i}}{0}{0}{+\ldots+}{5}$
\end{verbatim}
yields:\bigskip
$\replaceiandreplicate{x^{i}}{0}{0}{+\ldots+}{5}$
\bigskip\hrule
\begin{verbatim}
$\replaceiandreplicate{\if i0\else+\fi x^{i}}{0}{4}{}{5}$
\end{verbatim}
yields:\bigskip
$\replaceiandreplicate{\if i0\else+\fi x^{i}}{0}{4}{}{5}$
\bigskip\hrule
\begin{verbatim}
$\replaceiandreplicate{\ifnum i=-2 \else+\fi x^{\ifnum i<0(i)\else i\fi}}{-2}{4}{}{5}$
\end{verbatim}
yields:\bigskip
$\replaceiandreplicate{\ifnum i=-2 \else+\fi x^{\ifnum i<0(i)\else i\fi}}{-2}{4}{}{5}$
\bigskip\hrule
\begin{verbatim}
$\replaceiandreplicate{p_{i}^{\epsilon_{i}}}{1}{3}{\cdots}{n}$
\end{verbatim}
yields:\bigskip
$\replaceiandreplicate{p_{i}^{\epsilon_{i}}}{1}{3}{\cdots}{n}$
\bigskip\hrule
\begin{verbatim}
$\replaceiandreplicate{\if in+\fi p_{i}^{\epsilon_{i}}\if in\else+\fi}%
{1}%
{3}%
{\cdots}%
{n}$
\end{verbatim}
yields:\bigskip
$\replaceiandreplicate{\if in+\fi p_{i}^{\epsilon_{i}}\if in\else+\fi}{1}{3}{\cdots}{n}$
\end{document}
Bitte verschachteln Sie Aufrufe nicht \replaceiandreplicate
innerhalb des ersten Arguments von \replaceiandreplicate
. ;-)