Subversion Repositories configs

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
192 - 1
#!/usr/libexec/platform-python
2
 
3
import os, sys, subprocess
4
from optparse import *
5
 
6
__AUTHOR__ = "Gouichi Iisaka <iisaka51@gmail.com>"
7
__VERSION__ = '1.1.4'
8
 
9
class EApp(Exception):
10
    '''Application specific exception.'''
11
    pass
12
 
13
class Application():
14
    '''
15
NAME
16
    graphviz2png - Converts textual graphviz notation to PNG file
17
 
18
SYNOPSIS
19
    graphviz2png [options] INFILE
20
 
21
DESCRIPTION
22
    This filter reads Graphviz notation text from the input file
23
    INFILE (or stdin if INFILE is -), converts it to a PNG image file.
24
 
25
 
26
OPTIONS
27
    -o OUTFILE, --outfile=OUTFILE
28
        The file name of the output file. If not specified the output file is
29
        named like INFILE but with a .png file name extension.
30
 
31
    -L LAYOUT, --layout=LAYOUT
32
        Graphviz layout: dot, neato, twopi, circo, fdp
33
        Default is 'dot'.
34
 
35
    -F FORMAT, --format=FORMAT
36
        Graphviz output format: png, svg, or any other format Graphviz
37
        supports. Run dot -T? to get the full list.
38
        Default is 'png'.
39
 
40
    -v, --verbose
41
        Verbosely print processing information to stderr.
42
 
43
    -h, --help
44
        Print this documentation.
45
 
46
    -V, --version
47
        Print program version number.
48
 
49
SEE ALSO
50
    graphviz(1)
51
 
52
AUTHOR
53
    Written by Gouichi Iisaka, <iisaka51@gmail.com>
54
    Format support added by Elmo Todurov, <todurov@gmail.com>
55
 
56
THANKS
57
    Stuart Rackham, <srackham@gmail.com>
58
    This script was inspired by his music2png.py and AsciiDoc
59
 
60
LICENSE
61
    Copyright (C) 2008-2009 Gouichi Iisaka.
62
    Free use of this software is granted under the terms of
63
    the GNU General Public License (GPL).
64
    '''
65
 
66
    def __init__(self, argv=None):
67
        # Run dot, get the list of supported formats. It's prefixed by some junk.
68
        format_output = subprocess.Popen(["dot", "-T?"], stderr=subprocess.PIPE, stdout=subprocess.PIPE).communicate()[1].decode('utf-8')
69
        # The junk contains : and ends with :. So we split it, then strip the final endline, then split the list for future usage.
70
        supported_formats = format_output.split(": ")[2][:-1].split(" ")
71
 
72
        if not argv:
73
            argv = sys.argv
74
 
75
        self.usage = '%prog [options] inputfile'
76
        self.version = 'Version: %s\n' % __VERSION__
77
        self.version += 'Copyright(c) 2008-2009: %s\n' % __AUTHOR__
78
 
79
        self.option_list = [
80
            Option("-o", "--outfile", action="store",
81
                dest="outfile",
82
                help="Output file"),
83
            Option("-L", "--layout", action="store",
84
                dest="layout", default="dot", type="choice",
85
                choices=['dot','neato','twopi','circo','fdp'],
86
                help="Layout type. LAYOUT=<dot|neato|twopi|circo|fdp>"),
87
            Option("-F", "--format", action="store",
88
                dest="format", default="png", type="choice",
89
                choices=supported_formats,
90
                help="Format type. FORMAT=<" + "|".join(supported_formats) + ">"),
91
            Option("--debug", action="store_true",
92
                dest="do_debug",
93
                help=SUPPRESS_HELP),
94
            Option("-v", "--verbose", action="store_true",
95
                dest="do_verbose", default=False,
96
                help="verbose output"),
97
            ]
98
 
99
        self.parser = OptionParser( usage=self.usage, version=self.version,
100
                                    option_list=self.option_list)
101
        (self.options, self.args) = self.parser.parse_args()
102
 
103
        if len(self.args) != 1:
104
            self.parser.print_help()
105
            sys.exit(1)
106
 
107
        self.options.infile = self.args[0]
108
 
109
    def systemcmd(self, cmd):
110
        if self.options.do_verbose:
111
            msg = 'Execute: %s' % cmd
112
            sys.stderr.write(msg + os.linesep)
113
        else:
114
            cmd += ' 2>%s' % os.devnull
115
        if os.system(cmd):
116
            raise EApp('failed command: %s' % cmd)
117
 
118
    def graphviz2png(self, infile, outfile):
119
        '''Convert Graphviz notation in file infile to
120
           PNG file named outfile.'''
121
 
122
        outfile = os.path.abspath(outfile)
123
        outdir = os.path.dirname(outfile)
124
 
125
        if not os.path.isdir(outdir):
126
            raise EApp('directory does not exist: %s' % outdir)
127
 
128
        basefile = os.path.splitext(outfile)[0]
129
        saved_cwd = os.getcwd()
130
        os.chdir(outdir)
131
        try:
132
            cmd = '%s -T%s "%s" > "%s"' % (
133
                  self.options.layout, self.options.format, infile, outfile)
134
            self.systemcmd(cmd)
135
        finally:
136
            os.chdir(saved_cwd)
137
 
138
        if not self.options.do_debug:
139
            os.unlink(infile)
140
 
141
    def run(self):
142
        if self.options.format == '':
143
            self.options.format = 'png'
144
 
145
        if self.options.infile == '-':
146
            if self.options.outfile is None:
147
                sys.stderr.write('OUTFILE must be specified')
148
                sys.exit(1)
149
            infile = os.path.splitext(self.options.outfile)[0] + '.txt'
150
            lines = sys.stdin.readlines()
151
            open(infile, 'w').writelines(lines)
152
 
153
        if not os.path.isfile(infile):
154
            raise EApp('input file does not exist: %s' % infile)
155
 
156
        if self.options.outfile is None:
157
            outfile = os.path.splitext(infile)[0] + '.png'
158
        else:
159
            outfile = self.options.outfile
160
 
161
        self.graphviz2png(infile, outfile)
162
 
163
        # To suppress asciidoc 'no output from filter' warnings.
164
        if self.options.infile == '-':
165
            sys.stdout.write(' ')
166
 
167
if __name__ == "__main__":
168
    app = Application()
169
    app.run()