diff --git a/README b/README index cc8b4ed9b..96fde8ac1 100644 --- a/README +++ b/README @@ -1,6 +1,10 @@ doctools README =============== +FIXME: This is already outdated since the conversion has happened and the +reST sources are in the Python tree now. + + What you need to know --------------------- diff --git a/sphinx/builder.py b/sphinx/builder.py index d4f6b278a..c2bb17f22 100644 --- a/sphinx/builder.py +++ b/sphinx/builder.py @@ -291,7 +291,7 @@ class StandaloneHTMLBuilder(Builder): doc, source_class=DocTreeInput, reader=doctree.Reader(), - writer=HTMLWriter(self.config), + writer=HTMLWriter(self.config, self.name), settings_overrides={'output_encoding': 'unicode'} ) @@ -299,7 +299,7 @@ class StandaloneHTMLBuilder(Builder): from .search import IndexBuilder self.indexer = IndexBuilder() self.load_indexer(filenames) - self.docwriter = HTMLWriter(self.config) + self.docwriter = HTMLWriter(self.config, self.name) self.docsettings = OptionParser( defaults=self.env.settings, components=(self.docwriter,)).get_default_values() diff --git a/sphinx/templates/layout.html b/sphinx/templates/layout.html index 004de5dd4..2447ae9da 100644 --- a/sphinx/templates/layout.html +++ b/sphinx/templates/layout.html @@ -15,6 +15,7 @@ {%- endif %} + {%- if builder != 'htmlhelp' %} + {%- endif %} diff --git a/sphinx/writer.py b/sphinx/writer.py index 61664e29d..1084dc782 100644 --- a/sphinx/writer.py +++ b/sphinx/writer.py @@ -16,12 +16,9 @@ from .util.smartypants import sphinx_smarty_pants class HTMLWriter(Writer): - def __init__(self, config): + def __init__(self, config, buildername): Writer.__init__(self) - if config.get('use_smartypants', False): - self.translator_class = SmartyPantsHTMLTranslator - else: - self.translator_class = HTMLTranslator + self.translator_class = translator_class(config, buildername) version_text = { @@ -30,244 +27,251 @@ version_text = { 'versionadded': 'New in version %s', } -class HTMLTranslator(BaseTranslator): - """ - Our custom HTML translator. - """ +def translator_class(config, buildername): + class HTMLTranslator(BaseTranslator): + """ + Our custom HTML translator. + """ - def __init__(self, *args, **kwds): - self.no_smarty = 0 - BaseTranslator.__init__(self, *args, **kwds) - self.highlightlang = 'python' - self.language.labels['warning'] = 'Caveat' + def __init__(self, *args, **kwds): + self.no_smarty = 0 + BaseTranslator.__init__(self, *args, **kwds) + self.highlightlang = 'python' + self.language.labels['warning'] = 'Caveat' - def visit_desc(self, node): - self.body.append(self.starttag(node, 'dl', CLASS=node['desctype'])) - def depart_desc(self, node): - self.body.append('\n\n') + def visit_desc(self, node): + self.body.append(self.starttag(node, 'dl', CLASS=node['desctype'])) + def depart_desc(self, node): + self.body.append('\n\n') - def visit_desc_signature(self, node): - # the id is set automatically - self.body.append(self.starttag(node, 'dt')) - # anchor for per-desc interactive data - if node.parent['desctype'] != 'describe' and node['ids'] and node['first']: - self.body.append('' % node['ids'][0]) - if node.parent['desctype'] in ('class', 'exception'): - self.body.append('%s ' % node.parent['desctype']) - def depart_desc_signature(self, node): - if node['ids']: - self.body.append(u'\u00B6') - self.body.append('\n') + def visit_desc_signature(self, node): + # the id is set automatically + self.body.append(self.starttag(node, 'dt')) + # anchor for per-desc interactive data + if node.parent['desctype'] != 'describe' and node['ids'] and node['first']: + self.body.append('' % node['ids'][0]) + if node.parent['desctype'] in ('class', 'exception'): + self.body.append('%s ' % node.parent['desctype']) + def depart_desc_signature(self, node): + if node['ids'] and buildername != 'htmlhelp': + self.body.append(u'\u00B6') + self.body.append('\n') - def visit_desc_classname(self, node): - self.body.append(self.starttag(node, 'tt', '', CLASS='descclassname')) - def depart_desc_classname(self, node): - self.body.append('') + def visit_desc_classname(self, node): + self.body.append(self.starttag(node, 'tt', '', CLASS='descclassname')) + def depart_desc_classname(self, node): + self.body.append('') - def visit_desc_name(self, node): - self.body.append(self.starttag(node, 'tt', '', CLASS='descname')) - def depart_desc_name(self, node): - self.body.append('') + def visit_desc_name(self, node): + self.body.append(self.starttag(node, 'tt', '', CLASS='descname')) + def depart_desc_name(self, node): + self.body.append('') - def visit_desc_parameterlist(self, node): - self.body.append('(') - self.first_param = 1 - def depart_desc_parameterlist(self, node): - self.body.append(')') + def visit_desc_parameterlist(self, node): + self.body.append('(') + self.first_param = 1 + def depart_desc_parameterlist(self, node): + self.body.append(')') - def visit_desc_parameter(self, node): - if not self.first_param: - self.body.append(', ') - else: - self.first_param = 0 - if not node.hasattr('noemph'): - self.body.append('') - def depart_desc_parameter(self, node): - if not node.hasattr('noemph'): + def visit_desc_parameter(self, node): + if not self.first_param: + self.body.append(', ') + else: + self.first_param = 0 + if not node.hasattr('noemph'): + self.body.append('') + def depart_desc_parameter(self, node): + if not node.hasattr('noemph'): + self.body.append('') + + def visit_desc_optional(self, node): + self.body.append('[') + def depart_desc_optional(self, node): + self.body.append(']') + + def visit_desc_content(self, node): + self.body.append(self.starttag(node, 'dd', '')) + def depart_desc_content(self, node): + self.body.append('') + + def visit_refcount(self, node): + self.body.append(self.starttag(node, 'em', '', CLASS='refcount')) + def depart_refcount(self, node): self.body.append('') - def visit_desc_optional(self, node): - self.body.append('[') - def depart_desc_optional(self, node): - self.body.append(']') - - def visit_desc_content(self, node): - self.body.append(self.starttag(node, 'dd', '')) - def depart_desc_content(self, node): - self.body.append('') - - def visit_refcount(self, node): - self.body.append(self.starttag(node, 'em', '', CLASS='refcount')) - def depart_refcount(self, node): - self.body.append('') - - def visit_versionmodified(self, node): - self.body.append(self.starttag(node, 'p')) - text = version_text[node['type']] % node['version'] - if len(node): - text += ': ' - else: - text += '.' - self.body.append('%s' % text) - def depart_versionmodified(self, node): - self.body.append('

\n') - - # overwritten - def visit_reference(self, node): - BaseTranslator.visit_reference(self, node) - if node.hasattr('reftitle'): - # ugly hack to add a title attribute - starttag = self.body[-1] - if not starttag.startswith('\n' % h_level) - else: - BaseTranslator.visit_title(self, node, move_ids) + text += '.' + self.body.append('%s' % text) + def depart_versionmodified(self, node): + self.body.append('

\n') - # overwritten - def visit_literal_block(self, node): - from .highlighting import highlight_block - self.body.append(highlight_block(node.rawsource, self.highlightlang)) - raise nodes.SkipNode + # overwritten + def visit_reference(self, node): + BaseTranslator.visit_reference(self, node) + if node.hasattr('reftitle'): + # ugly hack to add a title attribute + starttag = self.body[-1] + if not starttag.startswith('
::= ') - lastname = production['tokenname'] + # overwritten -- we don't want source comments to show up in the HTML + def visit_comment(self, node): + raise nodes.SkipNode + + # overwritten + def visit_admonition(self, node, name=''): + self.body.append(self.start_tag_with_title( + node, 'div', CLASS=('admonition ' + name))) + if name and name != 'seealso': + node.insert(0, nodes.title(name, self.language.labels[name])) + self.set_first_last(node) + + def visit_seealso(self, node): + self.visit_admonition(node, 'seealso') + def depart_seealso(self, node): + self.depart_admonition(node) + + # overwritten + def visit_title(self, node, move_ids=1): + # if we have a section we do our own processing in order + # to have ids in the hN-tags and not in additional a-tags + if isinstance(node.parent, nodes.section): + h_level = self.section_level + self.initial_header_level - 1 + if node.parent.get('ids'): + attrs = {'ids': node.parent['ids']} + else: + attrs = {} + self.body.append(self.starttag(node, 'h%d' % h_level, '', **attrs)) + self.context.append('\n' % h_level) else: - self.body.append('%s ' % (' '*len(lastname))) - production.walkabout(self) - self.body.append('\n') - self.body.append('\n') - raise nodes.SkipNode - def depart_productionlist(self, node): - pass + BaseTranslator.visit_title(self, node, move_ids) - def visit_production(self, node): - pass - def depart_production(self, node): - pass + # overwritten + def visit_literal_block(self, node): + from .highlighting import highlight_block + self.body.append(highlight_block(node.rawsource, self.highlightlang)) + raise nodes.SkipNode - def visit_centered(self, node): - self.body.append(self.starttag(node, 'p', CLASS="centered") + '') - def depart_centered(self, node): - self.body.append('

') + def visit_productionlist(self, node): + self.body.append(self.starttag(node, 'pre')) + names = [] + for production in node: + names.append(production['tokenname']) + maxlen = max(len(name) for name in names) + for production in node: + if production['tokenname']: + self.body.append(self.starttag(production, 'strong', '')) + self.body.append(production['tokenname'].ljust(maxlen) + + ' ::= ') + lastname = production['tokenname'] + else: + self.body.append('%s ' % (' '*len(lastname))) + production.walkabout(self) + self.body.append('\n') + self.body.append('\n') + raise nodes.SkipNode + def depart_productionlist(self, node): + pass - def visit_compact_paragraph(self, node): - pass - def depart_compact_paragraph(self, node): - pass + def visit_production(self, node): + pass + def depart_production(self, node): + pass - def visit_highlightlang(self, node): - self.highlightlang = node['lang'] - def depart_highlightlang(self, node): - pass + def visit_centered(self, node): + self.body.append(self.starttag(node, 'p', CLASS="centered") + '') + def depart_centered(self, node): + self.body.append('

') - def visit_toctree(self, node): - # this only happens when formatting a toc from env.tocs -- in this - # case we don't want to include the subtree - raise nodes.SkipNode + def visit_compact_paragraph(self, node): + pass + def depart_compact_paragraph(self, node): + pass - def visit_index(self, node): - raise nodes.SkipNode + def visit_highlightlang(self, node): + self.highlightlang = node['lang'] + def depart_highlightlang(self, node): + pass - def visit_glossary(self, node): - pass - def depart_glossary(self, node): - pass + def visit_toctree(self, node): + # this only happens when formatting a toc from env.tocs -- in this + # case we don't want to include the subtree + raise nodes.SkipNode - # these are only handled specially in the SmartyPantsHTMLTranslator - def visit_literal_emphasis(self, node): - return self.visit_emphasis(node) - def depart_literal_emphasis(self, node): - return self.depart_emphasis(node) + def visit_index(self, node): + raise nodes.SkipNode - def depart_title(self, node): - close_tag = self.context[-1] - if close_tag.startswith(('\u00B6
') - BaseTranslator.depart_title(self, node) + def visit_glossary(self, node): + pass + def depart_glossary(self, node): + pass + + # these are only handled specially in the SmartyPantsHTMLTranslator + def visit_literal_emphasis(self, node): + return self.visit_emphasis(node) + def depart_literal_emphasis(self, node): + return self.depart_emphasis(node) + + def depart_title(self, node): + close_tag = self.context[-1] + if buildername != 'htmlhelp' and \ + close_tag.startswith(('\u00B6') + BaseTranslator.depart_title(self, node) -class SmartyPantsHTMLTranslator(HTMLTranslator): - """ - Handle ordinary text via smartypants, converting quotes and dashes - to the correct entities. - """ + class SmartyPantsHTMLTranslator(HTMLTranslator): + """ + Handle ordinary text via smartypants, converting quotes and dashes + to the correct entities. + """ - def __init__(self, *args, **kwds): - self.no_smarty = 0 - HTMLTranslator.__init__(self, *args, **kwds) + def __init__(self, *args, **kwds): + self.no_smarty = 0 + HTMLTranslator.__init__(self, *args, **kwds) - def visit_literal(self, node): - self.no_smarty += 1 - try: - # this raises SkipNode - HTMLTranslator.visit_literal(self, node) - finally: + def visit_literal(self, node): + self.no_smarty += 1 + try: + # this raises SkipNode + HTMLTranslator.visit_literal(self, node) + finally: + self.no_smarty -= 1 + + def visit_literal_emphasis(self, node): + self.no_smarty += 1 + self.visit_emphasis(node) + + def depart_literal_emphasis(self, node): + self.depart_emphasis(node) self.no_smarty -= 1 - def visit_literal_emphasis(self, node): - self.no_smarty += 1 - self.visit_emphasis(node) + def visit_productionlist(self, node): + self.no_smarty += 1 + try: + HTMLTranslator.visit_productionlist(self, node) + finally: + self.no_smarty -= 1 - def depart_literal_emphasis(self, node): - self.depart_emphasis(node) - self.no_smarty -= 1 + def encode(self, text): + text = HTMLTranslator.encode(self, text) + if self.no_smarty <= 0: + text = sphinx_smarty_pants(text) + return text - def visit_productionlist(self, node): - self.no_smarty += 1 - try: - HTMLTranslator.visit_productionlist(self, node) - finally: - self.no_smarty -= 1 - - def encode(self, text): - text = HTMLTranslator.encode(self, text) - if self.no_smarty <= 0: - text = sphinx_smarty_pants(text) - return text + if config.get('use_smartypants', False): + return SmartyPantsHTMLTranslator + else: + return HTMLTranslator