jbe/bsw@0: #!/usr/bin/env lua jbe/bsw@0: jbe/bsw@0: local _G = _G jbe/bsw@0: local _VERSION = _VERSION jbe/bsw@0: local assert = assert jbe/bsw@0: local error = error jbe/bsw@0: local getmetatable = getmetatable jbe/bsw@0: local ipairs = ipairs jbe/bsw@0: local next = next jbe/bsw@0: local pairs = pairs jbe/bsw@0: local print = print jbe/bsw@0: local rawequal = rawequal jbe/bsw@0: local rawget = rawget jbe@64: local rawlen = rawlen jbe/bsw@0: local rawset = rawset jbe/bsw@0: local select = select jbe/bsw@0: local setmetatable = setmetatable jbe/bsw@0: local tonumber = tonumber jbe/bsw@0: local tostring = tostring jbe/bsw@0: local type = type jbe/bsw@0: jbe/bsw@0: local io = io jbe/bsw@0: local math = math jbe/bsw@0: local os = os jbe/bsw@0: local string = string jbe/bsw@0: local table = table jbe/bsw@0: jbe@64: local multirand = require("multirand") jbe/bsw@0: jbe@64: local _M = {} jbe@64: if _ENV then jbe@64: _ENV = _M jbe@64: else jbe@64: _G[...] = _M jbe@64: setfenv(1, _M) jbe@64: end jbe/bsw@0: jbe@64: -- NOTE: jbe@64: -- temp_dir MUST NOT contain any charactes interpreted by system shell jbe@64: -- and has to be set to a private directory (/tmp may be unsafe) jbe@64: temp_dir = false jbe/bsw@0: jbe/bsw@0: function escape(str) jbe/bsw@0: return ( jbe/bsw@0: string.gsub( jbe/bsw@0: str, jbe/bsw@0: "[\001-\031\127\\#$&~_^%%{}]", jbe/bsw@0: function(char) jbe/bsw@0: local b = string.byte(char) jbe/bsw@0: if (b > 1 and b < 31) or b == 127 then jbe/bsw@0: return " " jbe/bsw@0: elseif jbe/bsw@0: char == "#" or char == "$" or char == "&" or char == "_" or jbe/bsw@0: char == "%" or char == "{" or char == "}" jbe/bsw@0: then jbe/bsw@0: return "\\" .. char jbe/bsw@0: else jbe/bsw@0: return "\\symbol{" .. b .. "}" jbe/bsw@0: end jbe/bsw@0: end jbe/bsw@0: ) jbe/bsw@0: ) jbe/bsw@0: end jbe/bsw@0: jbe/bsw@0: document_methods = {} jbe/bsw@0: jbe/bsw@0: document_mt = { jbe/bsw@0: __index = document_methods, jbe/bsw@0: __call = function(...) return document_methods.write(...) end jbe/bsw@0: } jbe/bsw@0: jbe/bsw@0: function new_document() jbe/bsw@0: return setmetatable({}, document_mt) jbe/bsw@0: end jbe/bsw@0: jbe/bsw@0: function document_methods:write(...) jbe/bsw@0: local i = 1 jbe/bsw@0: while true do jbe/bsw@0: local v = select(i, ...) jbe/bsw@0: if v == nil then jbe/bsw@0: break jbe/bsw@0: end jbe/bsw@0: self[#self+1] = v jbe/bsw@0: i = i + 1 jbe/bsw@0: end jbe/bsw@0: end jbe/bsw@0: jbe/bsw@0: function document_methods:get_latex() jbe/bsw@0: local str = table.concat(self) jbe/bsw@0: for i in ipairs(self) do jbe/bsw@0: self[i] = nil jbe/bsw@0: end jbe/bsw@0: self[1] = str jbe/bsw@0: return str jbe/bsw@0: end jbe/bsw@0: jbe/bsw@0: function document_methods:get_pdf() jbe@64: -- TODO: proper escaping of shell commands jbe@64: -- (not a security risk, as args are safe) jbe/bsw@0: if not temp_dir then jbe/bsw@0: error("luatex.temp_dir not set") jbe/bsw@0: end jbe/bsw@0: local basename = temp_dir .. "/tmp.luatex_" .. multirand.string(16) jbe/bsw@0: local latex_file = assert(io.open(basename .. ".tex", "w")) jbe/bsw@0: latex_file:write(self:get_latex()) jbe/bsw@0: latex_file:close() jbe@64: local result1, result2, result3 = os.execute( jbe/bsw@0: 'latex -output-format=pdf "-output-directory=' .. temp_dir .. '" ' .. jbe/bsw@0: basename .. '< /dev/null > /dev/null 2> /dev/null' jbe/bsw@0: ) jbe@64: -- NOTE: use result1 and result3 for lua5.1 and lua5.2 compatibility jbe@64: if not (result1 == 0 or (result2 == "exit" and result3 == 0)) then jbe/bsw@0: error('LaTeX failed, see "' .. basename .. '.log" for details.') jbe/bsw@0: end jbe/bsw@0: local pdf_file = assert(io.open(basename .. ".pdf", "r")) jbe/bsw@0: local pdf_data = pdf_file:read("*a") jbe/bsw@0: pdf_file:close() jbe/bsw@0: os.execute('rm -f "' .. basename .. '.*"') jbe/bsw@0: return pdf_data jbe/bsw@0: end jbe/bsw@0: jbe@64: return _M jbe@64: jbe/bsw@0: --[[ jbe/bsw@0: jbe@64: luatex = require("luatex") jbe/bsw@0: luatex.temp_dir = "." jbe/bsw@0: jbe/bsw@0: local tex = luatex.new_document() jbe/bsw@0: jbe/bsw@0: tex "\\documentclass[a4paper,12pt]{article}\n" jbe/bsw@0: tex "\\usepackage{german}\n" jbe/bsw@0: tex "\\usepackage{amsfonts}\n" jbe/bsw@0: tex "\\usepackage{amssymb}\n" jbe/bsw@0: tex "\\usepackage{ulem}\n" jbe/bsw@0: tex "\\pagestyle{headings}\n" jbe/bsw@0: tex "\\begin{document}\n" jbe/bsw@0: tex "\\title{Demo}\n" jbe/bsw@0: tex "\\author{John Doe}\n" jbe/bsw@0: tex "\\date{\\small 25. August 2008}\n" jbe/bsw@0: tex "\\maketitle\n" jbe/bsw@0: tex "\\end{document}\n" jbe/bsw@0: jbe/bsw@0: local pdf = tex:get_pdf() jbe/bsw@0: jbe/bsw@0: --]]