# -*- coding: utf-8 -*-
"""
sphinx.builders.websupport
~~~~~~~~~~~~~~~~~~~~~~~~~~
Builder for the web support package.
:copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
import cPickle as pickle
from os import path
from cgi import escape
import posixpath
import shutil
from docutils.io import StringOutput
from sphinx.util.osutil import os_path, relative_uri, ensuredir, copyfile
from sphinx.util.jsonimpl import dumps as dump_json
from sphinx.builders.html import StandaloneHTMLBuilder
from sphinx.writers.websupport import WebSupportTranslator
class WebSupportBuilder(StandaloneHTMLBuilder):
"""
Builds documents for the web support package.
"""
name = 'websupport'
out_suffix = '.fpickle'
def init_translator_class(self):
self.translator_class = WebSupportTranslator
def write_doc(self, docname, doctree):
destination = StringOutput(encoding='utf-8')
doctree.settings = self.docsettings
self.cur_docname = docname
self.secnumbers = self.env.toc_secnumbers.get(docname, {})
self.imgpath = '/' + posixpath.join(self.app.staticdir, '_images')
self.post_process_images(doctree)
self.dlpath = '/' + posixpath.join(self.app.staticdir, '_downloads')
self.docwriter.write(doctree, destination)
self.docwriter.assemble_parts()
body = self.docwriter.parts['fragment']
metatags = self.docwriter.clean_meta
ctx = self.get_doc_context(docname, body, metatags)
self.index_page(docname, doctree, ctx.get('title', ''))
self.handle_page(docname, ctx, event_arg=doctree)
def get_target_uri(self, docname, typ=None):
return docname
def load_indexer(self, docnames):
self.indexer = self.app.search
self.indexer.init_indexing(changed=docnames)
def handle_page(self, pagename, addctx, templatename='page.html',
outfilename=None, event_arg=None):
# This is mostly copied from StandaloneHTMLBuilder. However, instead
# of rendering the template and saving the html, create a context
# dict and pickle it.
ctx = self.globalcontext.copy()
ctx['pagename'] = pagename
def pathto(otheruri, resource=False,
baseuri=self.get_target_uri(pagename)):
if not resource:
otheruri = self.get_target_uri(otheruri)
return relative_uri(baseuri, otheruri) or '#'
else:
return '/' + posixpath.join(self.app.staticdir, otheruri)
ctx['pathto'] = pathto
ctx['hasdoc'] = lambda name: name in self.env.all_docs
ctx['encoding'] = encoding = self.config.html_output_encoding
ctx['toctree'] = lambda **kw: self._get_local_toctree(pagename, **kw)
self.add_sidebars(pagename, ctx)
ctx.update(addctx)
self.app.emit('html-page-context', pagename, templatename,
ctx, event_arg)
# Create a dict that will be pickled and used by webapps.
css = '' % \
pathto('_static/pygments.css', 1)
doc_ctx = {'body': ctx.get('body', ''),
'title': ctx.get('title', ''),
'css': css,
'js': self._make_js(ctx)}
# Partially render the html template to proved a more useful ctx.
template = self.templates.environment.get_template(templatename)
template_module = template.make_module(ctx)
if hasattr(template_module, 'sidebar'):
doc_ctx['sidebar'] = template_module.sidebar()
if hasattr(template_module, 'relbar'):
doc_ctx['relbar'] = template_module.relbar()
if not outfilename:
outfilename = path.join(self.outdir, 'pickles',
os_path(pagename) + self.out_suffix)
ensuredir(path.dirname(outfilename))
f = open(outfilename, 'wb')
try:
pickle.dump(doc_ctx, f, 2)
finally:
f.close()
# if there is a source file, copy the source file for the
# "show source" link
if ctx.get('sourcename'):
source_name = path.join(self.app.builddir, self.app.staticdir,
'_sources', os_path(ctx['sourcename']))
ensuredir(path.dirname(source_name))
copyfile(self.env.doc2path(pagename), source_name)
def handle_finish(self):
StandaloneHTMLBuilder.handle_finish(self)
shutil.move(path.join(self.outdir, '_images'),
path.join(self.app.builddir, self.app.staticdir,
'_images'))
shutil.move(path.join(self.outdir, '_static'),
path.join(self.app.builddir, self.app.staticdir,
'_static'))
def dump_search_index(self):
self.indexer.finish_indexing()
def _make_js(self, ctx):
def make_script(file):
path = ctx['pathto'](file, 1)
return '' % path
opts = {
'URL_ROOT': ctx.get('url_root', ''),
'VERSION': ctx['release'],
'COLLAPSE_INDEX': False,
'FILE_SUFFIX': '',
'HAS_SOURCE': ctx['has_source']
}
scripts = [make_script('_static/websupport.js')]
scripts += [make_script(file) for file in ctx['script_files']]
return '\n'.join([
''
] + scripts)