mtx-convert.lua /size: 6064 b    last modification: 2020-07-01 14:35
1if not modules then modules = { } end modules ['mtx-convert'] = {
2    version   = 1.001,
3    comment   = "companion to mtxrun.lua",
4    author    = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
5    copyright = "PRAGMA ADE / ConTeXt Development Team",
6    license   = "see context related readme files"
7}
8
9-- todo: eps and svg
10
11local helpinfo = [[
12<?xml version="1.0"?>
13<application>
14 <metadata>
15  <entry name="name">mtx-convert</entry>
16  <entry name="detail">ConTeXT Graphic Conversion Helpers</entry>
17  <entry name="version">0.10</entry>
18 </metadata>
19 <flags>
20  <category name="basic">
21   <subcategory>
22    <flag name="convertall"><short>convert all graphics on path</short></flag>
23    <flag name="inputpath" value="string"><short>original graphics path</short></flag>
24    <flag name="outputpath" value="string"><short>converted graphics path</short></flag>
25    <flag name="watch"><short>watch folders</short></flag>
26    <flag name="force"><short>force conversion (even if older)</short></flag>
27    <flag name="delay"><short>time between sweeps</short></flag>
28   </subcategory>
29  </category>
30 </flags>
31</application>
32]]
33
34local application = logs.application {
35    name     = "mtx-convert",
36    banner   = "ConTeXT Graphic Conversion Helpers 0.10",
37    helpinfo = helpinfo,
38}
39
40local format, find = string.format, string.find
41local concat = table.concat
42
43local report = application.report
44
45scripts              = scripts or { }
46scripts.convert      = scripts.convert or { }
47local convert        = scripts.convert
48convert.converters   = convert.converters or { }
49local converters     = convert.converters
50
51local gsprogram      = (os.type == "windows" and (os.which("gswin64c.exe") or os.which("gswin32c.exe"))) or "gs"
52
53if string.find(gsprogram," ") then
54    -- c:/program files/...../gswinNNc.exe"
55    gsprogram = '"' .. gsprogram .. '"'
56end
57
58local gstemplate_eps = "%s -q -sDEVICE=pdfwrite -dPDFSETTINGS=/prepress -dEPSCrop -dNOPAUSE -dSAFER -dNOCACHE -dBATCH -dAutoRotatePages=/None -dProcessColorModel=/DeviceCMYK -sOutputFile=%s %s -c quit"
59local gstemplate_ps  = "%s -q -sDEVICE=pdfwrite -dPDFSETTINGS=/prepress -dNOPAUSE -dSAFER -dNOCACHE -dBATCH -dAutoRotatePages=/None -dProcessColorModel=/DeviceCMYK -sOutputFile=%s %s -c quit"
60
61function converters.eps(oldname,newname)
62    return format(gstemplate_eps,gsprogram,newname,oldname)
63end
64
65function converters.ps(oldname,newname)
66    return format(gstemplate_ps,gsprogram,newname,oldname)
67end
68
69local improgram  = "convert"
70local imtemplate = {
71    low    = "%s -quality   0 -compress zip %s pdf:%s",
72    medium = "%s -quality  75 -compress zip %s pdf:%s",
73    high   = "%s -quality 100 -compress zip %s pdf:%s",
74}
75
76function converters.jpg(oldname,newname)
77    local ea = environment.arguments
78    local quality = (ea.high and 'high') or (ea.medium and 'medium') or (ea.low and 'low') or 'high'
79    return format(imtemplate[quality],improgram,oldname,newname)
80end
81
82converters.gif  = converters.jpg
83converters.tif  = converters.jpg
84converters.tiff = converters.jpg
85converters.png  = converters.jpg
86
87function converters.convertgraphic(kind,oldname,newname)
88    if converters[kind] then -- extra test
89        local tmpname = file.replacesuffix(newname,"tmp")
90        local command = converters[kind](oldname,tmpname)
91        report("command: %s",command)
92        io.flush()
93        os.execute(command)
94        os.remove(newname)
95        os.rename(tmpname,newname)
96        if lfs.attributes(newname,"size") == 0 then
97            os.remove(newname)
98        end
99    end
100end
101
102function converters.convertpath(inputpath,outputpath)
103    inputpath  = inputpath  or "."
104    outputpath = outputpath or "."
105    for name in lfs.dir(inputpath) do
106        local suffix = file.suffix(name)
107        if find(name,"%.$") then
108            -- skip . and ..
109        elseif converters[suffix] then
110            local oldname = file.join(inputpath,name)
111            local newname = file.join(outputpath,file.replacesuffix(name,"pdf"))
112            local et = lfs.attributes(oldname,"modification")
113            local pt = lfs.attributes(newname,"modification")
114            if not pt or et > pt then
115                dir.mkdirs(outputpath)
116                converters.convertgraphic(suffix,oldname,newname)
117            end
118        elseif lfs.isdir(inputpath .. "/".. name) then
119            converters.convertpath(inputpath .. "/".. name,outputpath .. "/".. name)
120        end
121    end
122end
123
124function converters.convertfile(oldname)
125    local suffix = file.suffix(oldname)
126    if converters[suffix] then
127        local newname = file.replacesuffix(oldname,"pdf")
128        if oldname == newname then
129            -- todo: downsample, crop etc
130        elseif environment.argument("force") then
131            converters.convertgraphic(suffix,oldname,newname)
132        else
133            local et = lfs.attributes(oldname,"modification")
134            local pt = lfs.attributes(newname,"modification")
135            if not pt or et > pt then
136                converters.convertgraphic(suffix,oldname,newname)
137            end
138        end
139    end
140end
141
142if environment.ownscript then
143    -- stand alone
144else
145    report(application.banner)
146    return convert
147end
148
149convert.delay = 5 * 60 -- 5 minutes
150
151function convert.convertall()
152    local watch  = environment.arguments.watch      or false
153    local delay  = environment.arguments.delay      or convert.delay
154    local input  = environment.arguments.inputpath  or "."
155    local output = environment.arguments.outputpath or "."
156    while true do
157        converters.convertpath(input, output)
158        if watch then
159            os.sleep(delay)
160        else
161            break
162        end
163    end
164end
165
166function convert.convertgiven()
167    local files = environment.files
168    for i=1,#files do
169        converters.convertfile(files[i])
170    end
171end
172
173if environment.arguments.convertall then
174    convert.convertall()
175elseif environment.files[1] then
176    convert.convertgiven()
177elseif environment.argument("exporthelp") then
178    application.export(environment.argument("exporthelp"),environment.files[1])
179else
180    application.help()
181end
182