| rev | line source | 
| jbe/bsw@0 | 1 #!/usr/bin/env lua | 
| jbe/bsw@0 | 2 | 
| jbe/bsw@0 | 3 local _G             = _G | 
| jbe/bsw@0 | 4 local _VERSION       = _VERSION | 
| jbe/bsw@0 | 5 local assert         = assert | 
| jbe/bsw@0 | 6 local error          = error | 
| jbe/bsw@0 | 7 local getmetatable   = getmetatable | 
| jbe/bsw@0 | 8 local ipairs         = ipairs | 
| jbe/bsw@0 | 9 local next           = next | 
| jbe/bsw@0 | 10 local pairs          = pairs | 
| jbe/bsw@0 | 11 local print          = print | 
| jbe/bsw@0 | 12 local rawequal       = rawequal | 
| jbe/bsw@0 | 13 local rawget         = rawget | 
| jbe@64 | 14 local rawlen         = rawlen | 
| jbe/bsw@0 | 15 local rawset         = rawset | 
| jbe/bsw@0 | 16 local select         = select | 
| jbe/bsw@0 | 17 local setmetatable   = setmetatable | 
| jbe/bsw@0 | 18 local tonumber       = tonumber | 
| jbe/bsw@0 | 19 local tostring       = tostring | 
| jbe/bsw@0 | 20 local type           = type | 
| jbe/bsw@0 | 21 | 
| jbe/bsw@0 | 22 local io        = io | 
| jbe/bsw@0 | 23 local math      = math | 
| jbe/bsw@0 | 24 local os        = os | 
| jbe/bsw@0 | 25 local string    = string | 
| jbe/bsw@0 | 26 local table     = table | 
| jbe/bsw@0 | 27 | 
| jbe@64 | 28 local multirand = require("multirand") | 
| jbe/bsw@0 | 29 | 
| jbe@64 | 30 local _M = {} | 
| jbe@64 | 31 if _ENV then | 
| jbe@64 | 32   _ENV = _M | 
| jbe@64 | 33 else | 
| jbe@64 | 34   _G[...] = _M | 
| jbe@64 | 35   setfenv(1, _M) | 
| jbe@64 | 36 end | 
| jbe/bsw@0 | 37 | 
| jbe@64 | 38 -- NOTE: | 
| jbe@64 | 39 -- temp_dir MUST NOT contain any charactes interpreted by system shell | 
| jbe@64 | 40 -- and has to be set to a private directory (/tmp may be unsafe) | 
| jbe@64 | 41 temp_dir = false | 
| jbe/bsw@0 | 42 | 
| jbe/bsw@0 | 43 function escape(str) | 
| jbe/bsw@0 | 44   return ( | 
| jbe/bsw@0 | 45     string.gsub( | 
| jbe/bsw@0 | 46       str, | 
| jbe/bsw@0 | 47       "[\001-\031\127\\#$&~_^%%{}]", | 
| jbe/bsw@0 | 48       function(char) | 
| jbe/bsw@0 | 49         local b = string.byte(char) | 
| jbe/bsw@0 | 50         if (b > 1 and b < 31) or b == 127 then | 
| jbe/bsw@0 | 51           return " " | 
| jbe/bsw@0 | 52         elseif | 
| jbe/bsw@0 | 53           char == "#" or char == "$" or char == "&" or char == "_" or | 
| jbe/bsw@0 | 54           char == "%" or char == "{" or char == "}" | 
| jbe/bsw@0 | 55         then | 
| jbe/bsw@0 | 56           return "\\" .. char | 
| jbe/bsw@0 | 57         else | 
| jbe/bsw@0 | 58           return "\\symbol{" .. b .. "}" | 
| jbe/bsw@0 | 59         end | 
| jbe/bsw@0 | 60       end | 
| jbe/bsw@0 | 61     ) | 
| jbe/bsw@0 | 62   ) | 
| jbe/bsw@0 | 63 end | 
| jbe/bsw@0 | 64 | 
| jbe/bsw@0 | 65 document_methods = {} | 
| jbe/bsw@0 | 66 | 
| jbe/bsw@0 | 67 document_mt = { | 
| jbe/bsw@0 | 68   __index = document_methods, | 
| jbe/bsw@0 | 69   __call = function(...) return document_methods.write(...) end | 
| jbe/bsw@0 | 70 } | 
| jbe/bsw@0 | 71 | 
| jbe/bsw@0 | 72 function new_document() | 
| jbe/bsw@0 | 73   return setmetatable({}, document_mt) | 
| jbe/bsw@0 | 74 end | 
| jbe/bsw@0 | 75 | 
| jbe/bsw@0 | 76 function document_methods:write(...) | 
| jbe/bsw@0 | 77   local i = 1 | 
| jbe/bsw@0 | 78   while true do | 
| jbe/bsw@0 | 79     local v = select(i, ...) | 
| jbe/bsw@0 | 80     if v == nil then | 
| jbe/bsw@0 | 81       break | 
| jbe/bsw@0 | 82     end | 
| jbe/bsw@0 | 83     self[#self+1] = v | 
| jbe/bsw@0 | 84     i = i + 1 | 
| jbe/bsw@0 | 85   end | 
| jbe/bsw@0 | 86 end | 
| jbe/bsw@0 | 87 | 
| jbe/bsw@0 | 88 function document_methods:get_latex() | 
| jbe/bsw@0 | 89   local str = table.concat(self) | 
| jbe/bsw@0 | 90   for i in ipairs(self) do | 
| jbe/bsw@0 | 91     self[i] = nil | 
| jbe/bsw@0 | 92   end | 
| jbe/bsw@0 | 93   self[1] = str | 
| jbe/bsw@0 | 94   return str | 
| jbe/bsw@0 | 95 end | 
| jbe/bsw@0 | 96 | 
| jbe/bsw@0 | 97 function document_methods:get_pdf() | 
| jbe@64 | 98   -- TODO: proper escaping of shell commands | 
| jbe@64 | 99   -- (not a security risk, as args are safe) | 
| jbe/bsw@0 | 100   if not temp_dir then | 
| jbe/bsw@0 | 101     error("luatex.temp_dir not set") | 
| jbe/bsw@0 | 102   end | 
| jbe/bsw@0 | 103   local basename = temp_dir .. "/tmp.luatex_" .. multirand.string(16) | 
| jbe/bsw@0 | 104   local latex_file = assert(io.open(basename .. ".tex", "w")) | 
| jbe/bsw@0 | 105   latex_file:write(self:get_latex()) | 
| jbe/bsw@0 | 106   latex_file:close() | 
| jbe@64 | 107   local result1, result2, result3 = os.execute( | 
| jbe/bsw@0 | 108     'latex -output-format=pdf "-output-directory=' .. temp_dir .. '" ' .. | 
| jbe/bsw@0 | 109     basename .. '< /dev/null > /dev/null 2> /dev/null' | 
| jbe/bsw@0 | 110   ) | 
| jbe@64 | 111   -- NOTE: use result1 and result3 for lua5.1 and lua5.2 compatibility | 
| jbe@64 | 112   if not (result1 == 0 or (result2 == "exit" and result3 == 0)) then | 
| jbe/bsw@0 | 113     error('LaTeX failed, see "' .. basename .. '.log" for details.') | 
| jbe/bsw@0 | 114   end | 
| jbe/bsw@0 | 115   local pdf_file = assert(io.open(basename .. ".pdf", "r")) | 
| jbe/bsw@0 | 116   local pdf_data = pdf_file:read("*a") | 
| jbe/bsw@0 | 117   pdf_file:close() | 
| jbe/bsw@0 | 118   os.execute('rm -f "' .. basename .. '.*"') | 
| jbe/bsw@0 | 119   return pdf_data | 
| jbe/bsw@0 | 120 end | 
| jbe/bsw@0 | 121 | 
| jbe@64 | 122 return _M | 
| jbe@64 | 123 | 
| jbe/bsw@0 | 124 --[[ | 
| jbe/bsw@0 | 125 | 
| jbe@64 | 126 luatex = require("luatex") | 
| jbe/bsw@0 | 127 luatex.temp_dir = "." | 
| jbe/bsw@0 | 128 | 
| jbe/bsw@0 | 129 local tex = luatex.new_document() | 
| jbe/bsw@0 | 130 | 
| jbe/bsw@0 | 131 tex "\\documentclass[a4paper,12pt]{article}\n" | 
| jbe/bsw@0 | 132 tex "\\usepackage{german}\n" | 
| jbe/bsw@0 | 133 tex "\\usepackage{amsfonts}\n" | 
| jbe/bsw@0 | 134 tex "\\usepackage{amssymb}\n" | 
| jbe/bsw@0 | 135 tex "\\usepackage{ulem}\n" | 
| jbe/bsw@0 | 136 tex "\\pagestyle{headings}\n" | 
| jbe/bsw@0 | 137 tex "\\begin{document}\n" | 
| jbe/bsw@0 | 138 tex "\\title{Demo}\n" | 
| jbe/bsw@0 | 139 tex "\\author{John Doe}\n" | 
| jbe/bsw@0 | 140 tex "\\date{\\small 25. August 2008}\n" | 
| jbe/bsw@0 | 141 tex "\\maketitle\n" | 
| jbe/bsw@0 | 142 tex "\\end{document}\n" | 
| jbe/bsw@0 | 143 | 
| jbe/bsw@0 | 144 local pdf = tex:get_pdf() | 
| jbe/bsw@0 | 145 | 
| jbe/bsw@0 | 146 --]] |