hpgl_parser.py

changeset 18
c691b040e8c9
child 19
42af82fdb8bb
equal deleted inserted replaced
17:fb8aa055f6e4 18:c691b040e8c9
1 # -*- coding: utf-8 -*-
2
3 import re
4 import numpy
5
6 vsplitter = re.compile('[ ,]')
7 vextractor = re.compile('(?P<value>[^;\n\r\aA-DF-Za-df-z]*?)(?P<terminator>[;\n\r\a]+)', re.S+re.M)
8
9 class HPGLParser(object):
10 def __init__(self, data):
11 self.data = data
12 self.idx = 0
13 self.str_terminator = chr(0x03)
14
15 self.IN()
16
17 while self.idx<len(data):
18 while data[self.idx] in [';','\n','\r', '\a', ' ']:
19 self.idx += 1
20 if data[self.idx] == chr(0x03):
21 self.ESC()
22 else:
23 cmd = data[self.idx: self.idx+2]
24 self.idx += 2
25 getattr(self, cmd)()
26 while self.idx<len(data) and data[self.idx] in [';','\n','\r', '\a', ' ']:
27 self.idx += 1
28
29 def user_to_abs(self, pos):
30 """
31 converts a position (x, y) given in user units to absolute
32 units
33 """
34 return pos #TODO
35
36 def extract_value(self, raw=False):
37 m = vextractor.match(self.data[self.idx:])
38 if m:
39 val = m.group("value")
40 self.idx = self.idx + len(val) + len(m.group("terminator"))
41 val = vsplitter.split(val)
42 if not raw:
43 val = [eval(x) for x in val if x.strip()]
44 return val
45 return []
46
47 def extract_string(self):
48 idx2 = self.data.find(self.str_terminator, self.idx)
49 val = self.data[self.idx: idx2]
50 self.idx = idx2+1
51 return val
52
53 def polyline(self, values):
54 if (len(values)%2) == 1:
55 # this is a syntax error in the HPGL data
56 values = values[:-1]
57 values = numpy.array(values).reshape(-1, 2)
58 # TODO use scaling
59 # do plots
60 values = numpy.r_[[self.pos], values] #add self.pos as 1st value
61 if self.plot_mode == 'relative':
62 values = values.cumsum(axis=0)
63 if self.symbol_mode:
64 self.plot_symbols(values[1:])
65 if self.pen_state == "down":
66 self.plot_lines(values)
67 self.pos = values[-1]
68
69 def get_window_for_paper(self):
70 return 0,100,0,100
71 def get_scaling_points_for_paper(self):
72 return 0,100,0,100
73
74 # effective plot methods; to be defined in subclasses (backends)
75 def plot_symbols(self, points):
76 pass
77 def plot_lines(self, points):
78 pass
79
80 # HPGL-related methods
81 def ESC(self):
82 print "ESC"
83 self.idx += 1
84
85 def OE(self):
86 """ Output Error """
87 pass
88
89 def EC(self):
90 """? what's this """
91 values = self.extract_value()
92
93 def OO(self):
94 """idem"""
95 pass
96
97 def OP(self):
98 """idem"""
99 pass
100
101 def VS(self):
102 """idem"""
103 pass
104
105
106 def DF(self):
107 """ Default """
108 self.pen = 0
109 self.pos = 0,0
110 self.char_set = "std"
111 self.plot_mode = 'absolute'
112 self.char_direction = 1,0
113 self.line_type = 0 # 'solid'
114 self.pattern_len = 4 #percentage
115 self.window = self.get_window_for_paper()
116 self.char_size = 0.75, 1.5 #percentages
117 self.symbol_mode = False
118 self.tick_len = 0.5, 0.5 # %
119 self.std_char_set = 0
120 self.alt_char_set = 0
121 self.selected_char_set = 0
122 self.char_slant = 0 # degrees
123 self.scale = None
124 self.str_terminator = chr(0x03)
125 self.chord_ang = 5 #degrees
126 self.fill_type = 'bidirectionnal', 1
127 self.fill_distance = 1 # %
128 self.fill_slant = 0 # degrees
129 self.pen_thickness = 0.3 # mm
130
131 def IN(self):
132 """ Initialize """
133 self.DF()
134 self.pen_state = "up"
135 self.rotation = 0 #degrees
136 self.scaling_points = self.get_scaling_points_for_paper()
137
138 def IP(self):
139 """ Input Scale Point"""
140 values = self.extract_value()
141 if len(values) == 0:
142 self.scaling_points = self.get_scaling_points_for_paper()
143 elif len(values) == 2:
144 p1x, p1y, p2x, p2y = self.scaling_points
145 dx, dy = p2x-p1x, p2y-p1y
146 x, y = values
147 self.scaling = (x, y, x+dx, y+dy)
148 elif len(values) == 4:
149 self.values = tuple(values)
150
151 def SC(self):
152 """ Scale """
153 values = self.extract_value()
154 if len(values) == 4:
155 self.scale = tuple(values)
156 else:
157 self.scale = None
158
159 def IW(self):
160 values = self.extract_value()
161 if len(values) == 0:
162 self.window = self.get_window_for_paper()
163 elif len(value) == 4:
164 self.window = tuple(values)
165
166 def RO(self):
167 values = self.extract_value()
168 if len(values) == 0:
169 self.rotation = 0
170 elif len(values) == 1:
171 self.rotation = values[0]
172
173 def PG(self):
174 pass
175
176 def PU(self):
177 """ Pen Up"""
178 self.pen_state = "up"
179 values = self.extract_value()
180 self.polyline(values)
181
182 def PD(self):
183 """ Pen Down """
184 self.pen_state = "down"
185 values = self.extract_value()
186 self.polyline(values)
187
188 def PA(self):
189 """ Plot Absolute """
190 self.plot_mode = "absolute"
191 values = self.extract_value()
192 self.polyline(values)
193
194 def PR(self):
195 """ Plot Relative """
196 self.plot_mode = "relative"
197 values = self.extract_value()
198 self.polyline(values)
199
200 def AA(self):
201 """ Arc Absolute """
202 values = self.extract_value()
203 if len(values) in [3, 4]:
204 x, y, qc = values[:3]
205 if len(values)==4:
206 qd = values[-1]
207 else:
208 qd = self.chord_ang
209 # TODO : plot arc
210 print "plotting an arc"
211 def AR(self):
212 """ Arc Relative """
213 values = self.extract_value()
214 # TODO
215
216 def CI(self):
217 """ Circle Plot"""
218 values = self.extract_value()
219 # TODO
220
221 def EA(self):
222 """Edge Rectangle Absolute"""
223 values = self.extract_value()
224 # TODO
225
226 def ER(self):
227 """Edge Rectangle Relative"""
228 values = self.extract_value()
229 # TODO
230
231 def EW(self):
232 """ Edge Wedge """
233 values = self.extract_value()
234 # TODO
235
236 def RA(self):
237 """ Fill Rectangle Absolute """
238 values = self.extract_value()
239 # TODO
240
241 def RR(self):
242 """ Fill Rectangle Relative """
243 values = self.extract_value()
244 # TODO
245
246 def WG(self):
247 """ Fill Wedge """
248 values = self.extract_value()
249 # TODO
250
251 def FT(self):
252 """ Fill Type """
253 values = self.extract_value()
254 # TODO
255
256 def LT(self):
257 """ Line Type """
258 values = self.extract_value()
259
260 if len(values)==0:
261 self.line_type = 0 #'solid'
262 else:
263 self.line_type = values[0]
264 if len(values)>1:
265 self.pattern_len = values[1]
266
267 def PW(self):
268 """ Pen Width """
269 values = self.extract_value()
270 if len(values) == 1:
271 self.pen_thickness = values[0]
272
273 def SM(self):
274 """ Symbol Mode """
275 values = self.extract_value()
276 if len(values) == 0:
277 self.symbol_mode = False
278 elif len(values) == 1:
279 self.symbol_mode = values[0]
280
281 def SP(self):
282 """ Select Pen """
283 values = self.extract_value()
284 if len(values) == 1:
285 self.pen = values[0]
286
287 def TL(self):
288 """ Tick Len """
289 values = self.extract_value()
290 # TODO
291
292 def XT(self):
293 """ X-axis Tick """
294 # TODO
295 print "X ticks"
296
297 def YT(self):
298 """ X-axis Tick """
299 # TODO
300 print "Y ticks"
301
302 def PT(self):
303 """ Pen Thickness Select """
304 values = self.extract_value()
305 if len(values) == 0:
306 self.pen_thickness = 0.3
307 elif len(values) == 1:
308 self.pen_thickness = values[0]
309
310 def CS(self):
311 """ Standard Character Set """
312 values = self.extract_value()
313 if len(values) == 0:
314 self.std_char_set = 0
315 elif len(values) == 1:
316 self.std_char_set = values[0]
317
318 def CA(self):
319 """ Alternate Character Set """
320 values = self.extract_value()
321 if len(values) == 0:
322 self.alt_char_set = 0
323 elif len(values) == 1:
324 self.alt_char_set = values[0]
325
326 def SS(self):
327 """ Select Standard Character Set """
328 self.char_set = "std"
329
330 def SA(self):
331 """ Select Alternate Character Set """
332 self.char_set = "alt"
333
334 def DT(self):
335 """ Define Label Terminator """
336 values = self.extract_value(raw=True)
337 if len(values) == 0:
338 self.str_terminator = chr(0x03)
339 elif len(values) == 1:
340 self.str_terminator = values[0]
341
342 def LB(self):
343 """ Character Plot """
344 values = self.extract_string()
345 # TODO
346
347 def DI(self):
348 """ Absolute Direction """
349 values = self.extract_value()
350 if len(values) == 0:
351 self.char_direction = 1.0, 0.0
352 elif len(values) == 2:
353 self.char_direction = values
354
355 def DR(self):
356 """ Relative Direction """
357 values = self.extract_value()
358 if len(values) == 0:
359 self.char_direction = 1.0, 0.0
360 elif len(values) == 2:
361 # TODO : compute as percentages
362 self.char_direction = values
363
364 def CP(self):
365 """ Character Plot """
366 values = self.extract_value()
367 # TODO
368 if len(values) == 0:
369 values = 0, -1
370 #if len(values) == 2:
371 # self.pos =
372
373 def SI(self):
374 """ Set Absolute Character Size """
375 values = self.extract_value()
376 self.char_size = "absolute"
377 if len(values) == 0:
378 self.char_width = 0.1879
379 self.char_height = 0.2690
380 elif len(values) == 2:
381 self.char_width, self.char_height = values
382
383 def SR(self):
384 """ Set Relative Character Size """
385 values = self.extract_value()
386 self.char_size = "relative"
387 if len(values) == 0:
388 self.char_width = 0.75
389 self.char_height = 1.5
390 elif len(values) == 2:
391 self.char_width, self.char_height = values
392
393 def SL(self):
394 """ Character Slant """
395 values = self.extract_value()
396 # TODO
397
398 def UC(self):
399 """ User Defined Character """
400 values = self.extract_value()
401 # TODO
402
403 if __name__ == '__main__':
404 import sys
405 data = open(sys.argv[1]).read()
406
407 p = HPGLParser(data)
408

mercurial