sawsim/methods.tex: Tighten 'A short chain' -> 'Short chains'
[thesis.git] / site_cons / site_tools / pymol.py
1 import os.path
2 import re
3 import SCons.Action
4 import SCons.Scanner
5 import SCons.Script
6 import SCons.Util
7 import doctest
8
9
10 load_re = re.compile(r"^load (.*)")
11
12
13 def pymol_scan(node, env, path, arg=None):
14     """
15     >>> this_dir = os.path.dirname(__file__)
16     >>> src_dir = os.path.join(this_dir, '..', '..', 'src')
17     >>> class node (object):
18     ...     def __init__(self, path):
19     ...         self.path = path
20     ...         self.abspath = os.path.abspath(self.path)
21     ...         if os.path.isfile(self.path):
22     ...             self.dir = node(os.path.dirname(path))
23     ...     def get_text_contents(self):
24     ...         return open(self.path, 'r').read()
25     ...     def get_contents(self):
26     ...         return self.get_text_contents()
27     ...     def srcnode(self):
28     ...         return self
29     >>> for p in pymol_scan(
30     ...         node(os.path.join(src_dir, 'figures', 'i27', '1TIT.pml')),
31     ...         None, None, None):
32     ...     print p
33     1TIT.pdb
34     """
35     try:
36         contents = node.get_text_contents()
37     except AttributeError:
38         contents = node.get_contents() # for older versions of SCons, fall back on binary read
39     ret = []
40     for string in load_re.findall(contents):
41         p = os.path.join(node.dir.srcnode().abspath, string)
42         if len(string) > 0 and (string not in ret and os.path.exists(p)):
43             ret.append(string)
44     return ret
45
46
47 PymolAction = None
48
49 def generate(env):
50     """Add Builders and construction variables for Pymol to an Environment."""
51     global PymolAction
52     if PymolAction is None:
53         PymolAction = SCons.Action.Action(
54             '$PYMOLCOM', '$PYMOLCOMSTR')
55
56     env['BUILDERS']['Pymol'] = SCons.Script.Builder(
57         action=PymolAction, suffix='.png', src_suffix = '.pml')
58     env['PYMOL'] = 'pymol'
59     env['PYMOLFLAGS'] = '-cq'
60     env['PYMOLCOM'] = 'cd ${TARGET.dir} && $PYMOL $PYMOLFLAGS ${SOURCE.file}'
61     env.Append(SCANNERS=SCons.Scanner.Base(
62             function=pymol_scan,
63             name='pymol',
64             skeys=['.pml']))
65
66 def exists(env):
67     return env.Detect('pymol')
68
69 if __name__ == '__main__':
70     doctest.testmod()