
Einige Programmiereditoren und IDEs heben zulässige und unzulässige Variablennamen auf unterschiedliche Weise hervor. Ich wünschte, listings
eine 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, listings
aber 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 \Word
Makro speichert, bis ein .
Token gefunden wird. In diesem Stadium verarbeite ich es \Word
auf 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.
\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
\futurelet
Um Zeichen für Zeichen zu iterieren und an einem Leerzeichen anzuhalten, müssen Sie wahrscheinlich (oder gleichwertig ) verwenden, \@ifnextchar
aber 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 \def
bietet abgegrenzten Parametertext. In diesem Fall können Sie das Leerzeichen als Trennzeichen verwenden:
\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}
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}