X-Git-Url: https://git.stderr.nl/gitweb?p=matthijs%2Fmaster-project%2Freport.git;a=blobdiff_plain;f=pret-lam.lua;h=ed84d0a60eae09ecfaf10c8e4a0be6d7f541d77d;hp=568da7f565fbe7f28f7f63bf2f6986924baa418b;hb=b11f541f7d0b67f2871f1c7fed731155b1808343;hpb=0d14e5623d3d5fac4dd3485939c0c5ea9d62abba diff --git a/pret-lam.lua b/pret-lam.lua index 568da7f..ed84d0a 100644 --- a/pret-lam.lua +++ b/pret-lam.lua @@ -17,14 +17,19 @@ local colors = { -- Symbols that should have a different representation local symbols = { - [' '] = {repr = '\\obs '}, - ['_'] = {repr = '\\_'}, - ['->'] = {repr = '\\rightarrow'}, + -- Note, the space we replace with is a Unicode non-breaking space + -- (U+00A0). + {symbol = ' ', repr = ' '}, + {symbol = '_', repr = '\\_'}, + {symbol = '->', repr = '→'}, + {symbol = '=>', repr = '⇒'}, -- The default * sits very high above the baseline, \ast (u+2217) looks -- better. - ['*'] = {repr = '\\ast'}, - ['~'] = {repr = '\\HDLine[width=.20 * \\the\\textwidth]'}, - ['|'] = {repr = '\\char' .. utf.byte('|')}, + {symbol = '*', repr = '\\ast'}, + {symbol = '~', repr = '\\HDLine[width=.20 * \\the\\textwidth]'}, + {symbol = '|', repr = '\\char' .. utf.byte('|')}, + -- Use ▶ from our roman font, since Iwona doesn't have the glyph + {symbol = '▶', repr = '{\\rm{}▶}'}, } -- Keywords that should be bold @@ -35,6 +40,7 @@ local keywords = { ['letrec'] = {}, ['letnonrec'] = {}, ['in'] = {}, + ['DEFAULT'] = {small = true}, } local in_block = 0 @@ -43,14 +49,23 @@ local bases = {} -- Store the last line for each indent level local indentlines = {} +function array_concat(a1, a2) + local res = a1 + for k,v in ipairs(a2) do + table.insert(res, v) + end + return res +end + + -- See if str starts with a symbol, and return the remaining string and that -- symbol. If no symbol from the table is matched, just returns the first -- character. We can do a lookup directly, since symbols can be different in -- length, so we just loop over all symbols, trying them in turn. local function take_symbol(str) - for symbol,props in pairs(symbols) do + for i,props in ipairs(symbols) do -- Try to remove symbol from the start of str - symbol, newstr = utf.match(str, "^(" .. symbol .. ")(.*)") + symbol, newstr = utf.match(str, "^(" .. props.symbol .. ")(.*)") if symbol then -- Return this tokens repr, or just the token if it has no -- repr. @@ -103,7 +118,7 @@ local function do_subscripts(word) submatches[#submatches+1] = "^(" .. base .. ")([%a%d])$" -- Seconde, the base with a longer prefix that includes at least -- one of +-, (to catch things like ri+1, but not return). - submatches[#submatches+1] = "^(" .. base .. ")([%a%d]*[%-%+%,]+[%a%d%-%+%,]*)$" + submatches[#submatches+1] = "^(" .. base .. ")([%a%d]*[%-%+,]+[%a%d%-%+,]*)$" end end return word @@ -191,7 +206,7 @@ function vis.begin_of_display() if in_block == 0 then -- Initially allow subscripts using _ or just appending a number (later, -- we will add extra patterns here. - submatches = {"^(%a*)_([%a%d,]+)$", "^(%a+)(%d+)$"} + submatches = {"^(%a*)_([%a%d,]+)$", "^(%a+)(%d[%d,]+)$"} -- This stores all the bases we've encountered so far (to prevent -- duplicates). For each of them there will be a pattern in submatches -- above. @@ -206,35 +221,58 @@ vis.begin_of_inline = vis.begin_of_display vis.end_of_inline = vis.end_of_display function vis.flush_line(str,nested) - local result, state = { }, 0 - local finish, change = buffers.finish_state, buffers.change_state - str = do_indent(str) - -- Set the colorscheme, which is used by finish_state and change_state - buffers.currentcolors = colors + buffers.flush_result(vis.do_line(str, false), nested) +end + +function vis.do_line(str, no_indent) + local result = {} + if not no_indent then + -- Allow ignore of the indentation stuff when we're calling ourselves + -- for a partial line. + str = do_indent(str) + end while str ~= "" do local found = false local word, symbol - -- See if the next token is a word - word, str = take_word(str) - if word then - if keywords[res] then - -- Make all keywords bold - word = "{\\bold " .. word .. "}" + local text, rest = utf.match(str, "^%-%-(.-)%-%-(.*)") + if text then + table.insert(result, '\\strikethrough{') + -- Recursively call ourselves to handle spaces gracefully. + result = array_concat(result, vis.do_line(text, true)) + table.insert(result, '}') + -- Eat the processed characters + str = rest + elseif utf.match(str, "^%-%-") then + table.insert(result, '{\\italic{--') + -- Recursively call ourselves to handle spaces gracefully. + result = array_concat(result, vis.do_line(utf.sub(str, 3), true)) + table.insert(result, '}}') + -- Done with this line + str = '' + else + -- See if the next token is a word + word, str = take_word(str) + if word then + if keywords[res] then + -- Make all keywords bold + word = "{\\bold " .. word .. "}" + if keywords[res].small then + word = "\\small" .. word -- Curlies were added above + end + else + -- Process any subscripts in the word + word = do_subscripts(word) + end + table.insert(result, word) else - -- Process any subscripts in the word - word = do_subscripts(word) + -- The next token is not a word, it must be a symbol + symbol, str = take_symbol(str) + table.insert(result, symbol) end - else - -- The next token is not a word, it must be a symbol - symbol, str = take_symbol(str) end - - -- Append the resulting token - result[#result+1] = word or symbol end - - state = finish(state, result) - buffers.flush_result(result,nested) + + return result end -- vim: set sw=4 sts=4 expandtab ai: