From 43b52c85a0f874d3e5a9608014533f058b6120c2 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Sun, 18 Dec 2016 00:36:28 +0900 Subject: [PATCH] Add TitleCollector --- sphinx/application.py | 1 + sphinx/environment/__init__.py | 32 ------------- sphinx/environment/collectors/title.py | 65 ++++++++++++++++++++++++++ 3 files changed, 66 insertions(+), 32 deletions(-) create mode 100644 sphinx/environment/collectors/title.py diff --git a/sphinx/application.py b/sphinx/application.py index 6ada00b6d..a8049b933 100644 --- a/sphinx/application.py +++ b/sphinx/application.py @@ -106,6 +106,7 @@ builtin_extensions = ( 'sphinx.environment.collectors.dependencies', 'sphinx.environment.collectors.asset', 'sphinx.environment.collectors.metadata', + 'sphinx.environment.collectors.title', ) # type: Tuple[unicode, ...] CONFIG_FILENAME = 'conf.py' diff --git a/sphinx/environment/__init__.py b/sphinx/environment/__init__.py index 105c4e208..fd975c4ea 100644 --- a/sphinx/environment/__init__.py +++ b/sphinx/environment/__init__.py @@ -46,7 +46,6 @@ from sphinx.util.parallel import ParallelTasks, parallel_available, make_chunks from sphinx.util.websupport import is_commentable from sphinx.errors import SphinxError, ExtensionError from sphinx.versioning import add_uids, merge_doctrees -from sphinx.transforms import SphinxContentsFilter from sphinx.deprecation import RemovedInSphinx20Warning from sphinx.environment.managers.indexentries import IndexEntries from sphinx.environment.managers.toctree import Toctree @@ -312,8 +311,6 @@ class BuildEnvironment(object): if docname in self.all_docs: self.all_docs.pop(docname, None) self.reread_always.discard(docname) - self.titles.pop(docname, None) - self.longtitles.pop(docname, None) for version, changes in self.versionchanges.items(): 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] if docname in other.reread_always: self.reread_always.add(docname) - self.titles[docname] = other.titles[docname] - self.longtitles[docname] = other.longtitles[docname] for version, changes in other.versionchanges.items(): self.versionchanges.setdefault(version, []).extend( @@ -723,7 +718,6 @@ class BuildEnvironment(object): doctree = pub.document # post-processing - self.create_title_from(docname, doctree) for manager in itervalues(self.managers): manager.process_doc(docname, doctree) for domain in itervalues(self.domains): @@ -848,32 +842,6 @@ class BuildEnvironment(object): self.ref_context.get('py:module'), 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 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): # type: (unicode, addnodes.toctree) -> None """Note a TOC tree directive in a document and gather information about diff --git a/sphinx/environment/collectors/title.py b/sphinx/environment/collectors/title.py new file mode 100644 index 000000000..a5316fe94 --- /dev/null +++ b/sphinx/environment/collectors/title.py @@ -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)