Warning: this is an htmlized version!
The original is here, and
the conversion rules are here.
-- This file:
--   http://angg.twu.net/LUA/Fitch-old.lua.html
--   http://angg.twu.net/LUA/Fitch-old.lua
--           (find-angg "LUA/Fitch-old.lua")
-- Author: Eduardo Ochs <eduardoochs@gmail.com>
--
-- (defun n () (interactive) (find-angg "LUA/Fitch.lua"))
-- (defun o () (interactive) (find-angg "LUA/Fitch-old.lua"))

require "re"


FitchLine = Class {
  type = "FitchLine",
  new  = function (l, v, m, r)
      return FitchLine {l=l, v=v, m=m, r=r}
    end,
  __tostring = function (fl)
      return (""):replace(0,       fl.l or "")
                 :replace(fl.posv, fl.v or "")
                 :replace(fl.posm, fl.m or "")
                 :replace(fl.posr, fl.r or "")
    end,
  __index = {
    posv = 4,
    posm = 7,
    posr = 40,
    addbar = function (fl, barchar)
        fl    = copy(fl)
        fl.m0 = fl.m0 or fl.m
        fl.m  = barchar.." "..fl.m
        return fl
      end,
    addv = function (fl)
        fl    = copy(fl)
        fl.m0 = fl.m0 or fl.m
        fl.m  = ("  "..fl.m):replace(0, fl.v or "")
        fl.v  = nil
        return fl
      end,
    addkluwer = function (fl, char)
        fl   = copy(fl)
        fl.k = ("\\f"..(char or "a").." ") .. (fl.k or "")
        return fl
      end,
    -- (find-kocurekpage 8 "1.1.7 An Illustrative Example")
    -- (find-kocurektext 8 "1.1.7 An Illustrative Example")
    kluwerline = function (fl)
        if fl.m0:match("^%-+$") then return nil end
        return format("\\ftag{%s}{%s%s} & %s \\\\", fl.l, fl.k, fl.m0, fl.r or "")
      end,
  },
}

FitchHLine = FitchLine {m = "----"}

Fitch = Class {
  type    = "Fitch",
  __tostring = function (bigfi)
      return mapconcat(tostring, bigfi:blinearize(), "\n")
    end,
  __index = {
    linearize = function (bigfi)
        local linearized = {}
        for _,o in ipairs(bigfi) do
          if otype(o) == "FitchLine" then
            table.insert(linearized, o)
          elseif otype(o) == "Fitch" then
            for _,oo in ipairs(o:blinearize()) do
              table.insert(linearized, oo)
            end
          end
        end
        return Fitch(linearized)
      end,
    blinearize = function (bigfi)
        local linearized = bigfi:linearize()
        local blinearized = {}
        for i=1,#linearized do
	  --
          local barchar = "|"
          if i==1 then barchar = "/" end
          if i==#linearized then barchar = "\\" end
          --
          local lii = linearized[i]
          local liib = lii:addbar(barchar)
          local liibk = liib:addkluwer(bigfi:kluwerletter(i))
          table.insert(blinearized, liibk)
        end
        return Fitch(blinearized)
      end,
    --
    -- For Kluwer:
    isline = function (bigfi, n)
        return bigfi[n] and bigfi[n].m and bigfi[n].m:match("^%-+$")
      end,
    kluwerletter = function (bigfi, n)
        local isfirst = (n == 1)
        local isaboveline = bigfi:isline(n + 1)
        if isfirst and isaboveline then return "h" end
        if isfirst     then return "b" end
        if isaboveline then return "j" end
        return "a"
      end,
    tokluwer0 = function (bigfi, prefix)
        local lines = {}
        for _,fl in ipairs(bigfi) do
          local li = fl:kluwerline()
          if li then table.insert(lines, prefix..fl:kluwerline()) end
        end
        return table.concat(lines, "\n")
      end,
  },
}

bigfi = Fitch {
    FitchLine {l="1", m="PvQ"},
    FitchLine {l="2", m="not Q"},
    FitchHLine,
    Fitch {
      FitchLine {l="3", m="P"},
      FitchHLine,
      FitchLine {l="4", m="P", r="R,3"},
    },
    Fitch {
      FitchLine {l="5", m="Q"},
      FitchHLine,
      FitchLine {l="6", m="not Q", r="not E,5,6"},
      FitchLine {l="4", m="bot",   r="bot E, 7"},
      FitchLine {l="4", m="P",     r="or E, 1, 3-4, 5-8"},
    },
  }

fitch_bigstr = [=[
  1 / PvQ
  2 | not Q
    |----
  3 | / P
    | |----
  4 | \ P       R,3
  5 | / Q
    | |----
  6 | | not Q   R,2
  7 | | bot     not E, 5, 6
  8 | \ P       bot E, 7
  9 \ P         or E, 1, 3-4, 5-8
]=]

fitch_gram = [=[
  barchar    <-   [/|\]
  strchar    <- [^ /|\]
  spaces     <- (      " "* )
  manyspaces <- ( '  ' " "* )
  str        <- {~ strchar+ (' ' strchar+)* ~} 
  optstr     <- (spaces str spaces) / (spaces -> "")
  optstrbar  <- (optstr { barchar })
  optright   <- (manyspaces {:r: str :}) ?
  fitchline  <- {| optstrbar+ spaces str optright |}
]=]

