1 -- filename : type-trans.lua
2 -- comment : Pretty printing of core transformations. Parses a specific
3 -- syntax, consisting of a before / after with a dashed lined in
4 -- between, and some extra conditions to the right of the line.
5 -- Recreates this layout using frames and line commands.
6 -- author : Matthijs Kooijman, Universiteit Twente, NL
7 -- copyright: Matthijs Kooijman
10 local utf = unicode.utf8
12 local vis = buffers.newvisualizer("trans")
15 -- A command to create a horizontal rule.
16 commands.rule = "\\HLine[width=.40 * \\the\\textwidth]"
17 -- Typing environment to use for the stuff before and after the line. Will be
18 -- prefixed with \start and \stop automatically.
19 commands.beforeenv = "unboxedlambda"
20 commands.afterenv = "unboxedlambda"
21 -- Frame commands to use for the left (before + line + after) and right
22 -- (conditions) parts. Should include an opening {, which will be closed
24 commands.leftframe = "\\framed[offset=0mm,location=middle,strut=no,align=right,frame=off,width=.48\\textwidth]{"
25 commands.rightframe = "\\framed[offset=0mm,location=middle,strut=no,align=right,frame=off,width=.48\\textwidth]{"
27 -- A table to keep the lines in this buffer, so we can process them all at
30 -- A counter to keep track of the mininum amount of indentation found in each
34 -- Some helper functions
35 local function ltrim(s)
36 return (string.gsub(s, "^%s*", ""))
39 local function rtrim(s)
40 return (string.gsub(s, "%s*$", ""))
43 -- Insert n blank lines
44 local function blanks(n)
46 buffers.visualizers.handlers.default.empty_line()
50 -- Prettyprint the given lines using the given pretty printer
51 local function prettyprint(ppr, lines)
52 -- Change the current visualizer
53 buffers.setvisualizer('lam')
56 buffers.hooks.begin_of_display()
59 _, line = buffers.typeline(lines[i], i, #lines, line)
61 buffers.hooks.end_of_display()
63 -- Change the visualizer back
64 buffers.setvisualizer('trans')
67 -- Capture all lines, without generating any output
68 function vis.begin_of_display()
72 function vis.begin_of_line(n)
73 -- Don't generate output here
75 function vis.flush_line(str, nested)
76 -- Keep track of the minimum indent level of all lines. Note that we don't
77 -- look at empty lines, of course.
78 indent = utf.len(utf.match(str, "^%s*"))
79 -- Find the lowest indent (but don't count empty lines)
80 if (not min_indent or indent < min_indent) then
84 table.insert(lines, str)
85 -- Don't generate output here
87 function vis.end_of_line(n)
88 -- Don't generate output here
90 function vis.empty_line()
91 table.insert(lines, '')
92 -- Don't generate output here
95 -- We do the actual work here. Process all the lines in the buffer and
96 -- generate output for them.
97 function vis.end_of_display()
98 -- Strip indent that is present on every line
99 min_indent = min_indent or 0
101 lines[i] = utf.sub(lines[i], min_indent + 1)
104 -- Find the horizontal rule, and see how long it is.
107 match = utf.match(lines[i], "^%-%-%-*")
115 error("No horizontal separator found in:\n" .. table.concat(lines, "\n"))
118 -- Split the input in three parts. Stuff before the line, stuff
119 -- after the line, stuff to the right of the line.
120 before, after, rights = {}, {}, {}
124 -- Split the line into a left and right part
125 left = rtrim(utf.sub(line, 1, len))
126 right = ltrim(utf.sub(line, len + 1))
127 if utf.match(left, "^%-%-%-*") then
130 if utf.len(left) > 0 then
131 if not found_line then
132 table.insert(before, left)
134 table.insert(after, left)
138 if utf.len(right) > 0 then
139 table.insert(rights, right)
144 -- Real output starts here
147 -- Let all the lambda pretty printing in this buffer use shared subscript
149 tex.sprint("\\directlua{buffers.visualizers.handlers.lam.begin_of_block()}")
151 -- Ensure the left and right frames end up next to each other.
152 tex.sprint("\\dontleavehmode")
154 -- Open and fill the left frame
155 tex.sprint(commands.leftframe)
157 tex.sprint("\\start" .. commands.beforeenv)
159 tex.sprint(table.concat(before, "\n"))
161 tex.sprint("\\stop" .. commands.beforeenv)
163 tex.sprint(commands.rule)
165 tex.sprint("\\start" .. commands.afterenv)
167 tex.sprint(table.concat(after, "\n"))
169 tex.sprint("\\stop" .. commands.afterenv)
171 -- Close the left frame
174 -- Open and fill the right frame
175 tex.sprint(commands.rightframe)
177 -- Insert spacer blank lines to align the middle condition with the
179 n_blanks = #before - math.ceil((#rights - 1) / 2)
180 n_blanks = math.max(0, n_blanks)
183 -- Print the conditions
185 tex.sprint(rights[i])
186 buffers.visualizers.handlers.default.end_of_line()
189 -- Fill up the remaining space with blanks
190 n_blanks = (#before + 1 + #after) - (n_blanks + #rights)
191 n_blanks = math.max(0, n_blanks)
194 -- Close the right frame
197 tex.sprint("\\directlua{buffers.visualizers.handlers.lam.end_of_block()}")
203 -- vim: set sw=4 sts=4 expandtab ai: