--- ../MoinGraphViz-1.0rc4/wiki/data/plugin/parser/MoinGraphViz/main.py	2009-05-22 12:22:34.000000000 +0800
+++ wiki/data/plugin/parser/MoinGraphViz/main.py	2010-10-27 17:10:58.236666657 +0800
@@ -46,6 +46,12 @@
 
 #UID = 'BB962F5E-DB8E-424C-8E4D-D2B53286D6F3'
 
+class GraphvizRenderError(Exception):
+    pass
+
+class GraphvizSyntaxError(GraphvizRenderError):
+    pass
+
 class Parser:
     """
     MoinMoin GraphViz parser.
@@ -62,14 +68,21 @@
         self.renderer = Renderer(tool, targetdir=p.getPagePath('attachments'), encoding=config.charset)
 
     def format(self, formatter):
-        w = self.request.write
-        ##w('<div style="border:3px ridge gray; padding:5px; width:95%; overflow:auto">')
-        s = self.renderer.render(self.raw)
-        fmt = moinVersion >= (1,6) and '{{attachment:%s}}' or 'attachment:%s'
+        append_text = ''
+        try:
+            s = self.renderer.render(self.raw)
+        except GraphvizSyntaxError, e:
+            s = e.imagefilename
+            #eliminate source path in the error message, which annoys users 
+            append_text = "{{{%s}}}" % str(e).replace(e.dotfilename, "")
+        except GraphvizRenderError, e:
+            self.request.write("<strong class=\"error\">GraphViz: </strong><pre>%s</pre>" % e)
+            return
+        fmt = '{{attachment:%s}}' if moinVersion >= (1,6) else 'attachment:%s'
+        fmt += append_text
         s = wiki2html(self.request, fmt % os.path.basename(s))
-        if DEBUG: print '[TRACE] attachment URL:', s
-        w(s)
-        ##w('</div>')
+        if DEBUG: print '[TRACE] attachment html:', s
+        self.request.write(s)
 
 
 def parseArguments(s):
@@ -105,6 +118,7 @@
 import sys
 import sha
 import string
+from subprocess import Popen, PIPE
 
 try: __file = __file__
 except NameError: __file = sys.argv[0]
@@ -160,6 +174,7 @@
         imagefilename = 'graphviz-%s-%s.%s' % (gname, uid, self.format)
         imagefilename = os.path.join(self.targetdir, imagefilename)
         ##if DEBUG: print '[TRACE] imagefilename:', imagefilename
+
         if not os.path.isfile(imagefilename):
             if DEBUG: print '[TRACE] creating graph image:', imagefilename
             dotfilename = '%s-%s.%s' % ('graph', uid, 'graphviz.txt')
@@ -167,6 +182,15 @@
             fwrite(dotfilename, script)
             try:
                 renderGraphImage(self.toolpath, self.format, imagefilename, dotfilename)
+            except GraphvizRenderError, e:
+                if os.path.exists(imagefilename):
+                    #imagefilename exists means nothing terriblely happeded,
+                    #just little cases about dot syntax. 
+                    if DEBUG: print "[TRACE] Syntax Error"
+                    e = GraphvizSyntaxError(e)
+                    e.imagefilename = imagefilename
+                    e.dotfilename = dotfilename
+                raise e
             finally:
                 os.remove(dotfilename)
         return imagefilename
@@ -176,20 +200,23 @@
         ##return string.Template(script.strip()).safe_substitute(vars(Snippets)) # for syntax $name
         v =  vars(Snippets)
         s = string.Template(script.strip() % v).safe_substitute(v) # for both syntaxes
+
         # the following is a hint from an anonimous user, the purpose of which I do not quite
         # understand yet. it should fix a "unicode problem", but it is unclear what the problem
         # actually is and how it occurs. I'll take the patch in just in case, in the hope that
         # it really fixes something and someone can explain what that something is. -- ZI, 2008-04-20
-        ##return unicode(s).encode(self.encoding) 
-        return s
+        return unicode(s).encode(self.encoding) 
+        #return s
 
     def hashFor(self, content):
         return sha.new(content).hexdigest()
 
 def graphName(script):
     ##m = re.match(r'^(?:\n|\s)*(?:di)?graph\s*(\w*)', script) # allows spaces but no comments at beginning of script
-    m = re.search(r'^(?:di)?graph\s*(\w*)', script, re.M)
-    assert m, 'Could not derive graph name from graph script. Check the syntax, please!'
+    m = re.search(r'^(?:di)?graph\s+(\w*)', script, re.M)
+    if m is None:
+        raise GraphvizRenderError( \
+                "Could not derive graph name from graph script. Check the syntax, please!")
     return m.group(1)
 
 def renderGraphImage(tool, format, imagefilename, dotfilename):
@@ -220,17 +247,15 @@
 
 def oscmd(cmd):
     '''instead of simply calling os.system(cmd)
-    capture stderr and raise os.error if exit code != 0
+    capture stderr and raise GraphvizRenderError if exit code != 0
     '''
-    err = 'Unknown OS error'
-    w, r, e = os.popen3(cmd)
-    try:
-        err = e.read()
-        out = r.read()
-        ##return out, err
-    finally:
-        for f in w, r, e: xc = f.close()
-        if xc: raise os.error, err
+    p = Popen(cmd, stdout=PIPE, stderr=PIPE, shell=True, 
+            bufsize=1024, close_fds=True)
+    stdo, stde = p.communicate()
+
+    if p.returncode != 0:
+        raise GraphvizRenderError("%s\n%s" % (stdo, stde))
+
 
 ######################################################################
 ## 
