![Analizar lista csv, función con >1 parámetros como devolución de llamada](https://rvso.com/image/298815/Analizar%20lista%20csv%2C%20funci%C3%B3n%20con%20%3E1%20par%C3%A1metros%20como%20devoluci%C3%B3n%20de%20llamada.png)
En mis textos tengo que lidiar con listas, cuyos elementos deben formatearse por separado, es decir:
\funktion[3][]{T}--\funktion{S}--\funktion[3][7]{D}--\funktion{T}
En \funktion
lo que \emphsubsup
se lleva a cabo el formateo y se manejan los parámetros opcionales.
¿Cómo puedo acortar esta tarea mediante una función como \funktionen
? Es decir:
\funktionen{[3][]{T},{Sp},[3][{7,9,11}]{D},{T}}
o mejor:
\funktionen{[3][]T,Sp,[3][{7,9,11}]D,T}
Cada argumento puede contener más de 1 carácter, ¡incluida la coma!
Lo probé forcsvlist
desde el etoolbox
paquete, pero toma (por supuesto) el valor completo [3][]{T}
como un solo argumento. Además, no sé cómo realizar el separador --
.
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}
Respuesta1
Como realmente está buscando analizar 'más allá' de un comando de documento (es decir(esto no es realmente un argumento estándar de estilo LaTeX2e para un comando simple). Me sentiría tentado a codificar el bit del analizador yo mismo. Suponiendo que no necesita preocuparse por el [
/ anidado ]
(en cuyo caso supongo que sí lo necesita xparse
), podemos hacerlo de manera bastante simple utilizando un enfoque de anticipación "clásico". He hecho esto expl3
pero también se puede hacer fácilmente usando \@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}
He usado una secuencia para contener la lista 'parcial' de elementos, ya que esto facilita la inserción de los separadores ( --
) sin tener que hacer ninguna prueba yo mismo para el 'fin de la lista' o similar. En este caso, se podría utilizar un mapeo hecho a mano, pero a menos que el rendimiento sea vital, eso tiende a ser menos claro que el enfoque aquí.
Para los expl3
expertos, observo que aquí se podría utilizar \tl_if_head_eq_meaning:nNTF
en lugar de, \peek_meaning:NTF
ya que el argumento ya está entendido.
Respuesta2
Si no le importa que la función se ejecute dentro de un TeX
grupo, puede intentar 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}
Sin embargo, un analizador de listas personalizado es bastante sencillo:
\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}
El resultado es el mismo que antes.
Respuesta3
La solución sin necesidad de ningún paquete LaTeX es la siguiente. Después
\funktionen{[3][]T,Sp,[3][7,9,11]D,T}
Ha almacenado el siguiente contenido:
\funktion[3][]{T}--\funktion{Sp}--\funktion[3][7,9,11]{D}--\funktion{T}
en \funktionenL
macro. Puedes ejecutarlo simplemente ejecutando \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}