CSV-Liste analysieren, Funktion mit >1 Parameter als Rückruf

CSV-Liste analysieren, Funktion mit >1 Parameter als Rückruf

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 \funktionerfolgt \emphsubsupdie 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 forcsvlistdem etoolboxPaket 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, expl3aber 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 expl3Experten möchte ich anmerken, dass wir hier \tl_if_head_eq_meaning:nNTFanstelle von verwenden könnten \peek_meaning:NTF, da das Argument bereits aufgegriffen wurde.

Antwort2

Wenn es Ihnen nichts ausmacht, dass die Funktion innerhalb einer TeXGruppe 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}

Bildbeschreibung hier eingeben

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 \funktionenLMakro. 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}

verwandte Informationen