summaryrefslogtreecommitdiff
path: root/sphinx/environment.py
diff options
context:
space:
mode:
Diffstat (limited to 'sphinx/environment.py')
-rw-r--r--sphinx/environment.py82
1 files changed, 59 insertions, 23 deletions
diff --git a/sphinx/environment.py b/sphinx/environment.py
index 27111a525..58463cae8 100644
--- a/sphinx/environment.py
+++ b/sphinx/environment.py
@@ -38,9 +38,10 @@ from docutils.frontend import OptionParser
from sphinx import addnodes
from sphinx.util import url_re, get_matching_docs, docname_join, split_into, \
- FilenameUniqDict, get_figtype
+ FilenameUniqDict, get_figtype, import_object
from sphinx.util.nodes import clean_astext, make_refnode, WarningStream, is_translatable
-from sphinx.util.osutil import SEP, find_catalog_files, getcwd, fs_encoding
+from sphinx.util.osutil import SEP, getcwd, fs_encoding
+from sphinx.util.i18n import find_catalog_files
from sphinx.util.console import bold, purple
from sphinx.util.matching import compile_matchers
from sphinx.util.parallel import ParallelTasks, parallel_available, make_chunks
@@ -48,9 +49,11 @@ from sphinx.util.websupport import is_commentable
from sphinx.errors import SphinxError, ExtensionError
from sphinx.locale import _
from sphinx.versioning import add_uids, merge_doctrees
-from sphinx.transforms import DefaultSubstitutions, MoveModuleTargets, \
- HandleCodeBlocks, AutoNumbering, SortIds, CitationReferences, Locale, \
- RemoveTranslatableInline, SphinxContentsFilter, ExtraTranslatableNodes
+from sphinx.transforms import (
+ DefaultSubstitutions, MoveModuleTargets, ApplySourceWorkaround,
+ HandleCodeBlocks, AutoNumbering, SortIds, CitationReferences, Locale,
+ RemoveTranslatableInline, SphinxContentsFilter, ExtraTranslatableNodes,
+)
orig_role_function = roles.role
@@ -98,10 +101,33 @@ class SphinxStandaloneReader(standalone.Reader):
"""
Add our own transforms.
"""
- transforms = [ExtraTranslatableNodes, Locale, CitationReferences,
+ transforms = [ApplySourceWorkaround, ExtraTranslatableNodes, Locale, CitationReferences,
DefaultSubstitutions, MoveModuleTargets, HandleCodeBlocks,
AutoNumbering, SortIds, RemoveTranslatableInline]
+ def __init__(self, parsers={}, *args, **kwargs):
+ standalone.Reader.__init__(self, *args, **kwargs)
+ self.parser_map = {}
+ for suffix, parser_class in parsers.items():
+ if isinstance(parser_class, string_types):
+ parser_class = import_object(parser_class, 'source parser')
+ self.parser_map[suffix] = parser_class()
+
+ def read(self, source, parser, settings):
+ self.source = source
+
+ for suffix in self.parser_map:
+ if source.source_path.endswith(suffix):
+ self.parser = self.parser_map[suffix]
+ break
+
+ if not self.parser:
+ self.parser = parser
+ self.settings = settings
+ self.input = self.source.read()
+ self.parse()
+ return self.document
+
def get_transforms(self):
return standalone.Reader.get_transforms(self) + self.transforms
@@ -117,8 +143,6 @@ class SphinxFileInput(FileInput):
def __init__(self, app, env, *args, **kwds):
self.app = app
self.env = env
- # don't call sys.exit() on IOErrors
- kwds['handle_io_errors'] = False
kwds['error_handler'] = 'sphinx' # py3: handle error on open.
FileInput.__init__(self, *args, **kwds)
@@ -243,7 +267,7 @@ class BuildEnvironment:
self.files_to_rebuild = {} # docname -> set of files
# (containing its TOCs) to rebuild too
self.glob_toctrees = set() # docnames that have :glob: toctrees
- self.numbered_toctrees = set() # docnames that have :numbered: toctrees
+ self.numbered_toctrees = set() # docnames that have :numbered: toctrees
# domain-specific inventories, here to be pickled
self.domaindata = {} # domainname -> domain-specific dict
@@ -326,7 +350,7 @@ class BuildEnvironment:
fnset.discard(docname)
if not fnset:
del self.files_to_rebuild[subfn]
- for key, (fn, _) in list(self.citations.items()):
+ for key, (fn, _ignore) in list(self.citations.items()):
if fn == docname:
del self.citations[key]
for version, changes in self.versionchanges.items():
@@ -437,7 +461,7 @@ class BuildEnvironment:
config.exclude_patterns[:] +
config.templates_path +
config.html_extra_path +
- ['**/_sources', '.#*']
+ ['**/_sources', '.#*', '*.lproj/**']
)
self.found_docs = set(get_matching_docs(
self.srcdir, config.source_suffix, exclude_matchers=matchers))
@@ -752,7 +776,8 @@ class BuildEnvironment:
codecs.register_error('sphinx', self.warn_and_replace)
# publish manually
- pub = Publisher(reader=SphinxStandaloneReader(),
+ reader = SphinxStandaloneReader(parsers=self.config.source_parsers)
+ pub = Publisher(reader=reader,
writer=SphinxDummyWriter(),
destination_class=NullOutput)
pub.set_components(None, 'restructuredtext', None)
@@ -1292,7 +1317,7 @@ class BuildEnvironment:
else:
# cull sub-entries whose parents aren't 'current'
if (collapse and depth > 1 and
- 'iscurrent' not in subnode.parent):
+ 'iscurrent' not in subnode.parent):
subnode.parent.remove(subnode)
else:
# recurse on visible children
@@ -1449,8 +1474,8 @@ class BuildEnvironment:
toplevel[1][:] = subtrees
# resolve all sub-toctrees
for subtocnode in toc.traverse(addnodes.toctree):
- if not (subtocnode.get('hidden', False)
- and not includehidden):
+ if not (subtocnode.get('hidden', False) and
+ not includehidden):
i = subtocnode.parent.index(subtocnode) + 1
for item in _entries_from_toctree(
subtocnode, [refdoc] + parents,
@@ -1481,7 +1506,11 @@ class BuildEnvironment:
if not tocentries:
return None
- newnode = addnodes.compact_paragraph('', '', *tocentries)
+ newnode = addnodes.compact_paragraph('', '')
+ caption = toctree.attributes.get('caption')
+ if caption:
+ newnode += nodes.caption(caption, '', *[nodes.Text(caption)])
+ newnode.extend(tocentries)
newnode['toctree'] = True
# prune the tree to maxdepth, also set toc depth and current classes
@@ -1577,7 +1606,8 @@ class BuildEnvironment:
caption = node.astext()
else:
caption = clean_astext(self.titles[docname])
- innernode = nodes.emphasis(caption, caption)
+ innernode = nodes.inline(caption, caption)
+ innernode['classes'].append('doc')
newnode = nodes.reference('', '', internal=True)
newnode['refuri'] = builder.get_relative_uri(node['refdoc'], docname)
newnode.append(innernode)
@@ -1758,10 +1788,17 @@ class BuildEnvironment:
counter[secnum] = counter.get(secnum, 0) + 1
return secnum + (counter[secnum],)
- def register_fignumber(docname, secnum, figtype, figure_id):
+ def register_fignumber(docname, secnum, figtype, fignode):
self.toc_fignumbers.setdefault(docname, {})
fignumbers = self.toc_fignumbers[docname].setdefault(figtype, {})
- fignumbers[figure_id] = get_next_fignumber(figtype, secnum)
+ figure_id = fignode['ids'][0]
+
+ if (isinstance(fignode, nodes.image) and
+ isinstance(fignode.parent, nodes.figure) and
+ fignode.parent['ids']):
+ fignumbers[figure_id] = fignumbers[fignode.parent['ids'][0]]
+ else:
+ fignumbers[figure_id] = get_next_fignumber(figtype, secnum)
def _walk_doctree(docname, doctree, secnum):
for subnode in doctree.children:
@@ -1784,8 +1821,7 @@ class BuildEnvironment:
figtype = get_figtype(subnode)
if figtype and subnode['ids']:
- register_fignumber(docname, secnum,
- figtype, subnode['ids'][0])
+ register_fignumber(docname, secnum, figtype, subnode)
_walk_doctree(docname, subnode, secnum)
@@ -1911,8 +1947,8 @@ class BuildEnvironment:
else:
# get all other symbols under one heading
return _('Symbols')
- return [(key, list(group))
- for (key, group) in groupby(newlist, keyfunc2)]
+ return [(key_, list(group))
+ for (key_, group) in groupby(newlist, keyfunc2)]
def collect_relations(self):
relations = {}