fitch_reP = Re { print = PP, grammar = fitch_gram }
fitch_re0 = Re {             grammar = fitch_gram }
fitch_parseline = fitch_re0:c 'top <- fitchline'

ParseFitch = Class {
  type    = "ParseFitch",
  parseline = function (li) return fitch_parseline(li) end,
  parselines = function (bigstr)
      local grid = {}
      for _,li in ipairs(splitlines(bigstr)) do
        table.insert(grid, ParseFitch.parseline(untabify(li)))
      end
      return grid
    end,
  from = function (bigstr)
      return ParseFitch {grid = ParseFitch.parselines(bigstr)}
    end,
  __tostring = function (pf) return mytostringpv(pf.grid) end,
  __index = {
    fitchline = function (pf, y)
        local gridline = pf.grid[y]
        local maxx = #gridline
	local l = gridline[1]
        local v = (maxx >= 5) and gridline[maxx - 2]
        local m = gridline[maxx]
        local r = gridline.r
	return FitchLine {l=l, v=v, m=m, r=r}
      end,
    maxy = function (pf, x0, y0)
        local c = function (y1) return pf.grid[y1][x0] end
        if c(y0) ~= "/" then error("Not '/' in ("..x0..","..y0..")") end
        for y2=y0+1,#pf.grid do
          if c(y2) == "\\" then return y2 end
          if c(y2) ~= "|"  then error("Not '|'") end
        end
        error("Grid ends too soon")
      end,
    tofitch0 = function (pf, x0, y0)
        if pf.grid[y0][x0+2] == "/" then
          local y2 = pf:maxy(x0+2, y0)
          return nil, x0+2, y0, y2
        else
          return pf:fitchline(y0)
        end
      end,
    tofitch1 = function (pf, x0, y0)
        local fls = Fitch {}
        local y1, y2 = y0, pf:maxy(x0, y0)
        while y1<=y2 do
          local fl, x1beg,y1beg,y1end = pf:tofitch0(x0, y1)
          if fl then
            table.insert(fls, fl)
            y1 = y1 + 1
          else 
            table.insert(fls, pf:tofitch1(x1beg, y1beg))
            y1 = y1end + 1
          end
        end
        return fls
      end,
    tofitch = function (pf)
        return pf:tofitch1(2, 1)
      end,
    tokluwer = function (pf, prefix)
        return pf:tofitch():blinearize():tokluwer0(prefix or "  ")
      end,
  },
}






--[==[
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
dofile "Fitch-old.lua"

pf = ParseFitch.from(fitch_bigstr)
= pf
= pf:maxy(2, 1)
= pf:tofitch0(2, 1)
= pf:tofitch0(2, 4)
= pf:tofitch0(4, 4)
= pf:tofitch1(2, 1)
= pf:tofitch(2, 1)
= pf:tofitch()
PPPV(pf:tofitch())
PPPV(pf:tofitch():blinearize())
=   (pf:tofitch():blinearize():tokluwer0("  "))
= pf:tokluwer()


= mytostringpv(pf)
= mytostringpv(pf)

fitch_reP:c 'top <-    optstrbar *   ' [[4 | \ foo    bar]]
fitch_reP:c 'top <-    optstrbar +   ' [[4 | \ foo    bar]]
fitch_reP:c 'top <- {| optstrbar + |}' [[4 | \ foo    bar]]
fitch_reP:c 'top <- {| optstrbar + manyspaces |}' [[4 | \ foo    bar]]
fitch_reP:c 'top <- (  optstrbar + manyspaces  )' [[4 | \ foo    bar]]
fitch_reP:c 'top <- (  optstrbar               )' [[4 | \ foo    bar]]
fitch_reP:c 'top <- fitchline'        [[4 | \ foo    bar]]
fitch_reP:c 'top <- manyspaces'       [[      678]]
fitch_reP:c 'top <- manyspaces str'   [[      678]]
fitch_reP:c 'top <- manyspaces str'   [[      678]]
fitch_reP:c 'top <- barchar'          [[\]]


fitch_reP:c 'top <- optstrbar *' '4 | \ foo    bar'
fitch_reP:c 'top <- optstrbar *' '4 | a \ P(a)    bar'
fitch_reP:c 'top <- (optstrbar *)' '4 | a \ P(a)    bar'
fitch_reP:c 'top <- (optstrbar *)' '| a \ P(a)    bar'

PP(fitch_parseline '4 | \ foo    bar')

fitch_reP:c 'top <- str' 'ab cd  ef' 
fitch_reP:c 'top <- optstrbar' '  ab cd  | foo' 
fitch_reP:c 'top <- optstrbar' '         | foo' 

fl1 = FitchLine {l="1:", v="a", m="P(a)", r="by foo"}
= fl1
= fl1:addbar("|")
= fl1:addbar("|"):addv()

PPPV(bigfi[4])
= bigfi[4][1]:addbar("/")
= bigfi[4][2]:addbar("|")
= bigfi[4][3]:addbar("\\")

= bigfi
FitchLine.__index.posm = 4
FitchLine.__index.posr = 20
= bigfi


-- (find-es "tex" "selinger-fitch")



--]==]