I would like to create a command that checks whether an expression is fully expandable, and crashes if not (ideally printing an error message). I would like to do that without a specific TeX engine in mind. I think it's related to this question Check if macro is fully expandable, but the provided answer requires LuaTeX.
Test code
A test code would look like this:
\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}
In case it's too complicated
If it's not doable, then I am ok to modify the command signature to include a parameter that is what the command should expand to:
\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}
Comment on expandability
Since the definition of fully expandable is not as clear as one could think (see comment below), the context of this question is that I'm just trying to create something that helps me debug some code. I'm ok to restrain the question to this specific behavior : whether the macro would work in the context macros like the \color command:
\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}
Basically, the \color command does the kind of job I'm looking for, it's just that I would like to call it \checkexpandability, be a little more generic, and print a nice error message.
\relaxfor example is safe in an\edefbut not in\color. If you mean a command that expands to something legal in the current context, then there is no general definition. – David Carlisle Feb 03 '24 at 23:55\colorcommand, only the color command. The argument of\colorhas to expand to a valid color name otherwise you get an error. There is no sense in which it "checks for expandability" it just expects a color name (after expansion) – David Carlisle Feb 03 '24 at 23:57\color{\expandable{123}}would error too. – Ulrike Fischer Feb 04 '24 at 00:03unravelcode. But that is not a practical approach if you are wanting to use this in a document. I suspect there is some wider context ... which is not at all clear. – Joseph Wright Feb 04 '24 at 09:13\infiniteloop{a}where\infinteloopis defined as\def\infiniteloop#1{\infiniteloop{#1}}or as\def\infiniteloop#1{\infiniteloop{#1}#1}? (The latter definition might yield! TeX capacity exceeded, sorry [input stack size=...].) – Ulrich Diez Feb 04 '24 at 15:24\input(which is renamed to\@@inputin LaTeX 2e) is expandable as well... – Ulrich Diez Feb 04 '24 at 15:53\outer-tokens play a rôle, like the expression\macro{0}with\def\macro#1{#1 1 2 3 \willbeouter}\outer\def\willbeouter {4 5 6}? At some stage of expansion you get the outer token\willbeouter. Examining this by expandable methods only won't be that trivial. – Ulrich Diez Feb 04 '24 at 16:00