msgenator.py
Go to the documentation of this file.
00001 # Software License Agreement (BSD License)
00002 #
00003 # Copyright (c) 2009, Willow Garage, Inc.
00004 # All rights reserved.
00005 #
00006 # Redistribution and use in source and binary forms, with or without
00007 # modification, are permitted provided that the following conditions
00008 # are met:
00009 #
00010 #  * Redistributions of source code must retain the above copyright
00011 #    notice, this list of conditions and the following disclaimer.
00012 #  * Redistributions in binary form must reproduce the above
00013 #    copyright notice, this list of conditions and the following
00014 #    disclaimer in the documentation and/or other materials provided
00015 #    with the distribution.
00016 #  * Neither the name of Willow Garage, Inc. nor the names of its
00017 #    contributors may be used to endorse or promote products derived
00018 #    from this software without specific prior written permission.
00019 #
00020 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00021 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00022 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00023 # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00024 # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00025 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00026 # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00027 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00028 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00029 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00030 # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00031 # POSSIBILITY OF SUCH DAMAGE.
00032 #
00033 # Revision $Id$
00034 # $Author$
00035 
00036 import cStringIO
00037 import os
00038 import sys
00039 import time
00040 
00041 import roslib.msgs
00042 import roslib.srvs
00043 import roslib.stacks
00044 
00045 from roslib.msgs import msg_file
00046 from roslib.srvs import srv_file
00047 
00048 from rosdoc.rdcore import *
00049 import rosmsg
00050 
00051 msg_template = load_tmpl('msg.template')
00052 msg_index_template = load_tmpl('msg-index.template')
00053 
00054 def _href(link, text):
00055     return '<a href="%(link)s">%(text)s</a>'%locals()
00056 
00057 def type_link(type_, base_package):
00058     base_type = roslib.msgs.base_msg_type(type_)
00059     base_type = roslib.msgs.resolve_type(base_type, base_package)    
00060     if base_type in roslib.msgs.BUILTIN_TYPES:
00061         return type_
00062     package, base_type = roslib.names.package_resource_name(base_type)
00063     # always chain upwards to msg dir
00064     if not package or package == base_package:
00065         return _href("../msg/%s.html"%base_type, type_)
00066     else:
00067         return _href("../../../%(package)s/html/msg/%(base_type)s.html"%locals(), type_)
00068 
00069 def index_type_link(pref, type_, base_package):
00070     if type_ in roslib.msgs.BUILTIN_TYPES:
00071         return type_
00072     base_type_ = roslib.msgs.base_msg_type(type_)
00073     package, base_type_ = roslib.names.package_resource_name(base_type_)
00074     if not package or package == base_package:
00075         return _href("%s/%s.html"%(pref, base_type_), type_)
00076     else:
00077         return _href("../../%(package)s/html/%(pref)s/%(base_type_)s.html"%locals(), type_)
00078     
00079 def _generate_raw_text(raw_fn, msg):
00080     raw_text = raw_fn(msg, raw=True)
00081     s = ''
00082     for line in raw_text.split('\n'):
00083         line = line.replace(' ', '&nbsp;')
00084         parts = line.split('#')
00085         if len(parts) > 1:
00086             s = s + parts[0]+'<font color="blue">#%s</font><br/>'%('#'.join(parts[1:]))
00087         else:
00088             s = s + "%s<br/>"%parts[0]
00089     return s
00090 
00091 def _generate_msg_text_from_spec(package, spec, buff=None, indent=0):
00092     if buff is None:
00093         buff = cStringIO.StringIO()
00094     for c in spec.constants:
00095         buff.write("%s%s %s=%s<br />"%("&nbsp;"*indent, c.type, c.name, c.val_text))
00096     for type_, name in zip(spec.types, spec.names):
00097         buff.write("%s%s %s<br />"%("&nbsp;"*indent, type_link(type_, package), name))
00098         base_type = roslib.msgs.base_msg_type(type_)
00099         base_type = roslib.msgs.resolve_type(base_type, package)
00100         if not base_type in roslib.msgs.BUILTIN_TYPES:
00101             subspec = roslib.msgs.get_registered(base_type)
00102             _generate_msg_text_from_spec(package, subspec, buff, indent + 4)
00103     return buff.getvalue()
00104 
00105 def _generate_msg_text(package, type_):
00106     #print "generate", package, type_
00107     name, spec = roslib.msgs.load_from_file(msg_file(package, type_))
00108     return _generate_msg_text_from_spec(package, spec)
00109 
00110 def _generate_srv_text(package, type_):
00111     name, spec = roslib.srvs.load_from_file(srv_file(package, type_))
00112     return _generate_msg_text_from_spec(package, spec.request) + \
00113         '<hr />'+\
00114         _generate_msg_text_from_spec(package, spec.response) 
00115 
00116 def generate_srv_doc(srv):
00117     package, base_type = roslib.names.package_resource_name(srv)
00118     d = { 'name': srv, 'ext': 'srv', 'type': 'Service',
00119           'package': package, 'base_type' : base_type,
00120           'date': str(time.strftime('%a, %d %b %Y %H:%M:%S'))}
00121     d['fancy_text'] = _generate_srv_text(package, base_type)
00122     d['raw_text'] = _generate_raw_text(rosmsg.get_srv_text, srv)
00123     raw_text = _generate_raw_text(rosmsg.get_srv_text, srv)
00124     return msg_template%d
00125 
00126 def generate_msg_doc(msg):
00127     package, base_type = roslib.names.package_resource_name(msg)    
00128     d = { 'name': msg, 'ext': 'msg', 'type': 'Message',
00129           'package': package, 'base_type' : base_type,
00130           'date': str(time.strftime('%a, %d %b %Y %H:%M:%S'))}
00131     d['fancy_text'] = _generate_msg_text(package, base_type)
00132     d['raw_text'] = _generate_raw_text(rosmsg.get_msg_text, msg)
00133     return msg_template%d
00134 
00135 def generate_msg_index(package, file_d, msgs, srvs, wiki_url):
00136     d = {'package': package, 'msg_list' : '', 'srv_list': '',
00137          'package_url': wiki_url,
00138          'date': str(time.strftime('%a, %d %b %Y %H:%M:%S'))}
00139     if msgs:
00140         d['msg_list'] = """<h2>Message types</h2>
00141 <div class="msg-list">
00142   <ul>
00143 %s
00144   </ul>
00145 </div>"""%'\n'.join([" <li>%s</li>"%index_type_link('msg', m, package) for m in msgs])
00146 
00147     if srvs:
00148         d['srv_list'] = """<h2>Service types</h2>
00149 <div class="srv-list">
00150   <ul>
00151 %s
00152   </ul>
00153 </div>"""%'\n'.join([" <li>%s</li>"%index_type_link('srv', s, package) for s in srvs])
00154         
00155     file_p = os.path.join(file_d, 'index-msg.html')
00156     text = msg_index_template % d
00157     with open(file_p, 'w') as f:
00158         #print "writing", file_p
00159         f.write(text)
00160         
00161 
00162 ## generate manifest.yaml files for MoinMoin PackageHeader macro
00163 def generate_msg_docs(ctx):
00164     try:
00165         import yaml
00166     except ImportError:
00167         print >> sys.stderr, "Cannot import yaml, will not generate MoinMoin PackageHeader files"
00168         return
00169 
00170     docdir = ctx.docdir
00171     manifests = ctx.manifests
00172     packages = ctx.packages
00173     for p in packages.iterkeys():
00174         if not ctx.should_document(p):
00175             continue
00176 
00177         # roslib.msgs work, load specs into memory
00178         roslib.msgs.reinit()
00179         roslib.msgs.load_package_dependencies(p, load_recursive=True)
00180         roslib.msgs.load_package(p)
00181 
00182         # create the directory for the autogen files
00183         file_d = os.path.join(docdir, p, 'html')
00184         if not os.path.exists(file_d):
00185             os.makedirs(file_d)
00186 
00187         # get a list of what we are documenting
00188         msgs = roslib.msgs.list_msg_types(p, False)
00189         srvs = roslib.srvs.list_srv_types(p, False)
00190 
00191         # generate the top-level index
00192         wiki_url = '<li>%s</li>\n'%_href(ctx.manifests[p].url, 'Wiki page for %s'%p)
00193         generate_msg_index(p, file_d, msgs, srvs, wiki_url)
00194 
00195         # create dir for msg documentation
00196         if msgs:
00197             msg_d = os.path.join(file_d, 'msg')
00198             if not os.path.exists(msg_d):
00199                 os.makedirs(msg_d)
00200 
00201         # document the messages
00202         for m in msgs:
00203             try:
00204                 text = generate_msg_doc('%s/%s'%(p,m))
00205                 file_p = os.path.join(msg_d, '%s.html'%m)
00206                 with open(file_p, 'w') as f:
00207                     #print "writing", file_p
00208                     f.write(text)
00209             except Exception, e:
00210                 print >> sys.stderr, "FAILED to generate for %s/%s: %s"%(p, m, str(e))
00211 
00212         # create dir for srv documentation                
00213         if srvs:
00214             srv_d = os.path.join(file_d,'srv')
00215             if not os.path.exists(srv_d):
00216                 os.makedirs(srv_d)
00217 
00218         # document the services
00219         for s in srvs:
00220             try:
00221                 text = generate_srv_doc('%s/%s'%(p,s))
00222                 file_p = os.path.join(srv_d, '%s.html'%s)
00223                 with open(file_p, 'w') as f:
00224                     #print "writing", file_p
00225                     f.write(text)
00226             except Exception, e:
00227                 print >> sys.stderr, "FAILED to generate for %s/%s: %s"%(p, s, str(e))
00228 
00229     # we don't return an explicit list of artifacts as we generate into same tree
00230     return []
00231 
00232 
00233 
00234 
00235         
00236         
00237 
00238 
00239         
00240         


rosdoc
Author(s): Ken Conley/kwc@willowgarage.com
autogenerated on Sat Dec 28 2013 16:53:08