|
Warning: this is an htmlized version!
The original is here, and the conversion rules are here. |
-- This file:
-- https://anggtwu.net/LUA/TreeSegs1.lua.html
-- https://anggtwu.net/LUA/TreeSegs1.lua
-- (find-angg "LUA/TreeSegs1.lua")
-- Author: Eduardo Ochs <eduardoochs@gmail.com>
--
-- The functions in this file handle the whitespace-sparated
-- "segments" in "%:"-blocks, using data structures that are easy to
-- print, but that need classes that can't be defined in a bottom-up
-- fashion.
--
-- Each "%:"-line becomes a "Segments" object.
-- Each "Segments" object is a list of "Segment" objects.
-- The "AllSegments" object is almost a list of "Segments" objects -
-- "almost" because it can contains nils.
--
-- To obtain the segments above a "Segment" object `seg' we use
-- "seg:segsabove()", that takes the fields `y', `l', and `r' of
-- `seg', looks at allsegments[y-1], and returns the segments that
-- intersect the interval [l,r].
--
-- The code in heads["%:"] adds "Segments" objects to `allsegments',
-- and for each `rootseg' of the form "^Name" it runs
-- rootseg:rootnode():totreenode(), converts the resulting "TreeNode"
-- object to LaTeX, and outputs LaTeX code of this form:
--
-- \defded{Name}{...}
--
-- To understand the data structures, run the tests in:
-- (to "high-level-test")
--
-- Supersedes:
-- (find-dn6 "treesegs.lua")
--
-- (defun e () (interactive) (find-angg "LUA/TreeSegs1.lua"))
-- (defun o () (interactive) (find-dn6 "treesegs.lua"))
--
-- «.TreeNode» (to "TreeNode")
-- «.TreeNode-defded» (to "TreeNode-defded")
-- «.TreeNode-tests» (to "TreeNode-tests")
-- «.DefDed» (to "DefDed")
-- «.DefDed-tests» (to "DefDed-tests")
-- «.AllSegments» (to "AllSegments")
-- «.allsegments» (to "allsegments")
-- «.allsegments-tests» (to "allsegments-tests")
-- «.segtotreenode» (to "segtotreenode")
-- «.intersects» (to "intersects")
-- «.Segment» (to "Segment")
-- «.Segments» (to "Segments")
-- «.tosegments» (to "tosegments")
-- «.treesegtest» (to "treesegtest")
-- «.high-level-test» (to "high-level-test")
-- «.head» (to "head")
-- «.head-:» (to "head-:")
-- «.head-tests» (to "head-tests")
require "DednatParse1" -- (find-angg "LUA/DednatParse1.lua")
-- (find-angg "LUA/lua50init.lua" "DedTree")
-- (find-dn6 "heads6.lua" "tree-head")
-- _____ _ _ _
-- |_ _| __ ___ ___| \ | | ___ __| | ___
-- | || '__/ _ \/ _ \ \| |/ _ \ / _` |/ _ \
-- | || | | __/ __/ |\ | (_) | (_| | __/
-- |_||_| \___|\___|_| \_|\___/ \__,_|\___|
--
-- «TreeNode» (to ".TreeNode")
-- Based on: (find-dn6 "treetex.lua" "TreeNode")
-- See: (find-dn6 "treetex.lua" "TreeNode" "format is much more strict")
-- (find-angg "LUA/lua50init.lua" "DedTree")
-- (find-angg "LUA/Rect.lua" "DedTree")
--
TreeNode = Class {
type = "TreeNode",
from = function (o)
if type(o) == "string" then return TreeNode {[0]=o} end
if type(o) == "table" then
local tn = {[0]=o[0], bar=o.bar, label=o.label}
for i=1,#o do tn[i] = TreeNode.from(o[i]) end
if #tn > 0 then tn.bar = tn.bar or "-" end
return TreeNode(tn)
end
Error("TreeNode.from(o) failed")
end,
__tostring = function (tn) return tostring(tn:torect()) end,
__index = {
torect = function (tn) return dedtorect(tn) end,
hasbar = function (tn) return tn.bar ~= nil end,
barchar = function (tn) return tn.bar end,
TeX_root = function (tn) return tn[0] end,
TeX_label = function (tn) return tn.label end,
nhyps = function (tn) return #tn end,
hypslist = function (tn) return tn end,
outputdefded = function (tn) DefDed.fromnameseg(tn):output() end,
},
}
-- «TreeNode-tests» (to ".TreeNode-tests")
--[==[
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
dofile "TreeSegs1.lua"
ded = {[0]="a", "b", {[0]="c", "d", "e", bar="=", label="foo"}}
ded = {[0]="a", "b", {[0]="c", "d", {[0]="e", bar="-"}, bar="=", label="foo"}}
= dedtorect(ded)
tn = TreeNode.from(ded)
PPV(ded)
PPV(tn)
= tn
= otype(tn)
= otype(tn[1])
= otype(ded)
= otype(ded[1])
TreeNode_deftree
= tn:TeX_subtree("")
= tn:TeX_subtree(" ")
= tn:TeX_deftree("foo", "?")
--]==]
-- ____ __ ____ _
-- | _ \ ___ / _| _ \ ___ __| |
-- | | | |/ _ \ |_| | | |/ _ \/ _` |
-- | |_| | __/ _| |_| | __/ (_| |
-- |____/ \___|_| |____/ \___|\__,_|
--
-- «DefDed» (to ".DefDed")
-- See: (find-angg "LUA/TreeTeX1.lua" "ProofSty" "Replaces:")
DefDed = Class {
type = "DefDed",
fromnameseg = function (nameseg)
local name = nameseg.t:gsub("^%^", "")
local rootnode = nameseg:rootnode()
local comment = tf and (" % "..tf:hyperlink()) or ""
return DefDed {nameseg=nameseg, name=name, rootnode=rootnode, comment=comment}
end,
__index = {
output_print = function (dd)
print(dd.name..":")
print(" "..dd.rootnode:totreenode():torect())
print()
end,
output_proofsty = function (dd)
local p = proofsty:defded(dd.name, dd.rootnode:totreenode(), dd.comment)
output(tostring(p))
end,
output_ebproof = function (dd)
local p = ebproof:defded(dd.name, dd.rootnode:totreenode(), dd.comment)
output(tostring(p))
end,
--
output = function (dd) return dd:output_print() end,
},
}
-- «DefDed-tests» (to ".DefDed-tests")
--[==[
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
require "TreeSegs1"
= treesegtest [[
%: H
%: - ...
%: A B C E F \Pi
%: =======r ::::\phi ...
%: D G I
%: -------------------
%: J
%:
%: ^bars
]]
nameseg = allsegments[y-1][1]
= nameseg
dd = DefDed.fromnameseg(nameseg)
= dd.rootnode
= dd.rootnode:totreenode()
dd:output()
require "TreeTeX1"
output = print
dd:output_proofsty()
DefDed.__index.output = function (dd) return dd:output_proofsty() end
dd:output()
DefDed.__index.output = function (dd) return dd:output_ebproof() end
dd:output()
--]==]
-- _ _ _ ____ _
-- / \ | | / ___| ___ __ _ _ __ ___ ___ _ __ | |_ ___
-- / _ \ | | \___ \ / _ \/ _` | '_ ` _ \ / _ \ '_ \| __/ __|
-- / ___ \| | |___) | __/ (_| | | | | | | __/ | | | |_\__ \
-- /_/ \_\_|_|____/ \___|\__, |_| |_| |_|\___|_| |_|\__|___/
-- |___/
--
-- «AllSegments» (to ".AllSegments")
-- «allsegments» (to ".allsegments")
AllSegments = Class {
type = "AllSegments",
__tostring = function (allsegs) return allsegs:tostring() end,
__index = {
last = function (allsegs, linenow) -- unused?
for i=linenow,1,-1 do
if allsegs[i] and allsegs[i][1] then return allsegs[i][1] end
end
end,
lastlinen = function (allsegs)
return table.reverse(sortedkeys(allsegments))[1]
end,
tostring = function (allsegs)
local f = function (n) return pformat("%s: %s", n, allsegs[n]) end
return mapconcat(f, seq(1, allsegs:lastlinen() or 0), "\n")
end,
},
}
allsegments = AllSegments {}
-- «allsegments-tests» (to ".allsegments-tests")
-- See: (to "treesegtest-tests")
--[==[
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
dofile "TreeSegs1.lua"
= treesegtest [[
%:
%: a b
%: ----?
%: c
%:
%: ^C
]]
= allsegments
= allsegments[y-1]
= allsegments[y-3]
= allsegments[y-3][1]
= allsegments[y-3][1]:totreenode()
--]==]
-- _ _ _
-- ___ ___ __ _| |_ ___ | |_ _ __ ___ ___ _ __ ___ __| | ___
-- / __|/ _ \/ _` | __/ _ \| __| '__/ _ \/ _ \ '_ \ / _ \ / _` |/ _ \
-- \__ \ __/ (_| | || (_) | |_| | | __/ __/ | | | (_) | (_| | __/
-- |___/\___|\__, |\__\___/ \__|_| \___|\___|_| |_|\___/ \__,_|\___|
-- |___/
--
-- «segtotreenode» (to ".segtotreenode")
-- See: (find-angg "LUA/TreeTeX1.lua" "TreeNode")
segtotreenode = function (seg)
local bar = seg:firstsegabove()
if bar then
local bart = bar.t
local barchars = bart:match("^-+") or
bart:match("^=+") or
bart:match("^:+") or
bart:match("^.+")
if not barchars then Error("Bad bar: "..bart) end
local barchar = bart:sub(1, 1)
local label = bart:sub(1 + #barchars)
local hyps = bar:segsabove()
local T = map(segtotreenode, hyps)
T[0] = seg.t
T.bar = barchar
T.label = label
return TreeNode(T)
end
return TreeNode {[0]=seg.t}
end
-- «intersects» (to ".intersects")
intersects = function (start1, end1, start2, end2)
if end1 <= start2 then return false end
if end2 <= start1 then return false end
return true
end
-- ____ _
-- / ___| ___ __ _ _ __ ___ ___ _ __ | |_
-- \___ \ / _ \/ _` | '_ ` _ \ / _ \ '_ \| __|
-- ___) | __/ (_| | | | | | | __/ | | | |_
-- |____/ \___|\__, |_| |_| |_|\___|_| |_|\__|
-- |___/
--
-- «Segment» (to ".Segment")
Segment = Class {
type = "Segment",
__tostring = function (seg) return seg:tostring()
end,
__index = {
tostring = function (seg)
return pformat("[y:%s i:%s l-r:%s-%s t:%s]",
seg.y, seg.i, seg.l, seg.r, seg.t)
end,
iswithin = function (seg, l, r)
return intersects(seg.l, seg.r, l, r)
end,
intersects = function (seg1, seg2)
return intersects(seg1.l, seg1.r, seg2.l, seg2.r)
end,
segsabove_ = function (seg, dy)
return allsegments[seg.y - dy] or Segments {}
end,
segsabove = function (seg)
return seg:segsabove_(1):allintersecting(seg)
end,
firstsegabove = function (seg) return seg:segsabove()[1] end,
rootnode = function (seg)
return seg:segsabove_(2):firstwithin(seg.l, seg.l + 1)
end,
totreenode = function (seg) return segtotreenode(seg) end,
torect = function (seg) return dedtorect(seg:totreenode()) end,
},
}
-- ____ _
-- / ___| ___ __ _ _ __ ___ ___ _ __ | |_ ___
-- \___ \ / _ \/ _` | '_ ` _ \ / _ \ '_ \| __/ __|
-- ___) | __/ (_| | | | | | | __/ | | | |_\__ \
-- |____/ \___|\__, |_| |_| |_|\___|_| |_|\__|___/
-- |___/
--
-- «Segments» (to ".Segments")
Segments = Class {
type = "Segments",
__tostring = function (segs) return segs:tostring() end,
__index = {
tostring = function (segs)
local f = function (i) return pformat("%s=%s", i, segs[i]) end
return mapconcat(f, sortedkeys(segs), " ")
end,
--
allwithin = function (segs, l, r)
local segsw = Segments {}
for _,seg in ipairs(segs) do
if seg:iswithin(l, r) then table.insert(segsw, seg) end
end
return segsw
end,
firstwithin = function (segs, l, r)
return segs:allwithin(l, r)[1]
end,
allintersecting = function (segs, seg)
return segs:allwithin(seg.l, seg.r)
end,
firstintersecting = function (segs, seg)
return segs:allwithin(seg.l, seg.r)[1]
end,
--
outputdefdeds = function (segs)
for _,seg in ipairs(segs) do
local name = seg.t:match("^%^(.*)")
if name then DefDed.fromnameseg(seg):output() end
end
end,
},
}
-- «tosegments» (to ".tosegments")
-- Uses: (find-angg "LUA/DednatParse1.lua" "setsubj")
-- (find-angg "LUA/DednatParse1.lua" "getword")
tosegments = function (str, y, pos_)
local T = {}
setsubj(untabify8(str), pos_)
while getword() do
table.insert(T, Segment {y=y, i=#T+1, l=startcol, r=endcol, t=word})
end
return Segments(T)
end
-- «treesegtest» (to ".treesegtest")
treesegtest = function (bigstr)
y = 1
for _,li in ipairs(splitlines(bigstr)) do
allsegments[y] = tosegments(li, y)
y = y + 1
end
return allsegments[y - 1][1] -- return first segment from last line
end
-- «high-level-test» (to ".high-level-test")
--[==[
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
dofile "TreeSegs1.lua"
root = treesegtest [[
%:
%: a b
%: ====?
%: c
%:
%: ^r
]]
= otype(allsegments)
= otype(allsegments[y-1])
= otype(allsegments[y-1][1])
= otype(root)
= allsegments
= allsegments[y-1]
= allsegments[y-1][1]
= root
= root:rootnode()
= root:rootnode():totreenode()
= allsegments[3]
= allsegments[3][1]:segsabove()
= allsegments[3][1]:firstsegabove()
= allsegments[6]
= allsegments[6]:outputdefdeds()
--]==]
-- _ _ _
-- | | | | ___ __ _ __| |
-- | |_| |/ _ \/ _` |/ _` |
-- | _ | __/ (_| | (_| |
-- |_| |_|\___|\__,_|\__,_|
--
-- «head» (to ".head")
-- «head-:» (to ".head-:")
-- (find-dn6 "heads6.lua" "tree-head")
registerhead = registerhead or function () return nop end
registerhead "%:" {
name = "tree",
action = function ()
local i,j,treelines = tf:getblock()
for k=i,j do
allsegments[k] = tosegments(tf[k], k)
allsegments[k]:outputdefdeds()
end
end,
}
-- «head-tests» (to ".head-tests")
--[==[
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
loaddednat7()
dednat7oldheads()
= heads
= help(heads["%:"].action)
bigstr = [[
%: -
%: a b d e
%: ====? ::::foo
%: c f
%:
%: ^r ^s
]]
tf = TeXFile.from("A", bigstr)
texlines = tf
= tf:info()
pu("end")
= tf:info()
require "TreeSegs1"
tf = TeXFile.from("A", bigstr)
pu("end")
require "TreeTeX1"
tf = TeXFile.from("A", bigstr)
pu("end")
= help(heads["%:"].action)
--]==]
-- Local Variables:
-- coding: utf-8-unix
-- End: