| 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 --]]
 |