From a9256bfa707f5f0816ff554dcc44f1808b707d22 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Thu, 6 Apr 2017 09:41:49 +0900 Subject: [PATCH 01/32] Remove Sphinx.egg-info on `make clean` --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index 101cfca2c..6df3ef0ad 100644 --- a/Makefile +++ b/Makefile @@ -56,6 +56,7 @@ clean-backupfiles: clean-generated: find . -name '.DS_Store' -exec rm -f {} + + rm -rf Sphinx.egg-info/ rm -rf doc/_build/ rm -f sphinx/pycode/*.pickle rm -f utils/*3.py* From b6e4cceb8f34483d46a6cbf4410cad91f50531bf Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Sat, 8 Apr 2017 13:41:06 +0900 Subject: [PATCH 02/32] Fix #3614: Sphinx crashes with requests-2.5.0 --- CHANGES | 2 ++ sphinx/util/requests.py | 14 ++++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index 6ef2c3b2b..e192bf5b7 100644 --- a/CHANGES +++ b/CHANGES @@ -13,6 +13,8 @@ Features added Bugs fixed ---------- +* #3614: Sphinx crashes with requests-2.5.0 + Testing -------- diff --git a/sphinx/util/requests.py b/sphinx/util/requests.py index 48d9ae93a..9fe4cfdcd 100644 --- a/sphinx/util/requests.py +++ b/sphinx/util/requests.py @@ -36,6 +36,16 @@ except ImportError: # for requests < 2.4.0 InsecureRequestWarning = None +try: + from requests.packages.urllib3.exceptions import InsecurePlatformWarning +except ImportError: + try: + # for Debian-jessie + from urllib3.exceptions import InsecurePlatformWarning + except ImportError: + # for requests < 2.4.0 + InsecurePlatformWarning = None + # try to load requests[security] (but only if SSL is available) try: import ssl @@ -48,8 +58,8 @@ else: pkg_resources.VersionConflict): if not getattr(ssl, 'HAS_SNI', False): # don't complain on each url processed about the SSL issue - requests.packages.urllib3.disable_warnings( - requests.packages.urllib3.exceptions.InsecurePlatformWarning) + if InsecurePlatformWarning: + requests.packages.urllib3.disable_warnings(InsecurePlatformWarning) warnings.warn( 'Some links may return broken results due to being unable to ' 'check the Server Name Indication (SNI) in the returned SSL cert ' From b8fe49b0a43f8415e957a85bc005767c036eedf1 Mon Sep 17 00:00:00 2001 From: shimizukawa Date: Mon, 10 Apr 2017 10:33:53 +0900 Subject: [PATCH 03/32] add appveyor for testing on Windows --- .appveyor.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 .appveyor.yml diff --git a/.appveyor.yml b/.appveyor.yml new file mode 100644 index 000000000..0e40891d7 --- /dev/null +++ b/.appveyor.yml @@ -0,0 +1,11 @@ +environment: + matrix: + - PYTHON: 36-x64 + +install: + - pip install -U pip setuptools + - pip install -r test-reqs.txt + +test_script: + - tox -e py36 -- -vvv + From 317c86e9b926135f2cc1dfdee56a57ce06850d74 Mon Sep 17 00:00:00 2001 From: shimizukawa Date: Mon, 10 Apr 2017 10:34:53 +0900 Subject: [PATCH 04/32] Revert "add appveyor for testing on Windows" This reverts commit b8fe49b0a43f8415e957a85bc005767c036eedf1. --- .appveyor.yml | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 .appveyor.yml diff --git a/.appveyor.yml b/.appveyor.yml deleted file mode 100644 index 0e40891d7..000000000 --- a/.appveyor.yml +++ /dev/null @@ -1,11 +0,0 @@ -environment: - matrix: - - PYTHON: 36-x64 - -install: - - pip install -U pip setuptools - - pip install -r test-reqs.txt - -test_script: - - tox -e py36 -- -vvv - From 7897678777982e942aa6c22b823aced7ffd07095 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Tue, 11 Apr 2017 23:44:17 +0900 Subject: [PATCH 05/32] Fix #3618: autodoc crashes with tupled arguments --- CHANGES | 1 + sphinx/ext/autodoc.py | 17 +++++++++++++---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/CHANGES b/CHANGES index e192bf5b7..4035a50ce 100644 --- a/CHANGES +++ b/CHANGES @@ -14,6 +14,7 @@ Bugs fixed ---------- * #3614: Sphinx crashes with requests-2.5.0 +* #3618: autodoc crashes with tupled arguments Testing -------- diff --git a/sphinx/ext/autodoc.py b/sphinx/ext/autodoc.py index 9e513276f..9203e673b 100644 --- a/sphinx/ext/autodoc.py +++ b/sphinx/ext/autodoc.py @@ -380,10 +380,19 @@ def formatargspec(function, args, varargs=None, varkw=None, defaults=None, for i, arg in enumerate(args): arg_fd = StringIO() - arg_fd.write(format_arg_with_annotation(arg)) - if defaults and i >= defaults_start: - arg_fd.write(' = ' if arg in annotations else '=') - arg_fd.write(object_description(defaults[i - defaults_start])) + if isinstance(arg, list): + # support tupled arguments list (only for py2): def foo((x, y)) + arg_fd.write('(') + arg_fd.write(format_arg_with_annotation(arg[0])) + for param in arg[1:]: + arg_fd.write(', ') + arg_fd.write(format_arg_with_annotation(param)) + arg_fd.write(')') + else: + arg_fd.write(format_arg_with_annotation(arg)) + if defaults and i >= defaults_start: + arg_fd.write(' = ' if arg in annotations else '=') + arg_fd.write(object_description(defaults[i - defaults_start])) formatted.append(arg_fd.getvalue()) if varargs: From ac1020b540c7f5d04ebcc428b48fea5053fe734a Mon Sep 17 00:00:00 2001 From: jfbu Date: Mon, 24 Apr 2017 10:19:49 +0200 Subject: [PATCH 06/32] Remove empty 1.5.6 section in CHANGES file --- CHANGES | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/CHANGES b/CHANGES index 979c39ff3..bb682a792 100644 --- a/CHANGES +++ b/CHANGES @@ -193,24 +193,6 @@ Deprecated * #3628: ``sphinx_themes`` entry_point is deprecated. Please use ``sphinx.html_themes`` instead. -Release 1.5.6 (in development) -============================== - -Incompatible changes --------------------- - -Deprecated ----------- - -Features added --------------- - -Bugs fixed ----------- - -Testing --------- - Release 1.5.5 (released Apr 03, 2017) ===================================== From 2807175f10158da274d7a3714d0dc612bbcff403 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Tue, 25 Apr 2017 00:36:42 +0900 Subject: [PATCH 07/32] Fix #3661: sphinx-build crashes on parallel build --- CHANGES | 2 ++ sphinx/environment/__init__.py | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/CHANGES b/CHANGES index bb682a792..aecd3ce5b 100644 --- a/CHANGES +++ b/CHANGES @@ -13,6 +13,8 @@ Features added Bugs fixed ---------- +* #3661: sphinx-build crashes on parallel build + Testing -------- diff --git a/sphinx/environment/__init__.py b/sphinx/environment/__init__.py index 066f57209..fd89a07e4 100644 --- a/sphinx/environment/__init__.py +++ b/sphinx/environment/__init__.py @@ -20,7 +20,7 @@ import warnings from os import path from collections import defaultdict -from six import StringIO, itervalues, class_types, next +from six import BytesIO, itervalues, class_types, next from six.moves import cPickle as pickle from docutils.io import NullOutput @@ -121,7 +121,7 @@ class BuildEnvironment(object): @classmethod def loads(cls, string, app=None): # type: (unicode, Sphinx) -> BuildEnvironment - io = StringIO(string) + io = BytesIO(string) return cls.load(io, app) @classmethod @@ -156,7 +156,7 @@ class BuildEnvironment(object): @classmethod def dumps(cls, env): # type: (BuildEnvironment) -> unicode - io = StringIO() + io = BytesIO() cls.dump(env, io) return io.getvalue() From 10afb48b8e6e6db61dec9665ae3bd7035b571853 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Tue, 25 Apr 2017 00:39:00 +0900 Subject: [PATCH 08/32] Revert "Remove empty 1.5.6 section in CHANGES file" This reverts commit ac1020b540c7f5d04ebcc428b48fea5053fe734a. --- CHANGES | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/CHANGES b/CHANGES index aecd3ce5b..77f75a6c5 100644 --- a/CHANGES +++ b/CHANGES @@ -195,6 +195,24 @@ Deprecated * #3628: ``sphinx_themes`` entry_point is deprecated. Please use ``sphinx.html_themes`` instead. +Release 1.5.6 (in development) +============================== + +Incompatible changes +-------------------- + +Deprecated +---------- + +Features added +-------------- + +Bugs fixed +---------- + +Testing +-------- + Release 1.5.5 (released Apr 03, 2017) ===================================== From 7c2f5f16eb1898e8b154d1a9bcfa13782b3c2d24 Mon Sep 17 00:00:00 2001 From: jfbu Date: Tue, 25 Apr 2017 10:14:53 +0200 Subject: [PATCH 09/32] Fix #3664 relative to ``\labelsep`` setting in LaTeX fulllineitems This also removes re-definition of description environment which is not needed anymore as ``\labelsep`` is not modified. --- CHANGES | 1 + sphinx/texinputs/sphinx.sty | 21 +++++++-------------- 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/CHANGES b/CHANGES index 4035a50ce..b38d91c4d 100644 --- a/CHANGES +++ b/CHANGES @@ -15,6 +15,7 @@ Bugs fixed * #3614: Sphinx crashes with requests-2.5.0 * #3618: autodoc crashes with tupled arguments +* #3664: No space after the bullet in items of a latex list produced by Sphinx Testing -------- diff --git a/sphinx/texinputs/sphinx.sty b/sphinx/texinputs/sphinx.sty index 571f26c72..9c2a0d72f 100644 --- a/sphinx/texinputs/sphinx.sty +++ b/sphinx/texinputs/sphinx.sty @@ -6,7 +6,7 @@ % \NeedsTeXFormat{LaTeX2e}[1995/12/01] -\ProvidesPackage{sphinx}[2017/03/26 v1.5.4 LaTeX package (Sphinx markup)] +\ProvidesPackage{sphinx}[2017/04/25 v1.5.6 LaTeX package (Sphinx markup)] % this is the \ltx@ifundefined of ltxcmds.sty, which is loaded by % kvoptions (and later by hyperref), but the first release of @@ -1164,26 +1164,19 @@ % {fulllineitems} is the main environment for object descriptions. % \newcommand{\py@itemnewline}[1]{% + \kern\labelsep \@tempdima\linewidth - \advance\@tempdima \leftmargin\makebox[\@tempdima][l]{#1}% + \advance\@tempdima \labelwidth\makebox[\@tempdima][l]{#1}% + \kern-\labelsep } -\newenvironment{fulllineitems}{ - \begin{list}{}{\labelwidth \leftmargin \labelsep \z@ +\newenvironment{fulllineitems}{% + \begin{list}{}{\labelwidth \leftmargin \rightmargin \z@ \topsep -\parskip \partopsep \parskip \itemsep -\parsep - \let\makelabel=\py@itemnewline} + \let\makelabel=\py@itemnewline}% }{\end{list}} -% Redefine description environment so that it is usable inside fulllineitems. -% -% FIXME: use sphinxdescription, do not redefine description environment! -\renewcommand{\description}{% - \list{}{\labelwidth\z@ - \itemindent-\leftmargin - \labelsep5pt\relax - \let\makelabel=\descriptionlabel}} - % Signatures, possibly multi-line % \newlength{\py@argswidth} From 710ddb388045184f921666b2ad7aef16d131de3f Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Tue, 25 Apr 2017 20:05:18 +0900 Subject: [PATCH 10/32] Fix mypy violations --- sphinx/util/requests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sphinx/util/requests.py b/sphinx/util/requests.py index 09b7a43b1..6834e6368 100644 --- a/sphinx/util/requests.py +++ b/sphinx/util/requests.py @@ -41,7 +41,7 @@ try: except ImportError: try: # for Debian-jessie - from urllib3.exceptions import InsecurePlatformWarning + from urllib3.exceptions import InsecurePlatformWarning # type: ignore except ImportError: # for requests < 2.4.0 InsecurePlatformWarning = None From b3f596a1330137cf34bc9163cbeebba52ab511e5 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Tue, 25 Apr 2017 01:16:19 +0900 Subject: [PATCH 11/32] Fix #3662: ``builder.css_files`` is deprecated --- CHANGES | 3 +++ sphinx/builders/html.py | 33 ++++++++++++++++++++++++++++++++- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 0d72fa989..2e4e6f676 100644 --- a/CHANGES +++ b/CHANGES @@ -7,6 +7,9 @@ Incompatible changes Deprecated ---------- +* #3662: ``builder.css_files`` is deprecated. Please use ``add_stylesheet()`` + API instead. + Features added -------------- diff --git a/sphinx/builders/html.py b/sphinx/builders/html.py index 7369ea23d..cea14965a 100644 --- a/sphinx/builders/html.py +++ b/sphinx/builders/html.py @@ -13,6 +13,7 @@ import os import re import sys import codecs +import warnings import posixpath from os import path from hashlib import md5 @@ -38,6 +39,7 @@ from sphinx.util.docutils import is_html5_writer_available, __version_info__ from sphinx.util.fileutil import copy_asset from sphinx.util.matching import patmatch, Matcher, DOTFILES from sphinx.config import string_classes +from sphinx.deprecation import RemovedInSphinx20Warning from sphinx.locale import _, l_ from sphinx.search import js_index from sphinx.theming import HTMLThemeFactory @@ -87,6 +89,35 @@ def get_stable_hash(obj): return md5(text_type(obj).encode('utf8')).hexdigest() +class CSSContainer(list): + """The container of stylesheets. + + To support the extensions which access the container directly, this wraps + the entry with Stylesheet class. + """ + def append(self, obj): + warnings.warn('builder.css_files is deprecated. ' + 'Please use app.add_stylesheet() instead.', + RemovedInSphinx20Warning) + if isinstance(obj, Stylesheet): + super(CSSContainer, self).append(obj) + else: + super(CSSContainer, self).append(Stylesheet(obj, None, 'stylesheet')) + + def extend(self, other): + for item in other: + self.append(item) + + def __iadd__(self, other): + for item in other: + self.append(item) + + def __add__(self, other): + ret = CSSContainer(self) + ret += other + return ret + + class Stylesheet(text_type): """The metadata of stylesheet. @@ -136,7 +167,7 @@ class StandaloneHTMLBuilder(Builder): script_files = ['_static/jquery.js', '_static/underscore.js', '_static/doctools.js'] # type: List[unicode] # Ditto for this one (Sphinx.add_stylesheet). - css_files = [] # type: List[Dict[unicode, unicode]] + css_files = CSSContainer() # type: List[Dict[unicode, unicode]] imgpath = None # type: unicode domain_indices = [] # type: List[Tuple[unicode, Type[Index], List[Tuple[unicode, List[List[Union[unicode, int]]]]], bool]] # NOQA From edc7f30b9cc92f4d721eeef62ffa826f23a09a9f Mon Sep 17 00:00:00 2001 From: Dmitry Shachnev Date: Tue, 14 Mar 2017 23:43:04 +0300 Subject: [PATCH 12/32] Remove the custom smartypants code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead rely on docutils’ ‘smart_quotes’ option which is available since docutils 0.10. This adds support for internationalization: our code supported only English quotes, while docutils code supports 27 different languages. Closes #498, #580, #3345, #3472. --- sphinx/builders/_epub_base.py | 14 +- sphinx/builders/html.py | 15 +- sphinx/environment/__init__.py | 5 + sphinx/util/smartypants.py | 312 ------------------------------ sphinx/writers/html.py | 94 --------- sphinx/writers/html5.py | 94 --------- sphinx/writers/latex.py | 5 - tests/test_api_translator.py | 9 - tests/test_build_epub.py | 8 +- tests/test_environment_toctree.py | 6 +- tests/test_markup.py | 11 +- tests/test_metadata.py | 4 +- 12 files changed, 38 insertions(+), 539 deletions(-) delete mode 100644 sphinx/util/smartypants.py diff --git a/sphinx/builders/_epub_base.py b/sphinx/builders/_epub_base.py index f7ebaa0e8..a63ecbc39 100644 --- a/sphinx/builders/_epub_base.py +++ b/sphinx/builders/_epub_base.py @@ -25,6 +25,7 @@ except ImportError: Image = None from docutils import nodes +from docutils.utils import smartquotes from sphinx import addnodes from sphinx.builders.html import StandaloneHTMLBuilder @@ -32,7 +33,6 @@ from sphinx.util import logging from sphinx.util import status_iterator from sphinx.util.osutil import ensuredir, copyfile from sphinx.util.fileutil import copy_asset_file -from sphinx.util.smartypants import sphinx_smarty_pants as ssp if False: # For type annotation @@ -94,6 +94,18 @@ Guide = namedtuple('Guide', ['type', 'title', 'uri']) NavPoint = namedtuple('NavPoint', ['navpoint', 'playorder', 'text', 'refuri', 'children']) +def sphinx_smarty_pants(t, language='en'): + # type: (unicode, str) -> unicode + t = t.replace('"', '"') + t = smartquotes.educateDashesOldSchool(t) + t = smartquotes.educateQuotes(t, language) + t = t.replace('"', '"') + return t + + +ssp = sphinx_smarty_pants + + # The epub publisher class EpubBuilder(StandaloneHTMLBuilder): diff --git a/sphinx/builders/html.py b/sphinx/builders/html.py index 7369ea23d..a0b3d8e87 100644 --- a/sphinx/builders/html.py +++ b/sphinx/builders/html.py @@ -45,8 +45,7 @@ from sphinx.builders import Builder from sphinx.application import ENV_PICKLE_FILENAME from sphinx.highlighting import PygmentsBridge from sphinx.util.console import bold, darkgreen # type: ignore -from sphinx.writers.html import HTMLWriter, HTMLTranslator, \ - SmartyPantsHTMLTranslator +from sphinx.writers.html import HTMLWriter, HTMLTranslator from sphinx.environment.adapters.asset import ImageAdapter from sphinx.environment.adapters.toctree import TocTree from sphinx.environment.adapters.indexentries import IndexEntries @@ -59,7 +58,7 @@ if False: # Experimental HTML5 Writer if is_html5_writer_available(): - from sphinx.writers.html5 import HTML5Translator, SmartyPantsHTML5Translator + from sphinx.writers.html5 import HTML5Translator html5_ready = True else: html5_ready = False @@ -220,15 +219,9 @@ class StandaloneHTMLBuilder(Builder): @property def default_translator_class(self): if self.config.html_experimental_html5_writer and html5_ready: - if self.config.html_use_smartypants: - return SmartyPantsHTML5Translator - else: - return HTML5Translator + return HTML5Translator else: - if self.config.html_use_smartypants: - return SmartyPantsHTMLTranslator - else: - return HTMLTranslator + return HTMLTranslator def get_outdated_docs(self): # type: () -> Iterator[unicode] diff --git a/sphinx/environment/__init__.py b/sphinx/environment/__init__.py index fd89a07e4..b0a1a2ce5 100644 --- a/sphinx/environment/__init__.py +++ b/sphinx/environment/__init__.py @@ -26,6 +26,7 @@ from six.moves import cPickle as pickle from docutils.io import NullOutput from docutils.core import Publisher from docutils.utils import Reporter, get_source_line +from docutils.utils.smartquotes import smartchars from docutils.parsers.rst import roles from docutils.parsers.rst.languages import en as english from docutils.frontend import OptionParser @@ -671,6 +672,10 @@ class BuildEnvironment(object): self.settings['trim_footnote_reference_space'] = \ self.config.trim_footnote_reference_space self.settings['gettext_compact'] = self.config.gettext_compact + language = (self.config.language or 'en').replace('_', '-') + self.settings['language_code'] = language + if language in smartchars.quotes: + self.settings['smart_quotes'] = self.config.html_use_smartypants docutilsconf = path.join(self.srcdir, 'docutils.conf') # read docutils.conf from source dir, not from current dir diff --git a/sphinx/util/smartypants.py b/sphinx/util/smartypants.py deleted file mode 100644 index 0146ba6e9..000000000 --- a/sphinx/util/smartypants.py +++ /dev/null @@ -1,312 +0,0 @@ -r""" -This is based on SmartyPants.py by `Chad Miller`_ , -version 1.5_1.6. - -Copyright and License -===================== - -SmartyPants_ license:: - - Copyright (c) 2003 John Gruber - (http://daringfireball.net/) - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - - * Neither the name "SmartyPants" nor the names of its contributors - may be used to endorse or promote products derived from this - software without specific prior written permission. - - This software is provided by the copyright holders and contributors "as - is" and any express or implied warranties, including, but not limited - to, the implied warranties of merchantability and fitness for a - particular purpose are disclaimed. In no event shall the copyright - owner or contributors be liable for any direct, indirect, incidental, - special, exemplary, or consequential damages (including, but not - limited to, procurement of substitute goods or services; loss of use, - data, or profits; or business interruption) however caused and on any - theory of liability, whether in contract, strict liability, or tort - (including negligence or otherwise) arising in any way out of the use - of this software, even if advised of the possibility of such damage. - - -smartypants.py license:: - - smartypants.py is a derivative work of SmartyPants. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - - This software is provided by the copyright holders and contributors "as - is" and any express or implied warranties, including, but not limited - to, the implied warranties of merchantability and fitness for a - particular purpose are disclaimed. In no event shall the copyright - owner or contributors be liable for any direct, indirect, incidental, - special, exemplary, or consequential damages (including, but not - limited to, procurement of substitute goods or services; loss of use, - data, or profits; or business interruption) however caused and on any - theory of liability, whether in contract, strict liability, or tort - (including negligence or otherwise) arising in any way out of the use - of this software, even if advised of the possibility of such damage. - -.. _Chad Miller: http://web.chad.org/ -""" - -import re - -if False: - # For type annotation - from typing import Tuple # NOQA - - -def sphinx_smarty_pants(t): - # type: (unicode) -> unicode - t = t.replace('"', '"') - t = educate_dashes_oldschool(t) - t = educate_quotes(t) # type: ignore - t = t.replace('"', '"') - return t - - -# Constants for quote education. -punct_class = r"""[!"#\$\%'()*+,-.\/:;<=>?\@\[\\\]\^_`{|}~]""" -end_of_word_class = r"""[\s.,;:!?)]""" -close_class = r"""[^\ \t\r\n\[\{\(\-]""" -dec_dashes = r"""–|—""" - -# Special case if the very first character is a quote -# followed by punctuation at a non-word-break. Close the quotes by brute force: -single_quote_start_re = re.compile(r"""^'(?=%s\\B)""" % (punct_class,)) -double_quote_start_re = re.compile(r"""^"(?=%s\\B)""" % (punct_class,)) - -# Special case for double sets of quotes, e.g.: -#

He said, "'Quoted' words in a larger quote."

-double_quote_sets_re = re.compile(r""""'(?=\w)""") -single_quote_sets_re = re.compile(r"""'"(?=\w)""") - -# Special case for decade abbreviations (the '80s): -decade_abbr_re = re.compile(r"""\b'(?=\d{2}s)""") - -# Get most opening double quotes: -opening_double_quotes_regex = re.compile(r""" - ( - \s | # a whitespace char, or -   | # a non-breaking space entity, or - -- | # dashes, or - &[mn]dash; | # named dash entities - %s | # or decimal entities - &\#x201[34]; # or hex - ) - " # the quote - (?=\w) # followed by a word character - """ % (dec_dashes,), re.VERBOSE) - -# Double closing quotes: -closing_double_quotes_regex = re.compile(r""" - #(%s)? # character that indicates the quote should be closing - " - (?=%s) - """ % (close_class, end_of_word_class), re.VERBOSE) - -closing_double_quotes_regex_2 = re.compile(r""" - (%s) # character that indicates the quote should be closing - " - """ % (close_class,), re.VERBOSE) - -# Get most opening single quotes: -opening_single_quotes_regex = re.compile(r""" - ( - \s | # a whitespace char, or -   | # a non-breaking space entity, or - -- | # dashes, or - &[mn]dash; | # named dash entities - %s | # or decimal entities - &\#x201[34]; # or hex - ) - ' # the quote - (?=\w) # followed by a word character - """ % (dec_dashes,), re.VERBOSE) - -closing_single_quotes_regex = re.compile(r""" - (%s) - ' - (?!\s | s\b | \d) - """ % (close_class,), re.VERBOSE) - -closing_single_quotes_regex_2 = re.compile(r""" - (%s) - ' - (\s | s\b) - """ % (close_class,), re.VERBOSE) - - -def educate_quotes(s): - # type: (str) -> str - """ - Parameter: String. - - Returns: The string, with "educated" curly quote HTML entities. - - Example input: "Isn't this fun?" - Example output: “Isn’t this fun?” - """ - - # Special case if the very first character is a quote - # followed by punctuation at a non-word-break. Close the quotes - # by brute force: - s = single_quote_start_re.sub("’", s) - s = double_quote_start_re.sub("”", s) - - # Special case for double sets of quotes, e.g.: - #

He said, "'Quoted' words in a larger quote."

- s = double_quote_sets_re.sub("“‘", s) - s = single_quote_sets_re.sub("‘“", s) - - # Special case for decade abbreviations (the '80s): - s = decade_abbr_re.sub("’", s) - - s = opening_single_quotes_regex.sub(r"\1‘", s) - s = closing_single_quotes_regex.sub(r"\1’", s) - s = closing_single_quotes_regex_2.sub(r"\1’\2", s) - - # Any remaining single quotes should be opening ones: - s = s.replace("'", "‘") - - s = opening_double_quotes_regex.sub(r"\1“", s) - s = closing_double_quotes_regex.sub(r"”", s) - s = closing_double_quotes_regex_2.sub(r"\1”", s) - - # Any remaining quotes should be opening ones. - return s.replace('"', "“") - - -def educate_quotes_latex(s, dquotes=("``", "''")): - # type: (str, Tuple[str, str]) -> unicode - """ - Parameter: String. - - Returns: The string, with double quotes corrected to LaTeX quotes. - - Example input: "Isn't this fun?" - Example output: ``Isn't this fun?''; - """ - - # Special case if the very first character is a quote - # followed by punctuation at a non-word-break. Close the quotes - # by brute force: - s = single_quote_start_re.sub("\x04", s) - s = double_quote_start_re.sub("\x02", s) - - # Special case for double sets of quotes, e.g.: - #

He said, "'Quoted' words in a larger quote."

- s = double_quote_sets_re.sub("\x01\x03", s) - s = single_quote_sets_re.sub("\x03\x01", s) - - # Special case for decade abbreviations (the '80s): - s = decade_abbr_re.sub("\x04", s) - - s = opening_single_quotes_regex.sub("\\1\x03", s) - s = closing_single_quotes_regex.sub("\\1\x04", s) - s = closing_single_quotes_regex_2.sub("\\1\x04\\2", s) - - # Any remaining single quotes should be opening ones: - s = s.replace("'", "\x03") - - s = opening_double_quotes_regex.sub("\\1\x01", s) - s = closing_double_quotes_regex.sub("\x02", s) - s = closing_double_quotes_regex_2.sub("\\1\x02", s) - - # Any remaining quotes should be opening ones. - s = s.replace('"', "\x01") - - # Finally, replace all helpers with quotes. - return s.replace("\x01", dquotes[0]).replace("\x02", dquotes[1]).\ - replace("\x03", "`").replace("\x04", "'") - - -def educate_backticks(s): - # type: (unicode) -> unicode - """ - Parameter: String. - Returns: The string, with ``backticks'' -style double quotes - translated into HTML curly quote entities. - Example input: ``Isn't this fun?'' - Example output: “Isn't this fun?” - """ - return s.replace("``", "“").replace("''", "”") - - -def educate_single_backticks(s): - # type: (unicode) -> unicode - """ - Parameter: String. - Returns: The string, with `backticks' -style single quotes - translated into HTML curly quote entities. - - Example input: `Isn't this fun?' - Example output: ‘Isn’t this fun?’ - """ - return s.replace('`', "‘").replace("'", "’") - - -def educate_dashes_oldschool(s): - # type: (unicode) -> unicode - """ - Parameter: String. - - Returns: The string, with each instance of "--" translated to - an en-dash HTML entity, and each "---" translated to - an em-dash HTML entity. - """ - return s.replace('---', "—").replace('--', "–") - - -def educate_dashes_oldschool_inverted(s): - # type: (unicode) -> unicode - """ - Parameter: String. - - Returns: The string, with each instance of "--" translated to - an em-dash HTML entity, and each "---" translated to - an en-dash HTML entity. Two reasons why: First, unlike the - en- and em-dash syntax supported by - educate_dashes_oldschool(), it's compatible with existing - entries written before SmartyPants 1.1, back when "--" was - only used for em-dashes. Second, em-dashes are more - common than en-dashes, and so it sort of makes sense that - the shortcut should be shorter to type. (Thanks to Aaron - Swartz for the idea.) - """ - return s.replace('---', "–").replace('--', "—") - - -def educate_ellipses(s): - # type: (unicode) -> unicode - """ - Parameter: String. - Returns: The string, with each instance of "..." translated to - an ellipsis HTML entity. - - Example input: Huh...? - Example output: Huh…? - """ - return s.replace('...', "…").replace('. . .', "…") diff --git a/sphinx/writers/html.py b/sphinx/writers/html.py index 63aba3cd6..572b2825e 100644 --- a/sphinx/writers/html.py +++ b/sphinx/writers/html.py @@ -22,7 +22,6 @@ from sphinx import addnodes from sphinx.locale import admonitionlabels, _ from sphinx.util import logging from sphinx.util.images import get_image_size -from sphinx.util.smartypants import sphinx_smarty_pants if False: # For type annotation @@ -74,7 +73,6 @@ class HTMLTranslator(BaseTranslator): # type: (StandaloneHTMLBuilder, Any, Any) -> None BaseTranslator.__init__(self, *args, **kwds) self.highlighter = builder.highlighter - self.no_smarty = 0 self.builder = builder self.highlightlang = self.highlightlang_base = \ builder.config.highlight_language @@ -786,7 +784,6 @@ class HTMLTranslator(BaseTranslator): # type: (nodes.Node) -> None self.depart_admonition(node) - # these are only handled specially in the SmartyPantsHTMLTranslator def visit_literal_emphasis(self, node): # type: (nodes.Node) -> None return self.visit_emphasis(node) @@ -875,94 +872,3 @@ class HTMLTranslator(BaseTranslator): def unknown_visit(self, node): # type: (nodes.Node) -> None raise NotImplementedError('Unknown node: ' + node.__class__.__name__) - - -class SmartyPantsHTMLTranslator(HTMLTranslator): - """ - Handle ordinary text via smartypants, converting quotes and dashes - to the correct entities. - """ - - def __init__(self, *args, **kwds): - # type: (Any, Any) -> None - self.no_smarty = 0 - HTMLTranslator.__init__(self, *args, **kwds) - - def visit_literal(self, node): - # type: (nodes.Node) -> None - self.no_smarty += 1 - try: - # this raises SkipNode - HTMLTranslator.visit_literal(self, node) - finally: - self.no_smarty -= 1 - - def visit_literal_block(self, node): - # type: (nodes.Node) -> None - self.no_smarty += 1 - try: - HTMLTranslator.visit_literal_block(self, node) - except nodes.SkipNode: - # HTMLTranslator raises SkipNode for simple literal blocks, - # but not for parsed literal blocks - self.no_smarty -= 1 - raise - - def depart_literal_block(self, node): - # type: (nodes.Node) -> None - HTMLTranslator.depart_literal_block(self, node) - self.no_smarty -= 1 - - def visit_literal_emphasis(self, node): - # type: (nodes.Node) -> None - self.no_smarty += 1 - self.visit_emphasis(node) - - def depart_literal_emphasis(self, node): - # type: (nodes.Node) -> None - self.depart_emphasis(node) - self.no_smarty -= 1 - - def visit_literal_strong(self, node): - # type: (nodes.Node) -> None - self.no_smarty += 1 - self.visit_strong(node) - - def depart_literal_strong(self, node): - # type: (nodes.Node) -> None - self.depart_strong(node) - self.no_smarty -= 1 - - def visit_desc_signature(self, node): - # type: (nodes.Node) -> None - self.no_smarty += 1 - HTMLTranslator.visit_desc_signature(self, node) - - def depart_desc_signature(self, node): - # type: (nodes.Node) -> None - self.no_smarty -= 1 - HTMLTranslator.depart_desc_signature(self, node) - - def visit_productionlist(self, node): - # type: (nodes.Node) -> None - self.no_smarty += 1 - try: - HTMLTranslator.visit_productionlist(self, node) - finally: - self.no_smarty -= 1 - - def visit_option(self, node): - # type: (nodes.Node) -> None - self.no_smarty += 1 - HTMLTranslator.visit_option(self, node) - - def depart_option(self, node): - # type: (nodes.Node) -> None - self.no_smarty -= 1 - HTMLTranslator.depart_option(self, node) - - def bulk_text_processor(self, text): - # type: (unicode) -> unicode - if self.no_smarty <= 0: - return sphinx_smarty_pants(text) - return text diff --git a/sphinx/writers/html5.py b/sphinx/writers/html5.py index 9deb35a88..8e3843c09 100644 --- a/sphinx/writers/html5.py +++ b/sphinx/writers/html5.py @@ -21,7 +21,6 @@ from sphinx import addnodes from sphinx.locale import admonitionlabels, _ from sphinx.util import logging from sphinx.util.images import get_image_size -from sphinx.util.smartypants import sphinx_smarty_pants if False: # For type annotation @@ -44,7 +43,6 @@ class HTML5Translator(BaseTranslator): # type: (StandaloneHTMLBuilder, Any, Any) -> None BaseTranslator.__init__(self, *args, **kwds) self.highlighter = builder.highlighter - self.no_smarty = 0 self.builder = builder self.highlightlang = self.highlightlang_base = \ builder.config.highlight_language @@ -729,7 +727,6 @@ class HTML5Translator(BaseTranslator): # type: (nodes.Node) -> None self.depart_admonition(node) - # these are only handled specially in the SmartyPantsHTML5Translator def visit_literal_emphasis(self, node): # type: (nodes.Node) -> None return self.visit_emphasis(node) @@ -830,94 +827,3 @@ class HTML5Translator(BaseTranslator): def unknown_visit(self, node): # type: (nodes.Node) -> None raise NotImplementedError('Unknown node: ' + node.__class__.__name__) - - -class SmartyPantsHTML5Translator(HTML5Translator): - """ - Handle ordinary text via smartypants, converting quotes and dashes - to the correct entities. - """ - - def __init__(self, *args, **kwds): - # type: (Any, Any) -> None - self.no_smarty = 0 - HTML5Translator.__init__(self, *args, **kwds) - - def visit_literal(self, node): - # type: (nodes.Node) -> None - self.no_smarty += 1 - try: - # this raises SkipNode - HTML5Translator.visit_literal(self, node) - finally: - self.no_smarty -= 1 - - def visit_literal_block(self, node): - # type: (nodes.Node) -> None - self.no_smarty += 1 - try: - HTML5Translator.visit_literal_block(self, node) - except nodes.SkipNode: - # HTML5Translator raises SkipNode for simple literal blocks, - # but not for parsed literal blocks - self.no_smarty -= 1 - raise - - def depart_literal_block(self, node): - # type: (nodes.Node) -> None - HTML5Translator.depart_literal_block(self, node) - self.no_smarty -= 1 - - def visit_literal_emphasis(self, node): - # type: (nodes.Node) -> None - self.no_smarty += 1 - self.visit_emphasis(node) - - def depart_literal_emphasis(self, node): - # type: (nodes.Node) -> None - self.depart_emphasis(node) - self.no_smarty -= 1 - - def visit_literal_strong(self, node): - # type: (nodes.Node) -> None - self.no_smarty += 1 - self.visit_strong(node) - - def depart_literal_strong(self, node): - # type: (nodes.Node) -> None - self.depart_strong(node) - self.no_smarty -= 1 - - def visit_desc_signature(self, node): - # type: (nodes.Node) -> None - self.no_smarty += 1 - HTML5Translator.visit_desc_signature(self, node) - - def depart_desc_signature(self, node): - # type: (nodes.Node) -> None - self.no_smarty -= 1 - HTML5Translator.depart_desc_signature(self, node) - - def visit_productionlist(self, node): - # type: (nodes.Node) -> None - self.no_smarty += 1 - try: - HTML5Translator.visit_productionlist(self, node) - finally: - self.no_smarty -= 1 - - def visit_option(self, node): - # type: (nodes.Node) -> None - self.no_smarty += 1 - HTML5Translator.visit_option(self, node) - - def depart_option(self, node): - # type: (nodes.Node) -> None - self.no_smarty -= 1 - HTML5Translator.depart_option(self, node) - - def bulk_text_processor(self, text): - # type: (unicode) -> unicode - if self.no_smarty <= 0: - return sphinx_smarty_pants(text) - return text diff --git a/sphinx/writers/latex.py b/sphinx/writers/latex.py index fc2cbb272..c1e33374d 100644 --- a/sphinx/writers/latex.py +++ b/sphinx/writers/latex.py @@ -30,7 +30,6 @@ from sphinx.util.i18n import format_date from sphinx.util.nodes import clean_astext, traverse_parent from sphinx.util.template import LaTeXRenderer from sphinx.util.texescape import tex_escape_map, tex_replace_map -from sphinx.util.smartypants import educate_quotes_latex if False: # For type annotation @@ -2533,10 +2532,6 @@ class LaTeXTranslator(nodes.NodeVisitor): def visit_Text(self, node): # type: (nodes.Node) -> None text = self.encode(node.astext()) - if not self.no_contractions and not self.in_parsed_literal: - text = educate_quotes_latex(text, # type: ignore - dquotes=("\\sphinxquotedblleft{}", - "\\sphinxquotedblright{}")) self.body.append(text) def depart_Text(self, node): diff --git a/tests/test_api_translator.py b/tests/test_api_translator.py index 511fe1416..dadea50e5 100644 --- a/tests/test_api_translator.py +++ b/tests/test_api_translator.py @@ -28,15 +28,6 @@ def test_html_translator(app, status, warning): # no set_translator() translator_class = app.builder.get_translator_class() assert translator_class - assert translator_class.__name__ == 'SmartyPantsHTMLTranslator' - - -@pytest.mark.sphinx('html', confoverrides={ - 'html_use_smartypants': False}) -def test_html_with_smartypants(app, status, warning): - # no set_translator(), html_use_smartypants=False - translator_class = app.builder.get_translator_class() - assert translator_class assert translator_class.__name__ == 'HTMLTranslator' diff --git a/tests/test_build_epub.py b/tests/test_build_epub.py index cf0e2857a..e5d86b0ed 100644 --- a/tests/test_build_epub.py +++ b/tests/test_build_epub.py @@ -162,7 +162,7 @@ def test_nested_toc(app): app.build() # toc.ncx - toc = EPUBElementTree.fromstring((app.outdir / 'toc.ncx').text()) + toc = EPUBElementTree.fromstring((app.outdir / 'toc.ncx').bytes()) assert toc.find("./ncx:docTitle/ncx:text").text == 'Python documentation' # toc.ncx / navPoint @@ -175,7 +175,7 @@ def test_nested_toc(app): navpoints = toc.findall("./ncx:navMap/ncx:navPoint") assert len(navpoints) == 4 assert navinfo(navpoints[0]) == ('navPoint1', '1', 'index.xhtml', - "Welcome to Sphinx Tests's documentation!") + u"Welcome to Sphinx Tests’s documentation!") assert navpoints[0].findall("./ncx:navPoint") == [] # toc.ncx / nested navPoints @@ -192,11 +192,11 @@ def test_nested_toc(app): anchor = elem.find("./xhtml:a") return (anchor.get('href'), anchor.text) - nav = EPUBElementTree.fromstring((app.outdir / 'nav.xhtml').text()) + nav = EPUBElementTree.fromstring((app.outdir / 'nav.xhtml').bytes()) toc = nav.findall("./xhtml:body/xhtml:nav/xhtml:ol/xhtml:li") assert len(toc) == 4 assert navinfo(toc[0]) == ('index.xhtml', - "Welcome to Sphinx Tests's documentation!") + u"Welcome to Sphinx Tests’s documentation!") assert toc[0].findall("./xhtml:ol") == [] # nav.xhtml / nested toc diff --git a/tests/test_environment_toctree.py b/tests/test_environment_toctree.py index 0f1dffa43..a2d54fb79 100644 --- a/tests/test_environment_toctree.py +++ b/tests/test_environment_toctree.py @@ -36,7 +36,7 @@ def test_process_doc(app): list_item)]) assert_node(toctree[0][0], - [compact_paragraph, reference, "Welcome to Sphinx Tests's documentation!"]) + [compact_paragraph, reference, u"Welcome to Sphinx Tests’s documentation!"]) assert_node(toctree[0][0][0], reference, anchorname='') assert_node(toctree[0][1][0], addnodes.toctree, caption="Table of Contents", glob=False, hidden=False, @@ -150,7 +150,7 @@ def test_get_toc_for(app): addnodes.toctree)])], [list_item, compact_paragraph])]) # [2][0] assert_node(toctree[0][0], - [compact_paragraph, reference, "Welcome to Sphinx Tests's documentation!"]) + [compact_paragraph, reference, u"Welcome to Sphinx Tests’s documentation!"]) assert_node(toctree[0][1][2], ([compact_paragraph, reference, "subsection"], [bullet_list, list_item, compact_paragraph, reference, "subsubsection"])) @@ -177,7 +177,7 @@ def test_get_toc_for_only(app): addnodes.toctree)])], [list_item, compact_paragraph])]) # [2][0] assert_node(toctree[0][0], - [compact_paragraph, reference, "Welcome to Sphinx Tests's documentation!"]) + [compact_paragraph, reference, u"Welcome to Sphinx Tests’s documentation!"]) assert_node(toctree[0][1][1], ([compact_paragraph, reference, "Section for HTML"], [bullet_list, addnodes.toctree])) diff --git a/tests/test_markup.py b/tests/test_markup.py index ecc4b6a11..18c9d0bbd 100644 --- a/tests/test_markup.py +++ b/tests/test_markup.py @@ -14,11 +14,12 @@ import pickle from docutils import frontend, utils, nodes from docutils.parsers.rst import Parser as RstParser +from docutils.transforms.universal import SmartQuotes from sphinx import addnodes from sphinx.util import texescape from sphinx.util.docutils import sphinx_domains -from sphinx.writers.html import HTMLWriter, SmartyPantsHTMLTranslator +from sphinx.writers.html import HTMLWriter, HTMLTranslator from sphinx.writers.latex import LaTeXWriter, LaTeXTranslator import pytest @@ -31,6 +32,7 @@ def settings(app): optparser = frontend.OptionParser( components=(RstParser, HTMLWriter, LaTeXWriter)) settings = optparser.get_default_values() + settings.smart_quotes = True settings.env = app.builder.env settings.env.temp_data['docname'] = 'dummy' domain_context = sphinx_domains(settings.env) @@ -46,6 +48,7 @@ def parse(settings): document['file'] = 'dummy' parser = RstParser() parser.parse(rst, document) + SmartQuotes(document, startnode=None).apply() for msg in document.traverse(nodes.system_message): if msg['level'] == 1: msg.replace_self([]) @@ -62,7 +65,7 @@ class ForgivingTranslator: pass -class ForgivingHTMLTranslator(SmartyPantsHTMLTranslator, ForgivingTranslator): +class ForgivingHTMLTranslator(HTMLTranslator, ForgivingTranslator): pass @@ -178,8 +181,8 @@ def get_verifier(verify, verify_re): # verify smarty-pants quotes 'verify', '"John"', - '

“John”

', - r'\sphinxquotedblleft{}John\sphinxquotedblright{}', + u'

“John”

', + u"“John”", ), ( # ... but not in literal text diff --git a/tests/test_metadata.py b/tests/test_metadata.py index 77efff5ed..58f573b0a 100644 --- a/tests/test_metadata.py +++ b/tests/test_metadata.py @@ -34,14 +34,14 @@ def test_docinfo(app, status, warning): 'field name': u'This is a generic bibliographic field.', 'field name 2': (u'Generic bibliographic fields may contain multiple ' u'body elements.\n\nLike this.'), - 'status': u'This is a "work in progress"', + 'status': u'This is a “work in progress”', 'version': u'1', 'copyright': (u'This document has been placed in the public domain. ' u'You\nmay do with it as you wish. You may copy, modify,' u'\nredistribute, reattribute, sell, buy, rent, lease,\n' u'destroy, or improve it, quote it at length, excerpt,\n' u'incorporate, collate, fold, staple, or mutilate it, or ' - u'do\nanything else to it that your or anyone else\'s ' + u'do\nanything else to it that your or anyone else’s ' u'heart\ndesires.'), 'contact': u'goodger@python.org', 'date': u'2006-05-21', From c857f52f4b933ce50c8280f32b400092a9af2ac3 Mon Sep 17 00:00:00 2001 From: Dmitry Shachnev Date: Fri, 24 Mar 2017 21:29:51 +0300 Subject: [PATCH 13/32] =?UTF-8?q?Monkey=20patch=20docutils=E2=80=99=20educ?= =?UTF-8?q?ateQuotes=20function=20to=20fix=20apostrophes=20handling?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sphinx/util/__init__.py | 1 + sphinx/util/smartypants.py | 143 +++++++++++++++++++++++++++++++++++++ 2 files changed, 144 insertions(+) create mode 100644 sphinx/util/smartypants.py diff --git a/sphinx/util/__init__.py b/sphinx/util/__init__.py index d86882259..295848e40 100644 --- a/sphinx/util/__init__.py +++ b/sphinx/util/__init__.py @@ -34,6 +34,7 @@ from sphinx.util import logging from sphinx.util.console import strip_colors, colorize, bold, term_width_line # type: ignore from sphinx.util.fileutil import copy_asset_file from sphinx.util.osutil import fs_encoding +from sphinx.util import smartypants # noqa # import other utilities; partly for backwards compatibility, so don't # prune unused ones indiscriminately diff --git a/sphinx/util/smartypants.py b/sphinx/util/smartypants.py new file mode 100644 index 000000000..3932e9386 --- /dev/null +++ b/sphinx/util/smartypants.py @@ -0,0 +1,143 @@ +# -*- coding: utf-8 -*- +""" + sphinx.util.smartypants + ~~~~~~~~~~~~~~~~~~~~~~~ + + This code is copied from docutils’ docutils/utils/smartquotes.py + version 1.7.1 (from 2017-03-19). It should be removed in the future. + + :copyright: © 2010 Günter Milde, + original `SmartyPants`_: © 2003 John Gruber + smartypants.py: © 2004, 2007 Chad Miller + :license: Released under the terms of the `2-Clause BSD license`_, in short: + + Copying and distribution of this file, with or without modification, + are permitted in any medium without royalty provided the copyright + notices and this notice are preserved. + This file is offered as-is, without any warranty. + + .. _SmartyPants: http://daringfireball.net/projects/smartypants/ + .. _2-Clause BSD license: http://www.spdx.org/licenses/BSD-2-Clause + + See the LICENSE file and the original docutils code for details. +""" +from __future__ import absolute_import, unicode_literals + +import re +from docutils.utils import smartquotes +from sphinx.util.docutils import __version_info__ as docutils_version + + +def educateQuotes(text, language='en'): + # type: (unicode, unicode) -> unicode + """ + Parameter: - text string (unicode or bytes). + - language (`BCP 47` language tag.) + Returns: The `text`, with "educated" curly quote characters. + + Example input: "Isn't this fun?" + Example output: “Isn’t this fun?“; + """ + + smart = smartquotes.smartchars(language) + smart.apostrophe = u'’' + + # oldtext = text + punct_class = r"""[!"#\$\%'()*+,-.\/:;<=>?\@\[\\\]\^_`{|}~]""" + + # Special case if the very first character is a quote + # followed by punctuation at a non-word-break. + # Close the quotes by brute force: + text = re.sub(r"""^'(?=%s\\B)""" % (punct_class,), smart.csquote, text) + text = re.sub(r"""^"(?=%s\\B)""" % (punct_class,), smart.cpquote, text) + + # Special case for double sets of quotes, e.g.: + #

He said, "'Quoted' words in a larger quote."

+ text = re.sub(r""""'(?=\w)""", smart.opquote + smart.osquote, text) + text = re.sub(r"""'"(?=\w)""", smart.osquote + smart.opquote, text) + + # Special case for decade abbreviations (the '80s): + text = re.sub(r"""\b'(?=\d{2}s)""", smart.csquote, text) + + close_class = r"""[^\ \t\r\n\[\{\(\-]""" + dec_dashes = r"""–|—""" + + # Get most opening single quotes: + opening_single_quotes_regex = re.compile(r""" + ( + \s | # a whitespace char, or +   | # a non-breaking space entity, or + -- | # dashes, or + &[mn]dash; | # named dash entities + %s | # or decimal entities + &\#x201[34]; # or hex + ) + ' # the quote + (?=\w) # followed by a word character + """ % (dec_dashes,), re.VERBOSE | re.UNICODE) + text = opening_single_quotes_regex.sub(r'\1' + smart.osquote, text) + + # In many locales, single closing quotes are different from apostrophe: + if smart.csquote != smart.apostrophe: + apostrophe_regex = re.compile(r"(?<=(\w|\d))'(?=\w)", re.UNICODE) + text = apostrophe_regex.sub(smart.apostrophe, text) + + closing_single_quotes_regex = re.compile(r""" + (%s) + ' + (?!\s | # whitespace + s\b | + \d # digits ('80s) + ) + """ % (close_class,), re.VERBOSE | re.UNICODE) + text = closing_single_quotes_regex.sub(r'\1' + smart.csquote, text) + + closing_single_quotes_regex = re.compile(r""" + (%s) + ' + (\s | s\b) + """ % (close_class,), re.VERBOSE | re.UNICODE) + text = closing_single_quotes_regex.sub(r'\1%s\2' % smart.csquote, text) + + # Any remaining single quotes should be opening ones: + text = re.sub(r"""'""", smart.osquote, text) + + # Get most opening double quotes: + opening_double_quotes_regex = re.compile(r""" + ( + \s | # a whitespace char, or +   | # a non-breaking space entity, or + -- | # dashes, or + &[mn]dash; | # named dash entities + %s | # or decimal entities + &\#x201[34]; # or hex + ) + " # the quote + (?=\w) # followed by a word character + """ % (dec_dashes,), re.VERBOSE) + text = opening_double_quotes_regex.sub(r'\1' + smart.opquote, text) + + # Double closing quotes: + closing_double_quotes_regex = re.compile(r""" + #(%s)? # character that indicates the quote should be closing + " + (?=\s) + """ % (close_class,), re.VERBOSE) + text = closing_double_quotes_regex.sub(smart.cpquote, text) + + closing_double_quotes_regex = re.compile(r""" + (%s) # character that indicates the quote should be closing + " + """ % (close_class,), re.VERBOSE) + text = closing_double_quotes_regex.sub(r'\1' + smart.cpquote, text) + + # Any remaining quotes should be opening ones. + text = re.sub(r'"', smart.opquote, text) + + return text + + +if docutils_version < (0, 13, 2): + # Monkey patch the old docutils versions to fix the issue mentioned + # at https://sourceforge.net/p/docutils/bugs/313/ + smartquotes.educateQuotes = educateQuotes From 1f9e25194339835ab3c68f02ba42dca842bf2803 Mon Sep 17 00:00:00 2001 From: Dmitry Shachnev Date: Fri, 24 Mar 2017 21:51:21 +0300 Subject: [PATCH 14/32] Add tests for English, Russian and French smart quotes --- tests/root/markup.txt | 20 ++++++++++++++++++++ tests/test_build_html.py | 7 +++++++ 2 files changed, 27 insertions(+) diff --git a/tests/root/markup.txt b/tests/root/markup.txt index 714dabe8d..b514b3587 100644 --- a/tests/root/markup.txt +++ b/tests/root/markup.txt @@ -426,6 +426,26 @@ More domains: .. default-role:: +Smart quotes +------------ + +* Smart "quotes" in English 'text'. +* Smart --- long and -- short dashes. +* Ellipsis... +* No smartypants in literal blocks: ``foo--"bar"...``. + +.. only:: html + + .. LaTeX does not like Cyrillic letters in this test, so it is HTML only. + + .. rst-class:: language-ru + + Этот "абзац" должен использовать 'русские' кавычки. + + .. rst-class:: language-fr + + Il dit : "C'est 'super' !" + .. rubric:: Footnotes .. [#] Like footnotes. diff --git a/tests/test_build_html.py b/tests/test_build_html.py index 9265caed4..e8dc2b831 100644 --- a/tests/test_build_html.py +++ b/tests/test_build_html.py @@ -297,6 +297,13 @@ def test_static_output(app): # tests for ``any`` role (".//a[@href='#with']/span", 'headings'), (".//a[@href='objects.html#func_without_body']/code/span", 'objects'), + # tests for smartypants + (".//li", u'Smart “quotes” in English ‘text’.'), + (".//li", u'Smart — long and – short dashes.'), + (".//li", u'Ellipsis…'), + (".//li//code//span[@class='pre']", 'foo--"bar"...'), + (".//p", u'Этот «абзац» должен использовать „русские“ кавычки.'), + (".//p", u'Il dit : « C’est ‹ super › ! »'), ], 'objects.html': [ (".//dt[@id='mod.Cls.meth1']", ''), From 4f4014c7c0d5543cb9a3fdebc6b4cd569a026541 Mon Sep 17 00:00:00 2001 From: Dmitry Shachnev Date: Thu, 16 Mar 2017 19:41:23 +0300 Subject: [PATCH 15/32] Remove sphinxquotedblleft and sphinxquotedblright, no longer needed --- sphinx/texinputs/sphinx.sty | 4 ---- 1 file changed, 4 deletions(-) diff --git a/sphinx/texinputs/sphinx.sty b/sphinx/texinputs/sphinx.sty index a4ceb4940..cb443536c 100644 --- a/sphinx/texinputs/sphinx.sty +++ b/sphinx/texinputs/sphinx.sty @@ -1388,10 +1388,6 @@ \protected\def\sphinxstyleabbreviation {\textsc} \protected\def\sphinxstyleliteralintitle {\sphinxcode} -% LaTeX writer uses macros to hide double quotes from \sphinxcode's \@noligs -\protected\def\sphinxquotedblleft{``} -\protected\def\sphinxquotedblright{''} - % Tell TeX about pathological hyphenation cases: \hyphenation{Base-HTTP-Re-quest-Hand-ler} \endinput From 9236beb9ee41899897d8dbfa373ee21d7d4b252f Mon Sep 17 00:00:00 2001 From: Dmitry Shachnev Date: Mon, 17 Apr 2017 14:15:28 +0300 Subject: [PATCH 16/32] Deprecate the html_use_smartypants option --- doc/config.rst | 6 ++++++ sphinx/builders/html.py | 2 +- sphinx/environment/__init__.py | 10 ++++++++-- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/doc/config.rst b/doc/config.rst index 5e641cbfb..39feaae78 100644 --- a/doc/config.rst +++ b/doc/config.rst @@ -768,6 +768,12 @@ that use Sphinx's HTMLWriter class. will be used to convert quotes and dashes to typographically correct entities. Default: ``True``. + .. deprecated:: 1.6 + Use the `smart_quotes option`_ in the Docutils configuration file + (``docutils.conf``) instead. + + .. _`smart_quotes option`: http://docutils.sourceforge.net/docs/user/config.html#smart-quotes + .. confval:: html_add_permalinks Sphinx will add "permalinks" for each heading and description environment as diff --git a/sphinx/builders/html.py b/sphinx/builders/html.py index a0b3d8e87..16145beb3 100644 --- a/sphinx/builders/html.py +++ b/sphinx/builders/html.py @@ -1312,7 +1312,7 @@ def setup(app): app.add_config_value('html_static_path', [], 'html') app.add_config_value('html_extra_path', [], 'html') app.add_config_value('html_last_updated_fmt', None, 'html', string_classes) - app.add_config_value('html_use_smartypants', True, 'html') + app.add_config_value('html_use_smartypants', None, 'html') app.add_config_value('html_sidebars', {}, 'html') app.add_config_value('html_additional_pages', {}, 'html') app.add_config_value('html_domain_indices', True, 'html', [list]) diff --git a/sphinx/environment/__init__.py b/sphinx/environment/__init__.py index b0a1a2ce5..4c078a9a3 100644 --- a/sphinx/environment/__init__.py +++ b/sphinx/environment/__init__.py @@ -674,8 +674,14 @@ class BuildEnvironment(object): self.settings['gettext_compact'] = self.config.gettext_compact language = (self.config.language or 'en').replace('_', '-') self.settings['language_code'] = language - if language in smartchars.quotes: - self.settings['smart_quotes'] = self.config.html_use_smartypants + if self.config.html_use_smartypants is not None: + warnings.warn("html_use_smartypants option is deprecated. Use the " + "smart_quotes option in docutils.conf instead.", + RemovedInSphinx17Warning) + if language in smartchars.quotes: + self.settings['smart_quotes'] = self.config.html_use_smartypants + elif language in smartchars.quotes: # We enable smartypants by default + self.settings['smart_quotes'] = True docutilsconf = path.join(self.srcdir, 'docutils.conf') # read docutils.conf from source dir, not from current dir From f99f5b23ee630a33cf2c149a3928a533296e3129 Mon Sep 17 00:00:00 2001 From: Dmitry Shachnev Date: Mon, 17 Apr 2017 14:25:28 +0300 Subject: [PATCH 17/32] Backport fixes for French quotes from docutils --- sphinx/util/smartypants.py | 6 ++++++ tests/test_build_html.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/sphinx/util/smartypants.py b/sphinx/util/smartypants.py index 3932e9386..e42bfa82f 100644 --- a/sphinx/util/smartypants.py +++ b/sphinx/util/smartypants.py @@ -141,3 +141,9 @@ if docutils_version < (0, 13, 2): # Monkey patch the old docutils versions to fix the issue mentioned # at https://sourceforge.net/p/docutils/bugs/313/ smartquotes.educateQuotes = educateQuotes + + # Fix the issue with French quotes mentioned at + # https://sourceforge.net/p/docutils/mailman/message/35760696/ + quotes = smartquotes.smartchars.quotes + quotes['fr'] = (u'«\u00a0', u'\u00a0»', u'“', u'”') + quotes['fr-ch'] = u'«»‹›' diff --git a/tests/test_build_html.py b/tests/test_build_html.py index e8dc2b831..0758874a7 100644 --- a/tests/test_build_html.py +++ b/tests/test_build_html.py @@ -303,7 +303,7 @@ def test_static_output(app): (".//li", u'Ellipsis…'), (".//li//code//span[@class='pre']", 'foo--"bar"...'), (".//p", u'Этот «абзац» должен использовать „русские“ кавычки.'), - (".//p", u'Il dit : « C’est ‹ super › ! »'), + (".//p", u'Il dit : « C’est “super” ! »'), ], 'objects.html': [ (".//dt[@id='mod.Cls.meth1']", ''), From a9cbb42e7fd42dfbfd88df5d262fae343418528e Mon Sep 17 00:00:00 2001 From: Dmitry Shachnev Date: Mon, 17 Apr 2017 14:44:52 +0300 Subject: [PATCH 18/32] Remove bulk_text_processors methods, they are no longer needed --- sphinx/writers/html.py | 6 ------ sphinx/writers/html5.py | 6 ------ 2 files changed, 12 deletions(-) diff --git a/sphinx/writers/html.py b/sphinx/writers/html.py index 572b2825e..6dd8bafe5 100644 --- a/sphinx/writers/html.py +++ b/sphinx/writers/html.py @@ -683,10 +683,6 @@ class HTMLTranslator(BaseTranslator): BaseTranslator.visit_option_group(self, node) self.context[-2] = self.context[-2].replace(' ', ' ') - def bulk_text_processor(self, text): - # type: (unicode) -> unicode - return text - # overwritten def visit_Text(self, node): # type: (nodes.Node) -> None @@ -708,8 +704,6 @@ class HTMLTranslator(BaseTranslator): else: if self.in_mailto and self.settings.cloak_email_addresses: encoded = self.cloak_email(encoded) - else: - encoded = self.bulk_text_processor(encoded) self.body.append(encoded) def visit_note(self, node): diff --git a/sphinx/writers/html5.py b/sphinx/writers/html5.py index 8e3843c09..51c4e8ecb 100644 --- a/sphinx/writers/html5.py +++ b/sphinx/writers/html5.py @@ -626,10 +626,6 @@ class HTML5Translator(BaseTranslator): # type: (nodes.Node) -> None self.body.append('') - def bulk_text_processor(self, text): - # type: (unicode) -> unicode - return text - # overwritten def visit_Text(self, node): # type: (nodes.Node) -> None @@ -651,8 +647,6 @@ class HTML5Translator(BaseTranslator): else: if self.in_mailto and self.settings.cloak_email_addresses: encoded = self.cloak_email(encoded) - else: - encoded = self.bulk_text_processor(encoded) self.body.append(encoded) def visit_note(self, node): From 4721767d08a3e4700e72e5df39f7064f0d6ceba0 Mon Sep 17 00:00:00 2001 From: Dmitry Shachnev Date: Mon, 24 Apr 2017 15:12:35 +0300 Subject: [PATCH 19/32] Also monkey-patch the educate_tokens from Docutils To fix https://sourceforge.net/p/docutils/bugs/317/. --- sphinx/util/smartypants.py | 131 +++++++++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) diff --git a/sphinx/util/smartypants.py b/sphinx/util/smartypants.py index e42bfa82f..2c4fe7d92 100644 --- a/sphinx/util/smartypants.py +++ b/sphinx/util/smartypants.py @@ -27,6 +27,9 @@ import re from docutils.utils import smartquotes from sphinx.util.docutils import __version_info__ as docutils_version +if False: # For type annotation + from typing import Iterable, Iterator, Tuple # NOQA + def educateQuotes(text, language='en'): # type: (unicode, unicode) -> unicode @@ -137,11 +140,139 @@ def educateQuotes(text, language='en'): return text +def educate_tokens(text_tokens, attr='1', language='en'): + # type: (Iterable[Tuple[str, unicode]], unicode, unicode) -> Iterator + """Return iterator that "educates" the items of `text_tokens`. + """ + + # Parse attributes: + # 0 : do nothing + # 1 : set all + # 2 : set all, using old school en- and em- dash shortcuts + # 3 : set all, using inverted old school en and em- dash shortcuts + # + # q : quotes + # b : backtick quotes (``double'' only) + # B : backtick quotes (``double'' and `single') + # d : dashes + # D : old school dashes + # i : inverted old school dashes + # e : ellipses + # w : convert " entities to " for Dreamweaver users + + convert_quot = False # translate " entities into normal quotes? + do_dashes = 0 + do_backticks = 0 + do_quotes = False + do_ellipses = False + do_stupefy = False + + if attr == "0": # Do nothing. + pass + elif attr == "1": # Do everything, turn all options on. + do_quotes = True + do_backticks = 1 + do_dashes = 1 + do_ellipses = True + elif attr == "2": + # Do everything, turn all options on, use old school dash shorthand. + do_quotes = True + do_backticks = 1 + do_dashes = 2 + do_ellipses = True + elif attr == "3": + # Do everything, use inverted old school dash shorthand. + do_quotes = True + do_backticks = 1 + do_dashes = 3 + do_ellipses = True + elif attr == "-1": # Special "stupefy" mode. + do_stupefy = True + else: + if "q" in attr: + do_quotes = True + if "b" in attr: + do_backticks = 1 + if "B" in attr: + do_backticks = 2 + if "d" in attr: + do_dashes = 1 + if "D" in attr: + do_dashes = 2 + if "i" in attr: + do_dashes = 3 + if "e" in attr: + do_ellipses = True + if "w" in attr: + convert_quot = True + + prev_token_last_char = " " + # Last character of the previous text token. Used as + # context to curl leading quote characters correctly. + + for (ttype, text) in text_tokens: + + # skip HTML and/or XML tags as well as emtpy text tokens + # without updating the last character + if ttype == 'tag' or not text: + yield text + continue + + # skip literal text (math, literal, raw, ...) + if ttype == 'literal': + prev_token_last_char = text[-1:] + yield text + continue + + last_char = text[-1:] # Remember last char before processing. + + text = smartquotes.processEscapes(text) + + if convert_quot: + text = re.sub('"', '"', text) + + if do_dashes == 1: + text = smartquotes.educateDashes(text) + elif do_dashes == 2: + text = smartquotes.educateDashesOldSchool(text) + elif do_dashes == 3: + text = smartquotes.educateDashesOldSchoolInverted(text) + + if do_ellipses: + text = smartquotes.educateEllipses(text) + + # Note: backticks need to be processed before quotes. + if do_backticks: + text = smartquotes.educateBackticks(text, language) + + if do_backticks == 2: + text = smartquotes.educateSingleBackticks(text, language) + + if do_quotes: + # Replace plain quotes to prevent converstion to + # 2-character sequence in French. + context = prev_token_last_char.replace('"', ';').replace("'", ';') + text = educateQuotes(context + text, language)[1:] + + if do_stupefy: + text = smartquotes.stupefyEntities(text, language) + + # Remember last char as context for the next token + prev_token_last_char = last_char + + text = smartquotes.processEscapes(text, restore=True) + + yield text + + if docutils_version < (0, 13, 2): # Monkey patch the old docutils versions to fix the issue mentioned # at https://sourceforge.net/p/docutils/bugs/313/ smartquotes.educateQuotes = educateQuotes + # And the one mentioned at https://sourceforge.net/p/docutils/bugs/317/ + smartquotes.educate_tokens = educate_tokens + # Fix the issue with French quotes mentioned at # https://sourceforge.net/p/docutils/mailman/message/35760696/ quotes = smartquotes.smartchars.quotes From 50609f200006a24eefa44a80a5ce703831c2beb8 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Tue, 25 Apr 2017 23:28:13 +0900 Subject: [PATCH 20/32] Update CHANGES for PR #3666 --- CHANGES | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGES b/CHANGES index 0d72fa989..12d67a00a 100644 --- a/CHANGES +++ b/CHANGES @@ -4,6 +4,8 @@ Release 1.6 beta2 (in development) Incompatible changes -------------------- +* #3345: Replace the custom smartypants code with docutils' smart_quotes + Deprecated ---------- From f8b58e41cd1bb44d576f6b9da9f07b89f3d0a823 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Thu, 27 Apr 2017 00:17:07 +0900 Subject: [PATCH 21/32] Fix #3669: gettext builder fails with "ValueError: substring not found" --- CHANGES | 1 + sphinx/builders/gettext.py | 20 ++++++++++++-------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/CHANGES b/CHANGES index 12d67a00a..d6de0d3ad 100644 --- a/CHANGES +++ b/CHANGES @@ -16,6 +16,7 @@ Bugs fixed ---------- * #3661: sphinx-build crashes on parallel build +* #3669: gettext builder fails with "ValueError: substring not found" Testing -------- diff --git a/sphinx/builders/gettext.py b/sphinx/builders/gettext.py index 280f2be99..4da19bd2c 100644 --- a/sphinx/builders/gettext.py +++ b/sphinx/builders/gettext.py @@ -194,14 +194,18 @@ ltz = LocalTimeZone() def should_write(filepath, new_content): if not path.exists(filepath): return True - with open(filepath, 'r', encoding='utf-8') as oldpot: # type: ignore - old_content = oldpot.read() - old_header_index = old_content.index('"POT-Creation-Date:') - new_header_index = new_content.index('"POT-Creation-Date:') - old_body_index = old_content.index('"PO-Revision-Date:') - new_body_index = new_content.index('"PO-Revision-Date:') - return ((old_content[:old_header_index] != new_content[:new_header_index]) or - (new_content[new_body_index:] != old_content[old_body_index:])) + try: + with open(filepath, 'r', encoding='utf-8') as oldpot: # type: ignore + old_content = oldpot.read() + old_header_index = old_content.index('"POT-Creation-Date:') + new_header_index = new_content.index('"POT-Creation-Date:') + old_body_index = old_content.index('"PO-Revision-Date:') + new_body_index = new_content.index('"PO-Revision-Date:') + return ((old_content[:old_header_index] != new_content[:new_header_index]) or + (new_content[new_body_index:] != old_content[old_body_index:])) + except ValueError: + pass + return True From 02ff0863c671c2468b9c841b5a362eb7435bb4b2 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Thu, 27 Apr 2017 00:33:40 +0900 Subject: [PATCH 22/32] Move deprecation warning --- sphinx/builders/html.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/sphinx/builders/html.py b/sphinx/builders/html.py index cea14965a..a356c5f23 100644 --- a/sphinx/builders/html.py +++ b/sphinx/builders/html.py @@ -96,19 +96,22 @@ class CSSContainer(list): the entry with Stylesheet class. """ def append(self, obj): - warnings.warn('builder.css_files is deprecated. ' - 'Please use app.add_stylesheet() instead.', - RemovedInSphinx20Warning) if isinstance(obj, Stylesheet): super(CSSContainer, self).append(obj) else: super(CSSContainer, self).append(Stylesheet(obj, None, 'stylesheet')) def extend(self, other): + warnings.warn('builder.css_files is deprecated. ' + 'Please use app.add_stylesheet() instead.', + RemovedInSphinx20Warning) for item in other: self.append(item) def __iadd__(self, other): + warnings.warn('builder.css_files is deprecated. ' + 'Please use app.add_stylesheet() instead.', + RemovedInSphinx20Warning) for item in other: self.append(item) From 45a61843ece6049012ca117aecf9aebf81e8152b Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Thu, 27 Apr 2017 21:24:12 +0900 Subject: [PATCH 23/32] Make ImportWarning silent --- tests/run.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/run.py b/tests/run.py index 71a41c7c1..673ad1339 100755 --- a/tests/run.py +++ b/tests/run.py @@ -24,6 +24,7 @@ sys.path.insert(0, os.path.abspath(os.path.join(testroot, os.path.pardir))) # filter warnings of test dependencies warnings.filterwarnings('ignore', category=DeprecationWarning, module='site') # virtualenv warnings.filterwarnings('ignore', category=ImportWarning, module='backports') +warnings.filterwarnings('ignore', category=ImportWarning, module='pkgutil') warnings.filterwarnings('ignore', category=ImportWarning, module='pytest_cov') warnings.filterwarnings('ignore', category=PendingDeprecationWarning, module=r'_pytest\..*') From 8462d4bcdab78f1bd3f064e14c31f67519e023e7 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Thu, 27 Apr 2017 21:24:12 +0900 Subject: [PATCH 24/32] doc: Update --- doc/theming.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/theming.rst b/doc/theming.rst index 2a7063925..711d0ae72 100644 --- a/doc/theming.rst +++ b/doc/theming.rst @@ -47,7 +47,9 @@ file :file:`blue.zip`, you can put it right in the directory containing html_theme_path = ["."] The third form is a python package. If a theme you want to use is distributed -as a python package, you can use it after installing:: +as a python package, you can use it after installing + +.. code-block:: bash # installing theme package $ pip install sphinxjp.themes.dotted From 5c5272c4aba57b56290039d5b765e5ff07dea6b3 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Thu, 27 Apr 2017 21:44:46 +0900 Subject: [PATCH 25/32] Fix #3657: EPUB builder crashes if document startswith genindex exists --- CHANGES | 1 + sphinx/builders/epub.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index b38d91c4d..344e65fff 100644 --- a/CHANGES +++ b/CHANGES @@ -16,6 +16,7 @@ Bugs fixed * #3614: Sphinx crashes with requests-2.5.0 * #3618: autodoc crashes with tupled arguments * #3664: No space after the bullet in items of a latex list produced by Sphinx +* #3657: EPUB builder crashes if document startswith genindex exists Testing -------- diff --git a/sphinx/builders/epub.py b/sphinx/builders/epub.py index 152401447..ea90642bc 100644 --- a/sphinx/builders/epub.py +++ b/sphinx/builders/epub.py @@ -500,7 +500,7 @@ class EpubBuilder(StandaloneHTMLBuilder): This method is overwritten for genindex pages in order to fix href link attributes. """ - if pagename.startswith('genindex'): + if pagename.startswith('genindex') and 'genindexentries' in addctx: if not self.use_index: return self.fix_genindex(addctx['genindexentries']) From bd66ffc1fafd0e83f07e7143f99bc4023bc72508 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Fri, 28 Apr 2017 01:19:01 +0900 Subject: [PATCH 26/32] Fix the unreleased version number is shown (refs: #3678, #3027) --- doc/_templates/indexsidebar.html | 2 +- doc/conf.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/_templates/indexsidebar.html b/doc/_templates/indexsidebar.html index bfa0139cb..6359921a5 100644 --- a/doc/_templates/indexsidebar.html +++ b/doc/_templates/indexsidebar.html @@ -3,7 +3,7 @@ {%trans%}project{%endtrans%}

Download

-{% if version.endswith('a0') %} +{% if version.endswith('+') %}

{%trans%}This documentation is for version {{ version }}, which is not released yet.{%endtrans%}

{%trans%}You can use it from the diff --git a/doc/conf.py b/doc/conf.py index 95d14ec46..6817af12a 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -16,7 +16,7 @@ exclude_patterns = ['_build'] project = 'Sphinx' copyright = '2007-2017, Georg Brandl and the Sphinx team' -version = sphinx.__released__ +version = sphinx.__display_version__ release = version show_authors = True From ac5e76f5989eeb74b05d9332b6a3922952a161c7 Mon Sep 17 00:00:00 2001 From: shimizukawa Date: Sat, 29 Apr 2017 00:54:58 +0900 Subject: [PATCH 27/32] extract messages --- sphinx/locale/sphinx.pot | 920 ++++++++++++++++++++++++++++----------- utils/release-checklist | 7 +- 2 files changed, 666 insertions(+), 261 deletions(-) diff --git a/sphinx/locale/sphinx.pot b/sphinx/locale/sphinx.pot index f63434cc2..13e387dcd 100644 --- a/sphinx/locale/sphinx.pot +++ b/sphinx/locale/sphinx.pot @@ -1,14 +1,14 @@ # Translations template for Sphinx. -# Copyright (C) 2016 ORGANIZATION +# Copyright (C) 2017 ORGANIZATION # This file is distributed under the same license as the Sphinx project. -# FIRST AUTHOR , 2016. +# FIRST AUTHOR , 2017. # #, fuzzy msgid "" msgstr "" -"Project-Id-Version: Sphinx 1.5b1\n" +"Project-Id-Version: Sphinx 1.6\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2016-11-06 22:40+0900\n" +"POT-Creation-Date: 2017-04-28 15:54+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,600 +17,987 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.3.4\n" -#: sphinx/config.py:109 +#: sphinx/application.py:181 +#, python-format +msgid "" +"This project needs at least Sphinx v%s and therefore cannot be built with" +" this version." +msgstr "" + +#: sphinx/application.py:208 +msgid "" +"'setup' that is specified in the conf.py has not been callable. Please " +"provide a callable `setup` function in order to behave as a sphinx " +"extension conf.py itself." +msgstr "" + +#: sphinx/application.py:222 +#, python-format +msgid "primary_domain %r not found, ignored." +msgstr "" + +#: sphinx/application.py:259 sphinx/application.py:287 +msgid "done" +msgstr "" + +#: sphinx/application.py:280 +msgid "loading pickled environment... " +msgstr "" + +#: sphinx/application.py:290 +msgid "not yet created" +msgstr "" + +#: sphinx/application.py:292 +#, python-format +msgid "failed: %s" +msgstr "" + +#: sphinx/application.py:302 +msgid "No builder selected, using default: html" +msgstr "" + +#: sphinx/application.py:341 +msgid "succeeded" +msgstr "" + +#: sphinx/application.py:341 +msgid "finished with problems" +msgstr "" + +#: sphinx/application.py:343 +#, python-format +msgid "build %s, %s warning%s." +msgstr "" + +#: sphinx/application.py:347 +#, python-format +msgid "build %s." +msgstr "" + +#: sphinx/application.py:506 +#, python-format +msgid "Config value %r already present" +msgstr "" + +#: sphinx/application.py:518 +#, python-format +msgid "A Translator for the %s builder is changed." +msgstr "" + +#: sphinx/application.py:526 +#, python-format +msgid "" +"while setting up extension %s: node class %r is already registered, its " +"visitors will be overridden" +msgstr "" + +#: sphinx/application.py:535 +#, python-format +msgid "Value for key %r must be a (visit, depart) function tuple" +msgstr "" + +#: sphinx/application.py:582 +#, python-format +msgid "" +"while setting up extension %s: directive %r is already registered, it " +"will be overridden" +msgstr "" + +#: sphinx/application.py:593 sphinx/application.py:605 +#, python-format +msgid "" +"while setting up extension %s: role %r is already registered, it will be " +"overridden" +msgstr "" + +#: sphinx/config.py:127 #, python-format msgid "Section %s" msgstr "" -#: sphinx/config.py:110 +#: sphinx/config.py:128 #, python-format msgid "Fig. %s" msgstr "" -#: sphinx/config.py:111 +#: sphinx/config.py:129 #, python-format msgid "Table %s" msgstr "" -#: sphinx/config.py:112 +#: sphinx/config.py:130 #, python-format msgid "Listing %s" msgstr "" -#: sphinx/roles.py:187 +#: sphinx/config.py:236 +#, python-format +msgid "" +"cannot override dictionary config setting %r, ignoring (use %r to set " +"individual elements)" +msgstr "" + +#: sphinx/config.py:245 +#, python-format +msgid "invalid number %r for config value %r, ignoring" +msgstr "" + +#: sphinx/config.py:250 +#, python-format +msgid "cannot override config setting %r with unsupported type, ignoring" +msgstr "" + +#: sphinx/config.py:280 +#, python-format +msgid "unknown config value %r in override, ignoring" +msgstr "" + +#: sphinx/config.py:299 +#, python-format +msgid "No such config value: %s" +msgstr "" + +#: sphinx/events.py:56 +#, python-format +msgid "Event %r already present" +msgstr "" + +#: sphinx/events.py:62 +#, python-format +msgid "Unknown event name: %s" +msgstr "" + +#: sphinx/extension.py:53 +#, python-format +msgid "" +"needs_extensions config value specifies a version requirement for " +"extension %s, but it is not loaded" +msgstr "" + +#: sphinx/extension.py:59 +#, python-format +msgid "" +"This project needs the extension %s at least in version %s and therefore " +"cannot be built with the loaded version (%s)." +msgstr "" + +#: sphinx/registry.py:56 +#, python-format +msgid "Builder class %s has no \"name\" attribute" +msgstr "" + +#: sphinx/registry.py:58 +#, python-format +msgid "Builder %r already exists (in module %s)" +msgstr "" + +#: sphinx/registry.py:72 +#, python-format +msgid "Builder name %s not registered or available through entry point" +msgstr "" + +#: sphinx/registry.py:80 +#, python-format +msgid "Builder name %s not registered" +msgstr "" + +#: sphinx/registry.py:87 +#, python-format +msgid "domain %s already registered" +msgstr "" + +#: sphinx/registry.py:102 sphinx/registry.py:112 sphinx/registry.py:119 +#: sphinx/registry.py:125 +#, python-format +msgid "domain %s not yet registered" +msgstr "" + +#: sphinx/registry.py:104 +#, python-format +msgid "new domain not a subclass of registered %s domain" +msgstr "" + +#: sphinx/registry.py:160 +#, python-format +msgid "source_parser for %r is already registered" +msgstr "" + +#: sphinx/registry.py:187 +#, python-format +msgid "" +"the extension %r was already merged with Sphinx since version %s; this " +"extension is ignored." +msgstr "" + +#: sphinx/registry.py:198 +msgid "Original exception:\n" +msgstr "" + +#: sphinx/registry.py:199 +#, python-format +msgid "Could not import extension %s" +msgstr "" + +#: sphinx/registry.py:202 +#, python-format +msgid "" +"extension %r has no setup() function; is it really a Sphinx extension " +"module?" +msgstr "" + +#: sphinx/registry.py:211 +#, python-format +msgid "" +"The %s extension used by this project needs at least Sphinx v%s; it " +"therefore cannot be built with this version." +msgstr "" + +#: sphinx/registry.py:221 +#, python-format +msgid "" +"extension %r returned an unsupported object from its setup() function; it" +" should return None or a metadata dictionary" +msgstr "" + +#: sphinx/roles.py:200 #, python-format msgid "Python Enhancement Proposals; PEP %s" msgstr "" -#: sphinx/builders/changes.py:75 +#: sphinx/theming.py:83 +#, python-format +msgid "theme %r doesn't have \"theme\" setting" +msgstr "" + +#: sphinx/theming.py:85 +#, python-format +msgid "theme %r doesn't have \"inherit\" setting" +msgstr "" + +#: sphinx/theming.py:91 +#, python-format +msgid "no theme named %r found, inherited by %r" +msgstr "" + +#: sphinx/theming.py:116 +#, python-format +msgid "setting %s.%s occurs in none of the searched theme configs" +msgstr "" + +#: sphinx/theming.py:237 +#, python-format +msgid "Theme extension %r does not response correctly." +msgstr "" + +#: sphinx/theming.py:264 +#, python-format +msgid "file %r on theme path is not a valid zipfile or contains no theme" +msgstr "" + +#: sphinx/theming.py:280 +msgid "" +"sphinx_rtd_theme is no longer a hard dependency since version 1.4.0. " +"Please install it manually.(pip install sphinx_rtd_theme)" +msgstr "" + +#: sphinx/theming.py:284 +#, python-format +msgid "no theme named %r found (missing theme.conf?)" +msgstr "" + +#: sphinx/builders/changes.py:86 msgid "Builtins" msgstr "" -#: sphinx/builders/changes.py:77 +#: sphinx/builders/changes.py:88 msgid "Module level" msgstr "" -#: sphinx/builders/html.py:294 sphinx/transforms/__init__.py:46 -#: sphinx/writers/latex.py:393 sphinx/writers/manpage.py:100 -#: sphinx/writers/texinfo.py:221 +#: sphinx/builders/html.py:357 sphinx/transforms/__init__.py:119 +#: sphinx/writers/latex.py:561 sphinx/writers/manpage.py:110 +#: sphinx/writers/texinfo.py:241 #, python-format msgid "%b %d, %Y" msgstr "" -#: sphinx/builders/html.py:315 sphinx/themes/basic/defindex.html:30 +#: sphinx/builders/html.py:377 sphinx/themes/basic/defindex.html:30 msgid "General Index" msgstr "" -#: sphinx/builders/html.py:315 +#: sphinx/builders/html.py:377 msgid "index" msgstr "" -#: sphinx/builders/html.py:377 +#: sphinx/builders/html.py:441 msgid "next" msgstr "" -#: sphinx/builders/html.py:386 +#: sphinx/builders/html.py:450 msgid "previous" msgstr "" -#: sphinx/builders/html.py:1222 +#: sphinx/builders/html.py:1313 #, python-format msgid "%s %s documentation" msgstr "" -#: sphinx/builders/latex.py:177 sphinx/builders/texinfo.py:199 +#: sphinx/builders/latex.py:199 sphinx/builders/texinfo.py:217 msgid " (in " msgstr "" -#: sphinx/directives/code.py:140 sphinx/directives/code.py:370 +#: sphinx/directives/code.py:66 +msgid "Over dedent has detected" +msgstr "" + +#: sphinx/directives/code.py:86 #, python-format msgid "Invalid caption: %s" msgstr "" -#: sphinx/directives/other.py:149 +#: sphinx/directives/code.py:201 +#, python-format +msgid "Cannot use both \"%s\" and \"%s\" options" +msgstr "" + +#: sphinx/directives/code.py:218 +#, python-format +msgid "Include file %r not found or reading it failed" +msgstr "" + +#: sphinx/directives/code.py:220 +#, python-format +msgid "" +"Encoding %r used for reading included file %r seems to be wrong, try " +"giving an :encoding: option" +msgstr "" + +#: sphinx/directives/code.py:257 +#, python-format +msgid "Object named %r not found in include file %r" +msgstr "" + +#: sphinx/directives/code.py:283 +msgid "Cannot use \"lineno-match\" with a disjoint set of \"lines\"" +msgstr "" + +#: sphinx/directives/code.py:288 +#, python-format +msgid "Line spec %r: no lines pulled from include file %r" +msgstr "" + +#: sphinx/directives/other.py:158 msgid "Section author: " msgstr "" -#: sphinx/directives/other.py:151 +#: sphinx/directives/other.py:160 msgid "Module author: " msgstr "" -#: sphinx/directives/other.py:153 +#: sphinx/directives/other.py:162 msgid "Code author: " msgstr "" -#: sphinx/directives/other.py:155 +#: sphinx/directives/other.py:164 msgid "Author: " msgstr "" -#: sphinx/domains/__init__.py:277 +#: sphinx/domains/__init__.py:310 #, python-format msgid "%s %s" msgstr "" -#: sphinx/domains/c.py:58 sphinx/domains/cpp.py:4051 -#: sphinx/domains/python.py:149 +#: sphinx/domains/c.py:65 sphinx/domains/cpp.py:4436 +#: sphinx/domains/python.py:177 msgid "Parameters" msgstr "" -#: sphinx/domains/c.py:61 sphinx/domains/cpp.py:4060 -#: sphinx/domains/javascript.py:128 sphinx/domains/python.py:161 +#: sphinx/domains/c.py:68 sphinx/domains/cpp.py:4445 +#: sphinx/domains/javascript.py:210 sphinx/domains/python.py:189 msgid "Returns" msgstr "" -#: sphinx/domains/c.py:63 sphinx/domains/javascript.py:130 -#: sphinx/domains/python.py:163 +#: sphinx/domains/c.py:70 sphinx/domains/javascript.py:212 +#: sphinx/domains/python.py:191 msgid "Return type" msgstr "" -#: sphinx/domains/c.py:177 +#: sphinx/domains/c.py:188 #, python-format msgid "%s (C function)" msgstr "" -#: sphinx/domains/c.py:179 +#: sphinx/domains/c.py:190 #, python-format msgid "%s (C member)" msgstr "" -#: sphinx/domains/c.py:181 +#: sphinx/domains/c.py:192 #, python-format msgid "%s (C macro)" msgstr "" -#: sphinx/domains/c.py:183 +#: sphinx/domains/c.py:194 #, python-format msgid "%s (C type)" msgstr "" -#: sphinx/domains/c.py:185 +#: sphinx/domains/c.py:196 #, python-format msgid "%s (C variable)" msgstr "" -#: sphinx/domains/c.py:242 sphinx/domains/cpp.py:4418 -#: sphinx/domains/javascript.py:164 sphinx/domains/python.py:614 +#: sphinx/domains/c.py:257 sphinx/domains/cpp.py:4820 +#: sphinx/domains/javascript.py:299 sphinx/domains/python.py:696 msgid "function" msgstr "" -#: sphinx/domains/c.py:243 sphinx/domains/cpp.py:4419 +#: sphinx/domains/c.py:258 sphinx/domains/cpp.py:4821 msgid "member" msgstr "" -#: sphinx/domains/c.py:244 +#: sphinx/domains/c.py:259 msgid "macro" msgstr "" -#: sphinx/domains/c.py:245 sphinx/domains/cpp.py:4420 +#: sphinx/domains/c.py:260 sphinx/domains/cpp.py:4822 msgid "type" msgstr "" -#: sphinx/domains/c.py:246 +#: sphinx/domains/c.py:261 msgid "variable" msgstr "" -#: sphinx/domains/cpp.py:4054 +#: sphinx/domains/cpp.py:4439 msgid "Template Parameters" msgstr "" -#: sphinx/domains/cpp.py:4057 sphinx/domains/javascript.py:125 +#: sphinx/domains/cpp.py:4442 sphinx/domains/javascript.py:207 msgid "Throws" msgstr "" -#: sphinx/domains/cpp.py:4205 +#: sphinx/domains/cpp.py:4607 #, python-format msgid "%s (C++ type)" msgstr "" -#: sphinx/domains/cpp.py:4216 +#: sphinx/domains/cpp.py:4617 #, python-format msgid "%s (C++ concept)" msgstr "" -#: sphinx/domains/cpp.py:4227 +#: sphinx/domains/cpp.py:4627 #, python-format msgid "%s (C++ member)" msgstr "" -#: sphinx/domains/cpp.py:4238 +#: sphinx/domains/cpp.py:4637 #, python-format msgid "%s (C++ function)" msgstr "" -#: sphinx/domains/cpp.py:4249 +#: sphinx/domains/cpp.py:4647 #, python-format msgid "%s (C++ class)" msgstr "" -#: sphinx/domains/cpp.py:4260 +#: sphinx/domains/cpp.py:4657 #, python-format msgid "%s (C++ enum)" msgstr "" -#: sphinx/domains/cpp.py:4281 +#: sphinx/domains/cpp.py:4677 #, python-format msgid "%s (C++ enumerator)" msgstr "" -#: sphinx/domains/cpp.py:4417 sphinx/domains/javascript.py:165 -#: sphinx/domains/python.py:616 +#: sphinx/domains/cpp.py:4819 sphinx/domains/javascript.py:301 +#: sphinx/domains/python.py:698 msgid "class" msgstr "" -#: sphinx/domains/cpp.py:4421 +#: sphinx/domains/cpp.py:4823 msgid "concept" msgstr "" -#: sphinx/domains/cpp.py:4422 +#: sphinx/domains/cpp.py:4824 msgid "enum" msgstr "" -#: sphinx/domains/cpp.py:4423 +#: sphinx/domains/cpp.py:4825 msgid "enumerator" msgstr "" -#: sphinx/domains/javascript.py:106 sphinx/domains/python.py:307 +#: sphinx/domains/javascript.py:131 sphinx/domains/python.py:386 #, python-format msgid "%s() (built-in function)" msgstr "" -#: sphinx/domains/javascript.py:107 sphinx/domains/python.py:371 +#: sphinx/domains/javascript.py:132 sphinx/domains/python.py:451 #, python-format msgid "%s() (%s method)" msgstr "" -#: sphinx/domains/javascript.py:109 +#: sphinx/domains/javascript.py:134 #, python-format msgid "%s() (class)" msgstr "" -#: sphinx/domains/javascript.py:111 +#: sphinx/domains/javascript.py:136 #, python-format msgid "%s (global variable or constant)" msgstr "" -#: sphinx/domains/javascript.py:113 sphinx/domains/python.py:409 +#: sphinx/domains/javascript.py:138 sphinx/domains/python.py:489 #, python-format msgid "%s (%s attribute)" msgstr "" -#: sphinx/domains/javascript.py:122 +#: sphinx/domains/javascript.py:204 msgid "Arguments" msgstr "" -#: sphinx/domains/javascript.py:166 sphinx/domains/python.py:615 -msgid "data" -msgstr "" - -#: sphinx/domains/javascript.py:167 sphinx/domains/python.py:621 -msgid "attribute" -msgstr "" - -#: sphinx/domains/python.py:154 -msgid "Variables" -msgstr "" - -#: sphinx/domains/python.py:158 -msgid "Raises" -msgstr "" - -#: sphinx/domains/python.py:308 sphinx/domains/python.py:365 -#: sphinx/domains/python.py:377 sphinx/domains/python.py:390 -#, python-format -msgid "%s() (in module %s)" -msgstr "" - -#: sphinx/domains/python.py:311 -#, python-format -msgid "%s (built-in variable)" -msgstr "" - -#: sphinx/domains/python.py:312 sphinx/domains/python.py:403 -#, python-format -msgid "%s (in module %s)" -msgstr "" - -#: sphinx/domains/python.py:328 -#, python-format -msgid "%s (built-in class)" -msgstr "" - -#: sphinx/domains/python.py:329 -#, python-format -msgid "%s (class in %s)" -msgstr "" - -#: sphinx/domains/python.py:369 -#, python-format -msgid "%s() (%s.%s method)" -msgstr "" - -#: sphinx/domains/python.py:381 -#, python-format -msgid "%s() (%s.%s static method)" -msgstr "" - -#: sphinx/domains/python.py:384 -#, python-format -msgid "%s() (%s static method)" -msgstr "" - -#: sphinx/domains/python.py:394 -#, python-format -msgid "%s() (%s.%s class method)" -msgstr "" - -#: sphinx/domains/python.py:397 -#, python-format -msgid "%s() (%s class method)" -msgstr "" - -#: sphinx/domains/python.py:407 -#, python-format -msgid "%s (%s.%s attribute)" -msgstr "" - -#: sphinx/domains/python.py:488 +#: sphinx/domains/javascript.py:266 sphinx/domains/python.py:566 #, python-format msgid "%s (module)" msgstr "" -#: sphinx/domains/python.py:545 -msgid "Python Module Index" -msgstr "" - -#: sphinx/domains/python.py:546 -msgid "modules" -msgstr "" - -#: sphinx/domains/python.py:592 -msgid "Deprecated" -msgstr "" - -#: sphinx/domains/python.py:617 sphinx/locale/__init__.py:183 -msgid "exception" -msgstr "" - -#: sphinx/domains/python.py:618 +#: sphinx/domains/javascript.py:300 sphinx/domains/python.py:700 msgid "method" msgstr "" -#: sphinx/domains/python.py:619 -msgid "class method" +#: sphinx/domains/javascript.py:302 sphinx/domains/python.py:697 +msgid "data" msgstr "" -#: sphinx/domains/python.py:620 -msgid "static method" +#: sphinx/domains/javascript.py:303 sphinx/domains/python.py:703 +msgid "attribute" msgstr "" -#: sphinx/domains/python.py:622 sphinx/locale/__init__.py:179 +#: sphinx/domains/javascript.py:304 sphinx/domains/python.py:704 +#: sphinx/locale/__init__.py:218 msgid "module" msgstr "" -#: sphinx/domains/python.py:787 +#: sphinx/domains/python.py:182 +msgid "Variables" +msgstr "" + +#: sphinx/domains/python.py:186 +msgid "Raises" +msgstr "" + +#: sphinx/domains/python.py:387 sphinx/domains/python.py:445 +#: sphinx/domains/python.py:457 sphinx/domains/python.py:470 +#, python-format +msgid "%s() (in module %s)" +msgstr "" + +#: sphinx/domains/python.py:390 +#, python-format +msgid "%s (built-in variable)" +msgstr "" + +#: sphinx/domains/python.py:391 sphinx/domains/python.py:483 +#, python-format +msgid "%s (in module %s)" +msgstr "" + +#: sphinx/domains/python.py:411 +#, python-format +msgid "%s (built-in class)" +msgstr "" + +#: sphinx/domains/python.py:412 +#, python-format +msgid "%s (class in %s)" +msgstr "" + +#: sphinx/domains/python.py:449 +#, python-format +msgid "%s() (%s.%s method)" +msgstr "" + +#: sphinx/domains/python.py:461 +#, python-format +msgid "%s() (%s.%s static method)" +msgstr "" + +#: sphinx/domains/python.py:464 +#, python-format +msgid "%s() (%s static method)" +msgstr "" + +#: sphinx/domains/python.py:474 +#, python-format +msgid "%s() (%s.%s class method)" +msgstr "" + +#: sphinx/domains/python.py:477 +#, python-format +msgid "%s() (%s class method)" +msgstr "" + +#: sphinx/domains/python.py:487 +#, python-format +msgid "%s (%s.%s attribute)" +msgstr "" + +#: sphinx/domains/python.py:625 +msgid "Python Module Index" +msgstr "" + +#: sphinx/domains/python.py:626 +msgid "modules" +msgstr "" + +#: sphinx/domains/python.py:674 +msgid "Deprecated" +msgstr "" + +#: sphinx/domains/python.py:699 sphinx/locale/__init__.py:222 +msgid "exception" +msgstr "" + +#: sphinx/domains/python.py:701 +msgid "class method" +msgstr "" + +#: sphinx/domains/python.py:702 +msgid "static method" +msgstr "" + +#: sphinx/domains/python.py:874 msgid " (deprecated)" msgstr "" -#: sphinx/domains/rst.py:55 +#: sphinx/domains/rst.py:65 #, python-format msgid "%s (directive)" msgstr "" -#: sphinx/domains/rst.py:57 +#: sphinx/domains/rst.py:67 #, python-format msgid "%s (role)" msgstr "" -#: sphinx/domains/rst.py:106 +#: sphinx/domains/rst.py:119 msgid "directive" msgstr "" -#: sphinx/domains/rst.py:107 +#: sphinx/domains/rst.py:120 msgid "role" msgstr "" -#: sphinx/domains/std.py:72 sphinx/domains/std.py:88 +#: sphinx/domains/std.py:84 sphinx/domains/std.py:101 #, python-format msgid "environment variable; %s" msgstr "" -#: sphinx/domains/std.py:186 +#: sphinx/domains/std.py:200 #, python-format msgid "%scommand line option; %s" msgstr "" -#: sphinx/domains/std.py:434 +#: sphinx/domains/std.py:455 msgid "glossary term" msgstr "" -#: sphinx/domains/std.py:435 +#: sphinx/domains/std.py:456 msgid "grammar token" msgstr "" -#: sphinx/domains/std.py:436 +#: sphinx/domains/std.py:457 msgid "reference label" msgstr "" -#: sphinx/domains/std.py:438 +#: sphinx/domains/std.py:459 msgid "environment variable" msgstr "" -#: sphinx/domains/std.py:439 +#: sphinx/domains/std.py:460 msgid "program option" msgstr "" -#: sphinx/domains/std.py:473 sphinx/themes/basic/genindex-single.html:30 +#: sphinx/domains/std.py:461 +msgid "document" +msgstr "" + +#: sphinx/domains/std.py:497 sphinx/themes/basic/genindex-single.html:30 #: sphinx/themes/basic/genindex-single.html:55 #: sphinx/themes/basic/genindex-split.html:11 #: sphinx/themes/basic/genindex-split.html:14 #: sphinx/themes/basic/genindex.html:30 sphinx/themes/basic/genindex.html:33 -#: sphinx/themes/basic/genindex.html:66 sphinx/themes/basic/layout.html:135 -#: sphinx/writers/latex.py:381 sphinx/writers/texinfo.py:480 +#: sphinx/themes/basic/genindex.html:66 sphinx/themes/basic/layout.html:149 +#: sphinx/writers/latex.py:545 sphinx/writers/texinfo.py:517 msgid "Index" msgstr "" -#: sphinx/domains/std.py:474 +#: sphinx/domains/std.py:498 msgid "Module Index" msgstr "" -#: sphinx/domains/std.py:475 sphinx/themes/basic/defindex.html:25 +#: sphinx/domains/std.py:499 sphinx/themes/basic/defindex.html:25 msgid "Search Page" msgstr "" -#: sphinx/environment/managers/indexentries.py:104 +#: sphinx/environment/__init__.py:568 +#, python-format +msgid "" +"the %s extension does not declare if it is safe for parallel reading, " +"assuming it isn't - please ask the extension author to check and make it " +"explicit" +msgstr "" + +#: sphinx/environment/adapters/indexentries.py:85 #, python-format msgid "see %s" msgstr "" -#: sphinx/environment/managers/indexentries.py:108 +#: sphinx/environment/adapters/indexentries.py:89 #, python-format msgid "see also %s" msgstr "" -#: sphinx/environment/managers/indexentries.py:168 +#: sphinx/environment/adapters/indexentries.py:159 msgid "Symbols" msgstr "" -#: sphinx/ext/autodoc.py:1297 +#: sphinx/ext/autodoc.py:1451 #, python-format msgid "Bases: %s" msgstr "" -#: sphinx/ext/autodoc.py:1350 +#: sphinx/ext/autodoc.py:1506 #, python-format msgid "alias of :class:`%s`" msgstr "" -#: sphinx/ext/graphviz.py:331 sphinx/ext/graphviz.py:340 +#: sphinx/ext/doctest.py:134 +#, python-format +msgid "missing '+' or '-' in '%s' option." +msgstr "" + +#: sphinx/ext/doctest.py:139 +#, python-format +msgid "'%s' is not a valid option." +msgstr "" + +#: sphinx/ext/doctest.py:155 +#, python-format +msgid "'%s' is not a valid pyversion option" +msgstr "" + +#: sphinx/ext/graphviz.py:96 +msgid "Graphviz directive cannot have both content and a filename argument" +msgstr "" + +#: sphinx/ext/graphviz.py:107 +#, python-format +msgid "External Graphviz file %r not found or reading it failed" +msgstr "" + +#: sphinx/ext/graphviz.py:113 +msgid "Ignoring \"graphviz\" directive without content." +msgstr "" + +#: sphinx/ext/graphviz.py:204 +#, python-format +msgid "" +"dot command %r cannot be run (needed for graphviz output), check the " +"graphviz_dot setting" +msgstr "" + +#: sphinx/ext/graphviz.py:222 +#, python-format +msgid "" +"dot exited with error:\n" +"[stderr]\n" +"%s\n" +"[stdout]\n" +"%s" +msgstr "" + +#: sphinx/ext/graphviz.py:225 +#, python-format +msgid "" +"dot did not produce an output file:\n" +"[stderr]\n" +"%s\n" +"[stdout]\n" +"%s" +msgstr "" + +#: sphinx/ext/graphviz.py:236 +#, python-format +msgid "graphviz_output_format must be one of 'png', 'svg', but is %r" +msgstr "" + +#: sphinx/ext/graphviz.py:336 sphinx/ext/graphviz.py:345 #, python-format msgid "[graph: %s]" msgstr "" -#: sphinx/ext/graphviz.py:333 sphinx/ext/graphviz.py:342 +#: sphinx/ext/graphviz.py:338 sphinx/ext/graphviz.py:347 msgid "[graph]" msgstr "" -#: sphinx/ext/imgmath.py:258 sphinx/ext/jsmath.py:39 sphinx/ext/mathjax.py:40 +#: sphinx/ext/imgconverter.py:46 sphinx/ext/imgconverter.py:63 +#, python-format +msgid "convert command %r cannot be run.check the image_converter setting" +msgstr "" + +#: sphinx/ext/imgconverter.py:76 +#, python-format +msgid "" +"convert exited with error:\n" +"[stderr]\n" +"%s\n" +"[stdout]\n" +"%s" +msgstr "" + +#: sphinx/ext/imgmath.py:274 sphinx/ext/jsmath.py:39 sphinx/ext/mathjax.py:40 msgid "Permalink to this equation" msgstr "" -#: sphinx/ext/intersphinx.py:337 +#: sphinx/ext/intersphinx.py:319 #, python-format msgid "(in %s v%s)" msgstr "" -#: sphinx/ext/linkcode.py:69 sphinx/ext/viewcode.py:103 +#: sphinx/ext/linkcode.py:75 sphinx/ext/viewcode.py:112 msgid "[source]" msgstr "" -#: sphinx/ext/mathbase.py:92 +#: sphinx/ext/mathbase.py:106 #, python-format msgid "duplicate label of equation %s, other instance in %s" msgstr "" -#: sphinx/ext/todo.py:56 +#: sphinx/ext/todo.py:66 msgid "Todo" msgstr "" -#: sphinx/ext/todo.py:134 +#: sphinx/ext/todo.py:148 msgid "<>" msgstr "" -#: sphinx/ext/todo.py:137 +#: sphinx/ext/todo.py:151 #, python-format msgid "(The <> is located in %s, line %d.)" msgstr "" -#: sphinx/ext/todo.py:146 +#: sphinx/ext/todo.py:160 msgid "original entry" msgstr "" -#: sphinx/ext/viewcode.py:166 +#: sphinx/ext/viewcode.py:179 msgid "[docs]" msgstr "" -#: sphinx/ext/viewcode.py:180 +#: sphinx/ext/viewcode.py:193 msgid "Module code" msgstr "" -#: sphinx/ext/viewcode.py:186 +#: sphinx/ext/viewcode.py:199 #, python-format msgid "

Source code for %s

" msgstr "" -#: sphinx/ext/viewcode.py:212 +#: sphinx/ext/viewcode.py:225 msgid "Overview: module code" msgstr "" -#: sphinx/ext/viewcode.py:213 +#: sphinx/ext/viewcode.py:226 msgid "

All modules for which code is available

" msgstr "" -#: sphinx/ext/napoleon/__init__.py:313 +#: sphinx/ext/napoleon/__init__.py:320 msgid "Keyword Arguments" msgstr "" -#: sphinx/locale/__init__.py:159 +#: sphinx/locale/__init__.py:198 msgid "Attention" msgstr "" -#: sphinx/locale/__init__.py:160 +#: sphinx/locale/__init__.py:199 msgid "Caution" msgstr "" -#: sphinx/locale/__init__.py:161 +#: sphinx/locale/__init__.py:200 msgid "Danger" msgstr "" -#: sphinx/locale/__init__.py:162 +#: sphinx/locale/__init__.py:201 msgid "Error" msgstr "" -#: sphinx/locale/__init__.py:163 +#: sphinx/locale/__init__.py:202 msgid "Hint" msgstr "" -#: sphinx/locale/__init__.py:164 +#: sphinx/locale/__init__.py:203 msgid "Important" msgstr "" -#: sphinx/locale/__init__.py:165 +#: sphinx/locale/__init__.py:204 msgid "Note" msgstr "" -#: sphinx/locale/__init__.py:166 +#: sphinx/locale/__init__.py:205 msgid "See also" msgstr "" -#: sphinx/locale/__init__.py:167 +#: sphinx/locale/__init__.py:206 msgid "Tip" msgstr "" -#: sphinx/locale/__init__.py:168 +#: sphinx/locale/__init__.py:207 msgid "Warning" msgstr "" -#: sphinx/locale/__init__.py:172 +#: sphinx/locale/__init__.py:211 #, python-format msgid "New in version %s" msgstr "" -#: sphinx/locale/__init__.py:173 +#: sphinx/locale/__init__.py:212 #, python-format msgid "Changed in version %s" msgstr "" -#: sphinx/locale/__init__.py:174 +#: sphinx/locale/__init__.py:213 #, python-format msgid "Deprecated since version %s" msgstr "" -#: sphinx/locale/__init__.py:180 +#: sphinx/locale/__init__.py:219 msgid "keyword" msgstr "" -#: sphinx/locale/__init__.py:181 +#: sphinx/locale/__init__.py:220 msgid "operator" msgstr "" -#: sphinx/locale/__init__.py:182 +#: sphinx/locale/__init__.py:221 msgid "object" msgstr "" -#: sphinx/locale/__init__.py:184 +#: sphinx/locale/__init__.py:223 msgid "statement" msgstr "" -#: sphinx/locale/__init__.py:185 +#: sphinx/locale/__init__.py:224 msgid "built-in function" msgstr "" #: sphinx/themes/agogo/layout.html:46 sphinx/themes/basic/globaltoc.html:10 -#: sphinx/themes/basic/localtoc.html:11 sphinx/themes/scrolls/layout.html:35 +#: sphinx/themes/basic/localtoc.html:11 sphinx/themes/scrolls/layout.html:38 msgid "Table Of Contents" msgstr "" -#: sphinx/themes/agogo/layout.html:51 sphinx/themes/basic/layout.html:138 +#: sphinx/themes/agogo/layout.html:51 sphinx/themes/basic/layout.html:152 #: sphinx/themes/basic/search.html:11 sphinx/themes/basic/search.html:23 #: sphinx/themes/basic/searchresults.html:10 msgid "Search" @@ -688,39 +1075,39 @@ msgstr "" msgid "can be huge" msgstr "" -#: sphinx/themes/basic/layout.html:29 +#: sphinx/themes/basic/layout.html:31 msgid "Navigation" msgstr "" -#: sphinx/themes/basic/layout.html:123 +#: sphinx/themes/basic/layout.html:137 #, python-format msgid "Search within %(docstitle)s" msgstr "" -#: sphinx/themes/basic/layout.html:132 +#: sphinx/themes/basic/layout.html:146 msgid "About these documents" msgstr "" -#: sphinx/themes/basic/layout.html:141 +#: sphinx/themes/basic/layout.html:155 msgid "Copyright" msgstr "" -#: sphinx/themes/basic/layout.html:186 +#: sphinx/themes/basic/layout.html:200 #, python-format msgid "© Copyright %(copyright)s." msgstr "" -#: sphinx/themes/basic/layout.html:188 +#: sphinx/themes/basic/layout.html:202 #, python-format msgid "© Copyright %(copyright)s." msgstr "" -#: sphinx/themes/basic/layout.html:192 +#: sphinx/themes/basic/layout.html:206 #, python-format msgid "Last updated on %(last_updated)s." msgstr "" -#: sphinx/themes/basic/layout.html:195 +#: sphinx/themes/basic/layout.html:209 #, python-format msgid "" "Created using Sphinx " @@ -767,12 +1154,12 @@ msgid "search" msgstr "" #: sphinx/themes/basic/search.html:43 sphinx/themes/basic/searchresults.html:21 -#: sphinx/themes/basic/static/searchtools.js_t:287 +#: sphinx/themes/basic/static/searchtools.js_t:336 msgid "Search Results" msgstr "" #: sphinx/themes/basic/search.html:45 sphinx/themes/basic/searchresults.html:23 -#: sphinx/themes/basic/static/searchtools.js_t:289 +#: sphinx/themes/basic/static/searchtools.js_t:338 msgid "" "Your search did not match any documents. Please make sure that all words " "are spelled correctly and that you've selected enough categories." @@ -814,43 +1201,45 @@ msgstr "" msgid "Other changes" msgstr "" -#: sphinx/themes/basic/static/doctools.js_t:169 sphinx/writers/html.py:708 -#: sphinx/writers/html.py:713 +#: sphinx/themes/basic/static/doctools.js_t:171 sphinx/writers/html.py:405 +#: sphinx/writers/html.py:410 sphinx/writers/html5.py:352 +#: sphinx/writers/html5.py:357 msgid "Permalink to this headline" msgstr "" -#: sphinx/themes/basic/static/doctools.js_t:175 sphinx/writers/html.py:108 -#: sphinx/writers/html.py:117 +#: sphinx/themes/basic/static/doctools.js_t:177 sphinx/writers/html.py:126 +#: sphinx/writers/html.py:137 sphinx/writers/html5.py:96 +#: sphinx/writers/html5.py:107 msgid "Permalink to this definition" msgstr "" -#: sphinx/themes/basic/static/doctools.js_t:208 +#: sphinx/themes/basic/static/doctools.js_t:210 msgid "Hide Search Matches" msgstr "" -#: sphinx/themes/basic/static/searchtools.js_t:121 +#: sphinx/themes/basic/static/searchtools.js_t:142 msgid "Searching" msgstr "" -#: sphinx/themes/basic/static/searchtools.js_t:126 +#: sphinx/themes/basic/static/searchtools.js_t:147 msgid "Preparing search..." msgstr "" -#: sphinx/themes/basic/static/searchtools.js_t:291 +#: sphinx/themes/basic/static/searchtools.js_t:340 #, python-format msgid "Search finished, found %s page(s) matching the search query." msgstr "" -#: sphinx/themes/basic/static/searchtools.js_t:344 +#: sphinx/themes/basic/static/searchtools.js_t:398 msgid ", in " msgstr "" -#: sphinx/themes/classic/static/sidebar.js_t:83 +#: sphinx/themes/classic/static/sidebar.js_t:92 msgid "Expand sidebar" msgstr "" -#: sphinx/themes/classic/static/sidebar.js_t:96 -#: sphinx/themes/classic/static/sidebar.js_t:124 +#: sphinx/themes/classic/static/sidebar.js_t:105 +#: sphinx/themes/classic/static/sidebar.js_t:135 msgid "Collapse sidebar" msgstr "" @@ -858,54 +1247,65 @@ msgstr "" msgid "Contents" msgstr "" -#: sphinx/writers/html.py:389 -msgid "Permalink to this code" +#: sphinx/transforms/post_transforms/__init__.py:105 +#, python-format +msgid "more than one target found for 'any' cross-reference %r: could be %s" msgstr "" -#: sphinx/writers/html.py:393 -msgid "Permalink to this image" +#: sphinx/transforms/post_transforms/__init__.py:135 +#, python-format +msgid "%s:%s reference target not found: %%(target)s" msgstr "" -#: sphinx/writers/html.py:395 -msgid "Permalink to this toctree" +#: sphinx/transforms/post_transforms/__init__.py:138 +#, python-format +msgid "%r reference target not found: %%(target)s" msgstr "" -#: sphinx/writers/html.py:717 +#: sphinx/util/docutils.py:171 +msgid "when adding directive classes, no additional arguments may be given" +msgstr "" + +#: sphinx/writers/html.py:414 sphinx/writers/html5.py:361 msgid "Permalink to this table" msgstr "" -#: sphinx/writers/latex.py:380 +#: sphinx/writers/html.py:466 sphinx/writers/html5.py:413 +msgid "Permalink to this code" +msgstr "" + +#: sphinx/writers/html.py:470 sphinx/writers/html5.py:417 +msgid "Permalink to this image" +msgstr "" + +#: sphinx/writers/html.py:472 sphinx/writers/html5.py:419 +msgid "Permalink to this toctree" +msgstr "" + +#: sphinx/writers/latex.py:549 msgid "Release" msgstr "" -#: sphinx/writers/latex.py:483 +#: sphinx/writers/latex.py:654 msgid "page" msgstr "" -#: sphinx/writers/latex.py:528 +#: sphinx/writers/latex.py:704 #, python-format msgid "Unknown configure key: latex_elements[%r] is ignored." msgstr "" -#: sphinx/writers/latex.py:1003 sphinx/writers/manpage.py:238 -#: sphinx/writers/texinfo.py:619 +#: sphinx/writers/latex.py:1252 sphinx/writers/manpage.py:275 +#: sphinx/writers/texinfo.py:670 msgid "Footnotes" msgstr "" -#: sphinx/writers/latex.py:1112 -msgid "continued from previous page" -msgstr "" - -#: sphinx/writers/latex.py:1118 -msgid "Continued on next page" -msgstr "" - -#: sphinx/writers/manpage.py:287 sphinx/writers/text.py:591 +#: sphinx/writers/manpage.py:331 sphinx/writers/text.py:699 #, python-format msgid "[image: %s]" msgstr "" -#: sphinx/writers/manpage.py:288 sphinx/writers/text.py:592 +#: sphinx/writers/manpage.py:332 sphinx/writers/text.py:700 msgid "[image]" msgstr "" diff --git a/utils/release-checklist b/utils/release-checklist index e8f716acd..a79147724 100644 --- a/utils/release-checklist +++ b/utils/release-checklist @@ -4,7 +4,12 @@ Release checklist * open https://travis-ci.org/sphinx-doc/sphinx/branches and check stable branch is green * Check `git status` * Run `make style-check` -* if final major release ... +* Update sphinx/locale/sphinx.pot if first major release (beta1) + + * Run `pytho nsetup.py extract_messages` + * Run `(cd sphinx/locale; tx push -s)` + +* Update sphinx/locale// files if final major release ... * Run `(cd sphinx/locale; tx pull -a -f)` * Run `python setup.py compile_catalog` From 370bdddc7c9cc20383d6211a27ef6868773bd82e Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Sat, 29 Apr 2017 15:22:34 +0900 Subject: [PATCH 28/32] make websupport-dependency optional --- CHANGES | 1 + setup.py | 4 +++- sphinx/websupport/__init__.py | 19 ++++++++++++------- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/CHANGES b/CHANGES index 0ed869b50..c333a95f3 100644 --- a/CHANGES +++ b/CHANGES @@ -20,6 +20,7 @@ Bugs fixed * #3661: sphinx-build crashes on parallel build * #3669: gettext builder fails with "ValueError: substring not found" +* #3660: Sphinx always depends on sphinxcontrib-websupport and its dependencies Testing -------- diff --git a/setup.py b/setup.py index 1fd2d34d0..4354b0baa 100644 --- a/setup.py +++ b/setup.py @@ -51,7 +51,6 @@ requires = [ 'alabaster>=0.7,<0.8', 'imagesize', 'requests>=2.0.0', - 'sphinxcontrib-websupport', 'typing', 'setuptools', ] @@ -60,6 +59,9 @@ extras_require = { ':sys_platform=="win32"': [ 'colorama>=0.3.5', ], + 'websupport': [ + 'sphinxcontrib-websupport', + ], 'test': [ 'pytest', 'mock', # it would be better for 'test:python_version in 2.7' diff --git a/sphinx/websupport/__init__.py b/sphinx/websupport/__init__.py index f06d98433..f71034708 100644 --- a/sphinx/websupport/__init__.py +++ b/sphinx/websupport/__init__.py @@ -12,11 +12,16 @@ import warnings from sphinx.deprecation import RemovedInSphinx20Warning -from sphinxcontrib.websupport import WebSupport # NOQA -from sphinxcontrib.websupport import errors # NOQA -from sphinxcontrib.websupport.search import BaseSearch, SEARCH_ADAPTERS # NOQA -from sphinxcontrib.websupport.storage import StorageBackend # NOQA -warnings.warn('sphinx.websupport module is now provided as sphinxcontrib.webuspport. ' - 'sphinx.websupport will be removed in Sphinx-2.0. Please use it instaed', - RemovedInSphinx20Warning) +try: + from sphinxcontrib.websupport import WebSupport # NOQA + from sphinxcontrib.websupport import errors # NOQA + from sphinxcontrib.websupport.search import BaseSearch, SEARCH_ADAPTERS # NOQA + from sphinxcontrib.websupport.storage import StorageBackend # NOQA + + warnings.warn('sphinx.websupport module is now provided as sphinxcontrib-webuspport. ' + 'sphinx.websupport will be removed in Sphinx-2.0. Please use it instaed', + RemovedInSphinx20Warning) +except ImportError: + warnings.warn('Since Sphinx-1.6, sphinx.websupport module is now separated to ' + 'sphinxcontrib-webuspport package. Please add it into your dependency list.') From d8f57ea86525107e9f9a7e050fd12a5e95a63ec8 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Sat, 29 Apr 2017 23:26:28 +0900 Subject: [PATCH 29/32] Update CHANGES --- CHANGES | 6 ------ 1 file changed, 6 deletions(-) diff --git a/CHANGES b/CHANGES index c333a95f3..5350385bb 100644 --- a/CHANGES +++ b/CHANGES @@ -12,9 +12,6 @@ Deprecated * #3662: ``builder.css_files`` is deprecated. Please use ``add_stylesheet()`` API instead. -Features added --------------- - Bugs fixed ---------- @@ -22,9 +19,6 @@ Bugs fixed * #3669: gettext builder fails with "ValueError: substring not found" * #3660: Sphinx always depends on sphinxcontrib-websupport and its dependencies -Testing --------- - Release 1.6 beta1 (released Apr 24, 2017) ========================================= From 0960c7d8571e090827064f2229e404c5320dcb96 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Sat, 29 Apr 2017 23:29:43 +0900 Subject: [PATCH 30/32] Bump to 1.6b2 --- CHANGES | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index 5350385bb..d9ac606ad 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,5 @@ -Release 1.6 beta2 (in development) -================================== +Release 1.6 beta2 (released Apr 29, 2017) +========================================= Incompatible changes -------------------- From 0f25c18ce90dd1019db63fe29a6f4878aff702c9 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Sat, 29 Apr 2017 23:46:19 +0900 Subject: [PATCH 31/32] Bump to 1.6b2 --- sphinx/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sphinx/__init__.py b/sphinx/__init__.py index a071097da..62562c067 100644 --- a/sphinx/__init__.py +++ b/sphinx/__init__.py @@ -34,8 +34,8 @@ if 'PYTHONWARNINGS' not in os.environ: warnings.filterwarnings('ignore', "'U' mode is deprecated", DeprecationWarning, module='docutils.io') -__version__ = '1.6+' -__released__ = '1.6' # used when Sphinx builds its own docs +__version__ = '1.6b2' +__released__ = '1.6b2' # used when Sphinx builds its own docs # version info for better programmatic use # possible values for 3rd element: 'alpha', 'beta', 'rc', 'final' From 004dfae2db177eda4570bfdf4a04ae014ef6ada5 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Sat, 29 Apr 2017 23:50:17 +0900 Subject: [PATCH 32/32] Bump version --- CHANGES | 18 ++++++++++++++++++ sphinx/__init__.py | 6 +++--- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/CHANGES b/CHANGES index d9ac606ad..dea12e681 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,21 @@ +Release 1.6 beta3 (in development) +================================== + +Incompatible changes +-------------------- + +Deprecated +---------- + +Features added +-------------- + +Bugs fixed +---------- + +Testing +-------- + Release 1.6 beta2 (released Apr 29, 2017) ========================================= diff --git a/sphinx/__init__.py b/sphinx/__init__.py index 62562c067..cd8ad2c0d 100644 --- a/sphinx/__init__.py +++ b/sphinx/__init__.py @@ -34,13 +34,13 @@ if 'PYTHONWARNINGS' not in os.environ: warnings.filterwarnings('ignore', "'U' mode is deprecated", DeprecationWarning, module='docutils.io') -__version__ = '1.6b2' -__released__ = '1.6b2' # used when Sphinx builds its own docs +__version__ = '1.6+' +__released__ = '1.6' # used when Sphinx builds its own docs # version info for better programmatic use # possible values for 3rd element: 'alpha', 'beta', 'rc', 'final' # 'final' has 0 as the last element -version_info = (1, 6, 0, 'beta', 2) +version_info = (1, 6, 0, 'beta', 3) package_dir = path.abspath(path.dirname(__file__))