1if not modules then modules = { } end modules [ ' util-lib-imp-gs ' ] = {
2 version = 1 . 001 ,
3 comment = " a mkiv swiglib module " ,
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 insert = table . insert
10local formatters = string . formatters
11
12local ghostscript = utilities . ghostscript or { }
13utilities . ghostscript = ghostscript
14
15local report_gs = logs . reporter ( " swiglib ghostscript " )
16
17local gs = swiglib ( " ghostscript.core " )
18local helpers = swiglib ( " helpers.core " )
19
20if gs then
21 report_gs ( " library loaded " )
22
23else
24 return
25end
26
27
28
29local function luatable_to_c_array ( t )
30 local gsargv = helpers . new_char_p_array ( # t )
31 for i = 1 , # t do
32 helpers . char_p_array_setitem ( gsargv , i -1 , t [ i ] )
33 end
34 return gsargv
35end
36
37
38
39local interface = { }
40ghostscript . interface = interface
41
42function interface . new ( )
43
44 local instance = helpers . new_void_p_p ( )
45 local result = gs . gsapi_new_instance ( instance , nil )
46 local buffer = nil
47 local object = { }
48
49 local function reader ( instance , str , len )
50 return 0
51 end
52
53 local function writer ( instance , str , len )
54 if buffer then
55 str = buffer . . str
56 buffer = nil
57 end
58 if not string . find ( str , " [\n\r]$ " ) then
59 str , buffer = string . match ( str , " (.-)([^\n\r]+)$ " )
60 end
61 local log = object . log
62 for s in string . gmatch ( str , " [^\n\r]+ " ) do
63 insert ( log , s )
64 report_gs ( s )
65 end
66 return len
67 end
68
69 if result < 0 then
70 return nil
71 else
72 local job = helpers . void_p_p_value ( instance )
73 gs . gsapi_set_stdio_callback ( job , reader , writer , writer )
74 object . instance = instance
75 object . job = job
76 object . result = 0
77 object . log = { }
78 return object
79 end
80end
81
82function interface . dispose ( run )
83 if run . job then
84 gs . gsapi_delete_instance ( run . job )
85 run . job = nil
86 end
87 if run . instance then
88 helpers . delete_void_p_p ( run . instance )
89 run . instance = nil
90 end
91end
92
93function interface . init ( run , options )
94 if run . job then
95 if not options then
96 options = { " ps2pdf " }
97 else
98 insert ( options , 1 , " ps2pdf " )
99 end
100 run . log = { }
101 local ct = luatable_to_c_array ( options )
102 local result = gs . gsapi_init_with_args ( run . job , # options , ct )
103 helpers . delete_char_p_array ( ct )
104 run . initresult = result
105 return result > = 0
106 end
107end
108
109function interface . exit ( run )
110 if run . job then
111 local result = gs . gsapi_exit ( run . job )
112 if run . initresult = = 0 or run . initresult = = gs . e_Quit then
113 run . result = result
114 end
115 run . exitresult = result
116 return run . result > = 0
117 end
118end
119
120function interface . process ( run , options )
121 interface . init ( run , options )
122 return interface . exit ( run )
123end
124
125
126
127local nofruns = 0
128
129function ghostscript . convert ( specification )
130
131 nofruns = nofruns + 1
132 statistics . starttiming ( ghostscript )
133
134 local inputname = specification . inputname
135 if not inputname or inputname = = " " then
136 report_gs ( " invalid run %s, no inputname specified " , nofruns )
137 statistics . stoptiming ( ghostscript )
138 return false
139 end
140 local outputname = specification . outputname
141 if not outputname or outputname = = " " then
142 outputname = file . replacesuffix ( inputname , " pdf " )
143 end
144
145 if not lfs . isfile ( inputname ) then
146 report_gs ( " invalid run %s, input file %a is not found " , nofruns , inputname )
147 statistics . stoptiming ( ghostscript )
148 return false
149 end
150
151 local device = specification . device
152 if not device or device = = " " then
153 device = " pdfwrite "
154 end
155
156 local code = specification . code
157 if not code or code = = " " then
158 code = " .setpdfwrite "
159 end
160
161 local run = interface . new ( )
162 if gsinstance then
163 report_gs ( " invalid run %s, initialization error " , nofruns )
164 statistics . stoptiming ( ghostscript )
165 return false
166 end
167
168 local options = specification . options or { }
169
170 insert ( options , " -dNOPAUSE " )
171 insert ( options , " -dBATCH " )
172 insert ( options , " -dSAFER " )
173 insert ( options , formatters [ " -sDEVICE=%s " ] ( device ) )
174 insert ( options , formatters [ " -sOutputFile=%s " ] ( outputname ) )
175 insert ( options , " -c " )
176 insert ( options , code )
177 insert ( options , " -f " )
178 insert ( options , inputname )
179
180 report_gs ( " run %s, input file %a, outputfile %a " , nofruns , inputname , outputname )
181 report_gs ( " " )
182 local okay = interface . process ( run , options )
183 report_gs ( " " )
184
185 interface . dispose ( run )
186
187 statistics . stoptiming ( ghostscript )
188 if okay then
189 return outputname
190 else
191 report_gs ( " run %s quit with errors " , nofruns )
192 return false
193 end
194end
195
196function ghostscript . statistics ( report )
197 local runtime = statistics . elapsedtime ( ghostscript )
198 if report then
199 report_gs ( " nofruns %s, runtime %s " , nofruns , runtime )
200 else
201 return {
202 runtime = runtime ,
203 nofruns = nofruns ,
204 }
205 end
206end
207
208
209
210
211
212
213 |