
Ich habe in meinen Texten mit Aufzählungen zu tun, deren Einträge einzeln formatiert werden müssen, zB:
\funktion[3][]{T}--\funktion{S}--\funktion[3][7]{D}--\funktion{T}
Darin \funktion
erfolgt \emphsubsup
die Formatierung und die Verarbeitung der optionalen Parameter.
Wie kann ich diese Aufgabe durch eine Funktion wie verkürzen \funktionen
? Beispielsweise:
\funktionen{[3][]{T},{Sp},[3][{7,9,11}]{D},{T}}
oder noch besser:
\funktionen{[3][]T,Sp,[3][{7,9,11}]D,T}
Jedes Argument kann mehr als 1 Zeichen enthalten, einschließlich Komma!
Ich habe es mit forcsvlist
dem etoolbox
Paket versucht, aber es nimmt (natürlich) den gesamten Wert [3][]{T}
als ein einziges Argument. Außerdem weiß ich nicht, wie ich das Trennzeichen realisieren soll --
.
MWE:
\documentclass[border=5]{standalone}
\usepackage{etoolbox, xparse, fixltx2e, letltxmacro}
\DeclareDocumentCommand{\subsup}{ o o m }{%
\IfValueTF{#1}{%
\IfValueTF{#2}{%
\textsubscript{#1}#3\textsuperscript{#2}%
}{%
#3\textsuperscript{#1}}%
}{#3}%
}
\DeclareDocumentCommand{\emphsubsup}{ o o m }{\emph{\subsup[#1][#2]{#3}}}%same, only emphasized
\LetLtxMacro{\funktion}{\emphsubsup}
%test
\newcommand*{\funktionen}[1]{%
\forcsvlist{\funktion}{#1}
}
\begin{document}
\funktion[3][]{T}--\funktion{Sp}--\funktion[3][7,9,11]{D}--\funktion{T}
\hskip1ex
\funktionen{[3][]{T},{Sp},[3][{7,9,11}]{D},{T}}
\end{document}
Antwort1
Da Sie wirklich nach einer Analyse „über“ einen Dokumentbefehl hinaus suchen (dhdas ist nicht wirklich ein Standardargument im LaTeX2e-Stil für einen einfachen Befehl) Ich wäre versucht, den Parser-Teil selbst zu programmieren. Vorausgesetzt, Sie müssen sich keine Gedanken über verschachtelte [
/ ]
machen (in diesem Fall brauchen Sie vermutlich xparse
), können wir es ganz einfach mit einem „klassischen“ Look-Ahead-Ansatz machen. Ich habe das in gemacht, expl3
aber es könnte auch einfach mit gemacht werden \@ifnextchar
:
\RequirePackage{fixltx2e}
\documentclass{article}
\usepackage{expl3,xparse}
\ExplSyntaxOn
\DeclareDocumentCommand \funktionen { > { \SplitList { , } } m }
{
\musicman_parse:n {#1}
}
\seq_new:N \l__musicman_parse_seq
\tl_new:N \l__musicman_tmp_tl
\cs_new_protected:Npn \musicman_parse:n #1
{
\group_begin:
\seq_clear:N \l__musicman_parse_seq
\tl_map_inline:nn {#1}
{
\tl_clear:N \l__musicman_tmp_tl
\peek_meaning_ignore_spaces:NTF [ % ]
{ \__musicman_parse_auxi:w }
{ \__musicman_parse_auxiii:w }
##1 \q_stop
\seq_put_right:NV \l__musicman_parse_seq \l__musicman_tmp_tl
}
\seq_use:Nn \l__musicman_parse_seq { -- }
\group_end:
}
\cs_new_protected:Npn \__musicman_parse_auxi:w [ #1 ]
{
\tl_set:Nn \l__musicman_tmp_tl { \textsubscript {#1} }
\peek_meaning_ignore_spaces:NTF [ % ]
{ \__musicman_parse_auxii:w }
{ \__musicman_parse_auxiii:w }
}
\cs_new_protected:Npn \__musicman_parse_auxii:w [ #1 ] #2 \q_stop
{
\tl_put_right:Nx \l__musicman_tmp_tl
{
\exp_not:n {#2}
\tl_if_blank:nF {#1} { \exp_not:n { \textsuperscript {#1} } }
}
}
\cs_new_protected:Npn \__musicman_parse_auxiii:w #1 \q_stop
{ \tl_set:Nn \l__musicman_tmp_tl {#1} }
\ExplSyntaxOff
\begin{document}
\funktionen{[3][]{T},{Sp},[3][{7,9,11}]{D},{T}}
\end{document}
Ich habe eine Sequenz verwendet, um die „unvollständige“ Liste der Elemente zu speichern, da dies das Einfügen der Trennzeichen ( --
) erleichtert, ohne dass ich selbst Tests für „Ende der Liste“ oder Ähnliches durchführen muss. In diesem Fall könnte man stattdessen eine von Hand erstellte Zuordnung verwenden, aber wenn die Leistung nicht von entscheidender Bedeutung ist, ist dies tendenziell weniger klar als der Ansatz hier.
Für die expl3
Experten möchte ich anmerken, dass wir hier \tl_if_head_eq_meaning:nNTF
anstelle von verwenden könnten \peek_meaning:NTF
, da das Argument bereits aufgegriffen wurde.
Antwort2
Wenn es Ihnen nichts ausmacht, dass die Funktion innerhalb einer TeX
Gruppe ausgeführt wird, können Sie Folgendes versuchen pgffor
:
\documentclass[border=5]{standalone}
\usepackage{etoolbox, xparse, fixltx2e, pgffor}
\DeclareDocumentCommand{\funktion}{ o o m }{%
\IfValueTF{#1}{%
\IfValueTF{#2}{%
\textsubscript{#1}#3\textsuperscript{#2}%
}{%
#3\textsuperscript{#1}}%
}{#3}%
}
%test
\newcommand*{\funktionen}[1]{%%
\foreach \args [count=\x]in {#1}{%
\ifnum\x>1--\fi\expandafter\funktion\args%
}%
}
\begin{document}
\funktion[3][]{T}--\funktion{S}--\funktion[3][7]{D}--\funktion{T}
\hskip1ex
\funktionen{[3][]{T},{S},[3][7]{D},{T}}
\end{document}
Ein benutzerdefinierter Listenparser ist jedoch ziemlich unkompliziert:
\documentclass[border=5]{standalone}
\usepackage{etoolbox, xparse, fixltx2e}
\DeclareDocumentCommand{\funktion}{ o o m }{%
\IfValueTF{#1}{%
\IfValueTF{#2}{%
\textsubscript{#1}#3\textsuperscript{#2}%
}{%
#3\textsuperscript{#1}}%
}{#3}%
}
\newcommand*{\Funktionen}[1]{%
\let\FunctionenNext=\relax%
\FunctionenLoop#1,\FunctionenHalt,%
}
\def\FunctionenHalt{\FunctionenHalt}%
\def\FunctionenLoop#1,{%
\def\tmp{#1}%
\ifx\tmp\FunctionenHalt%
\let\FunctionenNext=\relax%
\else%
\ifx\FunctionenNext\relax\else--\fi%
\funktion#1%
\let\FunctionenNext=\FunctionenLoop%
\fi%
\FunctionenNext%
}
\begin{document}
\funktion[3][]{T}--\funktion{S}--\funktion[3][7]{D}--\funktion{T}
\hskip1ex
\Funktionen{[3][]{T},{S},[3][7]{D},{T}}
\end{document}
Das Ergebnis ist das gleiche wie zuvor.
Antwort3
Es folgt die Lösung, die kein LaTeX-Paket benötigt. Nach
\funktionen{[3][]T,Sp,[3][7,9,11]D,T}
Sie haben folgende Inhalte gespeichert:
\funktion[3][]{T}--\funktion{Sp}--\funktion[3][7,9,11]{D}--\funktion{T}
im \funktionenL
Makro. Sie können es ausführen, indem Sie einfach ausführen \funktionenL
.
\long\def\addto#1#2{\expandafter\def\expandafter#1\expandafter{#1#2}}
\def\funktionen#1{\def\funktionenL{}\funktionenA#1,,}
\def\funktionenA{\let\tmpa=\relax \let\tmpb=\relax \futurelet\next\funktionenB}
\def\funktionenB{\ifx\next[\expandafter\funktionenC \else \expandafter\funktionenF \fi}
\def\funktionenC[#1]{\def\tmpa{#1}\futurelet\next\funktionenD}
\def\funktionenD{\ifx\next[\expandafter\funktionenE \else \expandafter\funktionenF \fi}
\def\funktionenE[#1]{\def\tmpb{#1}\funktionenF}
\def\funktionenF#1,{\ifx,#1,\else
\ifx\funktionenL\empty \else \addto\funktionenL{--}\fi
\addto\funktionenL{\funktion}%
\ifx\tmpa\relax\else \funktionenG{\expandafter[\tmpa]}\fi
\ifx\tmpb\relax\else \funktionenG{\expandafter[\tmpb]}\fi
\addto\funktionenL{{#1}}%
\expandafter\funktionenA
\fi
}
\def\funktionenG{\expandafter\addto\expandafter\funktionenL\expandafter}
\funktionen{[3][]T,Sp,[3][7,9,11]D,T}
\message{\meaning\funktionenL}