mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Merge branch 'stable'
This commit is contained in:
commit
de11e54955
3
CHANGES
3
CHANGES
@ -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
|
||||
--------
|
||||
|
@ -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):
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
}
|
||||
|
@ -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())
|
||||
|
@ -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'
|
||||
|
Loading…
Reference in New Issue
Block a user