Don't use JavaScript and section anchors in the htmlhelp version.

This commit is contained in:
Georg Brandl
2007-08-24 20:49:57 +00:00
parent a84bedff72
commit acda414be2
4 changed files with 228 additions and 218 deletions

4
README
View File

@@ -1,6 +1,10 @@
doctools README 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 What you need to know
--------------------- ---------------------

View File

@@ -291,7 +291,7 @@ class StandaloneHTMLBuilder(Builder):
doc, doc,
source_class=DocTreeInput, source_class=DocTreeInput,
reader=doctree.Reader(), reader=doctree.Reader(),
writer=HTMLWriter(self.config), writer=HTMLWriter(self.config, self.name),
settings_overrides={'output_encoding': 'unicode'} settings_overrides={'output_encoding': 'unicode'}
) )
@@ -299,7 +299,7 @@ class StandaloneHTMLBuilder(Builder):
from .search import IndexBuilder from .search import IndexBuilder
self.indexer = IndexBuilder() self.indexer = IndexBuilder()
self.load_indexer(filenames) self.load_indexer(filenames)
self.docwriter = HTMLWriter(self.config) self.docwriter = HTMLWriter(self.config, self.name)
self.docsettings = OptionParser( self.docsettings = OptionParser(
defaults=self.env.settings, defaults=self.env.settings,
components=(self.docwriter,)).get_default_values() components=(self.docwriter,)).get_default_values()

View File

