![解析 csv-list,具有 >1 個參數的函數作為回調](https://rvso.com/image/298815/%E8%A7%A3%E6%9E%90%20csv-list%EF%BC%8C%E5%85%B7%E6%9C%89%20%3E1%20%E5%80%8B%E5%8F%83%E6%95%B8%E7%9A%84%E5%87%BD%E6%95%B8%E4%BD%9C%E7%82%BA%E5%9B%9E%E8%AA%BF.png)
在我的文字中,我必須處理列表,其項目需要單獨格式化,即:
\funktion[3][]{T}--\funktion{S}--\funktion[3][7]{D}--\funktion{T}
其中\funktion
會\emphsubsup
進行格式化並處理可選參數。
我怎麼能透過像這樣的函數來縮短這個任務\funktionen
? IE:
\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
因為您確實正在尋找解析“超越”文檔命令(IE這不是一個簡單指令的標準 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}