Warning: this is an htmlized version!
The original is across this link,
and the conversion rules are here.
-- This file:
--   http://angg.twu.net/LATEX/twot-pages.lua
--   http://angg.twu.net/LATEX/twot-pages.lua.html
-- From: http://wiki.luatex.org/index.php/TeX_without_TeX
-- (find-fline "$S/http/wiki.luatex.org/index.php/TeX_without_TeX.src" "two pages")

do
  -- this will hold the items that go onto the page
  local pagelist
 
  -- Call tex.shipout() with the contents of the pagelist
  function shipout()

    local vbox,b = node.vpack(pagelist) -- we ignore the badness 'b'
    tex.box[666] = vbox
    tex.shipout(666)

    pagelist = nil
    
    -- Not strictly necessary. TeX holds the current page number in counter 0.
    -- TeX displays the contents of this counter when it puts a page into
    -- the pdf (tex.shipout()). If we don't change the counter, TeX will
    -- display [1] [1], instead of [1] [2] for our two page document.
    tex.count[0] = tex.count[0] + 1
 end

  function add_to_page( list )
    -- We attach the nodelist 'list' to the end of the pagelist
    -- if pagelist doesn't exist, 'list' is our new pagelist
    -- if it exists, we go to the end with node.tail() and adjust
    -- the prev and next pointers, so list becomes part
    -- of pagelist.
    if not pagelist then pagelist = list
    else
      local tail = node.tail(pagelist)
      tail.next = list
      list.prev  = tail
    end
  end
end

-- This creates a new square rule and returns the pointer to it.
function mkrule( size )
  local r = node.new("rule")
  r.width  = size 
  r.height = size / 2
  r.depth  = size / 2
  return r
end

do
  local destcounter = 0
  -- Create a pdf anchor (dest object). It returns a whatsit node and the 
  -- number of the anchor, so it can be used in a pdf link or an outline.
  function mkdest()
    destcounter = destcounter + 1
    local d = node.new("whatsit","pdf_dest")
    d.named_id = 0
    d.dest_id = destcounter
    d.dest_type = 3

    return d, destcounter
  end
end

-- Take a list of nodes and put them into an hbox. The prev and next fields
-- of the nodes will be set automatically. Return a pointer to the hbox.
function hpack( ... )
  local start, tmp, cur
  start = select(1,...)
  tmp = start
  for i=2,select("#",...) do
    cur = select(i,...)
    tmp.next = cur
    cur.prev = tmp
    tmp = cur
  end
  local h,b = node.hpack(start) -- ignore badness
  return h
end

local tenpt = 10 * 2^16
---------------------------
-- page 1
---------------------------
local n,dest = mkdest() -- dest is needed for the link to this anchor

add_to_page(n)
add_to_page(mkrule(2 * tenpt))

-- The pagelist contains a pdf dest node (a link destination) and a rule of size 20pt x 20pt.

shipout()
---------------------------
-- page 2
---------------------------
-- This is the page with the link to the anchor (dest) on page one. A
-- link consists of three nodes: a pdf_start_link, a pdf_end_link and and 
-- action node that specifies the action to perform when the user clicks on
-- the link.
-- The pdf link must be inside a horizontal box, that's why we hpack() it.
-- The link_attr (link attributes) is optional, here it draws a yellowish border
-- around the link.
local start_link = node.new("whatsit","pdf_start_link")
local end_link   = node.new("whatsit","pdf_end_link")

start_link.width     = tenpt
start_link.height    = tenpt / 2
start_link.depth     = tenpt / 2
start_link.link_attr = "/C [0.9 1 0] /Border [0 0 2]"

start_link.action = node.new("action")
start_link.action.action_type = 1
start_link.action.action_id   = dest

local rule = mkrule(tenpt)
local hbox = hpack(start_link, rule, end_link)
add_to_page(hbox)

-- This pagelist consists of an hbox whose contents is "start_link",
-- the 10pt x 10pt rule and the "end_link" node. 

shipout()
---------------------------

-- Just to show you that you can get some memory usage statistics:
print(string.format("\nnode_mem_usage=%s",status.node_mem_usage))