@@ -15,6 +15,7 @@
<link rel="stylesheet" href="{{ pathto('style/default.css', 1) }}" type="text/css"> <link rel="stylesheet" href="{{ pathto('style/default.css', 1) }}" type="text/css">
<link rel="stylesheet" href="{{ pathto('style/pygments.css', 1) }}" type="text/css"> <link rel="stylesheet" href="{{ pathto('style/pygments.css', 1) }}" type="text/css">
{%- endif %} {%- endif %}
{%- if builder != 'htmlhelp' %}
<script type="text/javascript"> <script type="text/javascript">
var DOCUMENTATION_OPTIONS = { var DOCUMENTATION_OPTIONS = {
URL_ROOT: '{{ pathto("", 1) }}', URL_ROOT: '{{ pathto("", 1) }}',
@@ -24,6 +25,7 @@
<script type="text/javascript" src="{{ pathto('style/jquery.js', 1) }}"></script> <script type="text/javascript" src="{{ pathto('style/jquery.js', 1) }}"></script>
<script type="text/javascript" src="{{ pathto('style/interface.js', 1) }}"></script> <script type="text/javascript" src="{{ pathto('style/interface.js', 1) }}"></script>
<script type="text/javascript" src="{{ pathto('style/doctools.js', 1) }}"></script> <script type="text/javascript" src="{{ pathto('style/doctools.js', 1) }}"></script>
{%- endif %}
<link rel="author" title="About these documents" href="{{ pathto('about.rst') }}"> <link rel="author" title="About these documents" href="{{ pathto('about.rst') }}">
<link rel="contents" title="Global table of contents" href="{{ pathto('contents.rst') }}"> <link rel="contents" title="Global table of contents" href="{{ pathto('contents.rst') }}">
<link rel="index" title="Global index" href="{{ pathto('genindex.rst') }}"> <link rel="index" title="Global index" href="{{ pathto('genindex.rst') }}">

View File

@@ -16,12 +16,9 @@ from .util.smartypants import sphinx_smarty_pants
class HTMLWriter(Writer): class HTMLWriter(Writer):
def __init__(self, config): def __init__(self, config, buildername):
Writer.__init__(self) Writer.__init__(self)
if config.get('use_smartypants', False): self.translator_class = translator_class(config, buildername)
self.translator_class = SmartyPantsHTMLTranslator
else:
self.translator_class = HTMLTranslator
version_text = { version_text = {
@@ -30,244 +27,251 @@ version_text = {
'versionadded': 'New in version %s', 'versionadded': 'New in version %s',
} }
class HTMLTranslator(BaseTranslator): def translator_class(config, buildername):
""" class HTMLTranslator(BaseTranslator):
Our custom HTML translator. """
""" Our custom HTML translator.
"""
def __init__(self, *args, **kwds): def __init__(self, *args, **kwds):
self.no_smarty = 0 self.no_smarty = 0
BaseTranslator.__init__(self, *args, **kwds) BaseTranslator.__init__(self, *args, **kwds)
self.highlightlang = 'python' self.highlightlang = 'python'
self.language.labels['warning'] = 'Caveat' self.language.labels['warning'] = 'Caveat'
def visit_desc(self, node): def visit_desc(self, node):
self.body.append(self.starttag(node, 'dl', CLASS=node['desctype'])) self.body.append(self.starttag(node, 'dl', CLASS=node['desctype']))
def depart_desc(self, node): def depart_desc(self, node):
self.body.append('</dl>\n\n') self.body.append('</dl>\n\n')
def visit_desc_signature(self, node): def visit_desc_signature(self, node):
# the id is set automatically # the id is set automatically
self.body.append(self.starttag(node, 'dt')) self.body.append(self.starttag(node, 'dt'))
# anchor for per-desc interactive data # anchor for per-desc interactive data
if node.parent['desctype'] != 'describe' and node['ids'] and node['first']: if node.parent['desctype'] != 'describe' and node['ids'] and node['first']:
self.body.append('<!--#%s#-->' % node['ids'][0]) self.body.append('<!--#%s#-->' % node['ids'][0])
if node.parent['desctype'] in ('class', 'exception'): if node.parent['desctype'] in ('class', 'exception'):
self.body.append('%s ' % node.parent['desctype']) self.body.append('%s ' % node.parent['desctype'])
def depart_desc_signature(self, node): def depart_desc_signature(self, node):
if node['ids']: if node['ids'] and buildername != 'htmlhelp':
self.body.append(u'<a class="headerlink" href="#%s" ' % node['ids'][0] + self.body.append(u'<a class="headerlink" href="#%s" ' % node['ids'][0] +
u'title="Permalink to this definition">\u00B6</a>') u'title="Permalink to this definition">\u00B6</a>')
self.body.append('</dt>\n') self.body.append('</dt>\n')
def visit_desc_classname(self, node): def visit_desc_classname(self, node):
self.body.append(self.starttag(node, 'tt', '', CLASS='descclassname')) self.body.append(self.starttag(node, 'tt', '', CLASS='descclassname'))
def depart_desc_classname(self, node): def depart_desc_classname(self, node):
self.body.append('</tt>') self.body.append('</tt>')
def visit_desc_name(self, node): def visit_desc_name(self, node):
self.body.append(self.starttag(node, 'tt', '', CLASS='descname')) self.body.append(self.starttag(node, 'tt', '', CLASS='descname'))
def depart_desc_name(self, node): def depart_desc_name(self, node):
self.body.append('</tt>') self.body.append('</tt>')
def visit_desc_parameterlist(self, node): def visit_desc_parameterlist(self, node):
self.body.append('<big>(</big>') self.body.append('<big>(</big>')
self.first_param = 1 self.first_param = 1
def depart_desc_parameterlist(self, node): def depart_desc_parameterlist(self, node):
self.body.append('<big>)</big>') self.body.append('<big>)</big>')
def visit_desc_parameter(self, node): def visit_desc_parameter(self, node):
if not self.first_param: if not self.first_param:
self.body.append(', ') self.body.append(', ')
else: else:
self.first_param = 0 self.first_param = 0
if not node.hasattr('noemph'): if not node.hasattr('noemph'):
self.body.append('<em>') self.body.append('<em>')
def depart_desc_parameter(self, node): def depart_desc_parameter(self, node):
if not node.hasattr('noemph'): if not node.hasattr('noemph'):
self.body.append('</em>')
def visit_desc_optional(self, node):
self.body.append('<span class="optional">[</span>')
def depart_desc_optional(self, node):
self.body.append('<span class="optional">]</span>')
def visit_desc_content(self, node):
self.body.append(self.starttag(node, 'dd', ''))
def depart_desc_content(self, node):
self.body.append('</dd>')
def visit_refcount(self, node):
self.body.append(self.starttag(node, 'em', '', CLASS='refcount'))
def depart_refcount(self, node):
self.body.append('</em>') self.body.append('</em>')
def visit_desc_optional(self, node): def visit_versionmodified(self, node):
self.body.append('<span class="optional">[</span>') self.body.append(self.starttag(node, 'p'))
def depart_desc_optional(self, node): text = version_text[node['type']] % node['version']
self.body.append('<span class="optional">]</span>') if len(node):
text += ': '
def visit_desc_content(self, node):
self.body.append(self.starttag(node, 'dd', ''))
def depart_desc_content(self, node):
self.body.append('</dd>')
def visit_refcount(self, node):
self.body.append(self.starttag(node, 'em', '', CLASS='refcount'))
def depart_refcount(self, node):
self.body.append('</em>')
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('<span class="versionmodified">%s</span>' % text)
def depart_versionmodified(self, node):
self.body.append('</p>\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('<a '):
return
self.body[-1] = '<a title="%s"' % self.attval(node['reftitle']) + \
starttag[2:]
# 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: else:
attrs = {} text += '.'
self.body.append(self.starttag(node, 'h%d' % h_level, '', **attrs)) self.body.append('<span class="versionmodified">%s</span>' % text)
self.context.append('</h%d>\n' % h_level) def depart_versionmodified(self, node):
else: self.body.append('</p>\n')
BaseTranslator.visit_title(self, node, move_ids)
# overwritten # overwritten
def visit_literal_block(self, node): def visit_reference(self, node):
from .highlighting import highlight_block BaseTranslator.visit_reference(self, node)
self.body.append(highlight_block(node.rawsource, self.highlightlang)) if node.hasattr('reftitle'):
raise nodes.SkipNode # ugly hack to add a title attribute
starttag = self.body[-1]
if not starttag.startswith('<a '):
return
self.body[-1] = '<a title="%s"' % self.attval(node['reftitle']) + \
starttag[2:]
def visit_productionlist(self, node): # overwritten -- we don't want source comments to show up in the HTML
self.body.append(self.starttag(node, 'pre')) def visit_comment(self, node):
names = [] raise nodes.SkipNode
for production in node:
names.append(production['tokenname']) # overwritten
maxlen = max(len(name) for name in names) def visit_admonition(self, node, name=''):
for production in node: self.body.append(self.start_tag_with_title(
if production['tokenname']: node, 'div', CLASS=('admonition ' + name)))
self.body.append(self.starttag(production, 'strong', '')) if name and name != 'seealso':
self.body.append(production['tokenname'].ljust(maxlen) + node.insert(0, nodes.title(name, self.language.labels[name]))
'</strong> ::= ') self.set_first_last(node)
lastname = production['tokenname']
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('</h%d>\n' % h_level)
else: else:
self.body.append('%s ' % (' '*len(lastname))) BaseTranslator.visit_title(self, node, move_ids)
production.walkabout(self)
self.body.append('\n')
self.body.append('</pre>\n')
raise nodes.SkipNode
def depart_productionlist(self, node):
pass
def visit_production(self, node): # overwritten
pass def visit_literal_block(self, node):
def depart_production(self, node): from .highlighting import highlight_block
pass self.body.append(highlight_block(node.rawsource, self.highlightlang))
raise nodes.SkipNode
def visit_centered(self, node): def visit_productionlist(self, node):
self.body.append(self.starttag(node, 'p', CLASS="centered") + '<strong>') self.body.append(self.starttag(node, 'pre'))
def depart_centered(self, node): names = []
self.body.append('</strong></p>') 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) +
'</strong> ::= ')
lastname = production['tokenname']
else:
self.body.append('%s ' % (' '*len(lastname)))
production.walkabout(self)
self.body.append('\n')
self.body.append('</pre>\n')
raise nodes.SkipNode
def depart_productionlist(self, node):
pass
def visit_compact_paragraph(self, node): def visit_production(self, node):
pass pass
def depart_compact_paragraph(self, node): def depart_production(self, node):
pass pass
def visit_highlightlang(self, node): def visit_centered(self, node):
self.highlightlang = node['lang'] self.body.append(self.starttag(node, 'p', CLASS="centered") + '<strong>')
def depart_highlightlang(self, node): def depart_centered(self, node):
pass self.body.append('</strong></p>')
def visit_toctree(self, node): def visit_compact_paragraph(self, node):
# this only happens when formatting a toc from env.tocs -- in this pass
# case we don't want to include the subtree def depart_compact_paragraph(self, node):
raise nodes.SkipNode pass
def visit_index(self, node): def visit_highlightlang(self, node):
raise nodes.SkipNode self.highlightlang = node['lang']
def depart_highlightlang(self, node):
pass
def visit_glossary(self, node): def visit_toctree(self, node):
pass # this only happens when formatting a toc from env.tocs -- in this
def depart_glossary(self, node): # case we don't want to include the subtree
pass raise nodes.SkipNode
# these are only handled specially in the SmartyPantsHTMLTranslator def visit_index(self, node):
def visit_literal_emphasis(self, node): raise nodes.SkipNode
return self.visit_emphasis(node)
def depart_literal_emphasis(self, node):
return self.depart_emphasis(node)
def depart_title(self, node): def visit_glossary(self, node):
close_tag = self.context[-1] pass
if close_tag.startswith(('</h', '</a></h')) and \ def depart_glossary(self, node):
node.parent.hasattr('ids') and node.parent['ids']: pass
aname = node.parent['ids'][0]
# add permalink anchor # these are only handled specially in the SmartyPantsHTMLTranslator
self.body.append(u'<a class="headerlink" href="#%s" ' % aname + def visit_literal_emphasis(self, node):
u'title="Permalink to this headline">\u00B6</a>') return self.visit_emphasis(node)
BaseTranslator.depart_title(self, 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(('</h', '</a></h')) and \
node.parent.hasattr('ids') and node.parent['ids']:
aname = node.parent['ids'][0]
# add permalink anchor
self.body.append(u'<a class="headerlink" href="#%s" ' % aname +
u'title="Permalink to this headline">\u00B6</a>')
BaseTranslator.depart_title(self, node)
class SmartyPantsHTMLTranslator(HTMLTranslator): class SmartyPantsHTMLTranslator(HTMLTranslator):
""" """
Handle ordinary text via smartypants, converting quotes and dashes Handle ordinary text via smartypants, converting quotes and dashes
to the correct entities. to the correct entities.
""" """
def __init__(self, *args, **kwds): def __init__(self, *args, **kwds):
self.no_smarty = 0 self.no_smarty = 0
HTMLTranslator.__init__(self, *args, **kwds) HTMLTranslator.__init__(self, *args, **kwds)
def visit_literal(self, node): def visit_literal(self, node):
self.no_smarty += 1 self.no_smarty += 1
try: try:
# this raises SkipNode # this raises SkipNode
HTMLTranslator.visit_literal(self, node) HTMLTranslator.visit_literal(self, node)
finally: 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 self.no_smarty -= 1
def visit_literal_emphasis(self, node): def visit_productionlist(self, node):
self.no_smarty += 1 self.no_smarty += 1
self.visit_emphasis(node) try:
HTMLTranslator.visit_productionlist(self, node)
finally:
self.no_smarty -= 1
def depart_literal_emphasis(self, node): def encode(self, text):
self.depart_emphasis(node) text = HTMLTranslator.encode(self, text)
self.no_smarty -= 1 if self.no_smarty <= 0:
text = sphinx_smarty_pants(text)
return text
def visit_productionlist(self, node): if config.get('use_smartypants', False):
self.no_smarty += 1 return SmartyPantsHTMLTranslator
try: else:
HTMLTranslator.visit_productionlist(self, node) return HTMLTranslator
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