File: tcl2py.py

package info (click to toggle)
vtk7 7.1.1%2Bdfsg2-8
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 127,396 kB
  • sloc: cpp: 1,539,584; ansic: 124,382; python: 78,038; tcl: 47,013; xml: 8,142; yacc: 5,040; java: 4,439; perl: 3,132; lex: 1,926; sh: 1,500; makefile: 126; objc: 83
file content (247 lines) | stat: -rwxr-xr-x 8,336 bytes parent folder | download | duplicates (19)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
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
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
#!/usr/bin/env python
#
# tcl2py.py - try to Pythonize a vtk tcl script
#
# This code is based on tcl2py.py from VTK 3.2 which was written by
# Randy Heiland.
#
# Changes:
#
#  (21/12/2002) -- Prabhu Ramachandran
#  Made to work with re instead of regex.  Superficial cleanup of the
#  code, fixed a few issues, using new VTK package structure, added
#  support for VTK_DATA_ROOT and set keyword, primitive support for
#  expr, made code easier to run with usage message etc.  Seems to
#  generate decent output now.  Simple Tcl scripts work out of the
#  box!  Complex ones need work.  For a truly general solution the
#  code has to be rewritten.
#

import sys
import string
import re


def scanner(name,function):
    file = open(name,'r')
    while 1:
        line = file.readline()
        if not line: break
        function(line)
    file.close()


def processLine(line, output, keepTcl=1):
    line = string.strip(line) + "\n"
    if line[0] == '#':
        output.write(line)
    elif line[:15] == 'package require':
        if keepTcl == 1:
            output.write('# ' + line)
    elif string.find(line, "deiconify") > -1:
        output.write('# ' + line)
    else:
        if keepTcl == 1:
            output.write('#' + line)

        if string.find(line, 'expr') > -1:
            match = re.search("\[\s*expr ([^\]]+)\]", line).groups()[0]
            match = re.sub('\s+', '', match)
            line = re.sub("\[\s*expr ([^\]]+)\]", match, line)
        line = re.sub('\[','',line)
        line = re.sub('\]','',line)
        line = re.sub('ren1','ren',line)
        line = re.sub(';','\n',line)
        line = re.sub('\$','',line)
        line = re.sub('{',' ',line)
        line = re.sub('}',' ',line)

        n = len(line)

        keys = string.split(line)

        # handle set keyword.
        inSet = 0
        if len(keys) and keys[0] == 'set':
            output.write(keys[1] + ' = ')
            keys = keys[2:]
            inSet = 1

        keysLength = len(keys)

        inaModule = 0
        inaForLoop = 0
        if keysLength == 0:
            output.write(line)
        # Catch some tcl-specific keywords and comment out
        elif keys[0] == 'proc':
            inaModule = 0
            output.write( 'def ' + keys[1] + '(')
            if len(keys) > 2:
                output.write(keys[2])
                for i in range(3,len(keys)):
                    output.write(', ' + keys[i])
            output.write('):\n')
        elif keys[0] == 'catch':
            output.write( '#' + line)
        elif keys[0] == 'source':
            output.write( '#' + line)
            if re.search("colors.tcl",line) > -1:
                output.write("from colors import *")
        elif keys[0] == 'wm':
            output.write( '#' + line)
        elif keysLength > 1 and keys[1] == 'SetUserMethod':
            if keepTcl == 1:
                output.write( '#' + line)
        elif keys[0] == 'for' and keys[1]=='set':
            inaForLoop = 1
            #print '...Handling for loop'
            output.write( "for " + keys[2] + " in range(" + keys[3] +", ")
            upper = keys[6]
            if keys[5] == "<=":
                output.write( upper + "+1):\n" )
            else:
                output.write( upper + "):\n" )

        # Detect vtk class instance; Pythonize it.
        elif line[:3] == 'vtk':
            output.write( keys[1] + ' = vtk.' + keys[0] + '()\n' )
        else:
            lparen = 0
            finishedFlag = 0
            # for i in range(len(keys)-1):
            for i in range(len(keys)):
                ls = len(keys[i])
                if keys[i] == 'eval':
                    continue
                # continuation mark
                elif keys[i] == '\\':
                    output.write( "  \\\n")
                elif keys[i][-8:] == 'FileName':
                    if keys[i+1][0:1] == '"':
                        f_name = re.sub('"VTK_DATA_ROOT/', \
                                        'VTK_DATA_ROOT + "/', keys[i+1])
                        output.write( keys[i] + "(" + f_name + ")")
                    else:
                        f_name = re.sub('VTK_DATA_ROOT/', \
                                        'VTK_DATA_ROOT + "/', keys[i+1])
                        if f_name[:13] == 'VTK_DATA_ROOT':
                            output.write(keys[i] + "(" + f_name + "\")")
                        else:
                            output.write( keys[i] + "(\"" + keys[i+1] + "\")")
                    finishedFlag = 1
                    break
                elif keys[i] == 'SetColor':
                    #print '...doing SetColor'
                    #print keys
                    if not re.search('[-\d.]', keys[i+1][0:1]):
                        #print '...got a named color'
                        color = keys[i+1][0:]
                        #print 'color = ' + color
                        output.write( "SetColor(" + color+"[0]," + \
                        color+"[1]," + color+"[2])" )
                    else:
                        output.write( "SetColor("+keys[i+1]+", "+keys[i+2]+", "+keys[i+3]+")")
                    finishedFlag = 1
                    break
                elif keys[i][:3]=='Set' or keys[i][:3]=='Add' or keys[i][:6]=='Insert':
                    output.write( keys[i] + '(' )
                    lparen = 1
                elif i < len(keys)-1 and \
                                re.search('[-\d.]', keys[i+1][0:1]) and \
                not re.search('[-\d.]', keys[i][ls-1:ls]):
                    output.write( keys[i] + '(' )
                    lparen = 1
                elif keys[i][:3] == 'Get':
                    output.write( keys[i] + '()' )
                    if i < len(keys)-1:
                        output.write( '.' )
                else:
                    if i < len(keys)-1:
                        npos = re.search("[-\d.]", keys[i][0:1])
                        if npos > -1 or keys[i][0:3] == 'VTK':
                            output.write( keys[i] + ', ' )
                        else:
                            output.write( keys[i] + '.' )
                    else:
                        if inaModule == 1:
                            output.write( '\t' )
                        output.write( keys[i] )

            if finishedFlag == 0:
                if keys[-1][:3] != 'Get' and \
                   (not  re.search("[-+\d.]", keys[-1])):
                    if lparen == 0:
                        output.write( '(' )
                        lparen = 1
            else:
                output.write( '\n' )

            # Terminating right paren.
            #output.write( ')\n' )

            if lparen == 1:
                output.write( ')\n' )
            if inSet == 1:
                output.write( '\n' )


