-- 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 local vis = buffers.newvisualizer("trans") local commands = {} -- A command to create a horizontal rule. commands.rule = "\\HLine[width=.40 * \\the\\textwidth]" -- Typing environment to use for the stuff before and after the line. Will be -- prefixed with \start and \stop automatically. commands.beforeenv = "unboxedlambda" commands.afterenv = "unboxedlambda" -- 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=.48\\textwidth]{" commands.rightframe = "\\framed[offset=0mm,location=middle,strut=no,align=right,frame=off,width=.48\\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) for i = 1,n do buffers.visualizers.handlers.default.empty_line() end end -- Prettyprint the given lines using the given pretty printer local function prettyprint(ppr, lines) -- Change the current visualizer buffers.setvisualizer('lam') -- Output the lines buffers.hooks.begin_of_display() line = 0 for i = 1,#lines do _, line = buffers.typeline(lines[i], i, #lines, line) end buffers.hooks.end_of_display() -- Change the visualizer back buffers.setvisualizer('trans') end -- Capture all lines, without generating any output function vis.begin_of_display() lines = {} end function vis.begin_of_line(n) -- Don't generate output here end function vis.flush_line(str, nested) table.insert(lines, str) -- Don't generate output here end function vis.end_of_line(n) -- Don't generate output here end function vis.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 vis.end_of_display() -- 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 if not len then error("No horizontal separator found in:\n" .. table.concat(lines, "\n")) end -- 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 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 -- -- Let all the lambda pretty printing in this buffer use shared subscript -- detection tex.sprint("\\directlua{buffers.visualizers.handlers.lam.begin_of_block()}") -- 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) tex.sprint("\\start" .. commands.beforeenv) tex.sprint(table.concat(before, "\n")) tex.sprint("\\stop" .. commands.beforeenv) tex.sprint(commands.rule) tex.sprint("\\start" .. commands.afterenv) tex.sprint(table.concat(after, "\n")) tex.sprint("\\stop" .. commands.afterenv) -- 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.handlers.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("}") tex.sprint("\\directlua{buffers.visualizers.handlers.lam.end_of_block()}") -- Clean up lines = {} end -- vim: set sw=4 sts=4 expandtab ai: