Wie kann ich das erste Wort in einem Token-Stream Token für Token analysieren?

Wie kann ich das erste Wort in einem Token-Stream Token für Token analysieren?

Einige Programmiereditoren und IDEs heben zulässige und unzulässige Variablennamen auf unterschiedliche Weise hervor. Ich wünschte, listingseine solche Syntaxprüfung und Hervorhebung wäre problemlos möglich, aber das ist zumindest im Moment nicht der Fall. Mein längerfristiges Ziel ist die Implementierung einer kompatiblen Lösung, listingsaber im Moment betrachte ich eine sehr vereinfachte Version des Problems.

Ich möchte das erste Wort in einem Token-Stream analysieren, der nur aus Zeichen- und Leerzeichen-Token besteht. Dies muss getan werdenToken für Token, weil ich für jedes Token einige Prüfungen durchführen muss. Dazu verwende ich ein rekursives Makro, das den Stream analysiert und in einem \WordMakro speichert, bis ein .Token gefunden wird. In diesem Stadium verarbeite ich es \Wordauf eine bestimmte Weise, z. B. indem ich es in Rot drucke. Ich definiere einWortals eine Folge von Zeichen-Token, die nicht durch Leerzeichen unterbrochen wird.

Problem: Ich verwende hier nur ein .Token, weil ich nicht weiß, was ich in meinem Code ändern muss, um die Rekursion zu stoppen, wenn .im Stream das nächste Leerzeichen-Token (kein Token) gefunden wird. Das Ersetzen durch ein Kontroll-Leerzeichen ( \) .scheint nicht zu funktionieren. Was muss ich in meinem Code ändern?

Ich bevorzuge eine Lösung mit Low-Level-TeX-Befehlen zum Parsen, aber auch LaTeX2e- und LaTeX3-Alternativen sind für mich interessant.

Bearbeiten: Ich entschuldige mich, wenn es so aussieht, als würde ich die Spielregeln ändern, aber ich musste meine Frage ziemlich präzisieren, indem ich die Anforderung „Token für Token“ hinzugefügt habe, was einige der bereits geposteten Antworten ungültig machen könnte.

Bildbeschreibung hier eingeben

\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}

Antwort1

Ich werde dies im Lichte Ihrer bearbeiteten Frage wiederherstellen.

Es ist einfacher, das Wort auf einmal zu erfassen, wenn man ein durch Leerzeichen getrenntes Argument verwendet undDanniteriere darüber Buchstabe für Buchstabe. (Als Beispiel überprüfe ich hier, ob es Buchstaben sind, das letzte Beispiel ergibt

illegal character 0
illegal character 1

\futureletUm Zeichen für Zeichen zu iterieren und an einem Leerzeichen anzuhalten, müssen Sie wahrscheinlich (oder gleichwertig ) verwenden, \@ifnextcharaber das ist bei einem Wort, das Sie setzen möchten, nicht so gut, da es schwierig ist, Buchstabentrennungen und Ligaturen nicht zu verletzen. Daher ist es einfacher, das Wort zuerst zu greifen.

\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}

Antwort2

TeX \defbietet abgegrenzten Parametertext. In diesem Fall können Sie das Leerzeichen als Trennzeichen verwenden:

Bildbeschreibung hier eingeben

\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}

Antwort3

Mit LaTeX3 ist das ganz einfach:

\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}

Bildbeschreibung hier eingeben


Wenn Sie die Eingabe auch Token für Token verarbeiten möchten, können Sie eine Zuordnung der gespeicherten Elemente vornehmen. Nehmen wir an, Sie möchten jedes „d“ groß schreiben:

\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}

Bildbeschreibung hier eingeben

verwandte Informationen