Warning: this is an htmlized version!
The original is here, and
the conversion rules are here.
-- (find-es "texinfo" "texinfo.lua")
-- «.basic-functions»	(to "basic-functions")
-- «.DETMENUENTRIES»	(to "DETMENUENTRIES")
-- «.DETAILMENU»	(to "DETAILMENU")
-- «.output»		(to "output")
-- «.prefix»		(to "prefix")
-- «.suffix»		(to "suffix")
-- «.PUSH»		(to "PUSH")
-- «.COMMANDS»		(to "COMMANDS")
-- «.preproc»		(to "preproc")


-- «basic-functions»  (to ".basic-functions")
depthcommand = {"@top", "@chapter", "@section", "@subsection", "@subsubsection"}
unnumbered = {}
COMMAND = function (i)
    if unnumbered[long[i]] or unnumbered[short[i]] then return "@unnumbered" end
    return depthcommand[depth[i]]
  end

NEXT = function (i)
    if i == 1 then return short[2] or " " end
    -- if depth[i+1] and (depth[i+1] == depth[i]) then return short[i+1] end
    for j=i+1,#depth do
      if depth[j] == depth[i] then return short[j] end
      if depth[j] < depth[i] then return " " end
    end
    return " "
  end
PREVIOUS = function (i)
    for j=i-1,1,-1 do
      if depth[j] <= depth[i] then return short[j] end
    end
    return "(dir)"
  end
UP = function (i)
    for j=i-1,1,-1 do
      if depth[j] == depth[i] - 1 then return short[j] end
    end
    return "(dir)"
  end

MENUENTRIES = function (i)
    local arr = {}
    for j=i+1,#depth do
      if depth[j] == depth[i] + 1 then tinsert(arr, j) end
      if depth[j] <= depth[i] then return arr end
    end
    return arr
  end
MENUENTRY = function (j)
    return format("%-31s %s\n", "* "..short[j].."::", long[j])
  end
MENUBLOCK = function (entries) return concat(map(MENUENTRY, entries)) end
usedetailmenu = true
MENU = function (i)
    if i == 1 and usedetailmenu then return DETAILMENU() end
    local entries = MENUENTRIES(i)
    if #entries > 0 then
      return "\n@menu\n" .. MENUBLOCK(entries) .. "@end menu\n"
    else
      return ""
    end
  end

-- «DETMENUENTRIES»  (to ".DETMENUENTRIES")
-- This function returns the structure of the "detailed
-- menu" that goes into the top node.
-- This is tricky, and involves some ugly recursion...
-- Actually it's little more than bredth-first search, but, duh.
-- An example: if
--   depth = {1, 2, 3, 3, 2, 3, 4, 4, 3, 3, 2}
--        --  1  2  3  4  5  6  7  8  9 10 11
-- then the result of DETMENUENTRIES will be:
--   {{1}, {2, 5, 11}, {3, 4}, {6, 9, 10}, {7, 8}}
-- note that the "descendants" of depth[5] are depth[6,7,8,9,10],
-- and that the only "brother" of depth[6] is depth[9].
-- The comments "move down", "move left" etc in the code refer
-- to moving in this 2D representation of depth[]:
--    1:  1
--    2:    2
--    3:      3
--    4:      3
--    5:    2
--    ...
--
DETMENUENTRIES = function ()
    local adddescendants, nextbrother, addbrothers
    local bfs = {{1}}
    adddescendants = function (i)
        if not depth[i+1] then return end          -- end
        if depth[i+1] == depth[i] then return end  -- move down
        if depth[i+1] <  depth[i] then return end  -- move left
        local arr = {i+1}
        tinsert(bfs, arr)
        addbrothers(i+1, arr)
      end
    nextbrother = function (i)
        for j=i+1,#depth do
          if depth[j] <  depth[i] then return nil end -- move left
          if depth[j] == depth[i] then return j end   -- move down
        end
      end
    addbrothers = function (i, arr)
        adddescendants(i)
        local j = nextbrother(i)
        if j then tinsert(arr, j); addbrothers(j, arr) end
      end
    adddescendants(1)
    return bfs
  end
DETMENUBLOCK = function (entries)
    return long[entries[1] - 1].."\n\n"..concat(map(MENUENTRY, entries)).."\n"
  end

-- «DETAILMENU»  (to ".DETAILMENU")
DETAILMENU = function ()
    local blocks = DETMENUENTRIES()
    tremove(blocks, 1)
    local chapters = tremove(blocks, 1)
    return "@menu\n" ..
      MENUBLOCK(chapters) ..
      "\n@detailmenu\n --- The Detailed Node Listing ---\n\n" ..
      concat(map(DETMENUBLOCK, blocks)) ..
      "@end detailmenu\n@end menu\n"
  end



-- «output»  (to ".output")
nodebody = {}
nodebody_ = function (i)
    local b = nodebody[i]
    if b then return "\n"..b.."\n" else return "" end
  end
