Warning: this is an htmlized version!
The original is here, and
the conversion rules are here.
-- This file:
--   http://angg.twu.net/LATEX/2020dn6-error-handling.lua.html
--   http://angg.twu.net/LATEX/2020dn6-error-handling.lua
--           (find-angg "LATEX/2020dn6-error-handling.lua")
--                (find-LATEX "2020dn6-error-handling.lua")
-- Author: Eduardo Ochs <eduardoochs@gmail.com>
--
-- This file replaces some functions in dednat6 with versions with
-- better error handling. To use it, replace this
--
--   \catcode`\^^J=10
--   \directlua{dofile "dednat6load.lua"}
--
-- by this
--
--   \catcode`\^^J=10
--   \directlua{dofile "dednat6load.lua"}
--   \directlua{dofile "2020dn6-error-handling.lua"}
--
-- in your .tex file.
--
-- This is a PROTOTYPE, used by just these files:
--
--   (find-LATEXgrep "grep --color -nH --null -e 2020dn6-error-handling *.tex")
--
-- (find-es "dednat" "plabel-error-handling")
-- (dne)


-- «.getword»		(to "getword")
-- «.arrow-modifiers»	(to "arrow-modifiers")
-- «.dxyrun»		(to "dxyrun")
-- «.BussProofs»	(to "BussProofs")
-- «.BussProofs-test»	(to "BussProofs-test")




-- «getword»  (to ".getword")
-- (find-dn6 "parse.lua" "getword")
-- (find-dn6 "parse.lua" "getword" "getwordasluaexpr =")
--
-- These are higher-level variants of getword() that accept error
-- messages. Mnemonic: they have "_"s in their names, and
-- "getword_lua" is more readable than "getwordlua".

getword_1 = function (funname, errmsg)
    errmsg = errmsg or "argument"
    return getword() or error(format("In '%s': missing %s", funname, errmsg))
  end
getword_2 = function (funname, errmsg1, errmsg2)
    local a = getword_1(funname, errmsg1 or "first argument")
    local b = getword_1(funname, errmsg2 or "second argument")
    return a,b
  end

getword_lua = function (funname, errmsg)
    return expr(getword_1(funname, errmsg))
  end
getword_lualua = function (funname, errmsg1, errmsg2)
    local a, b = getword_2(funname, errmsg1, errmsg2)
    return expr(a), expr(b)
  end


-- «arrow-modifiers»  (to ".arrow-modifiers")
-- (find-dn6 "diagforth.lua" "arrow-modifiers")

forths[".plabel="] = function ()
    local p, label = getword_2(".plabel=", "first argument (placement)",
                                           "second argument (label)")
    ds:pick(0).placement, ds:pick(0).label = p, label
  end
forths[".slide="] = function ()
    ds:pick(0).slide = getword_1(".slide=")
  end
forths[".curve="] = function ()
    ds:pick(0).curve = getword_1(".curve=")
  end

forths["xy+="] = function ()
    local dx,dy = getword_lualua(".plabel=", "first argument (dx)",
                                             "second argument (dy)")
    ds:pick(0).x = ds:pick(0).x + dx
    ds:pick(0).y = ds:pick(0).y + dy
  end


-- «dxyrun»  (to ".dxyrun")
-- (find-dn6 "diagforth.lua" "diag-head" "dxyrun =")
-- (find-dn6file "parse.lua" "setsubj =")
-- (find-es "lua5" "xpcall-2020")

-- It should be possible to use dxyrun0 recursively (for macros!) and
-- it should be possible to call it using xpcall and display the
-- offending line before the traceback...

-- (find-dn6 "heads6.lua" "diag-head")
-- (find-es "lua5" "xpcall-2020")
-- dxyrun = function (str, pos, linenum)
--     dxyrun0(str, pos, linenum)
--   end

dxyrun0 = function (str, pos)
    local a,b,c,d = subj,pos,startcol,endcol -- backup globals
    setsubj(str, pos or 1)
    while getword() do
      -- PP(word)
      if    forths[word] then forths[word]()
      elseif nodes[word] then ds:push(nodes[word])
      else Error("Unknown word: "..word)
      end
    end
    local subj,pos,startcol,endcol = a,b,c,d -- restore globals
  end

dxyrun_errhandler = function (errmsg)
    local fname = tf.name
    local b = lastheadblock
    local blockinfo = format("%s-block in lines %d-%d", b.head, b.i, b.j)
    local where = format("In %s, in the %s, in line %d",
			 fname, blockinfo, dxyrun_linenum)
    local whereinsubj = (" "):rep(startcol - 1)..("^"):rep(endcol - startcol)
    local errmsg0 = errmsg:gsub("^[^ ]* ", "")
    print(errmsg0)
    print(where..":")
    print()
    print(subj)
    print(whereinsubj)
    -- print(debug.traceback())
    print()
    print("Dednat6 error - aborting!")
  end