def usage():
    msg = """Usage:\n  tcl2py.py script.tcl [keep_tcl_code]\n
This script attempts to convert a VTK-Tcl script to Python.
The converted code is printed on the standard output.

Options:

  keep_tcl_code -- If 1 it keeps the original tcl code
                   in a commented line.  If zero it does not print
                   the translated Tcl line.  Defaults to 1.

Example:

 $ ./tcl2py.py example.tcl 0 > example.py
"""
    print msg


def main():
    global keepTcl
    if len(sys.argv) < 2:
        usage()
        sys.exit(1)

    keepTcl = 1
    if len(sys.argv) > 2:
        try:
            keepTcl = int(sys.argv[2])
        except ValueError:
            usage()
            print "Second argument must be 0 or 1."
            sys.exit(1)

    name = sys.argv[1]
    output = sys.stdout
    if name[-4:] == '.tcl':
        input = open(name, 'r')
        #output = open(name[:-4] + '.py', 'w')
    else:
        input = open(name + '.tcl', 'r')
        #output = open(name + '.py', 'w')

    # Standard stuff; import useful things and handle VTK_DATA_ROOT.
    output.write('#!/usr/bin/env python\n')
    output.write('\nimport vtk\n')
    output.write('from vtk.util.misc import vtkGetDataRoot\n')
    output.write('VTK_DATA_ROOT = vtkGetDataRoot()\n\n')

    for line in input.readlines():
        processLine(line, output, keepTcl)
    input.close()

    output.write('iren.Initialize()\nrenWin.Render()\niren.Start()\n')
    output.close()


if __name__ == "__main__":
    main()