Typically a TeX command have arguments coming after it. But the command \over
, which is used to produce fractions, can access the token before it. How exactly is it implemented and can I define a custom command like that?
[Tex/LaTex] What’s behind \over
macrostex-core
Related Solutions
You can define a command with parameters:
\newcommand{\divbytwo}[1]{\frac{#1}{2}}
The #1
is the placeholder for the first parameter to the macro: \divbytwo{3}
will expand to \frac{3}{2}
.
Edit: incorporating comments from the OP and @SašoŽivanović asking/answering about macros with more than one argument -
\newcommand{\divby}[2]{\frac{#1}{#2}}
will do the job. The [2]
tells TeX
how many parameters there will be. They're put in places #1
and #2
. Of course in this simple example\divby
is just frac
so you gain little by defining it.
Update: this thing is patched (by making \noexpand
no-operation on \endwrite
) in new versions of (PDF)TeX, but another segmentation fault is possible. Detail in https://topanswers.xyz/tex?q=5286#a5394.
To be fair, maybe Bruno Le Floch (member of the LaTeX3 team, probably also the one wrote that paragraph in interface3.pdf) discovered this one before me.
error message - Shortest code that raises a SIGSEGV - Code Golf Stack Exchange
To be precise, correcting a comment below: both \show ⟨\endwrite⟩
and \meaning ⟨\endwrite⟩
will not segmentation fault in Knuth TeX -- the former shows
> \endwrite=\outer macro:
.
but it does in PDFTeX. Only \let ⟨some assignable thing⟩ ⟨\endwrite⟩
(or executing ⟨\endwrite⟩
directly) segmentation fault Knuth TeX.
No idea why nobody have posted an answer for the \endwrite
token, but here it is.
%! TEX program = pdflatex
\documentclass{article}
\begin{document}
\ExplSyntaxOn
% starting state of the input stream:
% \weird } \endwrite ...
\def \weird { \expandafter \weirda \expandafter { \iffalse } \fi }
% → \weirda { } \endwrite ...
\def \weirda #1 { \expandafter \weirdb \noexpand }
% \endwrite cannot be grabbed as #2 so we \noexpand it
% → \weirdb <safe \endwrite token>
\def \weirdb #1 { \iffalse { \fi } #1 \edef \mycontainendwrite { \noexpand #1 } }
% after it's grabbed once it becomes "unsafe" again
% → } \endwrite \edef \mycontainendwrite { \noexpand \endwrite } ...
% we need to restore the `} \endwrite` tokens otherwise it's an error
\setbox0=\vbox{
\write 16{\weird}
}
\tex_shipout:D\box0
\nonstopmode
\show \mycontainendwrite
\errorstopmode
\expandafter \let \expandafter \myendwrite \mycontainendwrite
\nonstopmode
\show \myendwrite % no output in LuaLaTeX, segmentation fault in pdflatex and XeLaTeX and latex
\errorstopmode
\ExplSyntaxOff
\end{document}
Basically if you do \write <some number> {<some token list>}
, the token list is stored unexpanded in the "whatsit", and when the box is shipped out e.g. with \shipout \box 0 \somemoretokens ...
, something similar to \immediate \write <the number> { <the token list> } \endwrite \somemoretokens ...
is executed.
(*) As pointed out below, \immediate\write
does this as well. Last time I tried it doesn't happen -- probably some mistake on my end.
To store the endwrite somewhere, inject it after the \write
(because the content inside is purely expandable, so you can't store it).
Interestingly it creates a segmentation fault. (I wonder if it's exploitable.) it's just a null pointer dereference, on normal environments it's guaranteed to SIGSEGV, so much less "interesting" than the month value arbitrary-location memory read fixed recently.
The output on LuaLaTeX is
> \mycontainendwrite=macro:
->\endwrite .
l.37 \show \mycontainendwrite
> \myendwrite=\outer macro:
.
l.43 \show \myendwrite
and on the rest is
> \mycontainendwrite=macro:
->\endwrite .
l.37 \show \mycontainendwrite
Segmentation fault (core dumped)
(the segmentation fault is caused by the \let
, not the \show
.)
Side note for the remaining tokens. You can read texdoc tex
and tweak around a bit to figure them out.
First trigger an error that causes the token to be generated. Then "guess" what the resulting following tokens in the input stream will be.
For example, for the \inaccessible
token which can be accessed by executing \def
followed by a non-control-sequence.
$ pdflatex
This is pdfTeX, Version 3.141592653-2.6-1.40.24 (TeX Live 2022/Arch Linux) (preloaded format=pdflatex)
restricted \write18 enabled.
**\def a
entering extended mode
LaTeX2e patch level 1
L3 programming layer
! Missing control sequence inserted.
\inaccessible
\def a
? I\a{}\show
> \inaccessible=undefined.
\inaccessible
\def a
? I\show
> the letter a.
a
\def a
?
The underlined parts are typed text. The rest are output from pdflatex.
As you can deduce, when \def a
is executed, TeX prints an error message, drops the user to the command prompt,
then continue as-if \def
is just executed and \inaccessible a
are following in the input stream.
If you type I\a{}\show
here, the content to be executed becomes \def\a{}\show\inaccessible a
as you can expect.
This token has .tok
value 0x20010001
(or 536936449
) in lualatex, but I don't think there's any way to create a token given its tok value anyway.
Alternatively (for academical purpose) it's also possible to use the error hook in Lua to intentionally trigger the error to create the inaccessible token, but if you do this 100 times in the same paragraph TeX will stop.
\directlua{
luatexbase.add_to_callback("show_error_hook",
function()
luatexbase.remove_from_callback("show_error_hook", "get inaccessible token")
inaccessible_token=token.get_next()
token.put_next(inaccessible_token)
end,
"get inaccessible token"
)
}
\ExplSyntaxOn
\batchmode
\def a{}
\errorstopmode
Try it online! (link to some online code execution service for a demo and see the result.)
Additional note.
Point 4. The \endtemplate
token
If you do the following (similar to the trick to get \endwrite
token, but don't need the brace hack)
\def\weird{\expandafter \weirda\noexpand}
\def\weirda #1{\global\edef\container{\noexpand #1}#1}
{\setbox0=\vbox{\halign{#\cr\noexpand\weird\cr}}}
you can obtain the outer endtemplate token itself, instead of just its meaning. It has the property
- string representation is also
\endtemplate
, just like the inner token - meaning is
\outer endtemplate:
, or[unknown command code! (151, 4)]:
on LuaTeX. (another bug...?) - is outer.
- is expandable.
- if
\noexpand
is applied on it, its meaning becomes\relax
, like a normal expandable token.
If it's expanded once, it becomes the inner token which has the property
- string representation is
\endtemplate
, as mentioned above - meaning is
end of alignment template
- is not outer.
- is not expandable.
Point 3. notexpanded
As mentioned in the book, its meaning is not equal to the meaning of the normal \relax
. It may be noticeable that its meaning can be assigned to another token, the new token would be unexpandable.
Also, this meaning is also obtained when \noexpand
is applied on an undefined token.
When \noexpand
is applied on a non-expandable token (including the frozen relax), it's not a no-op, but the effect is only shown if you either
- redefine it to be something else, then the meaning of the token on the input stream becomes
\relax
- apply
\show
, then\notexpanded
is printed on the console. (so\expandafter\show \noexpand\let
shows\notexpanded: let
even though\let
is not expandable)
Demo.
% ======== assign meaning \a = \noexpand of y
\def\y {}
\expandafter \let \expandafter \a \noexpand \y
% ======== assign meaning \b = \noexpand of z
\expandafter \let \expandafter \b \noexpand \z
% ======== assign meaning \c = \noexpand of \let
\expandafter \let \expandafter \c \noexpand \let
% ======== \a is different from \relax
\ifx\a\relax \errmessage{this cannot happen} \fi
% ======== \a expanded once is different from \relax
\expandafter\ifx\a\relax \errmessage{this cannot happen} \fi
% ======== \a is different from \y
\ifx\a\y \errmessage{this cannot happen} \fi
% ======== \a expanded once remains the same i.e. it's not expandable, unlike the notexpanded token
\expandafter\ifx\a\a \else \errmessage{this cannot happen} \fi
% ======== \a and \b is the same
\ifx\a\b \else \errmessage{this cannot happen} \fi
% ======== \c meaning is \let
\ifx\c\let \else \errmessage{this cannot happen} \fi
\bye
Best Answer
It's a TeX primitive so no you can't define commands like it. It's also a pain in the neck and the cause of many of the problems in math mode, as it means that you can not be sure when you first encounter any math mode token what style things will end up in, hence the need for
\mathchoice
and various other horrors. If the primitive had had normal prefix syntax like LaTeX's\frac
it wouldn't have been necessary.