Warning: this is an htmlized version!
The original is here, and
the conversion rules are here.
-- This file:
--   http://angg.twu.net/LATEX/2021groth-tops-children.lua.html
--   http://angg.twu.net/LATEX/2021groth-tops-children.lua
--           (find-angg "LATEX/2021groth-tops-children.lua")
-- Author: Eduardo Ochs <eduardoochs@gmail.com>
--
-- (defun e () (interactive) (find-LATEX "2021groth-tops-children.tex"))
-- (defun l () (interactive) (find-LATEX "2021groth-tops-children.lua"))

-- «.Rect-exts»		(to "Rect-exts")
-- «.color-non-open»	(to "color-non-open")


-- «Rect-exts»  (to ".Rect-exts")
-- (find-dn6 "rect.lua" "Rect")
-- (find-dn6 "rect.lua" "Rect-tests")
--
Rect.__index.charat = function (r, x, y)
    return (r[#r-y] or ""):sub(x+1, x+1)
  end
Rect.__index.charatcell = function (r, x, y)
    return r:charat(2*x, 2*y)
  end
Rect.__index.lineovercell = function (r, x, y, delta)
    return r:charat(2*x + delta, 2*y + 1)
  end
Rect.__index.maxxchar = function (r) return (r:width() - 1)/2 end
Rect.__index.maxychar = function (r) return (#r - 1)/2 end
Rect.__index.cdots = function (r)
    local bigstr = ""
    local Put = function (...) bigstr = bigstr..format(...).."\n" end
    -- local Put = printf
    for y=0,r:maxychar() do
      for x=0,r:maxxchar() do
        local c = r:charatcell(x,y)
        if c=="o" then Put("\\put(%d,%d){\\opendot}", x, y) end
        if c=="*" then Put("\\put(%d,%d){\\closeddot}", x, y) end
      end
      -- print()
    end
    return bigstr
  end
Rect.__index.clines = function (r)
    local bigstr = ""
    local Put = function (...) bigstr = bigstr..format(...).."\n" end
    -- local Put = printf
    for y=0,r:maxychar() do
      for x=1,r:maxxchar() do
        local c = r:lineovercell(x,y,-1)
        if c=="\\" or c=="X" then
          Put("\\Line(%d,%d)(%d,%d)", x, y, x-1, y+1)
        end
      end
      for x=0,r:maxxchar() do
        local c = r:lineovercell(x,y,0)
        if c=="|" then
          Put("\\Line(%d,%d)(%d,%d)", x, y, x+0, y+1)
        end
      end
      for x=0,r:maxxchar() do
        local c = r:lineovercell(x,y,1)
        if c=="/" or c=="X" then
          Put("\\Line(%d,%d)(%d,%d)", x, y, x+1, y+1)
        end
      end
      -- print()
    end
    return bigstr
  end
Rect.__index.cdimensions = function (r)
    return format("\\beginpicture(0,0)(%d,%d)\n", r:maxxchar(), r:maxychar())
  end




-- (find-books "__alg/__alg.el" "davey-priestley")
-- (find-daveypriestleypage (+ 14  54)   "Figure 2.10")
-- (find-daveypriestleytext (+ 14  54)   "Figure 2.10")

dp_2_10 = Rect.from [[
    o
   / \
  o   o
 / \ / \
*   o   *
 \ /|\ /
  o o o
  |X X|
  o * o
 / \|/ \
*   o   *
 \ / \ /
  *   *
   \ /
    o
]]

bottle = Rect.from [[
  *
   \
    o
   / \
  o   o
 / \ / \
*   o   *
 \ / \ /
  *   *
   \ /
    o
]]

obottle = Rect.from [[
  *
   \
    *
    |
    o
   / \
  o   o
 / \ / \
*   o   *
 \ /|\ /
  o o o
  |X X|
  o * o
 / \|/ \
*   o   *
 \ / \ /
  *   *
   \ /
    *
    |
    o
]]

N = Rect.from [[
o o
|\|
o o
]]

ON = Rect.from [[
  o
 / \
*   o
 \ / \
  o   *
 / \ /
*   *
 \ /
  o
]]



--[[
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
dofile "2021groth-tops-children.lua"

foo = dp_2_10
= foo
= foo:width()
= foo[1]
= #foo

= foo:clines()
= foo:cdots()
= foo:cdimensions()..foo:clines()..foo:cdots()

* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
dofile "2021groth-tops-children.lua"
foo = dp_2_10
foo = bottle
foo = obottle
foo = N
foo = ON
= foo:cdimensions()..foo:clines()..foo:cdots()


= foo:maxxchar()
= foo:width()
= foo[1]
= foo[2]
PP(foo[5])

= #foo
= (#foo - 1)/2


= foo:charat(4, 0)
= foo:charat(3, 1)
= foo:lineovercell(2, 0, -1)

--]]




-- «color-non-open»  (to ".color-non-open")
-- (find-es "dednat" "color-non-open")

betweens = function (A, B)
    A, B = v(A), v(B)
    local minl,minr = A:And(B):to_l_r()
    local maxl,maxr = A:Or (B):to_l_r()
    return cow(function ()
        for l=minl,maxl do
          for r=minr,maxr do
	    coy(l, r)
	  end
	end
      end)
  end
for l,r in betweens("46", "53") do print(l, r) end

MixedPicture.__index.putcolor = function (mp, A, str)
    A = v(A)
    str = str:gsub("~", A:lr())
    mp.ap:put(A, str)
    return mp
  end
MixedPicture.__index.putcolors = function (mp, A, B, str)
    for l,r in betweens(A, B) do
      mp:putcolor(v(l, r):lrtoxy(), str)
    end
    return mp
  end
MixedPicture.__index.putleftgen = function (mp, l, r, green, red, orange, yellow)
    local lr = function (l, r) return v(l, r):lrtoxy() end
    mp:putcolor (lr(l,   r),   green  or "\\G~")
    mp:putcolors(lr(l,   r-1), thisleft, yellow or "\\Y~")
    mp:putcolor (lr(l,   r-1), red    or "\\R~")
    mp:putcolor (lr(l,   r-2), orange or "\\O~")
    mp:putcolor (lr(l+1, r-1), orange or "\\O~")
    return mp
  end
MixedPicture.__index.putrightgen = function (mp, l, r, green, red, orange, yellow)
    local lr = function (l, r) return v(l, r):lrtoxy() end
    mp:putcolor (lr(l,   r),   green  or "\\G~")
    mp:putcolors(lr(l-1, r),   thisright, yellow or "\\Y~")
    mp:putcolor (lr(l-1, r),   red or "\\R~")
    mp:putcolor (lr(l-2, r),   orange or "\\O~")
    mp:putcolor (lr(l-1, r+1), orange or "\\O~")
    return mp
  end
MixedPicture.__index.transfercolors = function (mp)
    for l,r in betweens("00", thistop) do
      local str = bitrim(mp.ap:get(lr(l, r)))
      if str ~= "" then mp.lp:put(lr(l, r), str) end
    end
    return mp
  end