![csv リストを解析し、コールバックとして 1 を超えるパラメータを持つ関数](https://rvso.com/image/298815/csv%20%E3%83%AA%E3%82%B9%E3%83%88%E3%82%92%E8%A7%A3%E6%9E%90%E3%81%97%E3%80%81%E3%82%B3%E3%83%BC%E3%83%AB%E3%83%90%E3%83%83%E3%82%AF%E3%81%A8%E3%81%97%E3%81%A6%201%20%E3%82%92%E8%B6%85%E3%81%88%E3%82%8B%E3%83%91%E3%83%A9%E3%83%A1%E3%83%BC%E3%82%BF%E3%82%92%E6%8C%81%E3%81%A4%E9%96%A2%E6%95%B0.png)
私のテキストでは、項目を個別にフォーマットする必要があるリストを処理する必要があります。例:
\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}
1 つの引数として受け取ります。また、セパレータを実現する方法もわかりません--
。
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}
答え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}