
Betrachten Sie den folgenden Code vonDasAntwort, bei der einem Wort nur dann ein Präfix hinzugefügt wird, wenn das Präfix fehlt.
\documentclass[border=6pt,varwidth]{standalone}
\ExplSyntaxOn
\NewExpandableDocumentCommand { \forcebeginwith } { m m }
{
\str_if_eq:eeTF {#2} { \str_range:nnn {#1} { 1 } { \str_count:n {#2} } }
{#1}
{ #2#1 }
}
\ExplSyntaxOff
\newcommand{\mystringa}{fancycolor}
\newcommand{\mystringb}{\mystringa}
\newcommand{\mystringc}{\mystringb}
\newcommand{\prefixa}{fancy}
\newcommand{\prefixb}{\prefixa}
\newcommand{\prefixc}{\prefixb}
\begin{document}
\forcebeginwith{fancycolor}{fancy} \\% OK: fancycolor
\forcebeginwith{color}{fancy} \\% OK: fancycolor
\forcebeginwith{\mystringc}{\prefixc} \\% NOT WORKING: fancyfancycolor
\end{document}
FRAGE:Wie kann ich es zum Laufen bringen, wenn der Befehl erweiterbar sein muss?
Antwort1
Bei einer expl3-Basisfunktion können Sie eine Variante generieren, die ein oder mehrere Argumente verarbeitet, bevor die Ergebnisse an diese Funktion übergeben werden. Wenn eine Funktion beispielsweise einen Argumentspezifizierer (das Bit nach dem Doppelpunkt) hat n
, können Sie eine Variante definieren, die o
(expandÖnce) oder e
(erweiterntxmutfully) anstelle von n
. Dann verwenden Sie einfach die Variante, wo immer es erforderlich ist.
In diesem Fall wollen wir Varianten von zwei Funktionen
\cs_generate_variant:Nn \str_range:nnn { enn }
Dies stellt sicher, \str_range:enn
dass es existiert. Diese Variante erweitert das erste Argument, bevor es \str_range:nnn
zur Verarbeitung an die Funktion übergeben wird.
\cs_generate_variant:Nn \str_count:n { e }
Dadurch wird sichergestellt \str_count:e
, dass exists, das sein einziges Argument erweitert, bevor es an übergeben wird \str_count:n
.
Dann können wir diese Varianten genauso verwenden wie die Basisfunktionen
\NewExpandableDocumentCommand { \forcebeginwith } { m m }
{
\str_if_eq:eeTF {#2} { \str_range:enn {#1} { 1 } { \str_count:e {#2} } }
{#1}
{ #2#1 }
}
Vollständiger Code:
\documentclass[border=6pt,varwidth]{standalone}
\ExplSyntaxOn
\cs_generate_variant:Nn \str_range:nnn { enn }
\cs_generate_variant:Nn \str_count:n { e }
\NewExpandableDocumentCommand { \forcebeginwith } { m m }
{
\str_if_eq:eeTF {#2} { \str_range:enn {#1} { 1 } { \str_count:e {#2} } }
{#1}
{ #2#1 }
}
\ExplSyntaxOff
\newcommand{\mystringa}{fancycolor}
\newcommand{\mystringb}{\mystringa}
\newcommand{\mystringc}{\mystringb}
\newcommand{\prefixa}{fancy}
\newcommand{\prefixb}{\prefixa}
\newcommand{\prefixc}{\prefixb}
\begin{document}
\forcebeginwith{fancycolor}{fancy} \par% OK: fancycolor
\forcebeginwith{color}{fancy} \par% OK: fancycolor
\forcebeginwith{\mystringc}{\prefixc} \par% NOT WORKING: fancyfancycolor
\end{document}
Antwort2
Hier ist ein Beispiel:
\documentclass[border=6pt,varwidth]{standalone}
\ExplSyntaxOn
\cs_generate_variant:Nn \str_range:nnn { enn }
\NewExpandableDocumentCommand { \forcebeginwith } { m m }
{
\str_if_eq:eeTF {#2} { \str_range:enn {#1} { 1 } { \str_count:e {#2} } }
{#1}
{ #2#1 }
}
\ExplSyntaxOff
\newcommand{\mystringa}{fancycolor}
\newcommand{\mystringb}{\mystringa}
\newcommand{\mystringc}{\mystringb}
\newcommand{\prefixa}{fancy}
\newcommand{\prefixb}{\prefixa}
\newcommand{\prefixc}{\prefixb}
\begin{document}
\forcebeginwith{fancycolor}{fancy} \\% OK: fancycolor
\forcebeginwith{color}{fancy} \\% OK: fancycolor
\forcebeginwith{\mystringc}{\prefixc} \\% NOT WORKING: fancyfancycolor
\end{document}
Antwort3
Ein besserer Programmierstil besteht darin, den Befehl auf Benutzerebene als interne Funktion zu definieren.
\documentclass{article}
\ExplSyntaxOn
\NewExpandableDocumentCommand { \forcebeginwith } { m m }
{
\vincent_forcebeginwith:ee { #1 } { #2 }
}
\cs_new:Nn \vincent_forcebeginwith:nn
{
\str_if_eq:eeF {#2} { \str_range:nnn {#1} { 1 } { \str_count:n {#2} } } { #2 }
#1
}
\cs_generate_variant:Nn \vincent_forcebeginwith:nn { ee }
\ExplSyntaxOff
\newcommand{\mystringa}{fancycolor}
\newcommand{\mystringb}{\mystringa}
\newcommand{\mystringc}{\mystringb}
\newcommand{\prefixa}{fancy}
\newcommand{\prefixb}{\prefixa}
\newcommand{\prefixc}{\prefixb}
\begin{document}
\forcebeginwith{fancycolor}{fancy} % OK: fancycolor
\forcebeginwith{color}{fancy} % OK: fancycolor
\forcebeginwith{\mystringc}{\prefixc} % OK: fancycolor
\end{document}
Wie Sie sehen \vincent_forcebeginwith:nn
, ist definiert, aber im Befehl auf Benutzerebene verwenden wir eine Variante davon, die ihre Argumente vollständig erweitert, bevor sie an übergeben wird \vincent_forcebeginwith:nn
.