-- TODO: rewrite dxyrun using the MyXpcall class.
-- (find-angg "edrxrepl/edrxrepl.lua" "MyXpcall-class")
-- (find-angg "LUA/lua50init.lua" "MyXpcall")

dxyrun = function (str, pos, linenum)
    dxyrun_linenum = linenum
    local f = function () dxyrun0(str, pos) end
    local status = xpcall(f, dxyrun_errhandler)
    if status == false then os.exit(1) end
  end



-- «BussProofs»  (to ".BussProofs")
--
BussProofs = Class {
  type = "BussProofs",
  new  = function () return BussProofs {} end,
  __index = {
    unabbrev = function (bp, str) return unabbrev(str) end,
    subtreetolatex = function (bp, tn, i)
        local i_,i__ = i.." ", i.."  "
        if not tn:hasbar() then
          local r_ = tn:TeX_root()
          return i.."\\AxiomC{$"..bp:unabbrev(r_).."$}"
        else
          local r_ = tn:TeX_root()
          local b_ = tn:barchar()
          local l_ = tn:TeX_label()
          local h_ = tn:hypslist()
          local r  = "\\mathstrut "..bp:unabbrev(r_)
          local s  = function (indent, str)
	                 return str and (indent..str.."\n") or ""
                       end
          local Lines = {["-"]=nil,
                         ["="]="\\doubleLine",
                         ["."]="\\noLine"}
          local Line  = Lines[b_]
          local Label = l_ and l_ ~= "" and format("\\RightLabel{$%s$}", l_)
          local Infs  = {[0] = "\\UnaryInfC",
                         "\\UnaryInfC",
                         "\\BinaryInfC",
                         "\\TrinaryInfC",
                         "\\QuaternaryInfC",
                         "\\QuinaryInfC"}
          local Inf   = format("%s{$%s$}", Infs[#h_], bp:unabbrev(r_))
          local f  = function (tn) return bp:subtreetolatex(tn, i__) end
          local Hyps  = (#h_ > 0) and (mapconcat(f, h_, i__.."\n"))
                                  or i__.."\\AxiomC{}"
          return Hyps.."\n"..s(i_,Line)..s(i_,Label)..i..Inf
        end
      end,
    treetolatex = function (bp, tn, i)
        return i.."\\hbox{\n"..
               bp:subtreetolatex(tn, i).."\n"..
	       i.."\\DisplayProof\n"..
               i.."}\n"
      end,
    todefded = function (bp, tn, name, link)
        local comment = "   % "..(link or tf:hyperlink())
        return "\\defded{"..name.."}{"..comment.."\n"..
	       bp:treetolatex(tn, "  ")..
               " }"
      end,
  },
}


--[==[
-- «BussProofs-test»  (to ".BussProofs-test")
-- To test or use this, put this in the preamble:
\usepackage{bussproofs}
\def\mybussproof#1{\leavevmode\hbox{#1\DisplayProof}}
%\newenvironment{bprooftree}
%  {\leavevmode\hbox\bgroup}
%  {\DisplayProof\egroup}

* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
loaddednat6()
require "block"
dofile "2020dn6-error-handling.lua"
bigstr = [[
%:                       H
%:  -                   ...
%:  A  B  C   E  F      \Pi
%:  =======r  ::::\phi  ...
%:     D       G         I
%:     -------------------
%:             J
%:
%:             ^bars
%:
]]
output = print
output("foo")
texlines = TexLines.new("test", bigstr)
tf = texlines:toblock()
PP(headblocks)
tf:processuntil(texlines:nlines())
PP(headblocks)
= allsegments[9]
seg = allsegments[9][1]
name = "bars"
output(seg:rootnode():totreenode():TeX_deftree(name))
= seg:rootnode()
= seg:rootnode():totreenode()
tree = seg:rootnode():totreenode()
= tree
= tree[1]
= tree[3]
= tree[3][1]
= tree[3][1][1]
PPV(tree)
PPV(tree[3][1][1])

bp = BussProofs.new()
= bp:subtreetolatex(tree, "")
= bp:treetolatex(tree, "")
= bp:todefded(tree, "NAME")

--]==]





--[[
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
loaddednat6()
dofile "2020dn6-error-handling.lua"

--]]



-- Local Variables:
-- coding: utf-8-unix
-- End: