
Ich möchte erstellenein Befehl, der prüft, ob ein Ausdruck vollständig erweiterbar ist, und abstürzt, wenn dies nicht der Fall ist(idealerweise eine Fehlermeldung drucken). Das würde ich gerne machenohne eine bestimmte TeX-Engine im Sinn zu haben. Ich denke, es hängt mit dieser Frage zusammenÜberprüfen Sie, ob das Makro vollständig erweiterbar ist, aber die bereitgestellte Antwort erfordert LuaTeX.
Testcode
Ein Testcode würde folgendermaßen aussehen:
\documentclass[preview = true, varwidth = true]{standalone}
\usepackage{xparse}
\usepackage{xstring}
\NewDocumentCommand{\checkexpandability}{m}{
% CODE HERE
}
\newcommand{\expandable}[1]{#1}
\newcommand{\notexpandable}[1]{%
\edef\myvariable{\expandable{#1}}%
\myvariable%
}
\begin{document}
\checkexpandability{\expandable{test}} % Should be OK
\checkexpandability{\notexpandable{test}} % Should CRASH
\checkexpandability{\IfBeginWith{string}{str}{true}{false}} % Should CRASH
\end{document}
Falls es zu kompliziert ist
Wenn dies nicht machbar ist, bin ich damit einverstanden, die Befehlssignatur so zu ändern, dass sie einen Parameter einschließt, zu dem der Befehl erweitert werden soll:
\begin{document}
\checkexpandability{\expandable{test}}{test} % Should be OK
\checkexpandability{\notexpandable{test}}{test} % Should CRASH
\checkexpandability{\IfBeginWith{string}{str}{true}{false}}{true} % Should CRASH
\end{document}
Kommentar zur Erweiterbarkeit
Da die Definition von „vollständig erweiterbar“ nicht so klar ist, wie man meinen könnte (siehe Kommentar unten), besteht der Kontext dieser Frage darin, dass ich nur versuche, etwas zu erstellen, das mir beim Debuggen von Code hilft. Ich bin damit einverstanden, die Frage auf dieses spezifische Verhalten zu beschränken: ob das Makro im Kontext von Makros wie dem \color
Befehl funktionieren würde:
\documentclass[preview = true, varwidth = true]{standalone}
\usepackage{xcolor}
\newcommand{\expandable}[1]{#1}
\newcommand{\notexpandable}[1]{%
\edef\myvariable{\expandable{#1}}%
\myvariable%
}
\begin{document}
\color{\expandable{blue}} % OK
\color{\notexpandable{red}} % CRASHES
X
\end{document}
Im Grunde erledigt der \color
Befehl die von mir gesuchte Aufgabe. Ich möchte ihn nur \checkexpandability
etwas allgemeiner aufrufen und eine nette Fehlermeldung ausgeben lassen.
Antwort1
Ich denke, das grundlegende Missverständnis ist
Im Grunde erledigt der
\color
Befehl die Art von Arbeit, die ich suche.
Der \color
Befehl führt keine Überprüfungen des angeforderten Typs durch, sondern erwartet lediglich, dass das Argument nach der Erweiterung ein definierter Farbname ist. Wenn die Erweiterung fehlschlägt, erhalten Sie einen Fehler auf niedriger Ebene, oder wenn die Erweiterung zu einer undefinierten Farbe erfolgt, erhalten Sie eine spezifische Fehlermeldung, aber kein Teil der Verarbeitung ist generisch oder gilt für einen anderen Befehl als Befehle, die Farben erwarten.
Die einzige Version, die implementiert werden könnte, ist die Version mit einer erwarteten Erweiterung, da diese einfach fragt, ob die beiden Argumente nach der Erweiterung gleich sind. Die L3-Programmierschicht hat mehrere Varianten davon, oder Sie könnten das ifthen
Paket verwenden und
\ifthenelse{\equal{\expandable{test}}{test}}{yes}{no}
Dies gibt „yes“ zurück, wenn die Argumente auf dasselbe Ergebnis erweitert werden, „no“, wenn dies nicht der Fall ist, oder gibt einen Fehler auf niedriger Ebene aus, wenn das Argument in einem Erweiterungskontext nicht sicher ist (was normalerweise mit „ist nicht erweiterbar“ gemeint ist).
Antwort2
Zum Debuggen Ihres Codes würde ich einfach verwenden \typeout
.
\documentclass[preview = true, varwidth = true]{standalone}
\usepackage{xcolor}
\newcommand{\expandable}[1]{#1}
\newcommand{\notexpandable}[1]{%
\edef\myvariable{\expandable{#1}}%
\myvariable%
}
\begin{document}
\typeout{\expandable{blue}} % OK, print "blue"
\typeout{\notexpandable{red}} % CRASHES
X
\end{document}
Der Punkt ist, dass \typeout
das Argument vollständig erweitert wird und dann das vollständig erweiterte Ergebnis auf dem Terminal ausgedruckt wird – Sie können also einfach einen Blick auf das Terminal werfen.
Im ersten Fall wird gedruckt blue
, also ist alles in Ordnung. Im zweiten Fall stürzt es ab.
Natürlich gibt es mit dem obigen Ansatz zwei Probleme.
Selbst wenn
\expandable{blue}
Istvollständig erweiterbar (was auch immer das bedeutet),Es kann sein, dass nicht\color
garantiert ist, dass das Argument vollständig ausgearbeitet wird, bevor das Ergebnis als Farbwert interpretiert wird.. (Ich schätze durchHyrums GesetzIn der Praxis geht es jedoch darum, die Beschädigung „vorhandener Pakete“ zu vermeiden.)Wenn Sie also ganz sicher sein wollen, ist es besser, es im Voraus zu erweitern, beispielsweise mit
\ExpandArgs
.Dabei gehen die Informationen zum Kategoriecode sowie eventuell im Code enthaltene Sonderzeichen (z. B. Leerzeichen statt Tabulator) verloren.
In der Praxis wäre dies nicht so wichtig, manchmal ist es aber doch so (z. B. wenn Sie versuchen, ein Paket zu debuggen, das den Umgebungstext wörtlich zu erfassen versucht).
Wenn das der Fall ist, sollten Sie versuchenmein Paket. (der Code ist im Moment ein Durcheinander, aber er funktioniert, und es gibt Pakete mit schlechterem Quellcode)