docs: def render_source(output_dir, package_specs, version):
    """
    Render and output
    """
    destination_filename = "%s/sbp_out.tex" % output_dir
    py_template = JENV.get_template(TEMPLATE_NAME)
    stable_msgs = []
    unstable_msgs = []
    prims = []
    for p in sorted(package_specs, key=attrgetter('identifier')):
      pkg_name = p.identifier
      stable = p.stable
  
      # build list of required definitions (this package plus includes)
      # TODO: recursively include files
      definitions = p.definitions
      for inc in p.includes:
        inc_basename = inc.split(".")[0]
        for pkg in package_specs:
          if pkg.identifier.endswith(inc_basename):
            definitions += pkg.definitions
  
      if pkg_name == "swiftnav.sbp.types":
        prims = p.definitions
      for d in p.definitions:
        if d.public and d.static and d.sbp_id:
          items, size, multiplier \
            = handle_fields(definitions, d.fields, "", 0, None)
          adj_size = ""
          if multiplier == 1:
            adj_size = "N+%d" % (size - 1) if size > 1 else "N"
          elif multiplier:
             if multiplier == size:
               adj_size = "%dN" % multiplier
             else:
               adj_size = "%dN+%d" % (multiplier, size - multiplier)
          else:
            adj_size = "%d" % size
          ti = TableItem(pkg_name, d.identifier, d.sbp_id,
                         d.short_desc, d.desc, adj_size, items, p.stable,
                         p.description)
          pkg_name = ""
          if stable:
            stable_msgs.append(ti)
          else:
            unstable_msgs.append(ti)
    with open(destination_filename, 'w') as f:
      f.write(py_template.render(msgs=stable_msgs,
                                 umsgs=unstable_msgs,
                                 prims=prims,
                                 version=version))
    import subprocess
    import os
    os.chdir(output_dir)
    subprocess.call(["pdflatex", "--enable-write18",
                     "-shell-escape", "sbp_out.tex"])
    subprocess.call(["mv", "sbp_out.pdf", "../docs/sbp.pdf"])