В своих текстах мне приходится иметь дело со списками, пункты которых необходимо форматировать отдельно, например:
\funktion[3][]{T}--\funktion{S}--\funktion[3][7]{D}--\funktion{T}
В \funktion
котором происходит \emphsubsup
форматирование и обрабатываются необязательные параметры.
Как можно сократить эту задачу с помощью функции типа \funktionen
? То есть:
\funktionen{[3][]{T},{Sp},[3][{7,9,11}]{D},{T}}
или даже лучше:
\funktionen{[3][]T,Sp,[3][{7,9,11}]D,T}
Каждый аргумент может содержать более 1 символа, включая запятую!
Я пробовал это с forcsvlist
из etoolbox
пакета, но он (конечно) принимает все значение [3][]{T}
как один аргумент. Также я не знаю, как реализовать разделитель --
.
МВЭ:
\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}
решение1
Поскольку вы действительно ищете синтаксический анализ «за пределами» команды документа (то естьэто не совсем стандартный аргумент в стиле LaTeX2e для простой команды) Я бы поддался соблазну самому написать код для синтаксического анализатора. Предполагая, что вам не нужно беспокоиться о вложенных [
/ ]
(в этом случае, я полагаю, вам нужно xparse
), мы можем сделать это довольно просто, используя «классический» подход с опережением. Я сделал это в , expl3
но это также можно легко сделать с помощью \@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}
Я использовал последовательность для хранения «частичного» списка элементов, так как это упрощает вставку разделителей ( --
) без необходимости самостоятельно проводить какие-либо тесты для «конца списка» или чего-то подобного. Вместо этого в этом случае можно было бы использовать вручную созданное отображение, но если производительность не имеет решающего значения, то это будет менее понятно, чем подход здесь.
Для expl3
экспертов отмечу, что здесь мы могли бы использовать \tl_if_head_eq_meaning:nNTF
вместо , \peek_meaning:NTF
поскольку аргумент уже был услышан.
решение2
Если вас не смущает выполнение функции внутри TeX
группы, то вы можете попробовать 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}
Однако пользовательский парсер списков довольно прост:
\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}
Результат тот же, что и прежде.
решение3
Далее следует решение без необходимости использования какого-либо пакета LaTeX. После
\funktionen{[3][]T,Sp,[3][7,9,11]D,T}
Вы сохранили следующий контент:
\funktion[3][]{T}--\funktion{Sp}--\funktion[3][7,9,11]{D}--\funktion{T}
в \funktionenL
макросе. Вы можете выполнить его, просто запустив \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}