Merge branch 'master' into add_sphinx_factory

This commit is contained in:
Takeshi KOMIYA committed 2017-04-23 17:06:20 +09:00
commit 3a0f7d3bad
21 files changed
+579 -33

No files matched your search

+2 -1
View File
@@ -43,6 +43,7 @@ addons:
- texlive-xetex
- lmodern
- latex-xcolor
- imagemagick
install:
- pip install -U pip setuptools
- pip install docutils==$DOCUTILS
@@ -51,4 +52,4 @@ install:
script:
- flake8
- if [[ $TRAVIS_PYTHON_VERSION == '3.6' ]]; then make style-check type-check test-async; fi
- if [[ $TRAVIS_PYTHON_VERSION != '3.6' ]]; then make test; fi
- if [[ $TRAVIS_PYTHON_VERSION != '3.6' ]]; then SKIP_LATEX_BUILD=1 make test; fi
+1 -1
View File
@@ -12,6 +12,7 @@ Other co-maintainers:
* Robert Lehmann <@lehmannro>
* Roland Meister <@rolmei>
* Takeshi Komiya <@tk0miya>
* Jean-François Burnol <@jfbu>
* Yoshiki Shibukawa <@shibu_jp>
Other contributors, listed alphabetically, are:
@@ -21,7 +22,6 @@ Other contributors, listed alphabetically, are:
* Jakob Lykke Andersen -- Rewritten C++ domain
* Henrique Bastos -- SVG support for graphviz extension
* Daniel Bültmann -- todo extension
* Jean-François Burnol -- LaTeX improvements
* Marco Buttu -- doctest extension (pyversion option)
* Etienne Desautels -- apidoc module
* Michael Droettboom -- inheritance_diagram extension
+6
View File
@@ -118,6 +118,8 @@ Features added
* #3641: Epub theme supports HTML structures that are generated by HTML5 writer.
* #3644 autodoc uses inspect instead of checking types. Thanks to
Jeroen Demeyer.
* Add a new extension; ``sphinx.ext.imgconverter``. It converts images in the
document to appropriate format for builders
Bugs fixed
----------
@@ -132,6 +134,8 @@ Bugs fixed
* C++, properly look up ``any`` references.
* #3624: sphinx.ext.intersphinx couldn't load inventories compressed with gzip
* #3551: PDF information dictionary is lacking author and title data
* #3351: intersphinx does not refers context like ``py:module``, ``py:class``
and so on.
* Fail to load template file if the parent template is archived
Deprecated
@@ -165,6 +169,8 @@ Deprecated
removed at 1.7, and already its default value has changed from ``True`` to
``False``.
* #3221: epub2 builder is deprecated
* #3628: ``sphinx_themes`` entry_point is deprecated. Please use
``sphinx.html_themes`` instead.
Release 1.5.6 (in development)
==============================
+1
View File
@@ -15,6 +15,7 @@ These extensions are built in and can be activated by respective entries in the
githubpages
graphviz
ifconfig
imgconverter
inheritance
intersphinx
linkcode
+30
View File
@@ -0,0 +1,30 @@
.. highlight:: rest
:mod:`sphinx.ext.imgconverter` -- Convert images to appropriate format for builders
===================================================================================
.. module:: sphinx.ext.imgconverter
:synopsis: Convert images to appropriate format for builders
.. versionadded:: 1.6
This extension converts images in your document to appropriate format for builders.
For example, it allows you to use SVG images with LaTeX builder.
As a result, you don't mind what image format the builder supports.
Internally, this extension uses Imagemagick_ to convert images.
.. _Imagemagick: https://www.imagemagick.org/script/index.php
Configuration
-------------
.. confval:: image_converter
A path to :command:`convert` command. By default, the imgconverter uses
the command from search paths.
.. confval:: image_converter_args
Additional command-line arguments to give to :command:`convert`, as a list.
The default is an empty list ``[]``.
+7
View File
@@ -370,6 +370,13 @@ package.
.. versionadded:: 1.4
.. method:: Sphinx.add_html_theme(name, theme_path)
Register a HTML Theme. The *name* is a name of theme, and *path* is a
full path to the theme (refs: :ref:`distribute-your-theme`).
.. versionadded:: 1.6
.. method:: Sphinx.add_env_collector(collector)
Register an environment collector class (refs: :ref:`collector-api`)
+48 -26
View File
@@ -46,34 +46,14 @@ file :file:`blue.zip`, you can put it right in the directory containing
html_theme = "blue"
html_theme_path = ["."]
The third form provides your theme path dynamically to Sphinx if the
``setuptools`` package is installed. You can provide an entry point section
called ``sphinx_themes`` in your setup.py file and write a ``get_path`` function
that has to return the directory with themes in it::
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::
# 'setup.py'
# installing theme package
$ pip install sphinxjp.themes.dotted
setup(
...
entry_points = {
'sphinx_themes': [
'path = your_package:get_path',
]
},
...
)
# 'your_package.py'
from os import path
package_dir = path.abspath(path.dirname(__file__))
template_path = path.join(package_dir, 'themes')
def get_path():
return template_path
.. versionadded:: 1.2
'sphinx_themes' entry_points feature.
# use it in your conf.py
html_theme = "dotted"
.. _builtin-themes:
@@ -310,6 +290,48 @@ Python :mod:`ConfigParser` module) and has the following structure:
and are accessible from all templates as ``theme_<name>``.
.. _distribute-your-theme:
Distribute your theme as a python package
-----------------------------------------
As a way to distribute your theme, you can use python package. Python package
brings to users easy setting up ways.
To distribute your theme as a python package, please define an entry point
called ``sphinx.html_themes`` in your setup.py file, and write a ``setup()``
function to register your themes using ``add_html_theme()`` API in it::
# 'setup.py'
setup(
...
entry_points = {
'sphinx.html_themes': [
'name_of_theme = your_package',
]
},
...
)
# 'your_package.py'
from os import path
def setup(app):
app.add_html_theme('name_of_theme', path.abspath(path.dirname(__file__)))
If your theme package contains two or more themes, please call ``add_html_theme()``
twice or more.
.. versionadded:: 1.2
'sphinx_themes' entry_points feature.
.. deprecated:: 1.6
``sphinx_themes`` entry_points has been deprecated.
.. versionadded:: 1.6
``sphinx.html_themes`` entry_points feature.
Templating
~~~~~~~~~~
+5
View File
@@ -743,6 +743,11 @@ class Sphinx(object):
logger.debug('[app] adding environment collector: %r', collector)
collector().enable(self)
def add_html_theme(self, name, theme_path):
# type: (unicode, unicode) -> None
logger.debug('[app] adding HTML theme: %r, %r', name, theme_path)
self.html_themes[name] = theme_path
class TemplateBridge(object):
"""
+5
View File
@@ -308,3 +308,8 @@ class Domain(object):
if primary:
return type.lname
return _('%s %s') % (self.label, type.lname)
def get_full_qualified_name(self, node):
# type: (nodes.Node) -> unicode
"""Return full qualified name for given node."""
return None
+10
View File
@@ -885,6 +885,16 @@ class PythonDomain(Domain):
if type != 'module': # modules are already handled
yield (refname, refname, type, docname, refname, 1)
def get_full_qualified_name(self, node):
# type: (nodes.Node) -> unicode
modname = node.get('py:module')
clsname = node.get('py:class')
target = node.get('reftarget')
if target is None:
return None
else:
return '.'.join(filter(None, [modname, clsname, target]))
def setup(app):
# type: (Sphinx) -> Dict[unicode, Any]
+93
View File
@@ -0,0 +1,93 @@
# -*- coding: utf-8 -*-
"""
sphinx.ext.imgconverter
~~~~~~~~~~~~~~~~~~~~~~~
Image converter extension for Sphinx
:copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
import subprocess
from sphinx.errors import ExtensionError
from sphinx.locale import _
from sphinx.transforms.post_transforms.images import ImageConverter
from sphinx.util import logging
from sphinx.util.osutil import ENOENT, EPIPE, EINVAL
if False:
# For type annotation
from typing import Any, Dict # NOQA
from sphinx.application import Sphinx # NOQA
logger = logging.getLogger(__name__)
class ImagemagickConverter(ImageConverter):
conversion_rules = [
('image/svg+xml', 'image/png'),
('application/pdf', 'image/png'),
]
def is_available(self):
# type: () -> bool
"""Confirms the converter is available or not."""
try:
args = [self.config.image_converter, '-version']
logger.debug('Invoking %r ...', args)
ret = subprocess.call(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
if ret == 0:
return True
else:
return False
except (OSError, IOError):
logger.warning(_('convert command %r cannot be run.'
'check the image_converter setting'),
self.config.image_converter)
return False
def convert(self, _from, _to):
# type: (unicode, unicode) -> bool
"""Converts the image to expected one."""
try:
args = ([self.config.image_converter] +
self.config.image_converter_args +
[_from, _to])
logger.debug('Invoking %r ...', args)
p = subprocess.Popen(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
except OSError as err:
if err.errno != ENOENT: # No such file or directory
raise
logger.warning(_('convert command %r cannot be run.'
'check the image_converter setting'),
self.config.image_converter)
return False
try:
stdout, stderr = p.communicate()
except (OSError, IOError) as err:
if err.errno not in (EPIPE, EINVAL):
raise
stdout, stderr = p.stdout.read(), p.stderr.read()
p.wait()
if p.returncode != 0:
raise ExtensionError(_('convert exited with error:\n'
'[stderr]\n%s\n[stdout]\n%s') %
(stderr, stdout))
return True
def setup(app):
# type: (Sphinx) -> Dict[unicode, Any]
app.add_post_transform(ImagemagickConverter)
app.add_config_value('image_converter', 'convert', 'env')
app.add_config_value('image_converter_args', [], 'env')
return {
'version': 'builtin',
'parallel_read_safe': True,
'parallel_write_safe': True,
}
+8
View File
@@ -292,6 +292,10 @@ def missing_reference(app, env, node, contnode):
# until Sphinx-1.6, cmdoptions are stored as std:option
objtypes.append('std:option')
to_try = [(inventories.main_inventory, target)]
if domain:
full_qualified_name = env.get_domain(domain).get_full_qualified_name(node)
if full_qualified_name:
to_try.append((inventories.main_inventory, full_qualified_name))
in_set = None
if ':' in target:
# first part may be the foreign doc set name
@@ -299,6 +303,10 @@ def missing_reference(app, env, node, contnode):
if setname in inventories.named_inventory:
in_set = setname
to_try.append((inventories.named_inventory[setname], newtarget))
if domain:
full_qualified_name = env.get_domain(domain).get_full_qualified_name(node)
if full_qualified_name:
to_try.append((inventories.named_inventory[setname], full_qualified_name))
for inventory, target in to_try:
for objtype in objtypes:
if objtype not in inventory or target not in inventory[objtype]:
+20 -2
View File
@@ -12,6 +12,7 @@
import os
import shutil
import tempfile
import warnings
from os import path
from zipfile import ZipFile
@@ -20,7 +21,9 @@ from six import string_types, iteritems
from six.moves import configparser
from sphinx import package_dir
from sphinx.deprecation import RemovedInSphinx20Warning
from sphinx.errors import ThemeError
from sphinx.extension import load_extension
from sphinx.locale import _
from sphinx.util import logging
from sphinx.util.osutil import ensuredir
@@ -77,6 +80,8 @@ class Theme(object):
try:
inherit = self.config.get('theme', 'inherit')
except configparser.NoSectionError:
raise ThemeError(_('theme %r doesn\'t have "theme" setting') % name)
except configparser.NoOptionError:
raise ThemeError(_('theme %r doesn\'t have "inherit" setting') % name)
@@ -161,7 +166,7 @@ class HTMLThemeFactory(object):
def __init__(self, app):
# type: (Sphinx) -> None
self.confdir = app.confdir
self.app = app
self.themes = app.html_themes
self.load_builtin_themes()
if getattr(app.config, 'html_theme_path', None):
@@ -178,7 +183,7 @@ class HTMLThemeFactory(object):
# type: (unicode) -> None
"""Load additional themes placed at specified directories."""
for theme_path in theme_paths:
abs_theme_path = path.abspath(path.join(self.confdir, theme_path))
abs_theme_path = path.abspath(path.join(self.app.confdir, theme_path))
themes = self.find_themes(abs_theme_path)
for name, theme in iteritems(themes):
self.themes[name] = theme
@@ -215,6 +220,16 @@ class HTMLThemeFactory(object):
Sphinx refers to ``sphinx_themes`` entry_points.
"""
# look up for new styled entry_points at first
entry_points = pkg_resources.iter_entry_points('sphinx.html_themes', name)
try:
entry_point = next(entry_points)
load_extension(self.app, entry_point.module_name)
return
except StopIteration:
pass
# look up for old styled entry_points
for entry_point in pkg_resources.iter_entry_points('sphinx_themes'):
target = entry_point.load()
if callable(target):
@@ -228,6 +243,9 @@ class HTMLThemeFactory(object):
themes = self.find_themes(themedir)
for entry, theme in iteritems(themes):
if name == entry:
warnings.warn('``sphinx_themes`` entry point is now deprecated. '
'Please use ``sphinx.html_themes`` instead.',
RemovedInSphinx20Warning)
self.themes[name] = theme
def find_themes(self, theme_path):
+102 -1
View File
@@ -24,7 +24,7 @@ from sphinx.util.osutil import ensuredir
if False:
# For type annotation
from typing import Any, Dict # NOQA
from typing import Any, Dict, List, Tuple # NOQA
from sphinx.application import Sphinx # NOQA
@@ -136,6 +136,107 @@ class DataURIExtractor(BaseImageConverter):
self.app.env.images.add_file(self.env.docname, path)
def get_filename_for(filename, mimetype):
# type: (unicode, unicode) -> unicode
basename = os.path.basename(filename)
return os.path.splitext(basename)[0] + get_image_extension(mimetype)
class ImageConverter(BaseImageConverter):
"""A base class images converter.
The concrete image converters should derive this class and
overrides the following methods and attributes:
* default_priority (if needed)
* conversion_rules
* is_available()
* convert()
"""
default_priority = 200
#: A conversion rules between two mimetypes which this converters supports
conversion_rules = [] # type: List[Tuple[unicode, unicode]]
def __init__(self, *args, **kwargs):
# type: (Any, Any) -> None
self.available = None # type: bool
# the converter is available or not.
# Will be checked at first conversion
BaseImageConverter.__init__(self, *args, **kwargs) # type: ignore
def match(self, node):
# type: (nodes.Node) -> bool
if self.available is None:
self.available = self.is_available()
if not self.available:
return False
elif set(node['candidates']) & set(self.app.builder.supported_image_types):
# builder supports the image; no need to convert
return False
else:
rule = self.get_conversion_rule(node)
if rule:
return True
else:
return False
def get_conversion_rule(self, node):
# type: (nodes.Node) -> Tuple[unicode, unicode]
for candidate in self.guess_mimetypes(node):
for supported in self.app.builder.supported_image_types:
rule = (candidate, supported)
if rule in self.conversion_rules:
return rule
return None
def is_available(self):
# type: () -> bool
"""Confirms the converter is available or not."""
raise NotImplemented
def guess_mimetypes(self, node):
# type: (nodes.Node) -> List[unicode]
if '?' in node['candidates']:
return []
elif '*' in node['candidates']:
from sphinx.util.images import guess_mimetype
return [guess_mimetype(node['uri'])]
else:
return node['candidates'].keys()
def handle(self, node):
# type: (nodes.Node) -> None
_from, _to = self.get_conversion_rule(node)
if _from in node['candidates']:
srcpath = node['candidates'][_from]
else:
srcpath = node['candidates']['*']
filename = get_filename_for(srcpath, _to)
ensuredir(self.imagedir)
destpath = os.path.join(self.imagedir, filename)
abs_srcpath = os.path.join(self.app.srcdir, srcpath)
if self.convert(abs_srcpath, destpath):
if '*' in node['candidates']:
node['candidates']['*'] = destpath
else:
node['candidates'][_to] = destpath
node['uri'] = destpath
self.env.original_image_uri[destpath] = srcpath
self.env.images.add_file(self.env.docname, destpath)
def convert(self, _from, _to):
# type: (unicode, unicode) -> bool
"""Converts the image to expected one."""
raise NotImplemented
def setup(app):
# type: (Sphinx) -> Dict[unicode, Any]
app.add_post_transform(ImageDownloader)
@@ -0,0 +1,4 @@
# -*- coding: utf-8 -*-
master_doc = 'index'
extensions = ['sphinx.ext.imgconverter']
@@ -0,0 +1,4 @@
test-ext-imgconverter
=====================
.. image:: svgimg.svg
@@ -0,0 +1,158 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://web.resource.org/cc/"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://inkscape.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
height="60"
width="60"
_SVGFile__filename="oldscale/apps/warning.svg"
version="1.0"
y="0"
x="0"
id="svg1"
sodipodi:version="0.32"
inkscape:version="0.41"
sodipodi:docname="exclamation.svg"
sodipodi:docbase="/home/danny/work/icons/primary/scalable/actions">
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0000000"
inkscape:pageshadow="2"
inkscape:zoom="7.5136000"
inkscape:cx="42.825186"
inkscape:cy="24.316071"
inkscape:window-width="1020"
inkscape:window-height="691"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:current-layer="svg1" />
<defs
id="defs3">
<linearGradient
id="linearGradient1160">
<stop
style="stop-color: #000000;stop-opacity: 1.0;"
id="stop1161"
offset="0" />
<stop
style="stop-color:#ffffff;stop-opacity:1;"
id="stop1162"
offset="1" />
</linearGradient>
<linearGradient
xlink:href="#linearGradient1160"
id="linearGradient1163" />
</defs>
<metadata
id="metadata12">
<RDF
id="RDF13">
<Work
about=""
id="Work14">
<title
id="title15">Part of the Flat Icon Collection (Thu Aug 26 14:31:40 2004)</title>
<description
id="description17" />
<subject
id="subject18">
<Bag
id="Bag19">
<li
id="li20" />
</Bag>
</subject>
<publisher
id="publisher21">
<Agent
about=""
id="Agent22">
<title
id="title23" />
</Agent>
</publisher>
<creator
id="creator24">
<Agent
about=""
id="Agent25">
<title
id="title26">Danny Allen</title>
</Agent>
</creator>
<rights
id="rights28">
<Agent
about=""
id="Agent29">
<title
id="title30">Danny Allen</title>
</Agent>
</rights>
<date
id="date32" />
<format
id="format33">image/svg+xml</format>
<type
id="type35"
resource="http://purl.org/dc/dcmitype/StillImage" />
<license
id="license36"
resource="http://creativecommons.org/licenses/LGPL/2.1/">
<date
id="date37" />
</license>
<language
id="language38">en</language>
</Work>
</RDF>
<rdf:RDF
id="RDF40">
<cc:Work
rdf:about=""
id="Work41">
<dc:format
id="format42">image/svg+xml</dc:format>
<dc:type
id="type44"
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="g2099">
<path
style="color:#000000;fill:none;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#ffffff;stroke-width:8.1250000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none"
d="M 55.311891,51.920745 L 4.6880989,51.920744 L 29.999995,8.0792542 L 55.311891,51.920745 z "
id="path1724" />
<path
style="color:#000000;fill:#ffe940;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:3.1250010;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none"
d="M 55.311891,51.920745 L 4.6880989,51.920744 L 29.999995,8.0792542 L 55.311891,51.920745 z "
id="path1722" />
<path
style="font-size:12.000000;font-weight:900;fill:none;fill-opacity:1.0000000;stroke:#ffffff;stroke-width:8.1250000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000"
d="M 34.944960,10.779626 L 34.944960,33.186510 C 34.944960,34.752415 34.501979,36.081368 33.616007,37.173380 C 32.750636,38.265402 31.545298,38.811408 29.999995,38.811408 C 28.475302,38.811408 27.269965,38.265402 26.383993,37.173380 C 25.498020,36.060767 25.055030,34.731804 25.055030,33.186510 L 25.055030,10.779626 C 25.055030,9.1931155 25.498020,7.8641562 26.383993,6.7927462 C 27.269965,5.7007332 28.475302,5.1547262 29.999995,5.1547262 C 31.009593,5.1547262 31.885265,5.4019740 32.627010,5.8964706 C 33.389356,6.3909681 33.966274,7.0709005 34.357752,7.9362696 C 34.749221,8.7810349 34.944960,9.7288200 34.944960,10.779626 z "
id="path1099" />
<path
style="font-size:12.000000;font-weight:900;fill:#e71c02;fill-opacity:1.0000000;stroke:none;stroke-width:3.1249981;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1.0000000"
d="M 29.999995,3.5986440 C 28.102272,3.5986440 26.318514,4.3848272 25.156245,5.8173940 C 24.028906,7.1806889 23.499995,8.9087770 23.499995,10.786144 L 23.499995,33.192394 C 23.499995,35.036302 24.050685,36.772771 25.156245,38.161144 C 26.318514,39.593721 28.102273,40.379893 29.999995,40.379894 C 31.913354,40.379894 33.697195,39.576736 34.843745,38.129894 C 35.959941,36.754118 36.499995,35.052976 36.499995,33.192394 L 36.499995,10.786144 C 36.499995,9.5413010 36.276626,8.3551469 35.781245,7.2861440 C 35.278844,6.1755772 34.477762,5.2531440 33.468745,4.5986440 C 32.454761,3.9226545 31.264694,3.5986439 29.999995,3.5986440 z "
id="path835"
sodipodi:nodetypes="cccccccccccc" />
<path
style="color:#000000;fill:none;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#ffffff;stroke-width:5.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none"
d="M 36.506243,49.901522 C 36.506243,53.492972 33.591442,56.407773 29.999991,56.407773 C 26.408541,56.407773 23.493739,53.492972 23.493739,49.901522 C 23.493739,46.310071 26.408541,43.395270 29.999991,43.395270 C 33.591442,43.395270 36.506243,46.310071 36.506243,49.901522 z "
id="path1727" />
<path
style="color:#000000;fill:#e71c02;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:3.1250000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none"
d="M 36.506243,49.901522 C 36.506243,53.492972 33.591442,56.407773 29.999991,56.407773 C 26.408541,56.407773 23.493739,53.492972 23.493739,49.901522 C 23.493739,46.310071 26.408541,43.395270 29.999991,43.395270 C 33.591442,43.395270 36.506243,46.310071 36.506243,49.901522 z "
id="path1725" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 7.2 KiB

+9
View File
@@ -87,6 +87,14 @@ def compile_latex_document(app):
app.config.latex_engine, p.returncode)
def skip_if_requested(testfunc):
if 'SKIP_LATEX_BUILD' in os.environ:
msg = 'Skip LaTeX builds because SKIP_LATEX_BUILD is set'
return skip_if(True, msg)(testfunc)
else:
return testfunc
def skip_if_stylefiles_notfound(testfunc):
if kpsetest(*STYLEFILES) is False:
msg = 'not running latex, the required styles do not seem to be installed'
@@ -95,6 +103,7 @@ def skip_if_stylefiles_notfound(testfunc):
return testfunc
@skip_if_requested
@skip_if_stylefiles_notfound
@pytest.mark.parametrize(
"engine,docclass",
+32 -2
View File
@@ -10,9 +10,12 @@
"""
import pytest
from mock import Mock
from six import text_type
from docutils import nodes
from sphinx import addnodes
from sphinx.domains.python import py_sig_re, _pseudo_parse_arglist
from sphinx.domains.python import py_sig_re, _pseudo_parse_arglist, PythonDomain
from util import assert_node
@@ -28,7 +31,6 @@ def parse(sig):
def test_function_signatures():
rv = parse('func(a=1) -> int object')
assert text_type(rv) == u'a=1'
@@ -165,3 +167,31 @@ def test_domain_py_find_obj(app, status, warning):
[(u'NestedParentA.NestedChildA.subchild_1', (u'roles', u'method'))])
assert (find_obj(None, u'NestedParentA.NestedChildA', u'subchild_1', u'meth') ==
[(u'NestedParentA.NestedChildA.subchild_1', (u'roles', u'method'))])
def test_get_full_qualified_name():
env = Mock(domaindata={})
domain = PythonDomain(env)
# non-python references
node = nodes.reference()
assert domain.get_full_qualified_name(node) is None
# simple reference
node = nodes.reference(reftarget='func')
assert domain.get_full_qualified_name(node) == 'func'
# with py:module context
kwargs = {'py:module': 'module1'}
node = nodes.reference(reftarget='func', **kwargs)
assert domain.get_full_qualified_name(node) == 'module1.func'
# with py:class context
kwargs = {'py:class': 'Class'}
node = nodes.reference(reftarget='func', **kwargs)
assert domain.get_full_qualified_name(node) == 'Class.func'
# with both py:module and py:class context
kwargs = {'py:module': 'module1', 'py:class': 'Class'}
node = nodes.reference(reftarget='func', **kwargs)
assert domain.get_full_qualified_name(node) == 'module1.Class.func'
+22
View File
@@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
"""
test_ext_imgconverter
~~~~~~~~~~~~~~~~~~~~~
Test sphinx.ext.imgconverter extension.
:copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
import pytest
@pytest.mark.sphinx('latex', testroot='ext-imgconverter')
def test_ext_imgconverter(app, status, warning):
app.builder.build_all()
content = (app.outdir / 'Python.tex').text()
assert '\sphinxincludegraphics{{svgimg}.png}' in content
assert not (app.outdir / 'svgimg.svg').exists()
assert (app.outdir / 'svgimg.png').exists()
+12
View File
@@ -145,6 +145,18 @@ def test_missing_reference(tempdir, app, status, warning):
assert rn is None
assert contnode[0].astext() == 'py3k:unknown'
# no context data
kwargs = {}
node, contnode = fake_node('py', 'func', 'func', 'func()', **kwargs)
rn = missing_reference(app, app.env, node, contnode)
assert rn is None
# context data (like py:module) help to search objects
kwargs = {'py:module': 'module1'}
node, contnode = fake_node('py', 'func', 'func', 'func()', **kwargs)
rn = missing_reference(app, app.env, node, contnode)
assert rn[0].astext() == 'func()'
# check relative paths
rn = reference_check('py', 'mod', 'py3krel:module1', 'foo')
assert rn['refuri'] == 'py3k/foo.html#module-module1'