토큰화 및 적용 명령

토큰화 및 적용 명령

쉼표로 구분된 문자열이 있습니다. 이에 대해 각 요소를 가져오고 명령을 적용하고 싶습니다. 나는 다음을 가지고 있습니다.

\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의 대답과 거의 동일합니다. 직접 매핑을 수행하는 대신 목록의 끝을 찾는 작업을 처리하는 미리 작성된 명령을 사용합니다.

관련 정보