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_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 findfile = resolvers.findfile
324
325 local function profiles()
326 if not isfile(rgbprofile) then
327 local found = findfile(rgbprofile)
328 if not found or found == "" then
329 found = findfile("colo-imp-"..rgbprofile)
330 end
331 if found and found ~= "" then
332 rgbprofile = found
333 else
334 report_figures("unknown profile %a",rgbprofile)
335 end
336 end
337 if not isfile(cmykprofile) then
338 local found = resolvers.findfile(cmykprofile)
339 if not found or found == "" then
340 found = findfile("colo-imp-"..cmykprofile)
341 end
342 if found and found ~= "" then
343 cmykprofile = found
344 else
345 report_figures("unknown profile %a",cmykprofile)
346 end
347 end
348 return rgbprofile, cmykprofile
349 end
350
351 local checkers = {
352 oldname = "readable",
353 newname = "writable",
354 rgbprofile = "string",
355 cmykprofile = "string",
356 resolution = "string",
357 color = "string",
358 }
359
360 local defaults = {
361 resolution = "600",
362 }
363
364 local pngtocmykpdf = sandbox.registerrunner {
365 name = "png to cmyk pdf",
366 program = "gm",
367 template = [[convert -compress Zip -strip +profile "*" -profile %rgbprofile% -profile %cmykprofile% -sampling-factor 1x1 %oldname% %newname%]],
368 checkers = checkers,
369 defaults = defaults,
370 }
371
372 local jpgtocmykpdf = sandbox.registerrunner {
373 name = "jpg to cmyk pdf",
374 program = "gm",
375 template = [[convert -compress JPEG -strip +profile "*" -profile %rgbprofile% -profile %cmykprofile% -sampling-factor 1x1 %oldname% %newname%]],
376 checkers = checkers,
377 defaults = defaults,
378 }
379
380 local pngtograypdf = sandbox.registerrunner {
381 name = "png 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 local jpgtograypdf = sandbox.registerrunner {
389 name = "jpg to gray pdf",
390 program = "gm",
391 template = [[convert -colorspace gray -compress Zip -sampling-factor 1x1 %oldname% %newname%]],
392 checkers = checkers,
393 defaults = defaults,
394 }
395
396 programs.pngtocmykpdf = { runner = pngtocmykpdf }
397 programs.jpgtocmykpdf = { runner = jpgtocmykpdf }
398 programs.pngtograypdf = { runner = pngtograypdf }
399 programs.jpgtograypdf = { runner = jpgtograypdf }
400
401 pngconverters["cmyk.pdf"] = function(oldname,newname,resolution)
402 local rgbprofile, cmykprofile = profiles()
403 pngtocmykpdf {
404 oldname = oldname,
405 newname = newname,
406 rgbprofile = rgbprofile,
407 cmykprofile = cmykprofile,
408 resolution = resolution,
409 }
410 end
411
412 pngconverters["gray.pdf"] = function(oldname,newname,resolution)
413 pngtograypdf {
414 oldname = oldname,
415 newname = newname,
416 resolution = resolution,
417 }
418 end
419
420 jpgconverters["cmyk.pdf"] = function(oldname,newname,resolution)
421 local rgbprofile, cmykprofile = profiles()
422 jpgtocmykpdf {
423 oldname = oldname,
424 newname = newname,
425 rgbprofile = rgbprofile,
426 cmykprofile = cmykprofile,
427 resolution = resolution,
428 }
429 end
430
431 jpgconverters["gray.pdf"] = function(oldname,newname,resolution)
432 jpgtograypdf {
433 oldname = oldname,
434 newname = newname,
435 resolution = resolution,
436 }
437 end
438
439
440
441 local recolorpng = sandbox.registerrunner {
442 name = "recolor png",
443 program = "gm",
444 template = [[convert -recolor %color% %oldname% %newname%]],
445 checkers = checkers,
446 defaults = defaults,
447 }
448
449
450
451 programs.recolor = { runner = recolorpng }
452
453 pngconverters["recolor.png"] = function(oldname,newname,resolution,arguments)
454 recolorpng {
455 oldname = oldname,
456 newname = newname,
457 resolution = resolution,
458 color = arguments or ".5 0 0 .7 0 0 .9 0 0",
459 }
460 end
461
462end
463
464if CONTEXTLMTXMODE > 0 then
465
466
467
468
469 local function remap(specification)
470 local fullname = specification.fullname
471 if fullname then
472 local only = file.nameonly(fullname)
473 local name = formatters["svg-%s-inclusion"](only)
474 local code = formatters["\\includesvgfile[%s]\\resetbuffer[%s]"](fullname,name)
475 buffers.assign(name,code)
476 specification.format = "buffer"
477 specification.fullname = name
478 end
479 return specification
480 end
481
482 figures.remappers.svg = { mp = remap }
483
484end
485 |