Merge branch 'stable'

This commit is contained in:
Takeshi KOMIYA 2017-05-28 23:26:16 +09:00
commit de11e54955
7 changed files with 74 additions and 8 deletions

View File

@ -91,6 +91,9 @@ Bugs fixed
* #3791: PDF "continued on next page" for long tables isn't internationalized
* #3788: smartquotes emits warnings for unsupported languages
* #3807: docs do not say Latexmk is dependency on Windows for ``make latexpdf``
* #3781: double hyphens in option directive are compiled as endashes
* #3817: latex builder raises AttributeError
Testing
--------

View File

@ -83,6 +83,7 @@ builtin_extensions = (
'sphinx.directives.code',
'sphinx.directives.other',
'sphinx.directives.patches',
'sphinx.parsers',
'sphinx.roles',
'sphinx.transforms.post_transforms',
'sphinx.transforms.post_transforms.images',
@ -263,7 +264,7 @@ class Sphinx(object):
for suffix, parser in iteritems(self.config.source_parsers):
self.add_source_parser(suffix, parser)
for suffix, parser in iteritems(self.registry.get_source_parsers()):
if suffix not in self.config.source_suffix:
if suffix not in self.config.source_suffix and suffix != '*':
self.config.source_suffix.append(suffix)
def _init_env(self, freshenv):

View File

@ -20,6 +20,7 @@ from hashlib import md5
from six import iteritems, text_type, string_types
from six.moves import cPickle as pickle
import docutils
from docutils import nodes
from docutils.io import DocTreeInput, StringOutput
from docutils.core import Publisher
@ -34,7 +35,7 @@ from sphinx.util.inventory import InventoryFile
from sphinx.util.osutil import SEP, os_path, relative_uri, ensuredir, \
movefile, copyfile
from sphinx.util.nodes import inline_all_toctrees
from sphinx.util.docutils import is_html5_writer_available, __version_info__
from sphinx.util.docutils import is_html5_writer_available
from sphinx.util.fileutil import copy_asset
from sphinx.util.matching import patmatch, Matcher, DOTFILES
from sphinx.config import string_classes
@ -214,10 +215,9 @@ class StandaloneHTMLBuilder(Builder):
self.use_index = self.get_builder_config('use_index', 'html')
if self.config.html_experimental_html5_writer and not html5_ready:
self.app.warn(' '.join((
'html_experimental_html5_writer is set, but current version is old.',
'Docutils\' version should be or newer than 0.13, but %s.',
)) % '.'.join(map(str, __version_info__)))
self.app.warn(('html_experimental_html5_writer is set, but current version '
'is old. Docutils\' version should be 0.13 or newer, but %s.') %
docutils.__version__)
def _get_translations_js(self):
# type: () -> unicode

View File

@ -63,6 +63,9 @@ class SphinxBaseReader(standalone.Reader):
if source.source_path.endswith(suffix):
self.parser = self.parser_map[suffix]
break
else:
# use special parser for unknown file-extension '*' (if exists)
self.parser = self.parser_map.get('*')
if not self.parser:
self.parser = parser

View File

@ -10,9 +10,15 @@
"""
import docutils.parsers
import docutils.parsers.rst
from docutils.transforms.universal import SmartQuotes
from sphinx.transforms import SphinxSmartQuotes
if False:
# For type annotation
from typing import Any, Dict, List, Type # NOQA
from docutils.transforms import Transform # NOQA
from sphinx.application import Sphinx # NOQA
@ -47,3 +53,26 @@ class Parser(docutils.parsers.Parser):
self.env = app.env
self.warn = app.warn
self.info = app.info
class RSTParser(docutils.parsers.rst.Parser):
"""A reST parser customized for Sphinx."""
def get_transforms(self):
# type: () -> List[Type[Transform]]
"""Sphinx's reST parser replaces a transform class for smart-quotes by own's"""
transforms = docutils.parsers.rst.Parser.get_transforms(self)
transforms.remove(SmartQuotes)
transforms.append(SphinxSmartQuotes)
return transforms
def setup(app):
# type: (Sphinx) -> Dict[unicode, Any]
app.add_source_parser('*', RSTParser) # register as a special parser
return {
'version': 'builtin',
'parallel_read_safe': True,
'parallel_write_safe': True,
}

View File

@ -13,6 +13,7 @@ from docutils import nodes
from docutils.transforms import Transform, Transformer
from docutils.transforms.parts import ContentsFilter
from docutils.utils import new_document
from docutils.transforms.universal import SmartQuotes
from sphinx import addnodes
from sphinx.locale import _
@ -85,7 +86,7 @@ class SphinxTransformer(Transformer):
def apply_transforms(self):
# type: () -> None
if isinstance(self.document, nodes.document):
if hasattr(self.document.settings, 'env') and self.env:
if not hasattr(self.document.settings, 'env') and self.env:
self.document.settings.env = self.env
Transformer.apply_transforms(self)
@ -327,3 +328,32 @@ class SphinxContentsFilter(ContentsFilter):
def visit_image(self, node):
# type: (nodes.Node) -> None
raise nodes.SkipNode
class SphinxSmartQuotes(SmartQuotes):
"""
Customized SmartQuotes to avoid transform for some extra node types.
refs: sphinx.parsers.RSTParser
"""
def get_tokens(self, txtnodes):
# A generator that yields ``(texttype, nodetext)`` tuples for a list
# of "Text" nodes (interface to ``smartquotes.educate_tokens()``).
texttype = {True: 'literal', # "literal" text is not changed:
False: 'plain'}
for txtnode in txtnodes:
nodetype = texttype[isinstance(txtnode.parent,
(nodes.literal,
nodes.literal_block,
addnodes.literal_emphasis,
addnodes.literal_strong,
addnodes.desc_signature,
addnodes.productionlist,
addnodes.desc_optional,
addnodes.desc_name,
nodes.math,
nodes.image,
nodes.raw,
nodes.problematic))]
yield (nodetype, txtnode.astext())

View File

@ -83,6 +83,6 @@ def test_domain_override(app, status, warning):
@pytest.mark.sphinx(testroot='add_source_parser')
def test_add_source_parser(app, status, warning):
assert set(app.config.source_suffix) == set(['.rst', '.md', '.test'])
assert set(app.registry.get_source_parsers().keys()) == set(['.md', '.test'])
assert set(app.registry.get_source_parsers().keys()) == set(['*', '.md', '.test'])
assert app.registry.get_source_parsers()['.md'].__name__ == 'DummyMarkdownParser'
assert app.registry.get_source_parsers()['.test'].__name__ == 'TestSourceParser'