diff --git a/luametalatex-back-pdf.lua b/luametalatex-back-pdf.lua index 6d7d04c..e1265a4 100644 --- a/luametalatex-back-pdf.lua +++ b/luametalatex-back-pdf.lua @@ -63,6 +63,9 @@ function pdf.newcolorstack(default, mode, page) } return idx end +local function do_literal(prop, p, n, x, y) + pdf.write(prop.mode, prop.data, x, y, p) +end local function do_colorstack(prop, p, n, x, y) local colorstack = prop.colorstack local stack @@ -111,13 +114,19 @@ local function write_colorstack() }) node.write(whatsit) end +local function scan_literal_mode() + return token.scan_keyword"direct" and "direct" + or token.scan_keyword"page" and "page" + or token.scan_keyword"text" and "text" + or token.scan_keyword"direct" and "direct" + or token.scan_keyword"raw" and "raw" + or "origin" +end token.luacmd("pdffeedback", function() if token.scan_keyword"colorstackinit" then local page = token.scan_keyword'page' or (token.scan_keyword'nopage' and false) -- If you want to pass "page" as mode - local mode = token.scan_keyword'direct' and 'direct' - or token.scan_keyword'page' and 'page' - or 'origin' + local mode = scan_literal_mode() local default = token.scan_string() tex.sprint(tostring(pdf.newcolorstack(default, mode, page))) else @@ -129,9 +138,19 @@ end) token.luacmd("pdfextension", function() if token.scan_keyword"colorstack" then write_colorstack() + elseif token.scan_keyword"literal" then + local mode = scan_literal_mode() + local literal = token.scan_string() + local whatsit = node.new(whatsit_id, whatsits.pdf_literal) + node.setproperty(whatsit, { + handle = do_literal, + mode = mode, + data = literal, + }) + node.write(whatsit) else -- The following error message gobbles the next word as a side effect. -- This is intentional to make error-recovery easier. error(string.format("Unknown PDF extension %s", token.scan_word())) end -end) +end, "protected") diff --git a/luametalatex-nodewriter.lua b/luametalatex-nodewriter.lua index 8cb11ee..35d3a20 100644 --- a/luametalatex-nodewriter.lua +++ b/luametalatex-nodewriter.lua @@ -83,7 +83,7 @@ local function totext(p, fid) end local inspect = require'inspect' local function show(t) print(inspect(t)) end -local function topage(p) +function topage(p) local last = p.mode if last == page then return end if last <= text then @@ -372,14 +372,16 @@ local function do_commands(p, c, f, fid, x, y, outer, ...) stack[#stack] = nil x, y = top[1], top[2] elseif cmd[1] == "special" then - -- ??? + error[[specials aren't supported yet]] -- TODO elseif cmd[1] == "pdf" then - -- ??? + pdf.write(cmd[3] and cmd[2] or "origin", cmd[3], x, y, p) elseif cmd[1] == "lua" then cmd = cmd[2] if type(cmd) == "string" then cmd = load(cmd) end assert(type(cmd) == "function") + pdf._latelua(p, x, y, cmd, fid, c) elseif cmd[1] == "image" then + error[[images aren't supported yet]] -- TODO -- ??? -- else -- NOP, comment and invalid commands ignored @@ -431,19 +433,7 @@ end function nodehandler.whatsit(p, n, ...) -- Whatsit? return whatsithandler[n.subtype](p, n, ...) end -function whatsithandler.pdf_literal(p, n, x, y) - if n.mode == 2 then - topage(p) - p.strings[#p.strings + 1] = n.data - elseif n.mode == 0 then - write_matrix(p, 1, 0, 0, 1, x, y) - topage(p) - p.strings[#p.strings + 1] = n.data - write_matrix(p, 1, 0, 0, 1, -x, -y) - else - write(format('Literal type %i', n.mode)) - end -end +--[[ -- These use the old whatsit handling system which might get removed. function whatsithandler.pdf_save(p, n, x, y, outer) topage(p) p.strings[#p.strings + 1] = 'q' @@ -471,9 +461,10 @@ function whatsithandler.pdf_end_link(p, n, x, y, outer, _, level) local links = p.linkcontext local link = links[#links] links[#links] = nil - if link.level ~= level then error[[Wrong link level]] end + if link.level ~= level then error"Wrong link level" end addlinkpoint(p, link, x, y, outer, true) end +]] local global_p, global_x, global_y function pdf._latelua(p, x, y, func, ...) global_p, global_x, global_y = p, x, y @@ -481,9 +472,17 @@ function pdf._latelua(p, x, y, func, ...) end function pdf.write(mode, text, x, y, p) x, y, p = x or global_x, y or global_y, p or global_p - if mode == "direct" then + if mode == "page" then topage(p) p.strings[#p.strings + 1] = text + elseif mode == "text" then + topage(p) + p.strings[#p.strings + 1] = text + elseif mode == "direct" then + if p.mode ~= page then + totext(p, p.font.fid) + end + p.strings[#p.strings + 1] = text elseif mode == "origin" then write_matrix(p, 1, 0, 0, 1, x, y) topage(p)