-- 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: