konv.py


1
#!/usr/bin/python3
2
3
import svgwrite    #muss man installieren
4
import string
5
6
infilename = 'lesbar.txt'
7
outfilename = 'bild.svg'
8
9
# hides the ugliness of svgwrite (inverted y)
10
class SvgSheet:
11
    def __init__(self, filename):
12
        self.xmin=-100
13
        self.xmax=1800
14
        self.ymin=-100
15
        self.ymax=800
16
        worldwidth=self.xmax-self.xmin
17
        worldheight=self.ymax-self.ymin
18
        paperwidth=15 #cm
19
        paperheight=10 #cm
20
        paperdims=("%fcm" % paperwidth, "%fcm" % paperheight)
21
        self.dwg = svgwrite.Drawing(filename=filename, debug=True, size = paperdims)
22
        self.dwg.viewbox(minx=self.xmin-1, miny=self.ymin-1, width=worldwidth+2, height=worldheight+2)
23
24
    def w2g(self, xy):
25
        return (xy[0], self.ymax -xy[1])
26
27
    def save_image(self):
28
        self.dwg.save()
29
30
    def line(self, a, b, color='gray', lw='0.5mm'):
31
        self.dwg.add(self.dwg.line(self.w2g(a), self.w2g(b),  stroke=color, fill='none', stroke_width=lw, stroke_linecap="round")   )
32
33
    def draw_text(self, p, text, color='orange'):
34
        self.dwg.add(self.dwg.text(text, insert=self.w2g(p), font_family="Courier New", font_size="28pt", fill=color))
35
36
#helper to save typing
37
def coords(params):
38
    return int(params[0]), int(params[1])
39
40
class PlotParser:
41
    def __init__(self, painter):
42
        self.painter = painter
43
        # internal state:
44
        self.cursor = (0, 0)
45
        self.color = 'black'   
46
        # map command names to functions:
47
        self.commands = dict()
48
        self.commands['SP'] = self.select_pen
49
        self.commands['DA'] = self.draw_absolute
50
        self.commands['MA'] = self.move_absolute
51
        self.commands['MR'] = self.move_relative
52
        self.commands['DR'] = self.draw_relative
53
        self.commands['LA'] = self.label
54
        self.commands['AX'] = self.axis # halb falsch
55
        #so sieht das bild halbwegs gut aus, die wahrheit ist sicher komplizierter:
56
        self.commands['OR'] = self.origin # unfug
57
        self.commands['HO'] = self.origin # horizontal_origin #unfug
58
59
    # internal functions for the plot commands
60
    def move_relative(self, params):
61
        dx, dy = coords(params)
62
        self.cursor = (self.cursor[0] + dx, self.cursor[1] + dy)
63
        
64
    def label(self, params):
65
        text = params[0]
66
        self.painter.draw_text(self.cursor, text, self.color)
67
68
    def move_absolute(self, params):
69
        x, y = coords(params)
70
        self.cursor =(x, y)
71
72
    def draw_absolute(self, params):
73
        x, y = coords(params)
74
        self.painter.line(self.cursor, (x, y), self.color)
75
        self.cursor = (x, y)
76
77
    def draw_relative(self, params):
78
        dx, dy = coords(params)
79
        x = self.cursor[0] + dx
80
        y = self.cursor[1] + dy
81
        self.painter.line(self.cursor, (x, y), self.color)
82
        self.cursor =(x, y)
83
84
    def origin(self, params):
85
        self.cursor = (0, 0)
86
        
87
    def horizontal_origin(self, params):
88
        self.cursor = (0, self.cursor[1])
89
90
91
#AX2,890,10,0,0,250,20,1
92
#AX3,1500,7,0,0,7000,20,0
93
#AX2,890,7,0,0,140,-20,1
94
95
    def axis(self, params):     #haesslich und falsch
96
        length = int(params[1])
97
        partitions = int(params[2]) # abzahl der ticks. das kommt ganz gut hin und gibt mit 
98
        max_val  = int(params[5])
99
        tick_offs = int(params[6]) 
100
        direction = int(params[7])
101
        x = self.cursor[0]
102
        y = self.cursor[1]
103
        if direction == 1: #up
104
            y = y + length
105
        elif direction == 0: #right
106
            x = x + length
107
        else:
108
            return
109
        value_step = max_val/partitions
110
        self.painter.line(self.cursor, (x, y), self.color)
111
        self.painter.draw_text((x, y), str(max_val), self.color)            
112
        #ticks:        
113
        if direction == 1: #up
114
            i = 0
115
            while i <= partitions:
116
                ty = self.cursor[1] + i/partitions * (y - self.cursor[1])
117
                self.painter.line((x + tick_offs, ty), (x, ty), self.color)
118
                self.painter.draw_text((x, ty), str(int(i/partitions * max_val)), self.color)
119
                i = i + 1
120
        elif direction == 0: #right
121
           i = 0
122
           while i <= partitions:
123
                tx = self.cursor[0] + i/partitions * (x - self.cursor[0])
124
                self.painter.line((tx, y + tick_offs), (tx, y), self.color)
125
                self.painter.draw_text((tx, y), str(int(i/partitions * max_val)), self.color)
126
                i = i + 1
127
        self.cursor = (x,y)
128
129
    def select_pen(self, params):
130
        pen_num = int(params[0])
131
        colors = {1: 'blue', 2: 'red', 3: 'black', 4: 'green'}
132
        self.color = colors[pen_num]
133
134
    def unknown(self, command, params):
135
        print("unknown command %s(%s)" %(command, ','.join(params)))
136
137
    def interpret(self, s):
138
        if len(s) < 2:
139
            print('ignoring "%s"' % s)
140
            return
141
        command = s[0:2]
142
        params = s[2:].split(',')
143
        if command in self.commands:
144
            self.commands[command](params)
145
        else:
146
            self.unknown(command, params)
147
          
148
    def finish(self):
149
        self.painter.save_image()
150
151
152
if __name__ == '__main__':
153
    paper = SvgSheet(outfilename)
154
    printer = PlotParser(paper)
155
 
156
    infile = open(infilename, 'r')
157
    
158
    #nur die zeilen ab der zeile mit GRC
159
    graphics_begun = False
160
    for li in infile.readlines():
161
        line = ''.join(filter(lambda x: x in string.printable, li.strip())) # ugly: remove nonprintable chars
162
        if not graphics_begun:
163
            if 'GRC' in line:
164
                graphics_begun = True
165
        if graphics_begun:
166
            printer.interpret(line)
167
    printer.finish()