diff options
Diffstat (limited to 'Master/texmf-dist/tex/context/base/grph-inc.lua')
-rw-r--r-- | Master/texmf-dist/tex/context/base/grph-inc.lua | 530 |
1 files changed, 381 insertions, 149 deletions
diff --git a/Master/texmf-dist/tex/context/base/grph-inc.lua b/Master/texmf-dist/tex/context/base/grph-inc.lua index 3dfcee739ff..508240a3bc4 100644 --- a/Master/texmf-dist/tex/context/base/grph-inc.lua +++ b/Master/texmf-dist/tex/context/base/grph-inc.lua @@ -1,6 +1,6 @@ if not modules then modules = { } end modules ['grph-inc'] = { version = 1.001, - comment = "companion to grph-inc.tex", + comment = "companion to grph-inc.mkiv", author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", copyright = "PRAGMA ADE / ConTeXt Development Team", license = "see context related readme files" @@ -12,6 +12,8 @@ if not modules then modules = { } end modules ['grph-inc'] = { -- dimensions -- consult rlx +-- figures.boxnumber can go as we now can use names + --[[ The ConTeXt figure inclusion mechanisms are among the oldest code in ConTeXt and evolve dinto a complex whole. One reason is that we @@ -33,12 +35,20 @@ The TeX-Lua mix is suboptimal. This has to do with the fact that we cannot run TeX code from within Lua. Some more functionality will move to Lua. ]]-- -local texsprint, format, lower, find, match = tex.sprint, string.format, string.lower, string.find, string.match +local format, lower, find, match, gsub, gmatch = string.format, string.lower, string.find, string.match, string.gsub, string.gmatch +local texsprint, texbox = tex.sprint, tex.box +local contains = table.contains +local concat = table.concat +local todimen = string.todimen local ctxcatcodes = tex.ctxcatcodes local variables = interfaces.variables -local trace_figures = false trackers.register("figures.locating",function(v) trace_figures = v end) +local trace_figures = false trackers.register("figures.locating", function(v) trace_figures = v end) +local trace_bases = false trackers.register("figures.bases", function(v) trace_bases = v end) +local trace_programs = false trackers.register("figures.programs", function(v) trace_programs = v end) +local trace_conversion = false trackers.register("figures.conversion", function(v) trace_conversion = v end) +local trace_inclusion = false trackers.register("figures.inclusion", function(v) trace_inclusion = v end) --- some extra img functions --- @@ -69,7 +79,7 @@ local validtypes = table.tohash(img.types()) function img.check_size(size) if size then - size = size:gsub("box","") + size = gsub(size,"box","") return (validsizes[size] and size) or "crop" else return "crop" @@ -78,13 +88,13 @@ end --- -figures = figures or { } -figures.loaded = figures.loaded or { } -figures.used = figures.used or { } -figures.found = figures.found or { } -figures.suffixes = figures.suffixes or { } -figures.patterns = figures.patterns or { } -figures.boxnumber = figures.boxid or 0 +figures = figures or { } +figures.loaded = figures.loaded or { } +figures.used = figures.used or { } +figures.found = figures.found or { } +figures.suffixes = figures.suffixes or { } +figures.patterns = figures.patterns or { } +figures.boxnumber = figures.boxnumber or 0 figures.defaultsearch = true figures.defaultwidth = 0 figures.defaultheight = 0 @@ -104,7 +114,7 @@ figures.cachepaths = { figures.paths = table.copy(figures.localpaths) figures.order = { - "pdf", "mps", "jpg", "png", "jbig", "svg", "eps", "mov", "buffer", "tex" + "pdf", "mps", "jpg", "png", "jbig", "svg", "eps", "gif", "mov", "buffer", "tex", } figures.formats = { @@ -115,6 +125,7 @@ figures.formats = { ["jbig"] = { list = { "jbig", "jbig2", "jb2" } }, ["svg"] = { list = { "svg", "svgz" } }, ["eps"] = { list = { "eps", "ai" } }, + ["gif"] = { list = { "gif" } }, ["mov"] = { list = { "mov", "avi" } }, ["buffer"] = { list = { "tmp", "buffer", "buf" } }, ["tex"] = { list = { "tex" } }, @@ -122,19 +133,21 @@ figures.formats = { function figures.setlookups() figures.suffixes, figures.patterns = { }, { } - for _, format in pairs(figures.order) do + for _, format in next, figures.order do local data = figures.formats[format] local fs, fp = figures.suffixes, figures.patterns - if data.list then - for _, s in ipairs(data.list) do - fs[s] = format -- hash + local list = data.list + if list then + for i=1,#list do + fs[list[i]] = format -- hash end else fs[format] = format end - if data.patterns then - for _, s in ipairs(data.patterns) do - fp[#fp+1] = { s, format } -- array + local patterns = data.patterns + if patterns then + for i=1,#patterns do + fp[#fp+1] = { patterns[i], format } -- array end end end @@ -149,12 +162,12 @@ local function register(tag,target,what) figures.formats[target] = data end local d = data[tag] -- list or pattern - if d and not table.contains(d,what) then + if d and not contains(d,what) then d[#d+1] = what -- suffix or patternspec else data[tag] = { what } end - if not table.contains(figures.order,target) then + if not contains(figures.order,target) then figures.order[#figures.order+1] = target end figures.setlookups() @@ -182,35 +195,24 @@ function figures.setpaths(locationset,pathlist) last_locationset = locationset end if h[iv["global"]] then - for s in pathlist:gmatch("([^, ]+)") do - if not table.contains(t,s) then + -- for s in gmatch(pathlist,",* *([^,]+)") do + local list = aux.settings_to_array(pathlist) + for i=1,#list do + local s = list[i] + if not contains(t,s) then t[#t+1] = s end end end figures.paths, last_pathlist = t, pathlist if trace_figures then - logs.report("figures","locations: %s",last_locationset) - logs.report("figures","path list: %s",table.concat(figures.paths)) + commands.writestatus("figures","locations: %s",last_locationset) + commands.writestatus("figures","path list: %s",concat(figures.paths, " ")) end end -- check conversions and handle it here ---~ local keys = img.keys() - ---~ function figures.hash(data) ---~ local i = data.status.private ---~ local t = { } ---~ for _, v in ipairs(keys) do ---~ local iv = i[v] ---~ if iv then ---~ t[#t+1] = v .. '=' .. iv ---~ end ---~ end ---~ return table.concat(t,"+") ---~ end - function figures.hash(data) return data.status.hash or tostring(data.status.private) -- the <img object> -- return data.status.fullname .. "+".. (data.status.page or data.request.page or 1) -- img is still not perfect @@ -262,13 +264,16 @@ do end function figures.push(request) - statistics.starttiming(figures) + local ncs = #callstack + 1 + if ncs == 1 then + statistics.starttiming(figures) + end local figuredata = figures.new() if request then local iv = interfaces.variables - -- request.width/height are strings and are only used when no natural dimensions - -- can be determined; at some point the handlers might set them to numbers instead ---~ local w, h = tonumber(request.width), tonumber(request.height) + -- request.width/height are strings and are only used when no natural dimensions + -- can be determined; at some point the handlers might set them to numbers instead + -- local w, h = tonumber(request.width), tonumber(request.height) request.page = math.max(tonumber(request.page) or 1,1) request.size = img.check_size(request.size) request.object = iv[request.object] == variables.yes @@ -277,21 +282,25 @@ do request.cache = request.cache ~= "" and request.cache request.prefix = request.prefix ~= "" and request.prefix request.format = request.format ~= "" and request.format ---~ request.width = (w and w > 0) or false ---~ request.height = (h and h > 0) or false + -- request.width = (w and w > 0) or false + -- request.height = (h and h > 0) or false table.merge(figuredata.request,request) end - callstack[#callstack+1] = figuredata + callstack[ncs] = figuredata return figuredata end function figures.pop() - figuredata = callstack[#callstack] - callstack[#callstack] = nil - statistics.stoptiming(figures) + local ncs = #callstack + figuredata = callstack[ncs] + callstack[ncs] = nil + if ncs == 1 then + statistics.stoptiming(figures) + end end -- maybe move texsprint to tex function figures.get(category,tag,default) - local value = figuredata[category][tag] + local value = figuredata[category] + value = value and value[tag] if not value or value == "" or value == true then return default or "" else @@ -307,19 +316,48 @@ do end +local defaultformat = "pdf" +local defaultprefix = "m_k_v_i_" + local function register(askedname,specification) if specification then local format = specification.format if format then - local converter = figures.converters[format] + local conversion = specification.conversion + if conversion == "" then + conversion = nil + end + local newformat = conversion + if not newformat or newformat == "" then + newformat = defaultformat + end + local converter = (newformat ~= format) and figures.converters[format] + if trace_conversion then + logs.report("figures","checking conversion of '%s': old format '%s', new format '%s', conversion '%s'", + askedname,format,newformat,conversion or "default") + end + if converter then + if converter[newformat] then + converter = converter[newformat] + else + newformat = defaultformat + if converter[newformat] then + converter = converter[newformat] + else + newformat = defaultformat + end + end + end if converter then local oldname = specification.fullname - local newformat = "pdf" -- todo, other target than pdf local newpath = file.dirname(oldname) - local newbase = file.replacesuffix(file.basename(oldname),newformat) + local oldbase = file.basename(oldname) + local newbase = file.replacesuffix(oldbase,newformat) local fc = specification.cache or figures.cachepaths.path if fc and fc ~= "" and fc ~= "." then newpath = fc + else + newbase = defaultprefix .. newbase end local subpath = specification.subpath or figures.cachepaths.subpath if subpath and subpath ~= "" and subpath ~= "." then @@ -331,10 +369,19 @@ local function register(askedname,specification) end local newname = file.join(newpath,newbase) dir.makedirs(newpath) + oldname = file.collapse_path(oldname) + newname = file.collapse_path(newname) local oldtime = lfs.attributes(oldname,'modification') or 0 local newtime = lfs.attributes(newname,'modification') or 0 if oldtime > newtime then + if trace_conversion then + logs.report("figures","converting '%s' from '%s' to '%s'",askedname,format,newformat) + end converter(oldname,newname) + else + if trace_conversion then + logs.report("figures","no need to convert '%s' from '%s' to '%s'",askedname,format,newformat) + end end if io.exists(newname) then specification.foundname = oldname @@ -353,15 +400,15 @@ local function register(askedname,specification) if not found then specification.found = false if trace_figures then - logs.report("figures","format not supported: %s",format) + commands.writestatus("figures","format not supported: %s",format) end else specification.found = true if trace_figures then if validtypes[format] then - logs.report("figures","format natively supported by backend: %s",format) + commands.writestatus("figures","format natively supported by backend: %s",format) else - logs.report("figures","format supported by output file format: %s",format) + commands.writestatus("figures","format supported by output file format: %s",format) end end end @@ -369,24 +416,42 @@ local function register(askedname,specification) specification = { } end specification.foundname = specification.foundname or specification.fullname - figures.found[askedname] = specification + figures.found[askedname .. "->" .. (specification.conversion or "default")] = specification return specification end +local resolve_too = true -- urls + local function locate(request) -- name, format, cache local askedname = resolvers.clean_path(request.name) - if figures.found[askedname] then - return figures.found[askedname] + local foundname = figures.found[askedname .. "->" .. (request.conversion or "default")] + if foundname then + return foundname + end + -- protocol check + local hashed = url.hashed(askedname) + if hashed and hashed.scheme ~= "file" then + local foundname = resolvers.findbinfile(askedname) + if foundname then + askedname = foundname + end end - local askedpath= file.dirname(askedname) + -- we could use the hashed data instead + local askedpath= file.is_rootbased_path(askedname) local askedbase = file.basename(askedname) local askedformat = (request.format ~= "" and request.format ~= "unknown" and request.format) or file.extname(askedname) or "" local askedcache = request.cache + local askedconversion = request.conversion if askedformat ~= "" then + if trace_figures then + commands.writestatus("figures","strategy: forced format") + end askedformat = lower(askedformat) local format = figures.suffixes[askedformat] if not format then - for _, pattern in ipairs(figures.patterns) do + local figurepatterns = figures.patterns + for i=1,#figurepatterns do + local pattern = figurepatterns[i] if find(askedformat,pattern[1]) then format = pattern[2] break @@ -394,7 +459,7 @@ local function locate(request) -- name, format, cache end end if format then - local foundname = figures.exists(askedname,format) -- not askedformat + local foundname = figures.exists(askedname,format,resolve_too) -- not askedformat if foundname then return register(askedname, { askedname = askedname, @@ -402,29 +467,36 @@ local function locate(request) -- name, format, cache format = format, cache = askedcache, foundname = foundname, + conversion = askedconversion, }) end end - if askedpath ~= "" then + if askedpath then -- path and type given, todo: strip pieces of path - if figures.exists(askedname,askedformat) then + if figures.exists(askedname,askedformat,resolve_too) then return register(askedname, { askedname = askedname, fullname = askedname, format = askedformat, cache = askedcache, + conversion = askedconversion, }) end else -- type given - for _, path in ipairs(figures.paths) do + local figurepaths = figures.paths + for i=1,#figurepaths do + local path = figurepaths[i] local check = path .. "/" .. askedname - if figures.exists(check,askedformat) then + -- we pass 'true' as it can be an url as well, as the type + -- is given we don't waste much time + if figures.exists(check,askedformat,resolve_too) then return register(check, { askedname = askedname, fullname = check, format = askedformat, cache = askedcache, + conversion = askedconversion, }) end end @@ -436,56 +508,88 @@ local function locate(request) -- name, format, cache fullname = check, format = askedformat, cache = askedcache, + conversion = askedconversion, }) end end end - elseif askedpath ~= "" then - for _, format in ipairs(figures.order) do + elseif askedpath then + if trace_figures then + commands.writestatus("figures","strategy: rootbased path") + end + local figureorder = figures.order + for i=1,#figureorder do + local format = figureorder[i] local list = figures.formats[format].list or { format } - for _, suffix in ipairs(list) do + for j=1,#list do + local suffix = list[j] local check = file.addsuffix(askedname,suffix) - if figures.exists(check,format) then + if figures.exists(check,format,resolve_too) then return register(askedname, { askedname = askedname, fullname = check, format = format, cache = askedcache, + conversion = askedconversion, }) end end end else if figures.prefer_quality then - for _, format in ipairs(figures.order) do + if trace_figures then + commands.writestatus("figures","strategy: unknown format, prefer quality") + end + local figurepaths = figures.paths + local figureorder = figures.order + for j=1,#figureorder do + local format = figureorder[j] local list = figures.formats[format].list or { format } - for _, suffix in ipairs(list) do - local name = file.replacesuffix(askedbase,suffix) - for _, path in ipairs(figures.paths) do + for k=1,#list do + local suffix = list[k] + -- local name = file.replacesuffix(askedbase,suffix) + local name = file.replacesuffix(askedname,suffix) + for i=1,#figurepaths do + local path = figurepaths[i] local check = path .. "/" .. name - if figures.exists(check,format) then + local isfile = url.hashed(check).scheme == "file" + if not isfile then + if trace_figures then + commands.writestatus("figures","warning: skipping path %s",path) + end + elseif figures.exists(check,format,true) then return register(askedname, { askedname = askedname, fullname = check, format = format, cache = askedcache, + conversion = askedconversion, }) end end end end else -- 'location' - for _, path in ipairs(figures.paths) do - for _, format in ipairs(figures.order) do + if trace_figures then + commands.writestatus("figures","strategy: unknown format, prefer path") + end + local figurepaths = figures.paths + local figureorder = figures.order + for i=1,#figurepaths do + local path = figurepaths[i] + for j=1,#figureorder do + local format = figureorder[j] local list = figures.formats[format].list or { format } - for _, suffix in ipairs(list) do + for k=1,#list do + local suffix = list[k] local check = path .. "/" .. file.replacesuffix(askedbase,suffix) - if figures.exists(check,format) then + if figures.exists(check,format,resolve_too) then return register(askedname, { askedname = askedname, fullname = check, format = format, cache = askedcache, + conversion = askedconversion, }) end end @@ -493,9 +597,15 @@ local function locate(request) -- name, format, cache end end if figures.defaultsearch then - for _, format in ipairs(figures.order) do + if trace_figures then + commands.writestatus("figures","strategy: default tex path") + end + local figureorder = figures.order + for j=1,#figureorder do + local format = figureorder[j] local list = figures.formats[format].list or { format } - for _, suffix in ipairs(list) do + for k=1,#list do + local suffix = list[k] local check = resolvers.find_file(file.replacesuffix(askedname,suffix)) if check and check ~= "" then return register(askedname, { @@ -503,6 +613,7 @@ local function locate(request) -- name, format, cache fullname = check, format = format, cache = askedcache, + conversion = askedconversion, }) end end @@ -519,6 +630,7 @@ figures.checkers = figures.checkers or { } figures.includers = figures.includers or { } figures.converters = figures.converters or { } figures.identifiers = figures.identifiers or { } +figures.programs = figures.programs or { } figures.identifiers.list = { figures.identifiers.default @@ -541,7 +653,9 @@ end function figures.identify(data) data = data or figures.current() - for _, identifier in ipairs(figures.identifiers.list) do + local list = figures.identifiers.list + for i=1,#list do + local identifier = list[i] data = identifier(data) if data.status.status > 0 then break @@ -549,8 +663,8 @@ function figures.identify(data) end return data end -function figures.exists(askedname,format) - return (figures.existers[format] or figures.existers.generic)(askedname) +function figures.exists(askedname,format,resolve) + return (figures.existers[format] or figures.existers.generic)(askedname,resolve) end function figures.check(data) data = data or figures.current() @@ -569,38 +683,47 @@ end function figures.done(data) figures.n = figures.n + 1 data = data or figures.current() - local dr, du, ds = data.request, data.used, data.status - ds.width = tex.wd[figures.boxnumber] - ds.height = tex.ht[figures.boxnumber] - ds.xscale = ds.width/(du.width or 1) +--~ print(table.serialize(figures.current())) + local dr, du, ds, nr = data.request, data.used, data.status, figures.boxnumber + local box = texbox[nr] + ds.width = box.width + ds.height = box.height + ds.xscale = ds.width /(du.width or 1) ds.yscale = ds.height/(du.height or 1) +--~ print(table.serialize(figures.current())) return data end -function figures.dummy(data) -- fails ---~ data = data or figures.current() ---~ local dr, du, ds = data.request, data.used, data.status ---~ local r = node.new("rule") ---~ r.width = du.width or figures.defaultwidth ---~ r.height = du.height or figures.defaultheight ---~ r.depth = du.depth or figures.defaultdepth ---~ tex.box[figures.boxnumber] = node.write(r) - texsprint(ctxcatcodes,"\\emptyfoundexternalfigure") +function figures.dummy(data) + data = data or figures.current() + local dr, du, ds, nr = data.request, data.used, data.status, figures.boxnumber + local box = node.hpack(node.new("hlist")) -- we need to set the dir (luatex 0.60 buglet) + du.width = du.width or figures.defaultwidth + du.height = du.height or figures.defaultheight + du.depth = du.depth or figures.defaultdepth + -- box.dir = "TLT" + box.width = du.width + box.height = du.height + box.depth = du.depth + texbox[nr] = box -- hm, should be global (to be checked for consistency) end -- -- -- generic -- -- -- -function figures.existers.generic(askedname) ---~ local result = io.exists(askedname) ---~ result = (result==true and askedname) or result ---~ local result = resolvers.find_file(askedname) or "" - local result = resolvers.findbinfile(askedname) or "" - if result == "" then result = false end +function figures.existers.generic(askedname,resolve) + -- not findbinfile + local result + if lfs.isfile(askedname) then + result = askedname + elseif resolve then + result = resolvers.findbinfile(askedname) or "" + if result == "" then result = false end + end if trace_figures then if result then - logs.report("figures","found: %s -> %s",askedname,result) + commands.writestatus("figures","found: %s -> %s",askedname,result) else - logs.report("figures","not found: %s",askedname) + commands.writestatus("figures","not found: %s",askedname) end end return result @@ -608,7 +731,11 @@ end function figures.checkers.generic(data) local dr, du, ds = data.request, data.used, data.status local name, page, size, color = du.fullname or "unknown generic", du.page or dr.page, dr.size or "crop", dr.color or "natural" - local hash = name .. "->" .. page .. "->" .. size .. "->" .. color + local conversion = dr.conversion + if not conversion or conversion == "" then + conversion = "unknown" + end + local hash = name .. "->" .. page .. "->" .. size .. "->" .. color .. "->" .. conversion local figure = figures.loaded[hash] if figure == nil then figure = img.new { filename = name, page = page, pagebox = dr.size } @@ -617,6 +744,13 @@ function figures.checkers.generic(data) local f, d = backends.codeinjections.setfigurealternative(data,figure) figure, data = f or figure, d or data figures.loaded[hash] = figure + if trace_conversion then + logs.report("figures","new graphic, hash: %s",hash) + end + else + if trace_conversion then + logs.report("figures","existing graphic, hash: %s",hash) + end end if figure then du.width = figure.width @@ -643,9 +777,11 @@ function figures.includers.generic(data) figures.used[hash] = figure end if figure then - local n = figures.boxnumber - tex.box[n] = img.node(figure) -- img.write(figure) - tex.wd[n], tex.ht[n], tex.dp[n] = figure.width, figure.height, 0 -- new, hm, tricky, we need to do that in tex (yet) + local nr = figures.boxnumber + -- it looks like we have a leak in attributes here .. todo + local box = node.hpack(img.node(figure)) -- img.node(figure) not longer valid + box.width, box.height, box.depth = figure.width, figure.height, 0 -- new, hm, tricky, we need to do that in tex (yet) + texbox[nr] = box ds.objectnumber = figure.objnum texsprint(ctxcatcodes,"\\relocateexternalfigure") end @@ -678,22 +814,29 @@ end function figures.checkers.mov(data) local dr, du, ds = data.request, data.used, data.status - dr.width = (dr.width or figures.defaultwidth):todimen() - dr.height = (dr.height or figures.defaultheight):todimen() - du.width = dr.width - du.height = dr.height - du.foundname = du.fullname - local code = backends.codeinjections.insertmovie { - width = du.width or dr.width, - height = du.height or dr.height, - factor = number.dimenfactors.bp, - ["repeat"] = dr["repeat"], - controls = dr.controls, - preview = dr.preview, - label = dr.label, - foundname = du.foundname, - } - texsprint(ctxcatcodes,format("\\startfoundexternalfigure{%ssp}{%ssp}%s\\stopfoundexternalfigure",du.width,du.height,code)) + local width = todimen(dr.width or figures.defaultwidth) + local height = todimen(dr.height or figures.defaultheight) + local foundname = du.fullname + dr.width, dr.height = width, height + du.width, du.height, du.foundname = width, height, foundname + if trace_inclusion then + logs.report("figures","including movie '%s': width %s, height %s",foundname,width,height) + end + -- we need to push the node.write in between ... we could make a shared helper for this + context.startfoundexternalfigure(width .. "sp",height .. "sp") + context(function() + backends.codeinjections.insertmovie { + width = width, + height = height, + factor = number.dimenfactors.bp, + ["repeat"] = dr["repeat"], + controls = dr.controls, + preview = dr.preview, + label = dr.label, + foundname = foundname, + } + end) + context.stopfoundexternalfigure() return data end @@ -750,27 +893,100 @@ function figures.checkers.tex(data) end figures.includers.tex = figures.includers.nongeneric --- -- -- eps -- -- -- +-- -- -- converters -- -- -- + +local function makeoptions(program) + local to = type(options) + return (to == "table" and concat(options," ")) or (to == "string" and options) or "" +end -function figures.converters.eps(oldname,newname) - -- hack, we need a lua based converter script, or better, we should use - -- rlx as alternative - local outputpath = file.dirname(newname) - local outputbase = file.basename(newname) - local command = format("mtxrun bin:pstopdf --outputpath=%s %s",outputpath,oldname) +local function runprogram(...) + local command = format(...) + if trace_conversion or trace_programs then + logs.report("figures","running %s",command) + end os.spawn(command) end -figures.converters.svg = figures.converters.eps +-- -- -- eps -- -- -- + +local epsconverter = { } +figures.converters.eps = epsconverter + +figures.programs.gs = { + options = { + "-dAutoRotatePages=/None", + "-dPDFSETTINGS=/prepress", + "-dEPSCrop", + }, + command = (os.type == "windows" and "gswin32") or "gs" +} + +function epsconverter.pdf(oldname,newname) + local gs = figures.programs.gs + runprogram ( + '%s -q -sDEVICE=pdfwrite -dNOPAUSE -dNOCACHE -dBATCH %s -sOutputFile="%s" "%s" -c quit', + gs.command, makeoptions(gs.options), newname, oldname + ) +end + +epsconverter.default = epsconverter.pdf + +-- -- -- svg -- -- -- --- -- -- lowres -- -- -- +local svgconverter = { } +figures.converters.svg = svgconverter +figures.converters.svgz = svgconverter ---~ function figures.converters.pdf(oldname,newname) ---~ local outputpath = file.dirname(newname) ---~ local outputbase = file.basename(newname) ---~ local command = format("mtxrun bin:pstopdf --method=4 --outputpath=%s %s",outputpath,oldname) ---~ os.spawn(command) ---~ end +-- inkscape on windows only works with complete paths + +figures.programs.inkscape = { + options = { + "--export-dpi=600" + }, + command = "inkscape" +} + +function svgconverter.pdf(oldname,newname) + local inkscape = figures.programs.inkscape + runprogram ( + '%s "%s" --export-pdf="%s" %s', + inkscape.command, oldname, newname, makeoptions(inkscape.options) + ) +end + +function svgconverter.png(oldname,newname) + local inkscape = figures.programs.inkscape + runprogram ( + '%s "%s" --export-png="%s" %s', + inkscape.command, oldname, newname, makeoptions(inkscape.options) + ) +end + +svgconverter.default = svgconverter.pdf + +-- -- -- gif -- -- -- + +local gifconverter = { } +figures.converters.gif = gifconverter + +figures.programs.convert = { + command = "convert" -- imagemagick +} + +function gifconverter.pdf(oldname,newname) + local convert = figures.programs.convert + runprogram ( + "convert %s %s", + convert.command, makeoptions(convert.options), oldname, newname + ) +end + +gifconverter.default = gifconverter.pdf + +-- todo: lowres + +-- -- -- bases -- -- -- figures.bases = { } figures.bases.list = { } -- index => { basename, fullname, xmlroot } @@ -782,10 +998,7 @@ local bases = figures.bases function bases.use(basename) if basename == "reset" then - bases.list = { } - bases.used = { } - bases.found = { } - bases.enabled = false + bases.list, bases.used, bases.found, bases.enabled = { }, { }, { }, false else basename = file.addsuffix(basename,"xml") if not bases.used[basename] then @@ -796,11 +1009,17 @@ function bases.use(basename) bases.enabled = true xml.registerns("rlx","http://www.pragma-ade.com/schemas/rlx") -- we should be able to do this per xml file end + if trace_bases then + commands.writestatus("figures","registering base '%s'",basename) + end end end end function bases.find(basename,askedlabel) + if trace_bases then + commands.writestatus("figures","checking for '%s' in base '%s'",askedlabel,basename) + end basename = file.addsuffix(basename,"xml") local t = bases.found[askedlabel] if t == nil then @@ -808,30 +1027,41 @@ function bases.find(basename,askedlabel) local page = 0 if base[2] == nil then -- no yet located - for _, path in ipairs(figures.paths) do + local figurepaths = figures.paths + for i=1,#figurepaths do + local path = figurepaths[i] local xmlfile = path .. "/" .. basename if io.exists(xmlfile) then base[2] = xmlfile base[3] = xml.load(xmlfile) + if trace_bases then + commands.writestatus("figures","base '%s' loaded",xmlfile) + end break end end end t = false if base[2] and base[3] then -- rlx:library - for e, d, k in xml.elements(base[3],"/(*:library|figurelibrary)/*:figure/*:label") do + for e in xml.collected(base[3],"/(*:library|figurelibrary)/*:figure/*:label") do page = page + 1 - if xml.content(d[k]) == askedlabel then + if xml.text(e) == askedlabel then t = { base = file.replacesuffix(base[2],"pdf"), format = "pdf", - name = xml.filters.text(e,"*:file"), + name = xml.text(e,"../*:file"), -- to be checked page = page, } bases.found[askedlabel] = t + if trace_bases then + commands.writestatus("figures","figure '%s' found in base '%s'",askedlabel,base[2]) + end return t end end + if trace_bases and not t then + commands.writestatus("figures","figure '%s' not found in base '%s'",askedlabel,base[2]) + end end end return t @@ -840,7 +1070,9 @@ end -- we can access sequential or by name function bases.locate(askedlabel) - for _, entry in ipairs(bases.list) do + local list = bases.list + for i=1,#list do + local entry = list[i] local t = bases.find(entry[1],askedlabel) if t then return t |