1if not modules then modules = { } end modules ['grph-con'] = {
2 version = 1.001,
3 comment = "companion to grph-inc.mkiv",
4 author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
5 copyright = "PRAGMA ADE / ConTeXt Development Team",
6 license = "see context related readme files"
7}
8
9local P, R, S, Cc, C, Cs, Ct, lpegmatch = lpeg.P, lpeg.R, lpeg.S, lpeg.Cc, lpeg.C, lpeg.Cs, lpeg.Ct, lpeg.match
10
11local tonumber = tonumber
12local find = string.find
13local longtostring = string.longtostring
14local formatters = string.formatters
15local expandfilename = dir.expandname
16local isfile = lfs.isfile
17
18local settings_to_array = utilities.parsers.settings_to_array
19local settings_to_hash = utilities.parsers.settings_to_hash
20local allocate = utilities.storage.allocate
21local setmetatableindex = table.setmetatableindex
22
23local codeinjections = backends.codeinjections
24local nodeinjections = backends.nodeinjections
25
26local report_figures = logs.reporter("system","graphics")
27
28local variables = interfaces.variables
29local v_high = variables.high
30local v_low = variables.low
31local v_medium = variables.medium
32local v_yes = variables.yes
33
34local figures = figures
35
36local converters = figures.converters
37local programs = figures.programs
38
39local runprogram = programs.run
40
41do
42
43
44
45
46
47
48
49 local epsconverter = converters.eps
50 converters.ps = epsconverter
51
52 local function gscrop(specification)
53 return (specification and specification.crop == v_yes) and "-dEPSCrop" or ""
54 end
55
56 local resolutions = {
57 [v_low] = "screen",
58 [v_medium] = "ebook",
59 [v_high] = "prepress",
60 }
61
62 local runner = sandbox.registerrunner {
63 name = "eps to pdf",
64 program = {
65 windows = os.platform == "win64" and "gswin64c" or "gswin32c",
66 unix = "gs",
67 },
68 template = longtostring [[
69 -q
70 -sDEVICE=pdfwrite
71 -dNOPAUSE
72 -dNOCACHE
73 -dBATCH
74 -dAutoRotatePages=/None
75 -dPDFSETTINGS=/%presets%
76 %crop%
77 -dCompatibilityLevel=%level%
78 -sOutputFile=%newname%
79 %colorspace%
80 %oldname%
81 -c quit
82 ]],
83 checkers = {
84 oldname = "readable",
85 newname = "writable",
86 presets = "string",
87 level = "string",
88 colorspace = "string",
89
90 },
91 }
92
93 programs.epstopdf = { resolutions = epstopdf, runner = runner }
94 programs.gs = programs.epstopdf
95
96 local cleanups = { }
97 local cleaners = { }
98
99 local whitespace = lpeg.patterns.whitespace
100 local quadruple = Ct((whitespace^0 * lpeg.patterns.number/tonumber * whitespace^0)^4)
101 local betterbox = P("%%BoundingBox:") * quadruple
102 * P("%%HiResBoundingBox:") * quadruple
103 * P("%AI3_Cropmarks:") * quadruple
104 * P("%%CropBox:") * quadruple
105 / function(b,h,m,c)
106 return formatters["%%%%BoundingBox: %r %r %r %r\n%%%%HiResBoundingBox: %F %F %F %F\n%%%%CropBox: %F %F %F %F\n"](
107 m[1],m[2],m[3],m[4],
108 m[1],m[2],m[3],m[4],
109 m[1],m[2],m[3],m[4]
110 )
111 end
112 local nocrap = P("%") / "" * (
113 (P("AI9_PrivateDataBegin") * P(1)^0) / "%%%%EOF"
114 + (P("%EOF") * whitespace^0 * P("%AI9_PrintingDataEnd") * P(1)^0) / "%%%%EOF"
115 + (P("AI7_Thumbnail") * (1-P("%%EndData"))^0 * P("%%EndData")) / ""
116 )
117 local whatever = nocrap + P(1)
118 local pattern = Cs((betterbox * whatever^1 + whatever)^1)
119
120 directives.register("graphics.conversion.eps.cleanup.ai",function(v) cleanups.ai = v end)
121
122 cleaners.ai = function(name)
123 local tmpname = name .. ".tmp"
124 io.savedata(tmpname,lpegmatch(pattern,io.loaddata(name) or ""))
125 return tmpname
126 end
127
128 function epsconverter.pdf(oldname,newname,resolution,colorspace,specification)
129 local presets = resolutions[resolution or "high"] or resolutions.high
130 local level = codeinjections.getformatoption("pdf_level") or "1.3"
131 local tmpname = oldname
132 if not tmpname or tmpname == "" or not isfile(tmpname) then
133 return
134 end
135 if cleanups.ai then
136 tmpname = cleaners.ai(oldname)
137 end
138 if colorspace == "gray" then
139 colorspace = "-sColorConversionStrategy=Gray -sProcessColorModel=DeviceGray"
140
141 else
142 colorspace = nil
143 end
144 runner {
145 newname = newname,
146 oldname = tmpname,
147 presets = presets,
148 level = tostring(level),
149 colorspace = colorspace,
150 crop = gscrop(specification),
151 }
152 if tmpname ~= oldname then
153 os.remove(tmpname)
154 end
155 end
156
157 epsconverter["gray.pdf"] = function(oldname,newname,resolution,_,specification)
158 epsconverter.pdf(oldname,newname,resolution,"gray")
159 end
160
161 epsconverter.default = epsconverter.pdf
162
163end
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
196do
197
198 local svgconverter = converters.svg
199 converters.svgz = svgconverter
200
201
202
203
204
205
206
207
208
209
210
211 local new = nil
212
213 local function inkscapeformat(suffix)
214 if new == nil then
215 new = os.resultof("inkscape --version") or ""
216 new = new == "" or not find(new,"Inkscape%s*0")
217 end
218 return new and "filename" or suffix
219 end
220
221 local function inkscapecrop(specification)
222 return (specification and specification.crop == v_yes) and "--export-area-drawing" or ""
223 end
224
225 local runner = sandbox.registerrunner {
226 name = "svg to something",
227 program = "inkscape",
228 template = longtostring [[
229 %oldname%
230 %crop%
231 --export-dpi=%resolution%
232 --export-%format%=%newname%
233 ]],
234 checkers = {
235 oldname = "readable",
236 newname = "writable",
237 format = "string",
238 resolution = "string",
239 },
240 defaults = {
241 format = "pdf",
242 resolution = "600",
243 }
244 }
245
246 programs.inkscape = {
247 runner = runner,
248 }
249
250 function svgconverter.pdf(oldname,newname,resolution,arguments,specification)
251 runner {
252 format = inkscapeformat("pdf"),
253 resolution = "600",
254 crop = inkscapecrop(specification),
255 newname = expandfilename(newname),
256 oldname = expandfilename(oldname),
257 }
258 end
259
260 function svgconverter.png(oldname,newname)
261 runner {
262 format = inkscapeformat("png"),
263 resolution = "600",
264 crop = inkscapecrop(specification),
265 newname = expandfilename(newname),
266 oldname = expandfilename(oldname),
267 }
268 end
269
270 svgconverter.default = svgconverter.pdf
271
272end
273
274do
275
276 local gifconverter = converters.gif
277 local tifconverter = converters.tif
278 local bmpconverter = converters.bmp
279
280 programs.convert = {
281 command = "gm",
282 argument = [[convert "%oldname%" "%newname%"]],
283 }
284
285 local function converter(oldname,newname)
286 local convert = programs.convert
287 runprogram(convert.command, convert.argument, {
288 newname = newname,
289 oldname = oldname,
290 } )
291 end
292
293 tifconverter.pdf = converter
294 gifconverter.pdf = converter
295 bmpconverter.pdf = converter
296
297 gifconverter.default = converter
298 tifconverter.default = converter
299 bmpconverter.default = converter
300
301end
302
303do
304
305
306
307
308
309
310
311
312
313
314 local rgbprofile = "srgb_v4_icc_preference.icc"
315 local cmykprofile = "isocoated_v2_300_eci.icc"
316
317 directives.register("graphics.conversion.rgbprofile", function(v) rgbprofile = type(v) == "string" and v or rgbprofile end)
318 directives.register("graphics.conversion.cmykprofile",function(v) cmykprofile = type(v) == "string" and v or cmykprofile end)
319
320 local jpgconverters = converters.jpg
321 local pngconverters = converters.png
322
323 local function profiles()
324 if not isfile(rgbprofile) then
325 local found = resolvers.findfile(rgbprofile)
326 if found and found ~= "" then
327 rgbprofile = found
328 else
329 report_figures("unknown profile %a",rgbprofile)
330 end
331 end
332 if not isfile(cmykprofile) then
333 local found = resolvers.findfile(cmykprofile)
334 if found and found ~= "" then
335 cmykprofile = found
336 else
337 report_figures("unknown profile %a",cmykprofile)
338 end
339 end
340 return rgbprofile, cmykprofile
341 end
342
343 local checkers = {
344 oldname = "readable",
345 newname = "writable",
346 rgbprofile = "string",
347 cmykprofile = "string",
348 resolution = "string",
349 color = "string",
350 }
351
352 local defaults = {
353 resolution = "600",
354 }
355
356 local pngtocmykpdf = sandbox.registerrunner {
357 name = "png to cmyk pdf",
358 program = "gm",
359 template = [[convert -compress Zip -strip +profile "*" -profile %rgbprofile% -profile %cmykprofile% -sampling-factor 1x1 %oldname% %newname%]],
360 checkers = checkers,
361 defaults = defaults,
362 }
363
364 local jpgtocmykpdf = sandbox.registerrunner {
365 name = "jpg to cmyk pdf",
366 program = "gm",
367 template = [[convert -compress JPEG -strip +profile "*" -profile %rgbprofile% -profile %cmykprofile% -sampling-factor 1x1 %oldname% %newname%]],
368 checkers = checkers,
369 defaults = defaults,
370 }
371
372 local pngtograypdf = sandbox.registerrunner {
373 name = "png to gray pdf",
374 program = "gm",
375 template = [[convert -colorspace gray -compress Zip -sampling-factor 1x1 %oldname% %newname%]],
376 checkers = checkers,
377 defaults = defaults,
378 }
379
380 local jpgtograypdf = sandbox.registerrunner {
381 name = "jpg to gray pdf",
382 program = "gm",
383 template = [[convert -colorspace gray -compress Zip -sampling-factor 1x1 %oldname% %newname%]],
384 checkers = checkers,
385 defaults = defaults,
386 }
387
388 programs.pngtocmykpdf = { runner = pngtocmykpdf }
389 programs.jpgtocmykpdf = { runner = jpgtocmykpdf }
390 programs.pngtograypdf = { runner = pngtograypdf }
391 programs.jpgtograypdf = { runner = jpgtograypdf }
392
393 pngconverters["cmyk.pdf"] = function(oldname,newname,resolution)
394 local rgbprofile, cmykprofile = profiles()
395 pngtocmykpdf {
396 oldname = oldname,
397 newname = newname,
398 rgbprofile = rgbprofile,
399 cmykprofile = cmykprofile,
400 resolution = resolution,
401 }
402 end
403
404 pngconverters["gray.pdf"] = function(oldname,newname,resolution)
405 pngtograypdf {
406 oldname = oldname,
407 newname = newname,
408 resolution = resolution,
409 }
410 end
411
412 jpgconverters["cmyk.pdf"] = function(oldname,newname,resolution)
413 local rgbprofile, cmykprofile = profiles()
414 jpgtocmykpdf {
415 oldname = oldname,
416 newname = newname,
417 rgbprofile = rgbprofile,
418 cmykprofile = cmykprofile,
419 resolution = resolution,
420 }
421 end
422
423 jpgconverters["gray.pdf"] = function(oldname,newname,resolution)
424 jpgtograypdf {
425 oldname = oldname,
426 newname = newname,
427 resolution = resolution,
428 }
429 end
430
431
432
433 local recolorpng = sandbox.registerrunner {
434 name = "recolor png",
435 program = "gm",
436 template = [[convert -recolor %color% %oldname% %newname%]],
437 checkers = checkers,
438 defaults = defaults,
439 }
440
441
442
443 programs.recolor = { runner = recolorpng }
444
445 pngconverters["recolor.png"] = function(oldname,newname,resolution,arguments)
446 recolorpng {
447 oldname = oldname,
448 newname = newname,
449 resolution = resolution,
450 color = arguments or ".5 0 0 .7 0 0 .9 0 0",
451 }
452 end
453
454end
455
456if CONTEXTLMTXMODE > 0 then
457
458
459
460
461 local function remap(specification)
462 local fullname = specification.fullname
463 if fullname then
464 local only = file.nameonly(fullname)
465 local name = formatters["svg-%s-inclusion"](only)
466 local code = formatters["\\includesvgfile[%s]\\resetbuffer[%s]"](fullname,name)
467 buffers.assign(name,code)
468 specification.format = "buffer"
469 specification.fullname = name
470 end
471 return specification
472 end
473
474 figures.remappers.svg = { mp = remap }
475
476end
477 |