nodestr_ = function (i)
    return format("@node %s, %s, %s, %s\n" ..
                  "@comment  node-name,  next,  previous,  up\n" ..
                  "%s %s\n",
                  short[i], NEXT(i), PREVIOUS(i), UP(i),
                  COMMAND(i), long[i])
  end
nodestr = function (i) return nodestr_(i) .. nodebody_(i) .. MENU(i) end
allnodestrs = function ()
    return table.concat(map(nodestr, seq(1, #depth)), "\n")
  end
all = function () return prefix .. allnodestrs() .. "\n" end
all = function () return prefix .. allnodestrs() .. "\n" .. SUFFIX() end
pa = function () print(all()) end
sa = function () writefile("/tmp/tmp.texi", all()) end


-- «prefix»  (to ".prefix")
prefix = [=[
\input texinfo
@setfilename tmp.info
@settitle Test

@c (find-texinode "makeinfo options")
@c (find-sh "makeinfo tmp.texi")
@c (find-fline "/tmp/tmp.info")
@c (find-node "(/tmp/tmp.info)Top")
@c (find-sh "texi2dvi tmp.texi")
@c (find-dvipage "/tmp/tmp.dvi")

@c (find-angg "LUA/texinfo.lua" "prefix")
@c (find-es "texinfo" "texinfo.lua")
@c (find-es "texinfo" "sample.info")
@c (eek "C-c C-u C-a")
@c (eek "C-c C-u C-e")

]=]


-- «suffix»  (to ".suffix")
SUFFIX = function () return [=[
@printindex cp
@contents

@c Local Variables:
@c coding: raw-text-unix
@c End:

@bye
]=]
  end


-- «PUSH»  (to ".PUSH")
PUSH = function (dpth, shrt, lng, bdy)
    local n = #depth + 1
    depth[n] = dpth
    short[n] = shrt
    long[n]  = lng or shrt
    nodebody[n] = bdy
  end

-- «COMMANDS»  (to ".COMMANDS")
-- Basic uppercase commands.
TOP        = function (shrt, lng, bdy) PUSH(1, "Top", "Top", bdy) end
CHAPTER    = function (shrt, lng, bdy) PUSH(2, shrt, lng, bdy) end
SECTION    = function (shrt, lng, bdy) PUSH(3, shrt, lng, bdy) end
SUBSECTION = function (shrt, lng, bdy) PUSH(4, shrt, lng, bdy) end
INDEX      = function (shrt, lng, bdy)
    PUSH(2, shrt, lng, bdy)
    unnumbered[shrt] = true
  end


-- «preproc»  (to ".preproc")
-- (find-blogme3 "anggdefs.lua" "basic-special-words" "lua:")
ee_dofile "~/LUA/preproc.lua"  -- (find-angg "LUA/preproc.lua")
eval    = function (code) return assert(loadstring(code))() end
bitrim  = function (str)  return string.match(str, "^%s*(.*%S)%s*$") or "" end
sbitrim = function (str)  return string.match(str, "^[ \t]*\n?(.*%S)%s*$") or "" end
LUA_1   = function (code) return eval(code) end
pb      = function (body) return preproc(bitrim(body)) end
psb     = function (body) return preproc(sbitrim(body)) end

TOP_1  = function (body) TOP("Top", "Top", pb(body)) end
CHAPTER_3  = function (short, long, body)
    CHAPTER(pb(short), pb(long), pb(body))
  end
SECTION_3  = function (short, long, body)
    SECTION(pb(short), pb(long), pb(body))
  end
SUBSECTION_3  = function (short, long, body)
    SUBSECTION(pb(short), pb(long), pb(body))
  end
INDEX_3  = function (short, long, body)
    INDEX(pb(short), pb(long), pb(body))
  end
cmddef("LUA",        Curly1, eval)
cmddef("TOP",        Curly1, TOP_1)
cmddef("CHAPTER",    Curly3, CHAPTER_3)
cmddef("SECTION",    Curly3, SECTION_3)
cmddef("SUBSECTION", Curly3, SUBSECTION_3)
cmddef("INDEX",      Curly3, INDEX_3)

function preproctexi (texifile, body)
    long  = {}
    short = {}
    depth = {}
    unnumbered = {}
    preproc(body)
    writefile(texifile, all())
  end


-- For basic tests:
-- long = {"Top", "Chapter 1", "Section 1.1", "Section 1.2",
--                "Chapter 2", "Section 2.1", "Section 2.2",
--                "Chapter 3", "Section 3.1", "Section 3.2",
--                "Concept Index"}
-- short = {"top", "chap 1", "sec 1.1", "sec 1.2",
--                 "chap 2", "sec 2.1", "sec 2.2",
--                 "chap 3", "sec 3.1", "sec 3.2",
--                 "concept index"}
-- depth = {1, 2, 3, 3,
--             2, 3, 3,
--             2, 3, 3,
--             2}
-- unnumbered["Concept Index"] = true





-- Local Variables:
-- coding: raw-text-unix
-- modes: (fundamental-mode blogme-mode)
-- End: