Pml2py: Difference between revisions
Jump to navigation
Jump to search
(parse list arguments) |
(use pymol.parsing module) |
||
Line 5: | Line 5: | ||
<source lang="python"> | <source lang="python"> | ||
import sys | import sys | ||
from pymol import cmd | from pymol import cmd, parsing | ||
def pml2py(filename, out=sys.stdout): | def pml2py(filename, out=sys.stdout): | ||
Line 19: | Line 19: | ||
TODO | TODO | ||
comments, aliases | comments, aliases, multiple commands in one line | ||
''' | ''' | ||
def quote(args): | def quote(args): | ||
Line 30: | Line 30: | ||
prefix += '=' | prefix += '=' | ||
arg = arg.lstrip() | arg = arg.lstrip() | ||
yield prefix + repr(arg) | yield prefix + repr(arg) | ||
Line 47: | Line 41: | ||
''' % (filename) | ''' % (filename) | ||
handle = iter(open(filename)) | handle = iter(open(filename, 'rU')) | ||
for line in handle: | for line in handle: | ||
while line.endswith('\\\n'): | while line.endswith('\\\n'): | ||
Line 53: | Line 47: | ||
a = line.split(None, 1) | a = line.split(None, 1) | ||
if len(a) > 1 and a[0] == '_': | |||
line = a[1] | |||
a = line.split(None, 1) | |||
try: | try: | ||
name = a[0] | name = a[0] | ||
Line 59: | Line 57: | ||
raise | raise | ||
name = cmd.kwhash.shortcut.get(name, name) | name = cmd.kwhash.shortcut.get(name, name) | ||
kw = cmd.keyword[name] | |||
assert kw[4] != parsing.PYTHON | |||
func = kw[0] | |||
except: | except: | ||
out.write(line) | out.write(line) | ||
continue | |||
# PyMOL stuff without named python function | |||
if func.__name__ == '<lambda>' or name.startswith('@'): | |||
print >> out, 'cmd.do(%s)' % (repr(line.strip())) | |||
continue | continue | ||
if | # code blocks | ||
if name == 'python': | |||
for line in handle: | |||
if line.split() == ['python', 'end']: | |||
break | |||
out.write(line) | |||
continue | |||
if name == 'skip': | |||
for line in handle: | |||
if line.split() == ['skip', 'end']: | |||
break | |||
continue | continue | ||
# split args | |||
tok = ',' | |||
if kw[4] == parsing.MOVIE: | |||
tok = kw[3] | |||
split_mx = 1 | |||
else: | |||
split_mx = kw[4] - parsing.LITERAL | |||
if len(a) > 1: | if len(a) > 1: | ||
args = [i.strip() for i in a[1] | if split_mx == 0: | ||
args = [a[1]] | |||
else: | |||
args = [i.strip() for i in parsing.split(a[1], tok, max(0, split_mx))] | |||
else: | else: | ||
args = [] | args = [] | ||
# old syntax: set property=value | # old syntax: set property=value | ||
if | if kw[4] == parsing.LEGACY and '=' in args[0]: | ||
args = [i.strip() for i in args[0].split('=', 1)] + args[1:] | args = [i.strip() for i in args[0].split('=', 1)] + args[1:] | ||
# use 'cmd' module if possible | # use 'cmd' module if possible |
Revision as of 10:29, 20 May 2011
This script converts a pml script to a python script.
See pymol-users mailing list (Subject: Convert pml script to Pymol Python script, Fri, 8 Apr 2011).
import sys
from pymol import cmd, parsing
def pml2py(filename, out=sys.stdout):
'''
DESCRIPTION
Convert a pml script to python syntax.
USAGE
pml2py infile [, outfile]
TODO
comments, aliases, multiple commands in one line
'''
def quote(args):
args = iter(args)
for arg in args:
if '=' not in arg:
prefix = ''
else:
prefix, arg = arg.split('=', 1)
prefix += '='
arg = arg.lstrip()
yield prefix + repr(arg)
if isinstance(out, basestring):
out = open(out, 'w')
print >> out, '''
# automatically converted from "%s"
import pymol
from pymol import *
''' % (filename)
handle = iter(open(filename, 'rU'))
for line in handle:
while line.endswith('\\\n'):
line = line[:-2] + handle.next()
a = line.split(None, 1)
if len(a) > 1 and a[0] == '_':
line = a[1]
a = line.split(None, 1)
try:
name = a[0]
if name.startswith('/'):
line = line.lstrip()[1:]
raise
name = cmd.kwhash.shortcut.get(name, name)
kw = cmd.keyword[name]
assert kw[4] != parsing.PYTHON
func = kw[0]
except:
out.write(line)
continue
# PyMOL stuff without named python function
if func.__name__ == '<lambda>' or name.startswith('@'):
print >> out, 'cmd.do(%s)' % (repr(line.strip()))
continue
# code blocks
if name == 'python':
for line in handle:
if line.split() == ['python', 'end']:
break
out.write(line)
continue
if name == 'skip':
for line in handle:
if line.split() == ['skip', 'end']:
break
continue
# split args
tok = ','
if kw[4] == parsing.MOVIE:
tok = kw[3]
split_mx = 1
else:
split_mx = kw[4] - parsing.LITERAL
if len(a) > 1:
if split_mx == 0:
args = [a[1]]
else:
args = [i.strip() for i in parsing.split(a[1], tok, max(0, split_mx))]
else:
args = []
# old syntax: set property=value
if kw[4] == parsing.LEGACY and '=' in args[0]:
args = [i.strip() for i in args[0].split('=', 1)] + args[1:]
# use 'cmd' module if possible
try:
test = getattr(cmd, func.__name__)
assert func == test
module = 'cmd'
except:
module = func.__module__
print >> out, '%s.%s(%s)' % (module, func.__name__, ', '.join(quote(args)))
cmd.extend('pml2py', pml2py)
# vi:expandtab:smarttab