--- /dev/null
+-- filename : type-trans.lua
+-- comment : Pretty printing of core transformations. Parses a specific
+-- syntax, consisting of a before / after with a dashed lined in
+-- between, and some extra conditions to the right of the line.
+-- Recreates this layout using frames and line commands.
+-- author : Matthijs Kooijman, Universiteit Twente, NL
+-- copyright: Matthijs Kooijman
+-- license : None
+
+local utf = unicode.utf8
+
+if not buffers then buffers = { } end
+if not buffers.visualizers then buffers.visualizers = { } end
+if not buffers.visualizers.trans then buffers.visualizers.trans = { } end
+
+local commands = {}
+-- A command to create a horizontal rule.
+commands.rule = "\\blackrule[height=0.5pt,depth=0pt,width=.45\\textwidth]"
+-- Pretty printer to use for the stuff before and after the line
+commands.before_pret = "lam"
+commands.after_pret = "lam"
+-- Frame commands to use for the left (before + line + after) and right
+-- (conditions) parts. Should include an opening {, which will be closed
+-- automatically.
+commands.leftframe = "\\framed[offset=0mm,location=middle,strut=no,align=right,frame=off,width=.5\\textwidth]{\\sans"
+commands.rightframe = "\\framed[offset=0mm,location=middle,strut=no,align=right,frame=off,width=.5\\textwidth]{"
+
+-- A table to keep the lines in this buffer, so we can process them all at
+-- once at the end.
+local lines
+
+-- Some helper functions
+local function ltrim(s)
+ return (string.gsub(s, "^%s*", ""))
+end
+
+local function rtrim(s)
+ return (string.gsub(s, "%s*$", ""))
+end
+
+-- Insert n blank lines
+local function blanks(n)
+ print("Inserting " .. n .. " blanks")
+ for i = 1,n do
+ buffers.visualizers.default.empty_line()
+ end
+end
+
+-- Prettyprint the given lines using the given pretty printer
+local function prettyprint(ppr, lines)
+ -- Change the current visualizer
+ oldvisualizer = buffers.currentvisualizer
+ buffers.currentvisualizer = 'lam'
+
+ -- Output the lines
+ buffers.hooks.begin_of_buffer('buffer', 'pret-trans-internal')
+ line = 0
+ for i = 1,#lines do
+ _, line = buffers.typeline(lines[i], i, #lines, line)
+ end
+ buffers.hooks.end_of_buffer('buffer', 'pret-trans-internal')
+
+ -- Change the visualizer back
+ buffers.currentvisualizer = oldvisualizer
+end
+
+-- Capture all lines, without generating any output
+function buffers.visualizers.trans.begin_of_buffer(type, name)
+ lines = {}
+end
+function buffers.visualizers.trans.begin_of_line(n)
+ -- Don't generate output here
+end
+function buffers.visualizers.trans.flush_line(str, nested)
+ table.insert(lines, str)
+ -- Don't generate output here
+end
+function buffers.visualizers.trans.end_of_line(n)
+ -- Don't generate output here
+end
+function buffers.visualizers.empty_line()
+ table.insert(lines, '')
+ -- Don't generate output here
+end
+
+-- We do the actual work here. Process all the lines in the buffer and
+-- generate output for them.
+function buffers.visualizers.trans.end_of_buffer()
+ -- Find the horizontal rule, and see how long it is.
+ len = nil
+ for i = 1,#lines do
+ match = utf.match(lines[i], "^%-%-%-*")
+ if match then
+ len = utf.len(match)
+ break
+ end
+ end
+ print("Rule length: " .. len)
+
+ -- Split the input in three parts. Stuff before the line, stuff
+ -- after the line, stuff to the right of the line.
+ before, after, rights = {}, {}, {}
+ found_line = false
+ for i = 1,#lines do
+ line = lines[i]
+ -- Split the line into a left and right part
+ left = rtrim(utf.sub(line, 1, len))
+ right = ltrim(utf.sub(line, len + 1))
+ if utf.match(left, "^%-%-%-*") then
+ found_line = true
+ else
+ print("Looking at " .. line .. "('" .. left .. "', '" .. right .. "')")
+ if utf.len(left) > 0 then
+ if not found_line then
+ table.insert(before, left)
+ else
+ table.insert(after, left)
+ end
+ end
+ end
+ if utf.len(right) > 0 then
+ table.insert(rights, right)
+ end
+ end
+
+ --
+ -- Real output starts here
+ --
+
+ -- Ensure the left and right frames end up next to each other.
+ tex.sprint("\\dontleavehmode")
+
+ -- Open and fill the left frame
+ tex.sprint(commands.leftframe)
+
+ prettyprint('lam', before)
+
+ tex.sprint(commands.rule)
+
+ prettyprint('lam', after)
+
+ -- Close the left frame
+ tex.sprint("}")
+
+ -- Open and fill the right frame
+ tex.sprint(commands.rightframe)
+
+ -- Insert spacer blank lines to align the middle condition with the
+ -- conclusion rule
+ n_blanks = #before - math.ceil((#rights - 1) / 2)
+ n_blanks = math.max(0, n_blanks)
+ blanks(n_blanks)
+
+ -- Print the conditions
+ for i = 1,#rights do
+ tex.sprint(rights[i])
+ buffers.visualizers.default.end_of_line()
+ end
+
+ -- Fill up the remaining space with blanks
+ n_blanks = (#before + 1 + #after) - (n_blanks + #rights)
+ n_blanks = math.max(0, n_blanks)
+ blanks(n_blanks)
+
+ -- Close the right frame
+ tex.sprint("}")
+
+ -- Clean up
+ lines = {}
+end
+
+-- vim: set sw=4 sts=4 expandtab ai: