tex.outputmode = 1

-- Build a simple paragraph node from given text. This code does not do any complex shaping etc.
-- adapted from: http://tex.stackexchange.com/questions/114568/can-i-create-a-node-list-from-some-text-entirely-within-lua
local function text_to_paragraph(text)
  local current_font = font.current()
  local font_params = font.getfont(current_font).parameters

  local para_head = node.new("local_par")

  local last = para_head

  local indent = node.new("hlist",3)
  indent.width = tex.parindent
  indent.dir = "TRT"
  last.next = indent
  last = indent

  for c in text:gmatch"." do  -- FIXME use utf8 lib
    local v = string.byte(c)
    local n
    if v < 32 then
      goto skipchar
    elseif v == 32 then
      n = node.new("glue",13)
      node.setglue(n, font_params.space, font_params.space_shrink, font_params.space_stretch)
      n = node.new("glyph", 1)
      n.font = current_font
      n.char = v
      n.lang = tex.language
      n.uchyph = 1
      n.left = tex.lefthyphenmin
      n.right = tex.righthyphenmin
    last.next = n
    last = n

  -- now add the final parts: a penalty and the parfillskip glue
  local penalty = node.new("penalty", 0)
  penalty.penalty = 10000

  local parfillskip = node.new("glue", 14)
  parfillskip.stretch = 2^16
  parfillskip.stretch_order = 2

  last.next = penalty
  penalty.next = parfillskip

  return para_head

local content = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."

for i = 1,3 do
  local head = text_to_paragraph(content)
  -- Break the paragraph into vertically stacked boxes
  local vbox = tex.linebreak(head, { hsize = tex.hsize })
  print("PAGE TOTAL " .. tex.pagetotal)


Note that it gets cut off. I was expecting a page break to happen, and the rest of the content to move over to the next page.

bad output


The idea is to create paragraph nodes entirely in Lua, and feed them to LuaTeX using node.write().

  • I am overriding the Plain TeX output routine with the default output routine by doing: \output={\shipout\box255}

  • The tex.pagetotal parameter does not seem to increment itself automatically. Not sure if that is part of the problem

  • I guess another way to do this is to populate the entire box on my own and ship it out using tex.shipout, but I was hoping to exercise the page-building routines inside TeX to break the page at the right location, instead of doing it on my own.

How can I fix this?

  • The problem may not be what I think it is, because when I change \pageheight=2in to \pageheight=297mm and add more iterations to the loop (change 3 to 30), things fix themselves. I still need to fix the problem, but it seems to be a different problem from what I initally thought it to be. – vyom Jan 28 '17 at 5:36
  • This looks related: tex.stackexchange.com/questions/20893/…. LuaTeX does not evaluate the TeX tokens generated in Lua until it has encountered the closing brace of the \directlua{} invocation. I don’t know how that applies to node.write(). That would be – vyom Jan 28 '17 at 10:13

Turns out, it is a pretty silly oversight on my part. I was only adjusting the \pageheight. The \vsize parameter being used was the one set in the Plain TeX macro (which is 8.9in). If I change the size of \vsize to be a little less than \pageheight, then things work fine.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.