I am using TeX Live 2017, and the current luatex documentation of glue nodes says that the subtype field of a glue node has the following possible values:
0 = userskip, 1 = lineskip, 2 = baselineskip, 3 = parskip, 4 = abovedisplayskip, 5 = belowdisplayskip, 6 = abovedisplayshortskip, 7 = belowdisplayshortskip, 8 = leftskip, 9 = rightskip, 10 = topskip, 11 = splittopskip, 12 = tabskip, 13 = spaceskip, 14 = xspaceskip, 15 = parfillskip, 16 = mathskip, 17 = thinmuskip, 18 = medmuskip, 19 = thickmuskip, 98 = conditionalmathskip, 99 = muglue, 100 = leaders, 101 = cleaders, 102 = xleaders, 103 = gleaders
I was trying to learn about LuaTeX and wrote the following simple code to just spew out some informative output about each paragraph:
\documentclass{article}
\directlua{dofile("parinfo.lua")}
\begin{document}
Word1, word2 office. Word3. End.
\end{document}
where parinfo.lua is:
function traverse_paragraph(head)
while head do
print(string.format('In paragraph: %s %s', node.type(head.id), debugstr_node(head)))
head = head.next
end
return true
end
luatexbase.add_to_callback('pre_linebreak_filter', traverse_paragraph, 'Info for debugging')
function debugstr_node(n)
if node.type(n.id) == "glue" then
return debugstr_glue(n)
elseif node.type(n.id) == "glyph" then
return n.char < 128 and string.char(n.char) or string.format('[char %s]', n.char)
elseif node.type(n.id) == "kern" then
return string.format('%s', n.kern)
elseif node.type(n.id) == "penalty" then
return string.format('%s', n.penalty)
else
return ''
end
end
function debugstr_glue(n)
if n.subtype == 13 then
subtype = 'spaceskip'
elseif n.subtype == 14 then
subtype = 'xspaceskip'
elseif n.subtype == 15 then
subtype = 'parfillskip'
else
subtype = '' .. n.subtype
end
return string.format('<%s: %s plus %s(%s) minus %s(%s)', subtype, n.width, n.stretch, n.stretch_order, n.shrink, n.shrink_order)
end
So when the .tex file is compiled with lualatex, we get output like:
In paragraph: local_par
In paragraph: hlist
In paragraph: glyph W
In paragraph: kern -54395
In paragraph: glyph o
In paragraph: glyph r
In paragraph: glyph d
In paragraph: glyph 1
In paragraph: glyph ,
In paragraph: glue <spaceskip: 218235 plus 136396(0) minus 58196(0)
In paragraph: glyph w
In paragraph: kern -18350
In paragraph: glyph o
In paragraph: glyph r
In paragraph: glyph d
In paragraph: glyph 2
In paragraph: glue <spaceskip: 218235 plus 109117(0) minus 72745(0)
In paragraph: glyph o
In paragraph: glyph [char 64259]
In paragraph: glyph c
In paragraph: glyph e
In paragraph: glyph .
In paragraph: glue <spaceskip: 290980 plus 327351(0) minus 24248(0)
In paragraph: glyph W
In paragraph: kern -54395
In paragraph: glyph o
In paragraph: glyph r
In paragraph: glyph d
In paragraph: glyph 3
In paragraph: glyph .
In paragraph: glue <spaceskip: 290980 plus 327351(0) minus 24248(0)
In paragraph: glyph E
In paragraph: glyph n
In paragraph: glyph d
In paragraph: glyph .
In paragraph: penalty 10000
In paragraph: glue <parfillskip: 0 plus 65536(2) minus 0(0)
Note that the glue after the comma (which has larger stretch) and that after the . (which has larger width and larger stretch) are still both shown as having subtype spaceskip, rather than xspaceskip. (The glue at the end of the paragraph has subtype parfillskip, as expected.)
Is this expected? When would we see glue having type xspaceskip? And is there an alternative way in the pre_linebreak filter of detecting the larger glue that follows punctuation or end-of-sentence (with \nonfrenchspacing), other than keeping track of say recently seen interword glue and comparing for differences?
I don't fully understand the workings of these even for non-LuaTeX so I may just be confused :-) In case it matters, luatex --version says
This is LuaTeX, Version 1.0.4 (TeX Live 2017)