Add transformation pretty printer.
authorMatthijs Kooijman <m.kooijman@student.utwente.nl>
Mon, 27 Jul 2009 11:37:07 +0000 (13:37 +0200)
committerMatthijs Kooijman <m.kooijman@student.utwente.nl>
Mon, 27 Jul 2009 11:37:07 +0000 (13:37 +0200)
pret-trans.lua [new file with mode: 0644]

diff --git a/pret-trans.lua b/pret-trans.lua
new file mode 100644 (file)
index 0000000..9c6847e
--- /dev/null
@@ -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: