쉼표로 구분된 문자열이 있습니다. 이에 대해 각 요소를 가져오고 명령을 적용하고 싶습니다. 나는 다음을 가지고 있습니다.
\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의 대답과 거의 동일합니다. 직접 매핑을 수행하는 대신 목록의 끝을 찾는 작업을 처리하는 미리 작성된 명령을 사용합니다.