토큰 스트림의 첫 번째 단어를 토큰별로 어떻게 구문 분석할 수 있나요?

토큰 스트림의 첫 번째 단어를 토큰별로 어떻게 구문 분석할 수 있나요?

일부 프로그래밍 편집기 및 IDE는 합법적인 변수 이름과 불법적인 변수 이름을 다양한 방식으로 강조합니다. 이러한 구문 검사 및 강조 표시가 쉽게 허용되기를 바라지 listings만 적어도 지금은 그렇지 않습니다. 나의 장기적인 목표는 다음과 호환되는 솔루션을 구현하는 것입니다. listings그러나 지금은 문제의 매우 단순화된 버전을 보고 있습니다.

문자와 공백 토큰으로만 구성된 토큰 스트림의 첫 번째 단어를 구문 분석하고 싶습니다. 이건 꼭 해야 해토큰별 토큰하지만 각 토큰에 대해 몇 가지 확인을 수행해야 하기 때문입니다. 이를 위해 스트림을 구문 분석하고 토큰을 만날 \Word때까지 매크로 에 저장하는 재귀 매크로를 사용합니다. .그 단계에서는 \Word빨간색으로 인쇄하는 등 일정한 방식으로 가공합니다. 나는단어공백 토큰에 의해 중단되지 않는 일련의 문자 토큰으로.

문제: 스트림에서 토큰이 .아닌 다음 공간 토큰이 발견될 때 재귀를 중지하기 위해 코드에서 무엇을 변경해야 하는지 알 수 없기 때문에 여기서는 토큰 만 사용합니다. .제어 공간( \) 을 대체하는 것은 .트릭을 수행하지 않는 것 같습니다. 내 코드에서 무엇을 변경해야 합니까?

나는 구문 분석을 위해 낮은 수준의 TeX 명령을 사용하는 솔루션을 선호하지만 LaTeX2e 및 LaTeX3 대안도 관심이 있습니다.

편집하다: 골대를 옮기는 것 같다면 사과드립니다만, 이미 게시된 답변 중 일부가 무효화될 수 있는 "토큰별 토큰" 요구 사항을 추가하여 질문을 좀 더 명확하게 해야 했습니다.

여기에 이미지 설명을 입력하세요

\documentclass{article}

\usepackage{xcolor}

\def\ParseWordandPrint#1{%
    \if #1.%
        \textcolor{red}{\Word}\ %
    \else
        \edef\Word{\Word#1}
        \expandafter\ParseWordandPrint
    \fi%
}

\def\InitParseWordandPrint#1{%
    \def\Word{}
    \ParseWordandPrint#1%
}

\begin{document}

\InitParseWordandPrint Hello.World

\end{document}

답변1

편집된 질문에 따라 삭제를 취소합니다.

공백으로 구분된 인수를 사용하면 한 번에 단어를 파악하는 것이 더 쉽습니다.그 다음에해당 문자를 문자별로 반복합니다. (예를 들어 여기서는 문자인지 확인합니다. 마지막 예는 다음과 같습니다.

illegal character 0
illegal character 1

문자를 문자별로 반복하려면 사용해야 하는 \futurelet(또는 동등하게 \@ifnextchar) 텐트에서 멈추는 문자가 있지만 문자 간 커른과 합자를 깨뜨리지 않기가 어렵기 때문에 단어가 별로 좋지 않습니다. 그래서 단어를 먼저 잡는 것이 더 쉽습니다.

\documentclass{article}

\usepackage{xcolor}

\def\InitParseWordandPrint#1 {\check#1\relax\textcolor{red}{#1} }

\def\check#1{%
\ifx\relax#1%
\else
\ifcat a#1%
\else
\typeout{illegal character #1}%
\fi
\expandafter\check
\fi}

\begin{document}

\InitParseWordandPrint Hello World


\InitParseWordandPrint  World

Hello World

\InitParseWordandPrint  W0r1d 

\end{document}

답변2

TeX는 \def구분된 매개변수 텍스트를 제공합니다. 따라서 이 경우 공백을 구분 기호로 사용할 수 있습니다.

여기에 이미지 설명을 입력하세요

\documentclass{article}

\usepackage{xcolor}

\def\ParseWordandPrint#1{%
    \if #1.%
        \textcolor{red}{\Word}\ %
    \else%
        \edef\Word{\Word#1}%
        \expandafter\ParseWordandPrint%
    \fi%
}

\def\InitParseWordandPrint#1{%
    \def\Word{}%
    \ParseWordandPrint#1%
}
\def\highlightfirst#1 {\textcolor{red}{#1} }

\begin{document}

\InitParseWordandPrint Hello.World

\highlightfirst Hello World.

\end{document}

답변3

LaTeX3를 사용하면 정말 쉽습니다.

\documentclass{article}
\usepackage{xparse,xcolor}

\ExplSyntaxOn
\NewDocumentCommand{\printfirstwordincolor}{ O{red} m }
 {
  \jubobs_pfwr:nn { #1 } { #2 }
 }

\seq_new:N \l_jubobs_words_seq
\tl_new:N \l_jubobs_first_word_tl

\cs_new_protected:Npn \jubobs_pfwr:nn #1 #2
 {
  % split the input at spaces
  \seq_set_split:Nnn \l_jubobs_words_seq { ~ } { #2 }
  % pop off the leftmost item
  \seq_pop_left:NN \l_jubobs_words_seq \l_jubobs_first_word_tl
  % print the first item in the chosen color
  \textcolor{#1}{ \l_jubobs_first_word_tl } ~ %
  % print the other items adding spaces between them
  \seq_use:Nn \l_jubobs_words_seq { ~ }
 }

\ExplSyntaxOff

\begin{document}

\printfirstwordincolor{Hello World}

\printfirstwordincolor[green]{Addio mondo crudele}

\end{document}

여기에 이미지 설명을 입력하세요


입력 토큰을 토큰별로 처리하려는 경우 저장된 항목에 대한 매핑을 수행할 수 있습니다. 모든 'd'를 대문자로 쓰고 싶다고 가정해 보겠습니다.

\documentclass{article}
\usepackage{xparse,xcolor}

\ExplSyntaxOn
\NewDocumentCommand{\printfirstwordincolor}{ O{red} m }
 {
  \jubobs_pfwc:nn { #1 } { #2 }
 }

\seq_new:N \l_jubobs_words_seq
\tl_new:N \l_jubobs_first_word_tl
\bool_new:N \l_jubobs_first_item_bool

\cs_new_protected:Npn \jubobs_pfwc:nn #1 #2
 {
  \seq_set_split:Nnn \l_jubobs_words_seq { ~ } { #2 }
  \seq_pop_left:NN \l_jubobs_words_seq \l_jubobs_first_word_tl
  \textcolor{#1}{ \l_jubobs_first_word_tl } ~ %
  \seq_use:Nn \l_jubobs_words_seq { ~ }
 }

\NewDocumentCommand{\printfirstwordincolorandcapitalizeD} { O{red} m }
 {
  \jubobs_pfwcacd:nn { #1 } { #2 }
 }

\cs_new_protected:Npn \jubobs_pfwcacd:nn #1 #2
 {
  \seq_set_split:Nnn \l_jubobs_words_seq { ~ } { #2 }
  \leavevmode
  \bool_set_true:N \l_jubobs_first_item_bool
  \seq_map_inline:Nn \l_jubobs_words_seq
   {
    \bool_if:NT \l_jubobs_first_item_bool
     { \c_group_begin_token \color{#1} }
    \tl_map_inline:nn { ##1 }
     {
      \peek_charcode_remove:NT d { D } ####1
     }
    \bool_if:NT \l_jubobs_first_item_bool
     { \c_group_end_token \bool_set_false:N \l_jubobs_first_item_bool }
    \c_space_tl
   }
  \unskip
 }
\ExplSyntaxOff

\begin{document}

\printfirstwordincolor{Hello World}

\printfirstwordincolorandcapitalizeD[blue]{Addio mondo crudele}

\end{document}

여기에 이미지 설명을 입력하세요

관련 정보