summaryrefslogtreecommitdiff
path: root/sphinx/builders/websupport.py
diff options
context:
space:
mode:
Diffstat (limited to 'sphinx/builders/websupport.py')
-rw-r--r--sphinx/builders/websupport.py154
1 files changed, 154 insertions, 0 deletions
diff --git a/sphinx/builders/websupport.py b/sphinx/builders/websupport.py
new file mode 100644
index 000000000..e8f6aef35
--- /dev/null
+++ b/sphinx/builders/websupport.py
@@ -0,0 +1,154 @@
+# -*- coding: utf-8 -*-
+"""
+ sphinx.builders.websupport
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ Builder for the web support package.
+
+ :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
+ :license: BSD, see LICENSE for details.
+"""
+
+from os import path
+import posixpath
+import shutil
+
+from docutils.io import StringOutput
+
+from sphinx.jinja2glue import BuiltinTemplateLoader
+from sphinx.util.osutil import os_path, relative_uri, ensuredir, copyfile
+from sphinx.builders.html import PickleHTMLBuilder
+from sphinx.writers.websupport import WebSupportTranslator
+
+
+class WebSupportBuilder(PickleHTMLBuilder):
+ """
+ Builds documents for the web support package.
+ """
+ name = 'websupport'
+
+ def init(self):
+ PickleHTMLBuilder.init(self)
+ # templates are needed for this builder, but the serializing
+ # builder does not initialize them
+ self.init_templates()
+ if not isinstance(self.templates, BuiltinTemplateLoader):
+ raise RuntimeError('websupport builder must be used with '
+ 'the builtin templates')
+ # add our custom JS
+ self.script_files.append('_static/websupport.js')
+
+ def set_webinfo(self, staticdir, virtual_staticdir, search, storage):
+ self.staticdir = staticdir
+ self.virtual_staticdir = virtual_staticdir
+ self.search = search
+ self.storage = storage
+
+ def init_translator_class(self):
+ self.translator_class = WebSupportTranslator
+
+ def prepare_writing(self, docnames):
+ PickleHTMLBuilder.prepare_writing(self, docnames)
+ self.globalcontext['no_search_suffix'] = True
+
+ 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.virtual_staticdir, '_images')
+ self.post_process_images(doctree)
+ self.dlpath = '/' + posixpath.join(self.virtual_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 load_indexer(self, docnames):
+ self.indexer = self.search
+ self.indexer.init_indexing(changed=docnames)
+
+ def _render_page(self, pagename, addctx, templatename, 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 resource and '://' in otheruri:
+ return otheruri
+ elif not resource:
+ otheruri = self.get_target_uri(otheruri)
+ return relative_uri(baseuri, otheruri) or '#'
+ else:
+ return '/' + posixpath.join(self.virtual_staticdir, otheruri)
+ ctx['pathto'] = pathto
+ ctx['hasdoc'] = lambda name: name in self.env.all_docs
+ ctx['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
+ doc_ctx = {
+ 'body': ctx.get('body', ''),
+ 'title': ctx.get('title', ''),
+ }
+ # partially render the html template to get at interesting macros
+ template = self.templates.environment.get_template(templatename)
+ template_module = template.make_module(ctx)
+ for item in ['sidebar', 'relbar', 'script', 'css']:
+ if hasattr(template_module, item):
+ doc_ctx[item] = getattr(template_module, item)()
+
+ return ctx, doc_ctx
+
+ def handle_page(self, pagename, addctx, templatename='page.html',
+ outfilename=None, event_arg=None):
+ ctx, doc_ctx = self._render_page(pagename, addctx,
+ templatename, event_arg)
+
+ if not outfilename:
+ outfilename = path.join(self.outdir, 'pickles',
+ os_path(pagename) + self.out_suffix)
+ ensuredir(path.dirname(outfilename))
+ self.dump_context(doc_ctx, outfilename)
+
+ # if there is a source file, copy the source file for the
+ # "show source" link
+ if ctx.get('sourcename'):
+ source_name = path.join(self.staticdir,
+ '_sources', os_path(ctx['sourcename']))
+ ensuredir(path.dirname(source_name))
+ copyfile(self.env.doc2path(pagename), source_name)
+
+ def handle_finish(self):
+ # get global values for css and script files
+ _, doc_ctx = self._render_page('tmp', {}, 'page.html')
+ self.globalcontext['css'] = doc_ctx['css']
+ self.globalcontext['script'] = doc_ctx['script']
+
+ PickleHTMLBuilder.handle_finish(self)
+
+ # move static stuff over to separate directory
+ directories = ['_images', '_static']
+ for directory in directories:
+ src = path.join(self.outdir, directory)
+ dst = path.join(self.staticdir, directory)
+ if path.isdir(src):
+ if path.isdir(dst):
+ shutil.rmtree(dst)
+ shutil.move(src, dst)
+
+ def dump_search_index(self):
+ self.indexer.finish_indexing()