トークン ストリームの最初の単語をトークンごとに解析するにはどうすればよいですか?

トークン ストリームの最初の単語をトークンごとに解析するにはどうすればよいですか?

一部のプログラミング エディターと 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}

ここに画像の説明を入力してください

関連情報