From: Matthijs Kooijman Date: Mon, 27 Jul 2009 11:37:07 +0000 (+0200) Subject: Add transformation pretty printer. X-Git-Tag: final-thesis~312 X-Git-Url: https://git.stderr.nl/gitweb?p=matthijs%2Fmaster-project%2Freport.git;a=commitdiff_plain;h=c4abca08c46358134e3f73b2904293ef7a21b8b7 Add transformation pretty printer. --- diff --git a/pret-trans.lua b/pret-trans.lua new file mode 100644 index 0000000..9c6847e --- /dev/null +++ b/pret-trans.lua @@ -0,0 +1,172 @@ +-- 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: