diff options
Diffstat (limited to 'sphinx/builders/websupport.py')
-rw-r--r-- | sphinx/builders/websupport.py | 154 |
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() |