Add TitleCollector

This commit is contained in:
Takeshi KOMIYA 2016-12-18 00:36:28 +09:00
parent fc2a78434d
commit 43b52c85a0
3 changed files with 66 additions and 32 deletions

View File

@ -106,6 +106,7 @@ builtin_extensions = (
'sphinx.environment.collectors.dependencies', 'sphinx.environment.collectors.dependencies',
'sphinx.environment.collectors.asset', 'sphinx.environment.collectors.asset',
'sphinx.environment.collectors.metadata', 'sphinx.environment.collectors.metadata',
'sphinx.environment.collectors.title',
) # type: Tuple[unicode, ...] ) # type: Tuple[unicode, ...]
CONFIG_FILENAME = 'conf.py' CONFIG_FILENAME = 'conf.py'

View File

@ -46,7 +46,6 @@ from sphinx.util.parallel import ParallelTasks, parallel_available, make_chunks
from sphinx.util.websupport import is_commentable from sphinx.util.websupport import is_commentable
from sphinx.errors import SphinxError, ExtensionError from sphinx.errors import SphinxError, ExtensionError
from sphinx.versioning import add_uids, merge_doctrees from sphinx.versioning import add_uids, merge_doctrees
from sphinx.transforms import SphinxContentsFilter
from sphinx.deprecation import RemovedInSphinx20Warning from sphinx.deprecation import RemovedInSphinx20Warning
from sphinx.environment.managers.indexentries import IndexEntries from sphinx.environment.managers.indexentries import IndexEntries
from sphinx.environment.managers.toctree import Toctree from sphinx.environment.managers.toctree import Toctree
@ -312,8 +311,6 @@ class BuildEnvironment(object):
if docname in self.all_docs: if docname in self.all_docs:
self.all_docs.pop(docname, None) self.all_docs.pop(docname, None)
self.reread_always.discard(docname) self.reread_always.discard(docname)
self.titles.pop(docname, None)
self.longtitles.pop(docname, None)
for version, changes in self.versionchanges.items(): for version, changes in self.versionchanges.items():
new = [change for change in changes if change[1] != docname] new = [change for change in changes if change[1] != docname]
@ -337,8 +334,6 @@ class BuildEnvironment(object):
self.all_docs[docname] = other.all_docs[docname] self.all_docs[docname] = other.all_docs[docname]
if docname in other.reread_always: if docname in other.reread_always:
self.reread_always.add(docname) self.reread_always.add(docname)
self.titles[docname] = other.titles[docname]
self.longtitles[docname] = other.longtitles[docname]
for version, changes in other.versionchanges.items(): for version, changes in other.versionchanges.items():
self.versionchanges.setdefault(version, []).extend( self.versionchanges.setdefault(version, []).extend(
@ -723,7 +718,6 @@ class BuildEnvironment(object):
doctree = pub.document doctree = pub.document
# post-processing # post-processing
self.create_title_from(docname, doctree)
for manager in itervalues(self.managers): for manager in itervalues(self.managers):
manager.process_doc(docname, doctree) manager.process_doc(docname, doctree)
for domain in itervalues(self.domains): for domain in itervalues(self.domains):
@ -848,32 +842,6 @@ class BuildEnvironment(object):
self.ref_context.get('py:module'), self.ref_context.get('py:module'),
self.temp_data.get('object'), node.astext())) self.temp_data.get('object'), node.astext()))
# post-processing of read doctrees
def create_title_from(self, docname, document):
# type: (unicode, nodes.Node) -> None
"""Add a title node to the document (just copy the first section title),
and store that title in the environment.
"""
titlenode = nodes.title()
longtitlenode = titlenode
# explicit title set with title directive; use this only for
# the <title> tag in HTML output
if 'title' in document:
longtitlenode = nodes.title()
longtitlenode += nodes.Text(document['title'])
# look for first section title and use that as the title
for node in document.traverse(nodes.section):
visitor = SphinxContentsFilter(document)
node[0].walkabout(visitor)
titlenode += visitor.get_entry_text()
break
else:
# document has no title
titlenode += nodes.Text('<no title>')
self.titles[docname] = titlenode
self.longtitles[docname] = longtitlenode
def note_toctree(self, docname, toctreenode): def note_toctree(self, docname, toctreenode):
# type: (unicode, addnodes.toctree) -> None # type: (unicode, addnodes.toctree) -> None
"""Note a TOC tree directive in a document and gather information about """Note a TOC tree directive in a document and gather information about

View File

@ -0,0 +1,65 @@
# -*- coding: utf-8 -*-
"""
sphinx.environment.collectors.title
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The title collector components for sphinx.environment.
:copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
from docutils import nodes
from sphinx.environment.collectors import EnvironmentCollector
from sphinx.transforms import SphinxContentsFilter
if False:
# For type annotation
from docutils import nodes # NOQA
from sphinx.sphinx import Sphinx # NOQA
from sphinx.environment import BuildEnvironment # NOQA
class TitleCollector(EnvironmentCollector):
"""title collector for sphinx.environment."""
def clear_doc(self, app, env, docname):
# type: (Sphinx, BuildEnvironment, unicode) -> None
env.titles.pop(docname, None)
env.longtitles.pop(docname, None)
def merge_other(self, app, env, docnames, other):
# type: (Sphinx, BuildEnvironment, Set[unicode], BuildEnvironment) -> None
for docname in docnames:
env.titles[docname] = other.titles[docname]
env.longtitles[docname] = other.longtitles[docname]
def process_doc(self, app, doctree):
# type: (Sphinx, nodes.Node) -> None
"""Add a title node to the document (just copy the first section title),
and store that title in the environment.
"""
titlenode = nodes.title()
longtitlenode = titlenode
# explicit title set with title directive; use this only for
# the <title> tag in HTML output
if 'title' in doctree:
longtitlenode = nodes.title()
longtitlenode += nodes.Text(doctree['title'])
# look for first section title and use that as the title
for node in doctree.traverse(nodes.section):
visitor = SphinxContentsFilter(doctree)
node[0].walkabout(visitor)
titlenode += visitor.get_entry_text()
break
else:
# document has no title
titlenode += nodes.Text('<no title>')
app.env.titles[app.env.docname] = titlenode
app.env.longtitles[app.env.docname] = longtitlenode
def setup(app):
# type: (Sphinx) -> None
app.add_env_collector(TitleCollector)