標記化並應用命令

標記化並應用命令

我有一個用逗號分隔的字串。我想獲取每個元素並應用命令。我有以下內容,有效。

\documentclass[12pt]{article}

\usepackage[trim]{tokenizer}

\newcommand{\cadd}[1]{
        \def\Source{#1}
    \whiledo{\not\equal{\Source}{}}
    {
        \GetTokens{TokenOne}{TokenTwo}{\Source}
        \textbf{\TokenOne}
        \let\Source\TokenTwo
    }
}

\begin{document}

\cadd{a,b,c}

\end{document}

但我想要以下內容

\documentclass[12pt]{article}

\usepackage[trim]{tokenizer}

\newcommand{\cadd}[1]{
    \whiledo{\not\equal{#1}{}}
    {
        \GetTokens{TokenOne}{TokenTwo}{#1}
        \textbf{\TokenOne}
        \let\#1\TokenTwo
    }
}

\begin{document}

\cadd{a,b,c}

\end{document}

\let\#1\TokenTwo給了一個錯誤。我怎樣才能#1使用\let

答案1

#1在第一次呼叫巨集時被替換。如果宏\cadd

\newcommand{\cadd}[1]{
    \whiledo{\not\equal{#1}{}}
    {
        \GetTokens{TokenOne}{TokenTwo}{#1}
        \textbf{\TokenOne}
        \let\#1\TokenTwo
    }
}

稱為\cadd{a,b,c},則變為:

<space>
\whiledo{\not\equal{a,b,c}{}}<space>
{<space>
  \GetTokens{TokenOne}{TokenTwo}{a,b,c}<space>
  \textbf{\TokenOne}<space>
  \let\#1\TokenTwo
}<space>
  • 這行\let\#1\TokenTwo\let賦值\let\#=1和組成\TokenTwo#1僅在巨集擴充中用第一個參數取代。
  • 有許多空格標記(由行尾引起):

    • 第一個在垂直模式下被忽略,因為該段落尚未開始。
    • \whiledo如果將循環體作為無分隔參數讀取,則第二個被忽略。
    • 第三個和第四個將出現在輸出中。
    • 由於段落結尾,最後一個被刪除。

    透過使用註解字元可以避免行尾出現空格標記,如以下範例所示。

有許多用於逗號分隔清單的解析器。其中之一是由包包提供的kvsetkeys

\documentclass[12pt]{article}

\usepackage{kvsetkeys}

\makeatletter
\newcommand{\cadd}[1]{%
  \comma@parse{#1}{\caddentry}%
}
\newcommand*{\caddentry}[1]{%
  \textbf{[#1]}%
}
\makeatother

\begin{document}

\cadd{a,b,c}

\cadd{ a , b , c }

\cadd{abc, def, ghi}

\cadd{{ with spaces }, {a b c}}

\end{document}

結果

答案2

Heiko 在這裡很好地介紹了細節。為了完整起見,使用 LaTeX3 逗號列表映射函數的解決方案\clist_map_inline:nn

\documentclass{article}
\usepackage{expl3,xparse}
\ExplSyntaxOn
\NewDocumentCommand { \cadd } { m }
  { \clist_map_inline:nn {#1} { [ \textbf {##1} ] } }
\ExplSyntaxOff
\begin{document}
\cadd{a,b,c}

\cadd{ a , b , c }

\cadd{abc, def, ghi}

\cadd{{ with spaces }, {a b c}}

\end{document}

基本概念與 Heiko 的答案非常相似:不必手動進行映射,而是使用預先建立的命令來處理查找清單末尾。

相關內容