Merge branch 'master' into 5196_linkcheck_should_check_remote_image

This commit is contained in:
Takeshi KOMIYA 2019-02-08 00:10:14 +09:00 committed by GitHub
commit 500bf85443
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
39 changed files with 385 additions and 432 deletions

11
CHANGES
View File

@ -21,6 +21,7 @@ Dependencies
* The sphinxcontrib-websupport package is no longer a dependency
* Some packages are separated to sub packages:
- sphinxcontrib.applehelp
- sphinxcontrib.devhelp
- sphinxcontrib.jsmath
- sphinxcontrib.qthelp
@ -61,6 +62,9 @@ Incompatible changes
* websupport: unbundled from sphinx core. Please use sphinxcontrib-websupport
* C++, the visibility of base classes is now always rendered as present in the
input. That is, ``private`` is now shown, where it was ellided before.
* LaTeX: graphics inclusion of oversized images rescales to not exceed
the text width and height, even if width and/or height option were used.
(refs: #5956)
Deprecated
----------
@ -167,6 +171,11 @@ Features added
* #1341 the HTML search considers words that contain a search term of length
three or longer a match.
* #4611: epub: Show warning for duplicated ToC entries
* #1851: Allow to omit an argument for :rst:dir:`code-block` directive. If
omitted, it follows :rst:dir:`highlight` or :confval:`highlight_language`
* #6016: HTML search: A placeholder for the search summary prevents search
result links from changing their position when the search terminates. This
makes navigating search results easier.
* #5196: linkcheck also checks remote images exist
Bugs fixed
@ -216,6 +225,8 @@ Features added
Bugs fixed
----------
* LaTeX: Remove extraneous space after author names on PDF title page (refs: #6004)
Testing
--------

View File

@ -18,6 +18,7 @@ Documentation using the alabaster theme
* `Click <http://click.pocoo.org/>`__ (customized)
* `coala <https://docs.coala.io/>`__ (customized)
* `CodePy <https://documen.tician.de/codepy/>`__
* `Eve <https://docs.python-eve.org/>`__ (Python REST API framework)
* `Fabric <https://docs.fabfile.org/>`__
* `Fityk <https://fityk.nieto.pl/>`__
* `Flask <http://flask.pocoo.org/docs/>`__
@ -110,6 +111,7 @@ Documentation using the classic theme
Documentation using the sphinxdoc theme
---------------------------------------
* `ABRT <https://abrt.readthedocs.io/>`__
* `cartopy <https://scitools.org.uk/cartopy/docs/latest/>`__
* `Jython <http://www.jython.org/docs/>`__
* `Matplotlib <https://matplotlib.org/>`__
@ -183,11 +185,14 @@ Documentation using sphinx_rtd_theme
* `Elemental <http://libelemental.org/documentation/dev/>`__
* `ESWP3 <https://eswp3.readthedocs.io/>`__
* `Ethereum Homestead <http://www.ethdocs.org/>`__
* `Faker <https://faker.readthedocs.io/>`__
* `Fidimag <https://fidimag.readthedocs.io/>`__
* `Flake8 <http://flake8.pycqa.org/>`__
* `Flatpak <http://docs.flatpak.org/>`__
* `FluidDyn <https://fluiddyn.readthedocs.io/>`__
* `Fluidsim <https://fluidsim.readthedocs.io/>`__
* `GeoNode <http://docs.geonode.org/>`__
* `Glances <https://glances.readthedocs.io/>`__
* `Godot <https://godot.readthedocs.io/>`__
* `Graylog <http://docs.graylog.org/>`__
* `GPAW <https://wiki.fysik.dtu.dk/gpaw/>`__ (customized)
@ -225,6 +230,7 @@ Documentation using sphinx_rtd_theme
* `Phinx <http://docs.phinx.org/>`__
* `phpMyAdmin <https://docs.phpmyadmin.net/>`__
* `PROS <https://pros.cs.purdue.edu/v5/>`__ (customized)
* `Pushkin <http://docs.pushkin.io/>`__
* `Pweave <http://mpastell.com/pweave/>`__
* `PyPy <http://doc.pypy.org/>`__
* `python-sqlparse <https://sqlparse.readthedocs.io/>`__
@ -236,6 +242,7 @@ Documentation using sphinx_rtd_theme
* `Quex <http://quex.sourceforge.net/doc/html/main.html>`__
* `Satchmo <http://docs.satchmoproject.com/>`__
* `Scapy <https://scapy.readthedocs.io/>`__
* `SimGrid <http://simgrid.gforge.inria.fr/simgrid/latest/doc/>`__
* `SimPy <https://simpy.readthedocs.io/>`__
* `six <https://six.readthedocs.io/>`__
* `SlamData <https://newdocs.slamdata.com>`__
@ -249,12 +256,14 @@ Documentation using sphinx_rtd_theme
* `Sublime Text Unofficial Documentation <http://docs.sublimetext.info/>`__
* `SunPy <https://docs.sunpy.org/>`__
* `Sylius <http://docs.sylius.org/>`__
* `Syncthing <https://docs.syncthing.net/>`__
* `Tango Controls <https://tango-controls.readthedocs.io/>`__ (customized)
* `Topshelf <http://docs.topshelf-project.com/>`__
* `Theano <http://www.deeplearning.net/software/theano/>`__
* `ThreatConnect <https://docs.threatconnect.com/>`__
* `Tuleap <https://tuleap.net/doc/en/>`__
* `TYPO3 <https://docs.typo3.org/>`__ (customized)
* `Veyon <https://docs.veyon.io/>`__
* `uWSGI <https://uwsgi-docs.readthedocs.io/>`__
* `virtualenv <https://virtualenv.readthedocs.io/>`__
* `Wagtail <https://docs.wagtail.io/>`__
@ -262,6 +271,7 @@ Documentation using sphinx_rtd_theme
* `Weblate <https://docs.weblate.org/>`__
* `x265 <https://x265.readthedocs.io/>`__
* `ZeroNet <https://zeronet.readthedocs.io/>`__
* `Zulip <https://zulip.readthedocs.io/>`__
Documentation using sphinx_bootstrap_theme
------------------------------------------
@ -301,6 +311,7 @@ Documentation using a custom theme or integrated in a website
* `GHC - Glasgow Haskell Compiler <https://downloads.haskell.org/~ghc/master/users-guide/>`__
* `Guzzle <http://docs.guzzlephp.org/>`__
* `H2O.ai <http://docs.h2o.ai/>`__
* `Heka <https://hekad.readthedocs.io/>`__
* `Istihza (Turkish Python documentation project) <https://belgeler.yazbel.com/python-istihza/>`__
* `Kombu <http://docs.kombu.me/>`__
* `Lasso <http://lassoguide.com/>`__
@ -378,6 +389,7 @@ Books produced using Sphinx
* `"Mithril -- The fastest clientside MVC (Japanese)" <https://www.oreilly.co.jp/books/9784873117447/>`__
* `"Pioneers and Prominent Men of Utah" <http://pioneers.rstebbing.com/>`__
* `"Pomodoro Technique Illustrated" (Japanese translation) <https://www.amazon.co.jp/dp/4048689525/>`__
* `"Professional Software Development" <https://mixmastamyk.bitbucket.io/pro_soft_dev/>`__
* `"Python Professional Programming" (in Japanese) <http://www.amazon.co.jp/dp/4798032948/>`__
* `"Python Professional Programming 2nd Edition" (in Japanese) <https://www.amazon.co.jp/dp/479804315X/>`__
* `"Python Professional Programming 3rd Edition" (in Japanese) <https://www.amazon.co.jp/dp/4798053821/>`__

View File

@ -275,6 +275,11 @@ The following is a list of deprecated interfaces.
- 4.0
- ``docutils.nodes.abbreviation``
* - ``sphinx.builders.applehelp``
- 2.0
- 4.0
- ``sphinxcontrib.applehelp``
* - ``sphinx.builders.devhelp``
- 2.0
- 4.0

View File

@ -70,10 +70,6 @@ Options
Master document name. (see :confval:`master_doc`).
.. option:: --epub
Use epub.
.. rubric:: Extension Options
.. option:: --ext-autodoc

View File

@ -91,7 +91,7 @@ The builder's "name" must be given to the **-b** command-line option of
.. _Qt help: https://doc.qt.io/qt-4.8/qthelp-framework.html
.. module:: sphinx.builders.applehelp
.. module:: sphinxcontrib.applehelp
.. class:: AppleHelpBuilder
This builder produces an Apple Help Book based on the same output as the
@ -117,6 +117,10 @@ The builder's "name" must be given to the **-b** command-line option of
.. versionadded:: 1.3
.. versionchanged:: 2.0
Moved to sphinxcontrib.applehelp from sphinx.builders package.
.. module:: sphinxcontrib.devhelp
.. class:: DevhelpBuilder

View File

@ -463,7 +463,7 @@ __ http://pygments.org/docs/lexers/
This will produce line numbers for all code blocks longer than five lines.
.. rst:directive:: .. code-block:: language
.. rst:directive:: .. code-block:: [language]
Example::
@ -471,9 +471,11 @@ __ http://pygments.org/docs/lexers/
Some Ruby code.
The directive's alias name :rst:dir:`sourcecode` works as well. As with
:rst:dir:`highlight`\ 's ``language`` option, ``language`` can be any lexer
alias supported by Pygments.
The directive's alias name :rst:dir:`sourcecode` works as well. This
directive takes a language name as an argument. It can be any lexer alias
supported by Pygments. If it is not given, the setting of
:rst:dir:`highlight` directive will be used. If not set,
:confval:`highlight_language` will be used.
**Additional options**
@ -533,6 +535,9 @@ __ http://pygments.org/docs/lexers/
.. versionchanged:: 1.6.6
LaTeX supports the ``emphasize-lines`` option.
.. versionchanged:: 2.0
The ``language`` argument becomes optional.
.. rst:directive:: .. literalinclude:: filename
Longer displays of verbatim text may be included by storing the example text

View File

@ -15,6 +15,7 @@ if sys.version_info < (3, 5):
sys.exit(1)
install_requires = [
'sphinxcontrib-applehelp',
'sphinxcontrib-devhelp',
'sphinxcontrib-jsmath',
'sphinxcontrib-qthelp',

View File

@ -62,9 +62,9 @@ if False:
builtin_extensions = (
'sphinx.addnodes',
'sphinx.builders.applehelp',
'sphinx.builders.changes',
'sphinx.builders.epub3',
'sphinx.builders.dirhtml',
'sphinx.builders.dummy',
'sphinx.builders.gettext',
'sphinx.builders.html',
@ -106,6 +106,7 @@ builtin_extensions = (
'sphinx.environment.collectors.toctree',
'sphinx.environment.collectors.indexentries',
# 1st party extensions
'sphinxcontrib.applehelp',
'sphinxcontrib.devhelp',
'sphinxcontrib.qthelp',
# Strictly, alabaster theme is not a builtin extension,

View File

@ -8,21 +8,15 @@
:license: BSD, see LICENSE for details.
"""
import plistlib
import shlex
import subprocess
from os import path, environ
from subprocess import CalledProcessError, PIPE, STDOUT
import warnings
from sphinx import package_dir
from sphinx.builders.html import StandaloneHTMLBuilder
from sphinx.errors import SphinxError
from sphinx.locale import __
from sphinx.util import logging
from sphinx.util import SkipProgressMessage, progress_message
from sphinx.util.fileutil import copy_asset, copy_asset_file
from sphinx.util.matching import Matcher
from sphinx.util.osutil import ensuredir, make_filename
from sphinxcontrib.applehelp import (
AppleHelpCodeSigningFailed,
AppleHelpIndexerFailed,
AppleHelpBuilder,
)
from sphinx.deprecation import RemovedInSphinx40Warning, deprecated_alias
if False:
# For type annotation
@ -30,240 +24,20 @@ if False:
from sphinx.application import Sphinx # NOQA
logger = logging.getLogger(__name__)
template_dir = path.join(package_dir, 'templates', 'applehelp')
class AppleHelpIndexerFailed(SphinxError):
category = __('Help indexer failed')
class AppleHelpCodeSigningFailed(SphinxError):
category = __('Code signing failed')
class AppleHelpBuilder(StandaloneHTMLBuilder):
"""
Builder that outputs an Apple help book. Requires Mac OS X as it relies
on the ``hiutil`` command line tool.
"""
name = 'applehelp'
epilog = __('The help book is in %(outdir)s.\n'
'Note that won\'t be able to view it unless you put it in '
'~/Library/Documentation/Help or install it in your application '
'bundle.')
# don't copy the reST source
copysource = False
supported_image_types = ['image/png', 'image/gif', 'image/jpeg',
'image/tiff', 'image/jp2', 'image/svg+xml']
# don't add links
add_permalinks = False
# this is an embedded HTML format
embedded = True
# don't generate the search index or include the search page
search = False
def init(self):
# type: () -> None
super().init()
# the output files for HTML help must be .html only
self.out_suffix = '.html'
self.link_suffix = '.html'
if self.config.applehelp_bundle_id is None:
raise SphinxError(__('You must set applehelp_bundle_id before '
'building Apple Help output'))
self.bundle_path = path.join(self.outdir,
self.config.applehelp_bundle_name + '.help')
self.outdir = path.join(self.bundle_path,
'Contents',
'Resources',
self.config.applehelp_locale + '.lproj')
def handle_finish(self):
# type: () -> None
super().handle_finish()
self.finish_tasks.add_task(self.copy_localized_files)
self.finish_tasks.add_task(self.build_helpbook)
@progress_message(__('copying localized files'))
def copy_localized_files(self):
# type: () -> None
source_dir = path.join(self.confdir, self.config.applehelp_locale + '.lproj')
target_dir = self.outdir
if path.isdir(source_dir):
excluded = Matcher(self.config.exclude_patterns + ['**/.*'])
copy_asset(source_dir, target_dir, excluded,
context=self.globalcontext, renderer=self.templates)
def build_helpbook(self):
# type: () -> None
contents_dir = path.join(self.bundle_path, 'Contents')
resources_dir = path.join(contents_dir, 'Resources')
language_dir = path.join(resources_dir,
self.config.applehelp_locale + '.lproj')
ensuredir(language_dir)
self.build_info_plist(contents_dir)
self.copy_applehelp_icon(resources_dir)
self.build_access_page(language_dir)
self.build_helpindex(language_dir)
if self.config.applehelp_codesign_identity:
self.do_codesign()
@progress_message(__('writing Info.plist'))
def build_info_plist(self, contents_dir):
# type: (str) -> None
"""Construct the Info.plist file."""
info_plist = {
'CFBundleDevelopmentRegion': self.config.applehelp_dev_region,
'CFBundleIdentifier': self.config.applehelp_bundle_id,
'CFBundleInfoDictionaryVersion': '6.0',
'CFBundlePackageType': 'BNDL',
'CFBundleShortVersionString': self.config.release,
'CFBundleSignature': 'hbwr',
'CFBundleVersion': self.config.applehelp_bundle_version,
'HPDBookAccessPath': '_access.html',
'HPDBookIndexPath': 'search.helpindex',
'HPDBookTitle': self.config.applehelp_title,
'HPDBookType': '3',
'HPDBookUsesExternalViewer': False,
}
if self.config.applehelp_icon is not None:
info_plist['HPDBookIconPath'] = path.basename(self.config.applehelp_icon)
if self.config.applehelp_kb_url is not None:
info_plist['HPDBookKBProduct'] = self.config.applehelp_kb_product
info_plist['HPDBookKBURL'] = self.config.applehelp_kb_url
if self.config.applehelp_remote_url is not None:
info_plist['HPDBookRemoteURL'] = self.config.applehelp_remote_url
with open(path.join(contents_dir, 'Info.plist'), 'wb') as f:
plistlib.dump(info_plist, f)
def copy_applehelp_icon(self, resources_dir):
# type: (str) -> None
"""Copy the icon, if one is supplied."""
if self.config.applehelp_icon:
try:
with progress_message(__('copying icon... ')):
applehelp_icon = path.join(self.srcdir, self.config.applehelp_icon)
copy_asset_file(applehelp_icon, resources_dir)
except Exception as err:
logger.warning(__('cannot copy icon file %r: %s'), applehelp_icon, err)
@progress_message(__('building access page'))
def build_access_page(self, language_dir):
# type: (str) -> None
"""Build the access page."""
context = {
'toc': self.config.master_doc + self.out_suffix,
'title': self.config.applehelp_title,
}
copy_asset_file(path.join(template_dir, '_access.html_t'), language_dir, context)
@progress_message(__('generating help index'))
def build_helpindex(self, language_dir):
# type: (str) -> None
"""Generate the help index."""
args = [
self.config.applehelp_indexer_path,
'-Cf',
path.join(language_dir, 'search.helpindex'),
language_dir
]
if self.config.applehelp_index_anchors is not None:
args.append('-a')
if self.config.applehelp_min_term_length is not None:
args += ['-m', '%s' % self.config.applehelp_min_term_length]
if self.config.applehelp_stopwords is not None:
args += ['-s', self.config.applehelp_stopwords]
if self.config.applehelp_locale is not None:
args += ['-l', self.config.applehelp_locale]
if self.config.applehelp_disable_external_tools:
raise SkipProgressMessage(__('you will need to index this help book with:\n %s'),
' '.join([shlex.quote(arg) for arg in args]))
else:
try:
subprocess.run(args, stdout=PIPE, stderr=STDOUT, check=True)
except OSError:
raise AppleHelpIndexerFailed(__('Command not found: %s') % args[0])
except CalledProcessError as exc:
raise AppleHelpIndexerFailed(exc.stdout)
@progress_message(__('signing help book'))
def do_codesign(self):
# type: () -> None
"""If we've been asked to, sign the bundle."""
args = [
self.config.applehelp_codesign_path,
'-s', self.config.applehelp_codesign_identity,
'-f'
]
args += self.config.applehelp_codesign_flags
args.append(self.bundle_path)
if self.config.applehelp_disable_external_tools:
raise SkipProgressMessage(__('you will need to sign this help book with:\n %s'),
' '.join([shlex.quote(arg) for arg in args]))
else:
try:
subprocess.run(args, stdout=PIPE, stderr=STDOUT, check=True)
except OSError:
raise AppleHelpCodeSigningFailed(__('Command not found: %s') % args[0])
except CalledProcessError as exc:
raise AppleHelpCodeSigningFailed(exc.stdout)
deprecated_alias('sphinx.builders.applehelp',
{
'AppleHelpCodeSigningFailed': AppleHelpCodeSigningFailed,
'AppleHelpIndexerFailed': AppleHelpIndexerFailed,
'AppleHelpBuilder': AppleHelpBuilder,
},
RemovedInSphinx40Warning)
def setup(app):
# type: (Sphinx) -> Dict[str, Any]
app.setup_extension('sphinx.builders.html')
app.add_builder(AppleHelpBuilder)
app.add_config_value('applehelp_bundle_name',
lambda self: make_filename(self.project), 'applehelp')
app.add_config_value('applehelp_bundle_id', None, 'applehelp', [str])
app.add_config_value('applehelp_dev_region', 'en-us', 'applehelp')
app.add_config_value('applehelp_bundle_version', '1', 'applehelp')
app.add_config_value('applehelp_icon', None, 'applehelp', [str])
app.add_config_value('applehelp_kb_product',
lambda self: '%s-%s' % (make_filename(self.project), self.release),
'applehelp')
app.add_config_value('applehelp_kb_url', None, 'applehelp', [str])
app.add_config_value('applehelp_remote_url', None, 'applehelp', [str])
app.add_config_value('applehelp_index_anchors', False, 'applehelp', [str])
app.add_config_value('applehelp_min_term_length', None, 'applehelp', [str])
app.add_config_value('applehelp_stopwords',
lambda self: self.language or 'en', 'applehelp')
app.add_config_value('applehelp_locale', lambda self: self.language or 'en', 'applehelp')
app.add_config_value('applehelp_title', lambda self: self.project + ' Help', 'applehelp')
app.add_config_value('applehelp_codesign_identity',
lambda self: environ.get('CODE_SIGN_IDENTITY', None),
'applehelp')
app.add_config_value('applehelp_codesign_flags',
lambda self: shlex.split(environ.get('OTHER_CODE_SIGN_FLAGS', '')),
'applehelp')
app.add_config_value('applehelp_indexer_path', '/usr/bin/hiutil', 'applehelp')
app.add_config_value('applehelp_codesign_path', '/usr/bin/codesign', 'applehelp')
app.add_config_value('applehelp_disable_external_tools', False, None)
warnings.warn('sphinx.builders.applehelp has been moved to sphinxcontrib-applehelp.',
RemovedInSphinx40Warning)
app.setup_extension('sphinxcontrib.applehelp')
return {
'version': 'builtin',

View File

@ -0,0 +1,68 @@
"""
sphinx.builders.dirhtml
~~~~~~~~~~~~~~~~~~~~~~~
Directory HTML builders.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
from os import path
from sphinx.builders.html import StandaloneHTMLBuilder
from sphinx.util import logging
from sphinx.util.osutil import SEP, os_path
if False:
# For type annotation
from typing import Any, Dict, Set # NOQA
from sphinx.application import Sphinx # NOQA
logger = logging.getLogger(__name__)
class DirectoryHTMLBuilder(StandaloneHTMLBuilder):
"""
A StandaloneHTMLBuilder that creates all HTML pages as "index.html" in
a directory given by their pagename, so that generated URLs don't have
``.html`` in them.
"""
name = 'dirhtml'
def get_target_uri(self, docname, typ=None):
# type: (str, str) -> str
if docname == 'index':
return ''
if docname.endswith(SEP + 'index'):
return docname[:-5] # up to sep
return docname + SEP
def get_outfilename(self, pagename):
# type: (str) -> str
if pagename == 'index' or pagename.endswith(SEP + 'index'):
outfilename = path.join(self.outdir, os_path(pagename) +
self.out_suffix)
else:
outfilename = path.join(self.outdir, os_path(pagename),
'index' + self.out_suffix)
return outfilename
def prepare_writing(self, docnames):
# type: (Set[str]) -> None
super().prepare_writing(docnames)
self.globalcontext['no_search_suffix'] = True
def setup(app):
# type: (Sphinx) -> Dict[str, Any]
app.setup_extension('sphinx.builders.html')
app.add_builder(DirectoryHTMLBuilder)
return {
'version': 'builtin',
'parallel_read_safe': True,
'parallel_write_safe': True,
}

View File

@ -1169,39 +1169,6 @@ class StandaloneHTMLBuilder(Builder):
logger.info(__('done'))
class DirectoryHTMLBuilder(StandaloneHTMLBuilder):
"""
A StandaloneHTMLBuilder that creates all HTML pages as "index.html" in
a directory given by their pagename, so that generated URLs don't have
``.html`` in them.
"""
name = 'dirhtml'
def get_target_uri(self, docname, typ=None):
# type: (str, str) -> str
if docname == 'index':
return ''
if docname.endswith(SEP + 'index'):
return docname[:-5] # up to sep
return docname + SEP
def get_outfilename(self, pagename):
# type: (str) -> str
if pagename == 'index' or pagename.endswith(SEP + 'index'):
outfilename = path.join(self.outdir, os_path(pagename) +
self.out_suffix)
else:
outfilename = path.join(self.outdir, os_path(pagename),
'index' + self.out_suffix)
return outfilename
def prepare_writing(self, docnames):
# type: (Set[str]) -> None
super().prepare_writing(docnames)
self.globalcontext['no_search_suffix'] = True
class SerializingHTMLBuilder(StandaloneHTMLBuilder):
"""
An abstract builder that serializes the generated HTML.
@ -1417,10 +1384,12 @@ def validate_math_renderer(app):
# for compatibility
from sphinx.builders.dirhtml import DirectoryHTMLBuilder # NOQA
from sphinx.builders.singlehtml import SingleFileHTMLBuilder # NOQA
deprecated_alias('sphinx.builders.html',
{
'DirectoryHTMLBuilder': DirectoryHTMLBuilder,
'SingleFileHTMLBuilder': SingleFileHTMLBuilder,
},
RemovedInSphinx40Warning)
@ -1430,7 +1399,6 @@ def setup(app):
# type: (Sphinx) -> Dict[str, Any]
# builders
app.add_builder(StandaloneHTMLBuilder)
app.add_builder(DirectoryHTMLBuilder)
app.add_builder(PickleHTMLBuilder)
app.add_builder(JSONHTMLBuilder)

View File

@ -47,9 +47,11 @@ class Highlight(SphinxDirective):
def run(self):
# type: () -> List[nodes.Node]
language = self.arguments[0].strip()
linenothreshold = self.options.get('linenothreshold', sys.maxsize)
return [addnodes.highlightlang(lang=self.arguments[0].strip(),
linenothreshold=linenothreshold)]
self.env.temp_data['highlight_language'] = language
return [addnodes.highlightlang(lang=language, linenothreshold=linenothreshold)]
class HighlightLang(Highlight):
@ -110,8 +112,8 @@ class CodeBlock(SphinxDirective):
"""
has_content = True
required_arguments = 1
optional_arguments = 0
required_arguments = 0
optional_arguments = 1
final_argument_whitespace = False
option_spec = {
'linenos': directives.flag,
@ -152,10 +154,20 @@ class CodeBlock(SphinxDirective):
code = '\n'.join(lines)
literal = nodes.literal_block(code, code) # type: nodes.Element
literal['language'] = self.arguments[0]
literal['linenos'] = 'linenos' in self.options or \
'lineno-start' in self.options
literal['classes'] += self.options.get('class', [])
if self.arguments:
# highlight language specified
literal['language'] = self.arguments[0]
literal['force_highlighting'] = True
else:
# no highlight language specified. Then this directive refers the current
# highlight setting via ``highlight`` directive or ``highlight_language``
# configuration.
literal['language'] = self.env.temp_data.get('highlight_language',
self.config.highlight_language)
literal['force_highlighting'] = False
extra_args = literal['highlight_args'] = {}
if hl_lines is not None:
extra_args['hl_lines'] = hl_lines

View File

@ -266,7 +266,9 @@ def get_translation(catalog, namespace='general'):
With this code, sphinx searches a message catalog from
``${package_dir}/locales/${language}/LC_MESSAGES/${__name__}.mo``
The :confval:`language` is used for the searching.
(ex. ``sphinxcontrib.applehelp.mo``). Of course, you can use
arbitrary catalog name instead of ``__name__``. The
:confval:`language` is used for the searching.
.. versionadded:: 1.8
"""

View File

@ -1,12 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>{{ title|e }}</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="robots" content="noindex" />
<meta http-equiv="refresh" content="0;url={{ toc|e }}" />
</head>
<body>
</body>
</html>

View File

@ -707,53 +707,79 @@
%% GRAPHICS
%
% \sphinxincludegraphics defined to resize images larger than the line width,
% except if height or width option present.
% \sphinxincludegraphics resizes images larger than the TeX \linewidth (which
% is adjusted in indented environments), or taller than a certain maximal
% height (usually \textheight and this is reduced in the environments which use
% framed.sty to avoid infinite loop if image too tall).
%
% If scale is present, rescale before fitting to line width. (since 1.5)
\newbox\spx@image@box
\newcommand*{\sphinxincludegraphics}[2][]{%
\in@{height}{#1}\ifin@\else\in@{width}{#1}\fi
\ifin@ % height or width present
\includegraphics[#1]{#2}%
\else % no height nor width (but #1 may be "scale=...")
% In case height or width options are present the rescaling is done
% (since 2.0), in a way keeping the width:height ratio either native from
% image or from the width and height options if both were present.
%
\newdimen\spx@image@maxheight
\AtBeginDocument{\spx@image@maxheight\textheight}
% box scratch register
\newdimen\spx@image@box
\newcommand*{\sphinxsafeincludegraphics}[2][]{%
% #1 contains possibly width=, height=, but no scale= since 1.8.4
\setbox\spx@image@box\hbox{\includegraphics[#1,draft]{#2}}%
\in@false % use some handy boolean flag
\ifdim \wd\spx@image@box>\linewidth
\setbox\spx@image@box\box\voidb@x % clear memory
\includegraphics[#1,width=\linewidth]{#2}%
\in@true % flag to remember to adjust options and set box dimensions
% compute height which results from rescaling width to \linewidth
% and keep current aspect ratio. multiply-divide in \numexpr uses
% temporarily doubled precision, hence no overflow. (of course we
% assume \ht is not a few sp's below \maxdimen...(about 16384pt).
\edef\spx@image@rescaledheight % with sp units
{\the\numexpr\ht\spx@image@box
*\linewidth/\wd\spx@image@box sp}%
\ifdim\spx@image@rescaledheight>\spx@image@maxheight
% the rescaled height will be too big, so it is height which decides
% the rescaling factor
\def\spx@image@requiredheight{\spx@image@maxheight}% dimen register
\edef\spx@image@requiredwidth % with sp units
{\the\numexpr\wd\spx@image@box
*\spx@image@maxheight/\ht\spx@image@box sp}%
% TODO: decide if this commented-out block could be needed due to
% rounding in numexpr operations going up
% \ifdim\spx@image@requiredwidth>\linewidth
% \def\spx@image@requiredwidth{\linewidth}% dimen register
% \fi
\else
\def\spx@image@requiredwidth{\linewidth}% dimen register
\let\spx@image@requiredheight\spx@image@rescaledheight% sp units
\fi
\else
% width is ok, let's check height
\ifdim\ht\spx@image@box>\spx@image@maxheight
\in@true
\edef\spx@image@requiredwidth % with sp units
{\the\numexpr\wd\spx@image@box
*\spx@image@maxheight/\ht\spx@image@box sp}%
\def\spx@image@requiredheight{\spx@image@maxheight}% dimen register
\fi
\fi % end of check of width and height
\ifin@
\setbox\spx@image@box
\hbox{\includegraphics
[%#1,% contained only width and/or height and overruled anyhow
width=\spx@image@requiredwidth,height=\spx@image@requiredheight]%
{#2}}%
% \includegraphics does not set box dimensions to the exactly
% requested ones, see https://github.com/latex3/latex2e/issues/112
\wd\spx@image@box\spx@image@requiredwidth
\ht\spx@image@box\spx@image@requiredheight
\leavevmode\box\spx@image@box
\else
% here we do not modify the options, no need to adjust width and height
% on output, they will be computed exactly as with "draft" option
\setbox\spx@image@box\box\voidb@x % clear memory
\includegraphics[#1]{#2}%
\fi
\fi
}
% \sphinxsafeincludegraphics resizes images larger than the line width,
% or taller than about the text height (whether or not height/width options
% were used). This is requested to avoid a crash with \MakeFramed as used by
% sphinxShadowBox (topic/contents) and sphinxheavybox (admonitions), and also
% by sphinxVerbatim (but a priori no image inclusion there).
\newdimen\spx@image@maxheight
% default maximal setting will get reduced by sphinxShadowBox/sphinxheavybox
\AtBeginDocument{\spx@image@maxheight\textheight}
\newcommand*{\sphinxsafeincludegraphics}[2][]{%
\gdef\spx@includegraphics@options{#1}%
\setbox\spx@image@box\hbox{\includegraphics[#1,draft]{#2}}%
\in@false
\ifdim \wd\spx@image@box>\linewidth
\g@addto@macro\spx@includegraphics@options{,width=\linewidth}%
\in@true
\fi
% no rotation, no need to worry about depth
\ifdim \ht\spx@image@box>\spx@image@maxheight
\g@addto@macro\spx@includegraphics@options{,height=\spx@image@maxheight}%
\in@true
\fi
\ifin@
\g@addto@macro\spx@includegraphics@options{,keepaspectratio}%
\fi
\setbox\spx@image@box\box\voidb@x % clear memory
\expandafter\includegraphics\expandafter[\spx@includegraphics@options]{#2}%
}%
% Use the "safe" one by default (2.0)
\def\sphinxincludegraphics{\sphinxsafeincludegraphics}
%% FIGURE IN TABLE
@ -1374,7 +1400,6 @@
+2\sphinxshadowsep
+\sphinxshadowsize
+\baselineskip\relax
\let\sphinxincludegraphics\sphinxsafeincludegraphics
% configure framed.sty not to add extra vertical spacing
\ltx@ifundefined{OuterFrameSep}{}{\OuterFrameSep\z@skip}%
% the \trivlist will add the vertical spacing on top and bottom which is
@ -1461,7 +1486,6 @@
-\dimexpr2\FrameRule
+2\FrameSep
+\baselineskip\relax % will happen again if nested, needed indeed!
\let\sphinxincludegraphics\sphinxsafeincludegraphics
% configure framed.sty's parameters to obtain same vertical spacing
% as for "light" boxes. We need for this to manually insert parskip glue and
% revert a skip done by framed before the frame.

View File

@ -46,7 +46,7 @@
{\Large
\begin{tabular}[t]{c}
\@author
\end{tabular}}\par
\end{tabular}\kern-\tabcolsep}\par
\vspace{25pt}
\@date \par
\py@authoraddress \par

View File

@ -55,7 +55,7 @@
{\LARGE
\begin{tabular}[t]{c}
\@author
\end{tabular}
\end{tabular}\kern-\tabcolsep
\par}
\vfill\vfill
{\large

View File

@ -130,7 +130,7 @@ var Search = {
this.out = $('#search-results');
this.title = $('<h2>' + _('Searching') + '</h2>').appendTo(this.out);
this.dots = $('<span></span>').appendTo(this.title);
this.status = $('<p style="display: none"></p>').appendTo(this.out);
this.status = $('<p class="search-summary">&nbsp;</p>').appendTo(this.out);
this.output = $('<ul class="search"/>').appendTo(this.out);
$('#search-progress').text(_('Preparing search...'));

View File

@ -89,7 +89,7 @@ class HighlightLanguageVisitor(nodes.NodeVisitor):
if 'language' not in node:
node['language'] = setting.language
node['force_highlighting'] = False
else:
elif 'force_highlighting' not in node:
node['force_highlighting'] = True
if 'linenos' not in node:
lines = node.astext().count('\n')

View File

@ -7,6 +7,7 @@
"""
import os
import shutil
import docutils
import pytest
@ -23,13 +24,32 @@ collect_ignore = ['roots']
@pytest.fixture(scope='session')
def rootdir():
return path(os.path.dirname(__file__)).abspath() / 'roots'
return path(__file__).parent.abspath() / 'roots'
def pytest_report_header(config):
return ("libraries: Sphinx-%s, docutils-%s" %
(sphinx.__display_version__, docutils.__version__))
header = ("libraries: Sphinx-%s, docutils-%s" %
(sphinx.__display_version__, docutils.__version__))
if hasattr(config, '_tmp_path_factory'):
header += "\nbase tempdir: %s" % config._tmp_path_factory.getbasetemp()
return header
def pytest_assertrepr_compare(op, left, right):
comparer.pytest_assertrepr_compare(op, left, right)
def _initialize_test_directory(session):
if 'SPHINX_TEST_TEMPDIR' in os.environ:
tempdir = os.path.abspath(os.getenv('SPHINX_TEST_TEMPDIR'))
print('Temporary files will be placed in %s.' % tempdir)
if os.path.exists(tempdir):
shutil.rmtree(tempdir)
os.makedirs(tempdir)
def pytest_sessionstart(session):
_initialize_test_directory(session)

View File

@ -0,0 +1,20 @@
highlight
---------
.. code-block::
"A code-block without no language"
.. code-block:: python2
"A code-block with language argument"
.. highlight:: python3
.. code-block::
"A code-block without no language after highlight directive"
.. code-block:: python2
"A code-block without language argument after highlight directive"

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" height="60" width="60">
<circle cx="40" cy="40" r="24" style="stroke:#000000; fill:#ffffff"/>
</svg>

Before

Width:  |  Height:  |  Size: 220 B

After

Width:  |  Height:  |  Size: 243 B

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" height="60" width="60">
<circle cx="40" cy="40" r="24" style="stroke:#000000; fill:#ffffff"/>
</svg>

Before

Width:  |  Height:  |  Size: 220 B

After

Width:  |  Height:  |  Size: 243 B

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" height="60" width="60">
<circle cx="40" cy="40" r="24" style="stroke:#000000; fill:#ffffff"/>
</svg>

Before

Width:  |  Height:  |  Size: 220 B

After

Width:  |  Height:  |  Size: 243 B

View File

@ -0,0 +1,49 @@
master_doc = 'index'
exclude_patterns = ['_build']
latex_elements = {
'preamble': r'''
\makeatletter
\def\dividetwolengths#1#2{\the\dimexpr
\numexpr65536*\dimexpr#1\relax/\dimexpr#2\relax sp}%
\newwrite\out
\immediate\openout\out=\jobname-dimensions.txt
\def\toout{\immediate\write\out}
\def\getWfromoptions #1width=#2,#3\relax{\def\WidthFromOption{#2}}%
\def\getHfromoptions #1height=#2,#3\relax{\def\HeightFromOption{#2}}%
\def\tempincludegraphics[#1]#2{%
\sphinxsafeincludegraphics[#1]{#2}%
\edef\obtainedratio
{\dividetwolengths\spx@image@requiredheight\spx@image@requiredwidth}%
\getWfromoptions#1,width=,\relax
\getHfromoptions#1,height=,\relax
\def\ratiocheck{}%
\ifx\WidthFromOption\empty\else
\ifx\HeightFromOption\empty\else
\edef\askedforratio{\dividetwolengths\HeightFromOption\WidthFromOption}%
\edef\ratiocheck{\dividetwolengths\obtainedratio\askedforratio}%
\fi\fi
\toout{original options = #1^^J%
width = \the\dimexpr\spx@image@requiredwidth,
linewidth = \the\linewidth^^J%
height = \the\dimexpr\spx@image@requiredheight,
maxheight = \the\spx@image@maxheight^^J%
obtained H/W = \obtainedratio^^J%
\ifx\ratiocheck\empty
\else
asked for H/W = \askedforratio^^J%
ratio of ratios = \ratiocheck^^J%
\fi
}%
\ifx\ratiocheck\empty
\else
\ifpdfabsdim\dimexpr\ratiocheck-1pt\relax > 0.01pt
\ASPECTRATIOERROR
\fi
\fi
}
\def\sphinxincludegraphics#1#{\tempincludegraphics#1}
\makeatother
''',
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

View File

@ -0,0 +1,37 @@
====================
Test image inclusion
====================
Tests with both width and height
--------------------------------
.. an image with big dimensions, ratio H/W = 1/5
.. image:: img.png
:height: 200
:width: 1000
.. topic:: Oversized images
.. an image with big dimensions, ratio H/W = 5/1
.. image:: img.png
:height: 1000
:width: 200
.. height too big even if width reduced to linewidth, ratio H/W = 3/1
.. image:: img.png
:width: 1000
:height: 3000
Tests with only width or height
-------------------------------
.. topic:: Oversized images
.. tall image which does not fit in textheight even if width rescaled
.. image:: tall.png
:width: 1000
.. wide image which does not fit in linewidth even after height diminished
.. image:: sphinx.png
:height: 1000

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

View File

@ -40,9 +40,6 @@ html_sidebars = {'**': ['localtoc.html', 'relations.html', 'sourcelink.html',
html_last_updated_fmt = '%b %d, %Y'
html_context = {'hckey': 'hcval', 'hckey_co': 'wrong_hcval_co'}
applehelp_bundle_id = 'org.sphinx-doc.Sphinx.help'
applehelp_disable_external_tools = True
latex_additional_files = ['svgimg.svg']
coverage_c_path = ['special/*.h']

View File

@ -1,2 +0,0 @@
This file should be included in the final bundle by the applehelp builder.
It should be ignored by other builders.

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" height="60" width="60">
<circle cx="40" cy="40" r="24" style="stroke:#000000; fill:#ffffff"/>
</svg>

Before

Width:  |  Height:  |  Size: 220 B

After

Width:  |  Height:  |  Size: 243 B

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" height="60" width="60">
<circle cx="40" cy="40" r="24" style="stroke:#000000; fill:#ffffff"/>
</svg>

Before

Width:  |  Height:  |  Size: 220 B

After

Width:  |  Height:  |  Size: 243 B

View File

@ -61,7 +61,7 @@ def nonascii_srcdir(request, rootdir, sphinx_test_tempdir):
[
# note: no 'html' - if it's ok with dirhtml it's ok with html
'dirhtml', 'singlehtml', 'pickle', 'json', 'text', 'htmlhelp',
'applehelp', 'changes', 'xml', 'pseudoxml', 'linkcheck',
'changes', 'xml', 'pseudoxml', 'linkcheck',
],
)
@mock.patch('sphinx.builders.linkcheck.requests.head',

View File

@ -1,54 +0,0 @@
"""
test_build_applehelp
~~~~~~~~~~~~~~~~~~~~
Test the Apple Help builder and check its output. We don't need to
test the HTML itself; that's already handled by
:file:`test_build_html.py`.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
import plistlib
import pytest
from sphinx.testing.path import path
def check_structure(outdir):
contentsdir = outdir / 'Contents'
assert contentsdir.isdir()
assert (contentsdir / 'Info.plist').isfile()
with open(contentsdir / 'Info.plist', 'rb') as f:
plist = plistlib.load(f)
assert plist
assert len(plist)
assert plist.get('CFBundleIdentifier', None) == 'org.sphinx-doc.Sphinx.help'
assert (contentsdir / 'Resources').isdir()
assert (contentsdir / 'Resources' / 'en.lproj').isdir()
def check_localization(outdir):
lprojdir = outdir / 'Contents' / 'Resources' / 'en.lproj'
assert (lprojdir / 'localized.txt').isfile()
@pytest.mark.sphinx(
'applehelp', testroot='basic', srcdir='applehelp_output',
confoverrides={'applehelp_bundle_id': 'org.sphinx-doc.Sphinx.help',
'applehelp_disable_external_tools': True})
def test_applehelp_output(app, status, warning):
(app.srcdir / 'en.lproj').makedirs()
(app.srcdir / 'en.lproj' / 'localized.txt').write_text('')
app.builder.build_all()
# Have to use bundle_path, not outdir, because we alter the latter
# to point to the lproj directory so that the HTML arrives in the
# correct location.
bundle_path = path(app.builder.bundle_path)
check_structure(bundle_path)
check_localization(bundle_path)

View File

@ -10,20 +10,16 @@
import os
import re
import xml.etree.cElementTree as ElementTree
from itertools import cycle, chain
import pytest
from html5lib import getTreeBuilder, HTMLParser
from html5lib import HTMLParser
from sphinx.errors import ConfigError
from sphinx.testing.util import strip_escseq
from sphinx.util.inventory import InventoryFile
TREE_BUILDER = getTreeBuilder('etree', implementation=ElementTree)
HTML_PARSER = HTMLParser(TREE_BUILDER, namespaceHTMLElements=False)
ENV_WARNINGS = """\
%(root)s/autodoc_fodder.py:docstring of autodoc_fodder.MarkupError:\\d+: \
WARNING: Explicit markup ends without a blank line; unexpected unindent.
@ -53,7 +49,7 @@ def cached_etree_parse():
if fname in etree_cache:
return etree_cache[fname]
with (fname).open('rb') as fp:
etree = HTML_PARSER.parse(fp)
etree = HTMLParser(namespaceHTMLElements=False).parse(fp)
etree_cache.clear()
etree_cache[fname] = etree
return etree

View File

@ -14,18 +14,14 @@
"""
import re
import xml.etree.cElementTree as ElementTree
from hashlib import md5
import pytest
from html5lib import getTreeBuilder, HTMLParser
from html5lib import HTMLParser
from test_build_html import flat_dict, tail_check, check_xpath
from sphinx.util.docutils import is_html5_writer_available
TREE_BUILDER = getTreeBuilder('etree', implementation=ElementTree)
HTML_PARSER = HTMLParser(TREE_BUILDER, namespaceHTMLElements=False)
etree_cache = {}
@ -37,7 +33,7 @@ def cached_etree_parse():
if fname in etree_cache:
return etree_cache[fname]
with (fname).open('rb') as fp:
etree = HTML_PARSER.parse(fp)
etree = HTMLParser(namespaceHTMLElements=False).parse(fp)
etree_cache.clear()
etree_cache[fname] = etree
return etree

View File

@ -1387,3 +1387,13 @@ def test_default_latex_documents():
expected = [('index', 'stasi.tex', 'STASI™ Documentation',
r"Wolfgang Schäuble \& G'Beckstein.\@{}", 'manual')]
assert default_latex_documents(config) == expected
@skip_if_requested
@skip_if_stylefiles_notfound
@pytest.mark.sphinx('latex', testroot='latex-includegraphics')
def test_includegraphics_oversized(app, status, warning):
app.builder.build_all()
print(status.getvalue())
print(warning.getvalue())
compile_latex_document(app)

View File

@ -11,6 +11,7 @@
import os
import pytest
from docutils import nodes
from sphinx.config import Config
from sphinx.directives.code import LiteralIncludeReader
@ -552,3 +553,15 @@ def test_literalinclude_pydecorators(app, status, warning):
' pass\n'
)
assert actual == expect
@pytest.mark.sphinx('dummy', testroot='directive-code')
def test_code_block_highlighted(app, status, warning):
app.builder.build(['highlight'])
doctree = app.env.get_doctree('highlight')
codeblocks = doctree.traverse(nodes.literal_block)
assert codeblocks[0]['language'] == 'default'
assert codeblocks[1]['language'] == 'python2'
assert codeblocks[2]['language'] == 'python3'
assert codeblocks[3]['language'] == 'python2'