TeX works at various levels.
Initially it processes input characters in the file. These are never stored in TeX's internal structures they are parsed by its "eyes" and converted into tokens. Character tokens which encapsulate the character and its category code, or csname tokens that refer to other TeX constructs.
Token lists are the main data structure of the TeX macro language, when you use #1
in a definition, it is a token list that gets passed in to be processed at that point.
Once macros and other expandable tokens have been expanded, TeX executes the first non-expandable token. Operations at this level include all kinds of assignments, but also the actual process of typesetting things.
The structures that TeX uses to represent typeset material are exposed as (horizontal or vertical) boxes in TeX and the contents of a box are a (horizontal or vertical list).
The facilities that TeX offers to manipulate these typeset lists are very restricted compared to manipulating token lists. (The main technical difference that LuaTeX offers is that it offers Lua callbacks to manipulate these lists in arbitrary ways.) Basically the only thing you can do is determine the last item in a list (the e-TeX \lastnodetype
primitive, and \lastskip
, \lastpenalty
and similar friends) and remove the last item \lastbox
, \unskip
\unpenalty
. Note however there is not a full set of \un...
primitives: You can not remove specials or \write
nodes or \rules
(and while you can remove \leaders
with \unskip
You can not distinguish \leaders
from glue so you can not put them back if you remove them).
Consider
\tracingoutput1
\showboxbreadth\maxdimen\showboxdepth\maxdimen
abc def \hskip 1pt \vrule
\bye
In the file the list of characters abc def \hskip 1pt \vrule
gets converted (one at a time) to tokens a_11
, b_11
, _10
, \hskip
, 1_12
, ...
As each (non expandable) token gets processed it causes Tex to execute the appropriate command, in this case mostly adding things to the current horizontal list. The log file
shows the list as:
### horizontal mode entered at line 5
\hbox(0.0+0.0)x20.0
\tenrm a
\tenrm b
\kern0.27779
\tenrm c
\glue 3.33333 plus 1.66666 minus 1.11111
\tenrm d
\tenrm e
\tenrm f
\glue 3.33333 plus 1.66666 minus 1.11111
\glue 1.0
\rule(*+*)x0.4
spacefactor 1000
As I put the rule at the end that list can not be deconstructed by classical TeX but without that the classic way is to work backwards through the list.
\setbox0\hbox{abc def \hskip 1pt
\showthe\lastnodetype
\showthe\lastskip
\unskip
\showthe\lastnodetype
\showthe\lastskip
\unskip
\showthe\lastnodetype
Produces
(./lists.tex
> 11.
l.9 \showthe\lastnodetype
?
> 1.0pt.
l.10 \showthe\lastskip
?
> 11.
l.13 \showthe\lastnodetype
?
> 3.33333pt plus 1.66666pt minus 1.11111pt.
l.14 \showthe\lastskip
?
> 0.
l.17 \showthe\lastnodetype
?
)
Which shows, working backwards, that you have a node of type 11 (glue) with 11pt, which is removed, then another node of type 11 (glue) coming from the space token which is also removed. then there is a node of type 0 (character node) which is actually f
but in classic TeX you cannot see the f
or any other items in the list that are before that.