
Ist es möglich zu prüfen, ob ein Token ein Trennzeichen ist, also (
, )
, , |
, \vert
, \langle
, \rangle
usw., ohne jedes davon direkt in einer Bedingung zu prüfen?
Die Struktur des Trennzeichens wird hier gut beschrieben:https://tex.stackexchange.com/a/296650/213149. Es scheint, als würde man \delimiter
den Befehl verwenden
Meine Frage ist also, wie ich ein solches Trennzeichen mit reinem TeX oder LaTeX3 auf einigermaßen vielseitige Weise erkennen kann.
Ich möchte beispielsweise ein benutzerdefiniertes Makro \isDelimiter{...}
zum Drucken true
oder false
im Dokument, wenn sein Argument ein Trennzeichen ist oder nicht.
Antwort1
Ich bin nicht sicher, ob das bei Ihrem Problem hilfreich sein kann \veca
. Wie auch immer …
\documentclass{article}
\ExplSyntaxOn
\NewExpandableDocumentCommand{\isDelimiterTF}{mmm}
{
\antshar_isdel:Nnn #1 { #2 } { #3 }
}
% first check whether #1 is a control sequence
\cs_new:Nn \antshar_isdel:Nnn
{
\token_if_cs:NTF #1
{
\__antshar_isdel_cs:Nnn #1 { #2 } { #3 }
}
{
\__antshar_isdel_char:Nnn #1 { #2 } { #3 }
}
}
% it is a control sequence; first check the two exceptional cases \{ and \}
% which return true; otherwise go on: if the token is not expandable return false
\cs_new:Nn \__antshar_isdel_cs:Nnn
{
\str_case:nnF { #1 }
{
{\{}{#2}
{\}}{#2}
}
{
\token_if_expandable:NTF #1
{
\__antshar_isdel_csexp:Nnn #1 { #2 } { #3 }
}
{
#3
}
}
}
% the token is expandable, access its expansion
\cs_new:Nn \__antshar_isdel_csexp:Nnn
{
\__antshar_isdel_exp:onn { #1 } { #2 } { #3 }
}
% if the expansion begins with \delimiter return true, otherwise false
\cs_new:Nn \__antshar_isdel_exp:nnn
{
\__antshar_isdel_exp_aux:w #1 \q_nil \q_stop { #2 } { #3 }
}
\cs_generate_variant:Nn \__antshar_isdel_exp:nnn { o }
\cs_new:Npn \__antshar_isdel_exp_aux:w #1 #2 \q_stop #3 #4
{
\token_if_eq_meaning:NNTF #1 \delimiter { #3 } { #4 }
}
% when the token is a character, look at its \delcode;
% if positive return true, otherwise false
\cs_new:Nn \__antshar_isdel_char:Nnn
{
\int_compare:nTF { \delcode`#1 > 0 } { #2 } { #3 }
}
\ExplSyntaxOff
\begin{document}
\verb|a|: \isDelimiterTF{a}{T}{F}
\verb|(|: \isDelimiterTF{(}{T}{F}
\verb|]|: \isDelimiterTF{]}{T}{F}
\verb|\langle|: \isDelimiterTF{\langle}{T}{F}
\verb-\|-: \isDelimiterTF{\|}{T}{F}
\verb|\{|: \isDelimiterTF{\{}{T}{F}
\verb|\lbrace|: \isDelimiterTF{\lbrace}{T}{F}
\verb|\mbox|: \isDelimiterTF{\mbox}{T}{F}
\end{document}
Wie erkennen wir, wann eine Steuersequenz ein Trennzeichen ist? Die Erweiterung der ersten Ebene sollte mit beginnen \delimiter
oder, wenn es sich um ein Zeichen handelt, \delcode
positiv sein.
Die Prüfung auf ein Zeichen ist daher offensichtlich. Bei einer Steuersequenz müssen wir zunächst prüfen, ob sie erweiterbar ist oder nicht. Aber wir müssen auch darauf achten, dass \{
und \}
etwas Besonderes sind, sodass diese Fälle von selbst geregelt werden.
Wenn die von uns untersuchte Steuersequenz nicht erweiterbar ist, ist sie kein Trennzeichen (möglicherweise müssen bei einigen Schriftpaketen andere Ausnahmen wie \{
und hinzugefügt werden). Wenn sie erweiterbar ist, betrachten wir ihre Erweiterung auf erster Ebene durch Aufruf von\}
\__antshar_isdel_exp:onn { #1 } { #2 } { #3 }
so dass der o
Argumenttyp die erforderliche einstufige Erweiterung durchführt. Dies wird
\__antshar_isdel_exp_aux:w #1 \q_nil \q_stop { #2 } { #3 }
Die Definition von \__antshar_isdel_exp_aux:w
ist
\cs_new:Npn \__antshar_isdel_exp_aux:w #1 #2 \q_stop #3 #4
{
\token_if_eq_meaning:NNTF #1 \delimiter { #3 } { #4 }
}
daher wird das erste Token in der Erweiterung der von uns untersuchten Steuersequenz zu #1
und der Rest bis zu \q_nil
wird zu #2
. Der Rest, also #3
und #4
sind der wahre und falsche Text für \isDelimiterTF
. Das erste Argument ist nicht begrenzt, daher wird das erste Token im Eingabestrom als Argument verwendet; das zweite Argument endet, wenn TeX findet \q_stop
.
Das Seltsame \q_nil
dabei ist, dass, wenn Sie es versuchen, \isDelimiter{\empty}{T}{F}
in der Erweiterung nichts erscheinen würde; in diesem Fall \q_nil
wird als angenommen #1
und #2
ist leer. Da aber \q_nil
nicht ist \delimiter
, geht alles durch.