(No help to what you're ultimately trying to accomplish, but just to answer the question literally as asked.)
Recall that \discretionary
is supposed to be used as
\discretionary{⟨pre-break text⟩}{⟨post-break text⟩}{⟨no-break text⟩}
where the ⟨no-break text⟩
is what is printed by default, but if a line needs to be broken then the current line will end with ⟨pre-break text⟩
and the next line will start with ⟨post-break text⟩
. This is explained in The TeXbook page 95 (Chapter 14: How TeX Breaks Paragraphs into Lines).
How it works internally is that TeX inserts a "disc" node into the current list. For example, if you type
Here you find a st\discretionary{ra-}{ng}{rang}e word.
then TeX's internal list will look like (click on the image for proper resolution):
(note the kerns and “fi” ligature too—got the above using LuaTeX's pre_linebreak_filter
as here). To be more precise, what the disc
node points to are themselves lists of course:
In general, these three lists will contain only contain char_node
, kern_node
, hlist_node
, vlist_node
, rule_node
, and ligature_node
items.
Building these lists happens when TeX works on the \discretionary
command; later during line-breaking TeX will first use the link
(the no-break text) of the disc
node in its first (no-hyphenation) pass, then (if nothing satisfactory was found within \pretolerance
) use the pre
and post
links of the disc
node in the second pass of line-breaking.
To go into even more low-level detail:
When TeX encounters \discretionary
, if it's in vertical mode, then (just as when encountering a letter or \hskip
etc) it first backs up and starts a new paragraph (thus switches to horizontal mode). (See p. 283, "Chapter 24: Summary of Vertical Mode" of the TeXbook, or §1090 of the program.) So we can assume that TeX is in horizontal or math mode when it encounters a \discretionary
.
So when it encounters \discretionary
, it does the following:
- Append a new
disc
node to the current list.
- Push to the save stack, and start a new save level, keeping track that the current level is of type discretionary. (Rather than hbox, align, etc -- there are 16 kinds of groups; §269 of the program.)
- Scan the left brace.
- Go into restricted horizontal mode (with space factor 1000, the default).
- Then, until the right brace is encountered, continue processing things as usual (as if in restricted horizontal mode).
- When the right brace is encountered,
- Prune the list that has been built up so far, to contain only char, kern, hlist, vlist, rule and ligature nodes. (Else say "Improper discretionary list".)
- If the pre-break text was being scanned, make the
disc
node's pre_break
field point to it, and start scanning again (from step 3 above).
- If the post-break text was being scanned, make the
disc
node's post_break
field point to it, and start scanning again (from step 3 above).
- If the no-break text was being scanned, make the
disc
node's link
field point to it. (Here for math mode, this one should be empty.)
All this is in §1114–§1121 of the program, or page 287 (Chapter 25: Summary of Horizontal Mode) of The TeXbook:
\discretionary⟨general text⟩⟨general text⟩⟨general text⟩
The three general texts are processed in restricted horizontal mode. They
should contain only fixed-width things; hence they aren't really very
general in this case. More precisely, the horizontal list formed by each
discretionary general text must consist only of characters, ligatures,
kerns, boxes, and rules; there should be no glue or penalty items, etc.
This command appends a discretionary item to the current list; see
Chapter 14 for the meaning of a discretionary item. The space factor is
not changed.