Warning: this is an htmlized version!
The original is across this link,
and the conversion rules are here.
-- picture.lua: the Picture class for dednat6
-- This file:
-- http://angg.twu.net/dednat5/picture.lua
-- http://angg.twu.net/dednat5/picture.lua.html
--  (find-angg        "dednat5/picture.lua")
--
-- This file defines a class that generates LaTeX picture-mode
-- diagrams, and that can also output them as 2D ascii diagrams.
-- Older version: (find-angg "LUA/picture.lua" "Picture")
--
-- «.Picture»		(to "Picture")
-- «.Picture-tests»	(to "Picture-tests")



-- Min = function (a, b) return (a and b and min(a, b)) or a or b end
-- Max = function (a, b) return (a and b and max(a, b)) or a or b end



--  ____  _      _                         _
-- |  _ \(_) ___| |_ _   _ _ __ ___    ___| | __ _ ___ ___
-- | |_) | |/ __| __| | | | '__/ _ \  / __| |/ _` / __/ __|
-- |  __/| | (__| |_| |_| | | |  __/ | (__| | (_| \__ \__ \
-- |_|   |_|\___|\__|\__,_|_|  \___|  \___|_|\__,_|___/___/
--
-- «Picture» (to ".Picture")
-- We can ":put" things one by one into a Picture object, and ":totex"
-- will generate a "\begin{picture}...\end{picture}" LaTeX block with
-- the right size and offset. Also, ":toascii" generates an ascii
-- rendering of that picture object, great for debugging and stuff.

Picture = Class {
  type    = "Picture",
  new     = function (opts)
      local p = {whats={}, other={}}                -- start empty
      for k,v in pairs(opts or {}) do p[k] = v end  -- copy options
      return Picture(p)                             -- set metatable
    end,
  __index = {
    adjustbounds = function (p, x, y)
        p.minx, p.maxx = Min(p.minx, x), Max(x, p.maxx)
        p.miny, p.maxy = Min(p.miny, y), Max(y, p.maxy)
      end,
    put = function (p, x, y, what, what0)
        p:adjustbounds(x, y)
        -- p.minx = p.minx and min(x, p.minx) or x
        -- p.miny = p.miny and min(y, p.miny) or y
        -- p.maxx = p.maxx and max(p.maxx, x) or x
        -- p.maxy = p.maxy and max(p.maxy, y) or y
        table.insert(p.whats, {x=x, y=y, what=what, what0=what0})
        return p
      end,
    lrput = function (p, l, r, what, what0)
        local x = r - l
        local y = r + l
        p:put(x, y, what, what0)
        return p
      end,
    lrputline = function (p, l, r, dxdy, len)
        return p:lrput(l, r, nil, format("\\line(%s){%s}", dxdy, len))
      end,
    togrid = function (p)
        local lines = {}
        for y=p.miny,p.maxy do lines[y] = {} end
        for _,what in ipairs(p.whats) do
          lines[what.y][what.x] = what.what
        end
        return lines
      end,
    toasciilines = function (p, whitespace)
        local asciilines = {}
        local grid = p:togrid()
        for y=p.miny,p.maxy do
          for x=p.minx,p.maxx do
            local ascii = grid[y][x] or whitespace or "  "
            asciilines[y] = (asciilines[y] or "")..ascii
          end
        end
        return asciilines
      end,
    toascii = function (p, whitespace)
        local asciilines = p:toasciilines(whitespace)
        local lines = {}
        for y=p.maxy,p.miny,-1 do
          table.insert(lines, asciilines[y])
        end
        return table.concat(lines, "\n")
      end,
    --
    -- (find-es "tex" "dags")
    -- (find-kopkadaly4page (+ 12 289) "13.1.3 The positioning commands")
    -- (find-kopkadaly4text (+ 12 289) "13.1.3 The positioning commands")
    -- (find-kopkadaly4page (+ 12 298) "\\put")
    -- (find-kopkadaly4text (+ 12 298) "\\put")
    totex1 = function (p, what)
        -- local fmt = "  \\put(%s,%s){%s}\n"
        if what.what0 then
          return format("  \\put(%s,%s){%s}\n", what.x, what.y, what.what0)
        end
        local fmt = "  \\put(%s,%s){\\hbox to 0pt{\\hss %s%s\\hss}}\n"
        return format(fmt, what.x, what.y, p.font or "", what.what)
      end,
    totexputs = function (p)
        local f = function (what) return p:totex1(what) end
        return mapconcat(f, p.whats)
      end,
    --
    -- (find-kopkadaly4page (+ 12 301) "13.1.6 Shifting a picture environment")
    -- (find-kopkadaly4text            "13.1.6 Shifting a picture environment")
    -- (find-texbookpage (+ 12 66) "\\raise")
    -- (find-texbooktext (+ 12 66) "\\raise")
    totex = function (p)
        local a = {}
        a.scale   = p.scale or "1ex"
        a.xdimen  = p.maxx - p.minx + 1
        a.ydimen  = p.maxy - p.miny + 1
        a.xoffset = p.minx - 0.5
        -- a.yoffset = (p.miny + p.maxy + 1) / 2
        a.yoffset = p.miny
        a.lower   = (p.maxy - p.miny) / 2
        -- a.body = p:totexputs()
        a.body    = p:totexputs()..table.concat(p.other)
        local fmt = "{\\unitlength=!scale\n"..
                    "\\lower!lower\\unitlength\\hbox{"..
                    "\\begin{picture}(!xdimen,!ydimen)(!xoffset,!yoffset)\n"..
                    "!body"..
                    "\\end{picture}\n"..
                    "}}"
        return (fmt:gsub("!([a-z]+)", a))
      end,
  },
}



-- «Picture-tests» (to ".Picture-tests")
--[[
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
dofile "picture.lua"
p = Picture.new()
p:put(2, 3, "23")
p:put(4, 7, "47")
PP(p)
PP(p:togrid())
= p:toascii()
= p:totexputs()
p.scale = "10pt"
= p:totex()
-- (find-LATEX "tmp.tex")

f1 = function (p, lr)
    local l = lr:sub(1,1)+0
    local r = lr:sub(2,2)+0
    p:lrput(l, r, lr)
  end
f = function (p, str)
    for _,lr in ipairs(split(str)) do
      f1(p, lr)
    end
  end

p = Picture {whats={}}
f(p, "00 01 02 03 04")
f(p, "10 11 12 13 14")
f(p,       "22 23 24")
f(p,       "32 33 34")

= p:toascii()
p.scale = "10pt"
= p:totex()

--]]



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