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"])
Render and output