/usr/share/texmf-texlive/scripts/cachepic/cachepic.tlu is in texlive-pictures 2009-15.
This file is owned by root:root, with mode 0o755.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 | #!/usr/bin/env texlua
local options = {
pdfoutput=true,
redoall=false,
multipicfile=false,
noborder=false,
dotypesetting=true,
nopostprocess=false,
}
local usagetext = 'Usage: cachepic [options] latexfile'
local tryhelp = "Try `cachepic --help' for more information"
local helptext = [[
Options start with '-' or '--' and can be any of:
-pdf output in (e)pdf format (default)
-eps output in eps format
-all regenerate all graphics
-multi all graphics in one file (implies -pdf)
-tight no 0.5bp margin around the graphic
-notex no typesetting, only graphic postprocessing
-nopic generate no graphics, only .cachepic file
-usage display usage message
-help,-h,-? display help message]]
local msg = {
MultipleInputFiles = "cannot process multiple files:\t%s\t%s",
NoInputFile = "no input file given\n" .. tryhelp,
UnknownOption = "unknown option: %s\n" .. tryhelp,
FileOpenFailed = "could not open file: %s",
NoGhostScript = "could not locate ghostscript interpreter",
WrongOutputMode = "expected %s output but got %s",
NoPreviews = "no cachepic previews found",
MultiPicOnlyInPDF = "option '-multi' for all graphics in one file supported only in pdf mode"
}
function die(msgfmt, ...)
error(string.format(msgfmt, ...))
end
function warn(msgfmt, ...)
print('warning: ' .. string.format(msgfmt, ...))
end
local function qfile(filename)
filename = string.gsub(filename, '"', '')
if string.find(filename, "[%s%&%(%)%[%]%{%}%^%=%;%!%'%+%,%`%~]") then
filename = '"' .. filename .. '"'
end
return filename
end
local function syscall(command)
print('system: ' .. command)
local ret = os.execute(command)
if ret > 0 then os.exit(ret)
else return ret end
end
local function copyfile(src, dst)
print('copy ' .. qfile(src) .. ' ' .. qfile(dst))
local buffer, bufsize = '', 1024
local fin = io.open(src, 'rb')
if not fin then die(msg.FileOpenFailed, src) end
local fout = io.open(dst, 'wb')
if not fout then die(msg.FileOpenFailed, dst) end
while buffer do
fout:write(buffer)
buffer = fin:read(bufsize)
end
fin:close()
fout:close()
end
local isfile = lfs and lfs.isfile or function (fname)
-- if we are not running under texlua, then do it the hard way
local fh = io.open(fname)
return (fh and (fh:close() or true) or false)
end
local function whichfile(fname, path)
if isfile(fname) then return fname end
-- make the best guess if it is Windows or Unix
local dirsep, pathsep = '/', ':'
if (os.type == 'windows') or string.find(path, '\\') or string.find(path, ';') then
dirsep, pathsep = '\\', ';' -- Windows
end
-- iterate path
for dir in string.gmatch(path, '[^' .. pathsep .. ']+') do
local f = dir .. dirsep .. fname
-- print(f)
if isfile(f) then return f end
end
return nil
end
local function findgs()
local path = os.getenv('PATH')
for _, fname in ipairs{'gs', 'gswin32c.exe', 'mgs.exe'} do
if whichfile(fname, path) then return fname end
end
die(msg.NoGhostScript)
end
-- Process options --
if #arg == 0 then
print(usagetext)
print(tryhelp)
os.exit(0)
end
local filename = nil
for _, argn in ipairs(arg) do
local opt, num = string.gsub(argn, '^%-%-?', '')
if num == 0 then -- not an option
if filename then die(msg.MultipleInputFiles, filename, opt)
else filename = opt end
elseif opt == 'eps' then options.pdfoutput = false
elseif opt == 'pdf' then options.pdfoutput = true
elseif opt == 'all' then options.redoall = true
elseif opt == 'multi' then options.multipicfile = true
elseif opt == 'tight' then options.noborder = true
elseif opt == 'notex' then options.dotypesetting = false
elseif opt == 'nopic' then options.nopostprocess = true
elseif (opt == 'usage') or (opt == 'help') or (opt == 'h') or (opt == '?') then
print(usagetext)
if opt == 'usage' then os.exit(0) end
print(helptext)
os.exit(0)
else die(msg.UnknownOption, argn) end
end
if not filename then
die(msg.NoInputFile)
end
if options.multipicfile and not options.pdfoutput then
warn(msg.MultiPicOnlyInPDF)
options.multipicfile = false
end
filename = string.gsub(filename, '\\', '/')
local noextname = string.gsub(filename, '%.[^./]*$', '')
local jobname = string.match(noextname, '[^/]+$')
local jobsuffix = (options.dotypesetting and '_cptmp' or '')
local multipicfilename = noextname .. '-cachepic.pdf'
-- Typeset document --
if options.dotypesetting then
local engine = (options.pdfoutput and 'pdflatex' or 'latex')
local psfixbb = (options.pdfoutput and '' or ',psfixbb')
local noborder = (options.noborder and ' \\PreviewBorder=0pt' or '')
local redoall = (options.redoall and ' \\makeatletter\\def\\cachepic@tryincludepic#1#2{\\xdef\\cachepic@name{#1}#2}\\makeatother' or '')
local command = engine .. ' -interaction=nonstopmode -jobname=' .. jobname .. jobsuffix ..
' \\def\\jobname{' .. jobname .. '}' ..
' \\RequirePackage[active,tightpage,delayed,cachepic' .. psfixbb .. ']{preview}' ..
noborder .. redoall .. ' \\input{' .. qfile(filename) .. '}'
syscall(command)
end
-- Process log file --
local iLines = io.lines(noextname .. jobsuffix .. '.log')
local pics = {}
local pdfmode = options.pdfoutput
local trim = '0 0 0 0'
for line in iLines do
local head, c1, c2, c3, c4, c5 = string.match(line,
'^Preview:%s*([A-Za-z]+)%s*(%-?%d*)%s*(%-?%d*)%s*(%-?%d*)%s*(%-?%d*)%s*(.*)')
if head == 'PDFoutput' then
pdfmode = (tonumber(c1) ~= 0)
elseif (head == 'Tightpage') and c1 and c2 and c3 and c4 then
trim = string.format('%dsp %dsp %dsp %dsp',
-tonumber(c1), -tonumber(c2), tonumber(c3), tonumber(c4))
elseif (head == 'CachePic') and c1 and c2 and c3 and c4 and c5 then
local picname = c5
local picpage = tonumber(c1)
local baseline = tonumber(c4) or 0
local texmacro = string.format('\\CachePicDefMacro{%s}{%d}{trim=%s}{%dsp}',
picname, picpage, trim, -baseline)
pics[#pics+1] = {name=picname, page=picpage, macro=texmacro}
end
end
if #pics == 0 then
warn(msg.NoPreviews)
return
end
if pdfmode ~= options.pdfoutput then
local expectedmode = options.pdfoutput and 'pdf' or 'dvi'
local actualmode = pdfmode and 'pdf' or 'dvi'
die(msg.WrongOutputMode, expectedmode, actualmode)
end
-- Write out cachepic macros --
io.output(noextname .. '.cachepic')
for i = 1, #pics do
io.write(pics[i].macro, '\n')
end
io.close()
if options.nopostprocess then return end
-- Postprocess pics --
if options.multipicfile then
if options.pdfoutput then
-- without option -all the file size will slowly grow
-- extra run through GhostScript seems to prevent that
-- but it degrades raster graphics or makes them much larger
-- no perfect solution it seems
copyfile(noextname .. jobsuffix .. '.pdf', multipicfilename)
else die(msg.MultiPicOnlyInPDF) end -- this should never happen
else
local ext, cmdtmpl
if options.pdfoutput then
ext = '.pdf'
filename = qfile(noextname .. jobsuffix .. '.pdf')
cmdtmpl = findgs() ..
' -sDEVICE=pdfwrite -dQUIET -dBATCH -dNOPAUSE -dCompatibilityLevel=1.4' ..
' -dFirstPage=%s -dLastPage=%s -sOutputFile=%s %s'
else
ext = '.eps'
filename = qfile(noextname .. jobsuffix .. '.dvi')
cmdtmpl = 'dvips -E -p %s -l %s -o %s %s'
end
for i = 1, #pics do
local outfile = string.gsub(pics[i].name, '"', '') .. ext
if not isfile(outfile) or options.redoall then
outfile = qfile(outfile)
syscall(string.format(cmdtmpl, pics[i].page, pics[i].page, outfile, filename))
end
end
end
--[[-- GS options preventing lossy image recompression
' -dMonoImageFilter=/CCITTFaxEncode' ..
' -dAutoFilterColorImages=false -dColorImageFilter=/FlateEncode' ..
' -dAutoFilterGrayImages=false -dGrayImageFilter=/FlateEncode' ..
]]
|