Pml2py

From PyMOLWiki
Revision as of 14:22, 9 April 2011 by Speleo3 (talk | contribs) (parse list arguments)
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

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

def pml2py(filename, out=sys.stdout):
    '''
DESCRIPTION

    Convert a pml script to python syntax.

USAGE

    pml2py infile [, outfile]

TODO

    comments, aliases
    '''
    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()
            if arg.startswith('['):
                while not arg.endswith(']'):
                    arg += ',' + args.next()
            elif arg.startswith('('):
                while not arg.endswith(')'):
                    arg += ',' + args.next()
            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))
    for line in handle:
        while line.endswith('\\\n'):
            line = line[:-2] + handle.next()

        a = line.split(None, 1)
        try:
            name = a[0]
            if name.startswith('/'):
                line = line.lstrip()[1:]
                raise
            name = cmd.kwhash.shortcut.get(name, name)
            func = cmd.keyword[name][0]
            assert func.__name__ != 'python_help'
        except:
            out.write(line)
            continue

        if func.__name__ == '<lambda>':
            print >> out, 'cmd.do(%s)' % (repr(line.strip()))
            continue

        if len(a) > 1:
            args = [i.strip() for i in a[1].split(',')]
        else:
            args = []

        # old syntax: set property=value
        if name in ['set', 'set_color'] and '=' in args[0]:
            args = [i.strip() for i in args[0].split('=', 1)] + args[1:]

        if name == 'python':
            for line in handle:
                if line.split() == ['python', 'end']:
                    break
                out.write(line)
            continue

        # 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