mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Merge with default
This commit is contained in:
commit
0853176305
4
CHANGES
4
CHANGES
@ -44,6 +44,8 @@ Features added
|
||||
directive is now supported.
|
||||
* PR#214: Added stemming support for 14 languages, so that the built-in document
|
||||
search can now handle these. Thanks to Shibukawa Yoshiki.
|
||||
* PR#296: numfig feature: Assign numbers to figures, tables and code-blocks.
|
||||
Thanks to Takeshi Komiya.
|
||||
* PR#202: Allow "." and "~" prefixed references in ``:param:`` doc fields
|
||||
for Python.
|
||||
* PR#184: Add `autodoc_mock_imports`, allowing to mock imports of
|
||||
@ -83,6 +85,8 @@ Features added
|
||||
``+``.
|
||||
* PR#291: The caption of :rst:dir:`code-block` is recognised as a title of ref
|
||||
target. Thanks to Takeshi Komiya.
|
||||
* PR#298: Add new API: :meth:`~sphinx.application.Sphinx.add_latex_package`.
|
||||
Thanks to Takeshi Komiya.
|
||||
|
||||
Bugs fixed
|
||||
----------
|
||||
|
@ -288,6 +288,12 @@ package.
|
||||
|
||||
.. versionadded:: 1.0
|
||||
|
||||
.. method:: Sphinx.add_latex_package(packagename)
|
||||
|
||||
Add *packagename* to the list of packages that LaTeX source code will include.
|
||||
|
||||
.. versionadded:: 1.3
|
||||
|
||||
.. method:: Sphinx.add_lexer(alias, lexer)
|
||||
|
||||
Use *lexer*, which must be an instance of a Pygments lexer class, to
|
||||
|
@ -694,6 +694,11 @@ class Sphinx(object):
|
||||
StandaloneHTMLBuilder.css_files.append(
|
||||
posixpath.join('_static', filename))
|
||||
|
||||
def add_latex_package(self, packagename):
|
||||
self.debug('[app] adding latex package: %r', packagename)
|
||||
from sphinx.builders.latex import LaTeXBuilder
|
||||
LaTeXBuilder.usepackages.append(packagename)
|
||||
|
||||
def add_lexer(self, alias, lexer):
|
||||
self.debug('[app] adding lexer: %r', (alias, lexer))
|
||||
from sphinx.highlighting import lexers
|
||||
|
@ -425,7 +425,8 @@ class StandaloneHTMLBuilder(Builder):
|
||||
doctree.settings = self.docsettings
|
||||
|
||||
self.secnumbers = self.env.toc_secnumbers.get(docname, {})
|
||||
self.imgpath = relative_uri(self.get_target_uri(docname), self.imagedir)
|
||||
self.fignumbers = self.env.toc_fignumbers.get(docname, {})
|
||||
self.imgpath = relative_uri(self.get_target_uri(docname), '_images')
|
||||
self.dlpath = relative_uri(self.get_target_uri(docname), '_downloads')
|
||||
self.current_docname = docname
|
||||
self.docwriter.write(doctree, destination)
|
||||
|
@ -37,6 +37,7 @@ class LaTeXBuilder(Builder):
|
||||
format = 'latex'
|
||||
supported_image_types = ['application/pdf', 'image/png',
|
||||
'image/gif', 'image/jpeg']
|
||||
usepackages = []
|
||||
|
||||
def init(self):
|
||||
self.docnames = []
|
||||
|
@ -58,6 +58,7 @@ class WebSupportBuilder(PickleHTMLBuilder):
|
||||
doctree.settings = self.docsettings
|
||||
|
||||
self.secnumbers = self.env.toc_secnumbers.get(docname, {})
|
||||
self.fignumbers = self.env.toc_fignumbers.get(docname, {})
|
||||
self.imgpath = '/' + posixpath.join(self.virtual_staticdir, self.imagedir)
|
||||
self.dlpath = '/' + posixpath.join(self.virtual_staticdir, '_downloads')
|
||||
self.current_docname = docname
|
||||
|
@ -70,6 +70,12 @@ class Config(object):
|
||||
needs_extensions = ({}, None),
|
||||
nitpicky = (False, 'env'),
|
||||
nitpick_ignore = ([], 'html'),
|
||||
numfig = (False, 'env'),
|
||||
numfig_secnum_depth = (1, 'env'),
|
||||
numfig_prefix = ({'figure': l_('Fig.'),
|
||||
'table': l_('Table '),
|
||||
'code-block': l_('List ')},
|
||||
'env'),
|
||||
|
||||
# HTML options
|
||||
html_theme = ('default', 'html'),
|
||||
|
@ -48,7 +48,7 @@ from sphinx.errors import SphinxError, ExtensionError
|
||||
from sphinx.locale import _
|
||||
from sphinx.versioning import add_uids, merge_doctrees
|
||||
from sphinx.transforms import DefaultSubstitutions, MoveModuleTargets, \
|
||||
HandleCodeBlocks, SortIds, CitationReferences, Locale, \
|
||||
HandleCodeBlocks, AutoNumbering, SortIds, CitationReferences, Locale, \
|
||||
RemoveTranslatableInline, SphinxContentsFilter
|
||||
|
||||
|
||||
@ -98,7 +98,7 @@ class SphinxStandaloneReader(standalone.Reader):
|
||||
Add our own transforms.
|
||||
"""
|
||||
transforms = [Locale, CitationReferences, DefaultSubstitutions,
|
||||
MoveModuleTargets, HandleCodeBlocks, SortIds,
|
||||
MoveModuleTargets, HandleCodeBlocks, AutoNumbering, SortIds,
|
||||
RemoveTranslatableInline]
|
||||
|
||||
def get_transforms(self):
|
||||
@ -234,6 +234,8 @@ class BuildEnvironment:
|
||||
# used to determine when to show the TOC
|
||||
# in a sidebar (don't show if it's only one item)
|
||||
self.toc_secnumbers = {} # docname -> dict of sectionid -> number
|
||||
self.toc_fignumbers = {} # docname -> dict of figtype ->
|
||||
# dict of figureid -> number
|
||||
|
||||
self.toctree_includes = {} # docname -> list of toctree includefiles
|
||||
self.files_to_rebuild = {} # docname -> set of files
|
||||
@ -635,8 +637,8 @@ class BuildEnvironment:
|
||||
self._warnfunc(*warning)
|
||||
|
||||
def check_dependents(self, already):
|
||||
to_rewrite = self.assign_section_numbers()
|
||||
for docname in to_rewrite:
|
||||
to_rewrite = self.assign_section_numbers() + self.assign_figure_numbers()
|
||||
for docname in set(to_rewrite):
|
||||
if docname not in already:
|
||||
yield docname
|
||||
|
||||
@ -1693,6 +1695,87 @@ class BuildEnvironment:
|
||||
|
||||
return rewrite_needed
|
||||
|
||||
def assign_figure_numbers(self):
|
||||
"""Assign a figure number to each figure under a numbered toctree."""
|
||||
|
||||
rewrite_needed = []
|
||||
|
||||
assigned = set()
|
||||
old_fignumbers = getattr(self, 'toc_fignumbers', {}) # compatible with old envs
|
||||
self.toc_fignumbers = {}
|
||||
fignum_counter = {}
|
||||
|
||||
def has_child(node, cls):
|
||||
return any(isinstance(child, cls) for child in node)
|
||||
|
||||
def get_section_number(docname, section):
|
||||
anchorname = '#' + section['ids'][0]
|
||||
secnumbers = self.toc_secnumbers.get(docname, {})
|
||||
if anchorname in secnumbers:
|
||||
secnum = secnumbers.get(anchorname)
|
||||
else:
|
||||
secnum = secnumbers.get('')
|
||||
|
||||
return secnum or tuple()
|
||||
|
||||
def get_next_fignumber(figtype, secnum):
|
||||
counter = fignum_counter.setdefault(figtype, {})
|
||||
|
||||
secnum = secnum[:self.config.numfig_secnum_depth]
|
||||
counter[secnum] = counter.get(secnum, 0) + 1
|
||||
return secnum + (counter[secnum],)
|
||||
|
||||
def register_fignumber(docname, secnum, figtype, figure_id):
|
||||
self.toc_fignumbers.setdefault(docname, {})
|
||||
fignumbers = self.toc_fignumbers[docname].setdefault(figtype, {})
|
||||
fignumbers[figure_id] = get_next_fignumber(figtype, secnum)
|
||||
|
||||
def _walk_doctree(docname, doctree, secnum):
|
||||
for subnode in doctree.children:
|
||||
if isinstance(subnode, nodes.section):
|
||||
next_secnum = get_section_number(docname, subnode)
|
||||
if next_secnum:
|
||||
_walk_doctree(docname, subnode, next_secnum)
|
||||
else:
|
||||
_walk_doctree(docname, subnode, secnum)
|
||||
continue
|
||||
elif isinstance(subnode, addnodes.toctree):
|
||||
for title, subdocname in subnode['entries']:
|
||||
if url_re.match(subdocname) or subdocname == 'self':
|
||||
# don't mess with those
|
||||
continue
|
||||
|
||||
_walk_doc(subdocname, secnum)
|
||||
|
||||
continue
|
||||
|
||||
if isinstance(subnode, nodes.figure):
|
||||
figure_id = subnode['ids'][0]
|
||||
register_fignumber(docname, secnum, 'figure', figure_id)
|
||||
elif isinstance(subnode, nodes.table):
|
||||
table_id = subnode['ids'][0]
|
||||
register_fignumber(docname, secnum, 'table', table_id)
|
||||
elif isinstance(subnode, nodes.container):
|
||||
if has_child(subnode, nodes.literal_block):
|
||||
code_block_id = subnode['ids'][0]
|
||||
register_fignumber(docname, secnum, 'code-block', code_block_id)
|
||||
|
||||
_walk_doctree(docname, subnode, secnum)
|
||||
|
||||
def _walk_doc(docname, secnum):
|
||||
if docname not in assigned:
|
||||
assigned.add(docname)
|
||||
doctree = self.get_doctree(docname)
|
||||
_walk_doctree(docname, doctree, secnum)
|
||||
|
||||
if self.config.numfig:
|
||||
_walk_doc(self.config.master_doc, tuple())
|
||||
for docname, fignums in iteritems(self.toc_fignumbers):
|
||||
if fignums != old_fignumbers.get(docname):
|
||||
rewrite_needed.append(docname)
|
||||
|
||||
return rewrite_needed
|
||||
|
||||
def create_index(self, builder, group_entries=True,
|
||||
_fixre=re.compile(r'(.*) ([(][^()]*[)])')):
|
||||
"""Create the real index from the collected index entries."""
|
||||
|
@ -101,6 +101,31 @@ class HandleCodeBlocks(Transform):
|
||||
# del node.parent[parindex+1]
|
||||
|
||||
|
||||
class AutoNumbering(Transform):
|
||||
"""
|
||||
Register IDs of tables, figures and literal_blocks to assign numbers.
|
||||
"""
|
||||
default_priority = 210
|
||||
|
||||
def apply(self):
|
||||
def has_child(node, cls):
|
||||
return any(isinstance(child, cls) for child in node)
|
||||
|
||||
for node in self.document.traverse(nodes.Element):
|
||||
if isinstance(node, nodes.figure):
|
||||
if has_child(node, nodes.caption):
|
||||
self.document.note_implicit_target(node)
|
||||
elif isinstance(node, nodes.image):
|
||||
if has_child(node.parent, nodes.caption):
|
||||
self.document.note_implicit_target(node.parent)
|
||||
elif isinstance(node, nodes.table):
|
||||
if has_child(node, nodes.title):
|
||||
self.document.note_implicit_target(node)
|
||||
elif isinstance(node, nodes.literal_block):
|
||||
if has_child(node.parent, nodes.caption):
|
||||
self.document.note_implicit_target(node.parent)
|
||||
|
||||
|
||||
class SortIds(Transform):
|
||||
"""
|
||||
Sort secion IDs so that the "id[0-9]+" one comes last.
|
||||
|
@ -250,6 +250,20 @@ class HTMLTranslator(BaseTranslator):
|
||||
self.body.append('.'.join(map(str, numbers)) +
|
||||
self.secnumber_suffix)
|
||||
|
||||
def add_fignumber(self, node):
|
||||
def append_fignumber(figtype, figure_id):
|
||||
if figure_id in self.builder.fignumbers.get(figtype, {}):
|
||||
prefix = self.builder.config.numfig_prefix.get(figtype, '')
|
||||
numbers = self.builder.fignumbers[figtype][figure_id]
|
||||
self.body.append(prefix + '.'.join(map(str, numbers)) + " ")
|
||||
|
||||
if isinstance(node.parent, nodes.figure):
|
||||
append_fignumber('figure', node.parent['ids'][0])
|
||||
elif isinstance(node.parent, nodes.table):
|
||||
append_fignumber('table', node.parent['ids'][0])
|
||||
elif isinstance(node.parent, nodes.container):
|
||||
append_fignumber('code-block', node.parent['ids'][0])
|
||||
|
||||
# overwritten to avoid emitting empty <ul></ul>
|
||||
def visit_bullet_list(self, node):
|
||||
if len(node) == 1 and node[0].tagname == 'toctree':
|
||||
@ -260,6 +274,7 @@ class HTMLTranslator(BaseTranslator):
|
||||
def visit_title(self, node):
|
||||
BaseTranslator.visit_title(self, node)
|
||||
self.add_secnumber(node)
|
||||
self.add_fignumber(node)
|
||||
|
||||
# overwritten
|
||||
def visit_literal_block(self, node):
|
||||
@ -291,6 +306,7 @@ class HTMLTranslator(BaseTranslator):
|
||||
self.body.append(self.starttag(node, 'div', '', CLASS='code-block-caption'))
|
||||
else:
|
||||
BaseTranslator.visit_caption(self, node)
|
||||
self.add_fignumber(node)
|
||||
|
||||
def depart_caption(self, node):
|
||||
if isinstance(node.parent, nodes.container) and node.parent.get('literal_block'):
|
||||
|
@ -42,6 +42,7 @@ HEADER = r'''%% Generated by Sphinx.
|
||||
%(longtable)s
|
||||
\usepackage{sphinx}
|
||||
\usepackage{multirow}
|
||||
%(usepackages)s
|
||||
%(preamble)s
|
||||
|
||||
\title{%(title)s}
|
||||
@ -153,6 +154,7 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
||||
'fontpkg': '\\usepackage{times}',
|
||||
'fncychap': '\\usepackage[Bjarne]{fncychap}',
|
||||
'longtable': '\\usepackage{longtable}',
|
||||
'usepackages': '',
|
||||
'preamble': '',
|
||||
'title': '',
|
||||
'date': '',
|
||||
@ -234,6 +236,9 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
||||
self.elements['fncychap'] = ''
|
||||
else:
|
||||
self.elements['classoptions'] += ',english'
|
||||
if getattr(builder, 'usepackages', None):
|
||||
usepackages = ('\\usepackage{%s}' % p for p in builder.usepackages)
|
||||
self.elements['usepackages'] += "\n".join(usepackages)
|
||||
# allow the user to override them all
|
||||
self.elements.update(builder.config.latex_elements)
|
||||
if self.elements['extraclassoptions']:
|
||||
|
58
tests/roots/test-numfig/bar.rst
Normal file
58
tests/roots/test-numfig/bar.rst
Normal file
@ -0,0 +1,58 @@
|
||||
===
|
||||
Bar
|
||||
===
|
||||
|
||||
Bar A
|
||||
=====
|
||||
|
||||
.. figure:: rimg.png
|
||||
|
||||
should be Fig.2.1
|
||||
|
||||
.. csv-table:: should be Table 2.1
|
||||
:header-rows: 0
|
||||
|
||||
hello,world
|
||||
|
||||
.. code-block:: python
|
||||
:caption: should be List 2.1
|
||||
|
||||
print('hello world')
|
||||
|
||||
.. toctree::
|
||||
|
||||
baz
|
||||
|
||||
.. figure:: rimg.png
|
||||
|
||||
should be Fig.2.3
|
||||
|
||||
.. csv-table:: should be Table 2.3
|
||||
:header-rows: 0
|
||||
|
||||
hello,world
|
||||
|
||||
.. code-block:: python
|
||||
:caption: should be List 2.3
|
||||
|
||||
print('hello world')
|
||||
|
||||
Bar B
|
||||
=====
|
||||
|
||||
Bar B1
|
||||
------
|
||||
|
||||
.. figure:: rimg.png
|
||||
|
||||
should be Fig.2.4
|
||||
|
||||
.. csv-table:: should be Table 2.4
|
||||
:header-rows: 0
|
||||
|
||||
hello,world
|
||||
|
||||
.. code-block:: python
|
||||
:caption: should be List 2.4
|
||||
|
||||
print('hello world')
|
16
tests/roots/test-numfig/baz.rst
Normal file
16
tests/roots/test-numfig/baz.rst
Normal file
@ -0,0 +1,16 @@
|
||||
Baz A
|
||||
-----
|
||||
|
||||
.. figure:: rimg.png
|
||||
|
||||
should be Fig.2.2
|
||||
|
||||
.. csv-table:: should be Table 2.2
|
||||
:header-rows: 0
|
||||
|
||||
hello,world
|
||||
|
||||
.. code-block:: python
|
||||
:caption: should be List 2.2
|
||||
|
||||
print('hello world')
|
3
tests/roots/test-numfig/conf.py
Normal file
3
tests/roots/test-numfig/conf.py
Normal file
@ -0,0 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
master_doc = 'index'
|
71
tests/roots/test-numfig/foo.rst
Normal file
71
tests/roots/test-numfig/foo.rst
Normal file
@ -0,0 +1,71 @@
|
||||
===
|
||||
Foo
|
||||
===
|
||||
|
||||
.. figure:: rimg.png
|
||||
|
||||
should be Fig.1.1
|
||||
|
||||
.. csv-table:: should be Table 1.1
|
||||
:header-rows: 0
|
||||
|
||||
hello,world
|
||||
|
||||
.. code-block:: python
|
||||
:caption: should be List 1.1
|
||||
|
||||
print('hello world')
|
||||
|
||||
Foo A
|
||||
=====
|
||||
|
||||
.. figure:: rimg.png
|
||||
|
||||
should be Fig.1.2
|
||||
|
||||
.. figure:: rimg.png
|
||||
|
||||
should be Fig.1.3
|
||||
|
||||
.. csv-table:: should be Table 1.2
|
||||
:header-rows: 0
|
||||
|
||||
hello,world
|
||||
|
||||
.. csv-table:: should be Table 1.3
|
||||
:header-rows: 0
|
||||
|
||||
hello,world
|
||||
|
||||
.. code-block:: python
|
||||
:caption: should be List 1.2
|
||||
|
||||
print('hello world')
|
||||
|
||||
.. code-block:: python
|
||||
:caption: should be List 1.3
|
||||
|
||||
print('hello world')
|
||||
|
||||
Foo A1
|
||||
------
|
||||
|
||||
Foo B
|
||||
=====
|
||||
|
||||
Foo B1
|
||||
------
|
||||
|
||||
.. figure:: rimg.png
|
||||
|
||||
should be Fig.1.4
|
||||
|
||||
.. csv-table:: should be Table 1.4
|
||||
:header-rows: 0
|
||||
|
||||
hello,world
|
||||
|
||||
.. code-block:: python
|
||||
:caption: should be List 1.4
|
||||
|
||||
print('hello world')
|
36
tests/roots/test-numfig/index.rst
Normal file
36
tests/roots/test-numfig/index.rst
Normal file
@ -0,0 +1,36 @@
|
||||
test-tocdepth
|
||||
=============
|
||||
|
||||
.. toctree::
|
||||
:numbered:
|
||||
|
||||
foo
|
||||
bar
|
||||
|
||||
.. figure:: rimg.png
|
||||
|
||||
should be Fig.1
|
||||
|
||||
.. figure:: rimg.png
|
||||
|
||||
should be Fig.2
|
||||
|
||||
.. csv-table:: should be Table 1
|
||||
:header-rows: 0
|
||||
|
||||
hello,world
|
||||
|
||||
.. csv-table:: should be Table 2
|
||||
:header-rows: 0
|
||||
|
||||
hello,world
|
||||
|
||||
.. code-block:: python
|
||||
:caption: should be List 1
|
||||
|
||||
print('hello world')
|
||||
|
||||
.. code-block:: python
|
||||
:caption: should be List 2
|
||||
|
||||
print('hello world')
|
BIN
tests/roots/test-numfig/rimg.png
Normal file
BIN
tests/roots/test-numfig/rimg.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 218 B |
@ -455,3 +455,402 @@ def test_tocdepth_singlehtml(app, status, warning):
|
||||
|
||||
for xpath, check, be_found in paths:
|
||||
yield check_xpath, etree, fname, xpath, check, be_found
|
||||
|
||||
|
||||
@gen_with_app(buildername='html', testroot='numfig')
|
||||
def test_numfig(app, status, warning):
|
||||
# issue #1251
|
||||
app.builder.build_all()
|
||||
|
||||
expects = {
|
||||
'index.html': [
|
||||
(".//div[@class='figure']/p[@class='caption']",
|
||||
'^should be Fig.1$', True),
|
||||
(".//div[@class='figure']/p[@class='caption']",
|
||||
'^should be Fig.2$', True),
|
||||
(".//table/caption", '^should be Table 1$', True),
|
||||
(".//table/caption", '^should be Table 2$', True),
|
||||
(".//div[@class='code-block-caption']",
|
||||
'^should be List 1$', True),
|
||||
(".//div[@class='code-block-caption']",
|
||||
'^should be List 2$', True),
|
||||
],
|
||||
'foo.html': [
|
||||
(".//div[@class='figure']/p[@class='caption']",
|
||||
'^should be Fig.1.1$', True),
|
||||
(".//div[@class='figure']/p[@class='caption']",
|
||||
'^should be Fig.1.2$', True),
|
||||
(".//div[@class='figure']/p[@class='caption']",
|
||||
'^should be Fig.1.3$', True),
|
||||
(".//div[@class='figure']/p[@class='caption']",
|
||||
'^should be Fig.1.4$', True),
|
||||
(".//table/caption", '^should be Table 1.1$', True),
|
||||
(".//table/caption", '^should be Table 1.2$', True),
|
||||
(".//table/caption", '^should be Table 1.3$', True),
|
||||
(".//table/caption", '^should be Table 1.4$', True),
|
||||
(".//div[@class='code-block-caption']",
|
||||
'^should be List 1.1$', True),
|
||||
(".//div[@class='code-block-caption']",
|
||||
'^should be List 1.2$', True),
|
||||
(".//div[@class='code-block-caption']",
|
||||
'^should be List 1.3$', True),
|
||||
(".//div[@class='code-block-caption']",
|
||||
'^should be List 1.4$', True),
|
||||
],
|
||||
'bar.html': [
|
||||
(".//div[@class='figure']/p[@class='caption']",
|
||||
'^should be Fig.2.1$', True),
|
||||
(".//div[@class='figure']/p[@class='caption']",
|
||||
'^should be Fig.2.3$', True),
|
||||
(".//div[@class='figure']/p[@class='caption']",
|
||||
'^should be Fig.2.4$', True),
|
||||
(".//table/caption", '^should be Table 2.1$', True),
|
||||
(".//table/caption", '^should be Table 2.3$', True),
|
||||
(".//table/caption", '^should be Table 2.4$', True),
|
||||
(".//div[@class='code-block-caption']",
|
||||
'^should be List 2.1$', True),
|
||||
(".//div[@class='code-block-caption']",
|
||||
'^should be List 2.3$', True),
|
||||
(".//div[@class='code-block-caption']",
|
||||
'^should be List 2.4$', True),
|
||||
],
|
||||
'baz.html': [
|
||||
(".//div[@class='figure']/p[@class='caption']",
|
||||
'^should be Fig.2.2$', True),
|
||||
(".//table/caption", '^should be Table 2.2$', True),
|
||||
(".//div[@class='code-block-caption']",
|
||||
'^should be List 2.2$', True),
|
||||
],
|
||||
}
|
||||
|
||||
for fname, paths in iteritems(expects):
|
||||
parser = NslessParser()
|
||||
parser.entity.update(html_entities.entitydefs)
|
||||
fp = open(os.path.join(app.outdir, fname), 'rb')
|
||||
try:
|
||||
etree = ET.parse(fp, parser)
|
||||
finally:
|
||||
fp.close()
|
||||
|
||||
for xpath, check, be_found in paths:
|
||||
yield check_xpath, etree, fname, xpath, check, be_found
|
||||
|
||||
|
||||
@gen_with_app(buildername='html', testroot='numfig',
|
||||
confoverrides={'numfig': True})
|
||||
def test_numfig_without_numbered_toctree(app, status, warning):
|
||||
# remove :numbered: option
|
||||
index = (app.srcdir / 'index.rst').text()
|
||||
index = re.sub(':numbered:.*', '', index, re.MULTILINE)
|
||||
(app.srcdir / 'index.rst').write_text(index, encoding='utf-8')
|
||||
app.builder.build_all()
|
||||
|
||||
expects = {
|
||||
'index.html': [
|
||||
(".//div[@class='figure']/p[@class='caption']",
|
||||
'^Fig.9 should be Fig.1$', True),
|
||||
(".//div[@class='figure']/p[@class='caption']",
|
||||
'^Fig.10 should be Fig.2$', True),
|
||||
(".//table/caption", '^Table 9 should be Table 1$', True),
|
||||
(".//table/caption", '^Table 10 should be Table 2$', True),
|
||||
(".//div[@class='code-block-caption']",
|
||||
'^List 9 should be List 1$', True),
|
||||
(".//div[@class='code-block-caption']",
|
||||
'^List 10 should be List 2$', True),
|
||||
],
|
||||
'foo.html': [
|
||||
(".//div[@class='figure']/p[@class='caption']",
|
||||
'^Fig.1 should be Fig.1.1$', True),
|
||||
(".//div[@class='figure']/p[@class='caption']",
|
||||
'^Fig.2 should be Fig.1.2$', True),
|
||||
(".//div[@class='figure']/p[@class='caption']",
|
||||
'^Fig.3 should be Fig.1.3$', True),
|
||||
(".//div[@class='figure']/p[@class='caption']",
|
||||
'^Fig.4 should be Fig.1.4$', True),
|
||||
(".//table/caption", '^Table 1 should be Table 1.1$', True),
|
||||
(".//table/caption", '^Table 2 should be Table 1.2$', True),
|
||||
(".//table/caption", '^Table 3 should be Table 1.3$', True),
|
||||
(".//table/caption", '^Table 4 should be Table 1.4$', True),
|
||||
(".//div[@class='code-block-caption']",
|
||||
'^List 1 should be List 1.1$', True),
|
||||
(".//div[@class='code-block-caption']",
|
||||
'^List 2 should be List 1.2$', True),
|
||||
(".//div[@class='code-block-caption']",
|
||||
'^List 3 should be List 1.3$', True),
|
||||
(".//div[@class='code-block-caption']",
|
||||
'^List 4 should be List 1.4$', True),
|
||||
],
|
||||
'bar.html': [
|
||||
(".//div[@class='figure']/p[@class='caption']",
|
||||
'^Fig.5 should be Fig.2.1$', True),
|
||||
(".//div[@class='figure']/p[@class='caption']",
|
||||
'^Fig.7 should be Fig.2.3$', True),
|
||||
(".//div[@class='figure']/p[@class='caption']",
|
||||
'^Fig.8 should be Fig.2.4$', True),
|
||||
(".//table/caption", '^Table 5 should be Table 2.1$', True),
|
||||
(".//table/caption", '^Table 7 should be Table 2.3$', True),
|
||||
(".//table/caption", '^Table 8 should be Table 2.4$', True),
|
||||
(".//div[@class='code-block-caption']",
|
||||
'^List 5 should be List 2.1$', True),
|
||||
(".//div[@class='code-block-caption']",
|
||||
'^List 7 should be List 2.3$', True),
|
||||
(".//div[@class='code-block-caption']",
|
||||
'^List 8 should be List 2.4$', True),
|
||||
],
|
||||
'baz.html': [
|
||||
(".//div[@class='figure']/p[@class='caption']",
|
||||
'^Fig.6 should be Fig.2.2$', True),
|
||||
(".//table/caption", '^Table 6 should be Table 2.2$', True),
|
||||
(".//div[@class='code-block-caption']",
|
||||
'^List 6 should be List 2.2$', True),
|
||||
],
|
||||
}
|
||||
|
||||
for fname, paths in iteritems(expects):
|
||||
parser = NslessParser()
|
||||
parser.entity.update(html_entities.entitydefs)
|
||||
fp = open(os.path.join(app.outdir, fname), 'rb')
|
||||
try:
|
||||
etree = ET.parse(fp, parser)
|
||||
finally:
|
||||
fp.close()
|
||||
|
||||
for xpath, check, be_found in paths:
|
||||
yield check_xpath, etree, fname, xpath, check, be_found
|
||||
|
||||
|
||||
@gen_with_app(buildername='html', testroot='numfig',
|
||||
confoverrides={'numfig': True})
|
||||
def test_numfig_with_numbered_toctree(app, status, warning):
|
||||
app.builder.build_all()
|
||||
|
||||
expects = {
|
||||
'index.html': [
|
||||
(".//div[@class='figure']/p[@class='caption']",
|
||||
'^Fig.1 should be Fig.1$', True),
|
||||
(".//div[@class='figure']/p[@class='caption']",
|
||||
'^Fig.2 should be Fig.2$', True),
|
||||
(".//table/caption", '^Table 1 should be Table 1$', True),
|
||||
(".//table/caption", '^Table 2 should be Table 2$', True),
|
||||
(".//div[@class='code-block-caption']",
|
||||
'^List 1 should be List 1$', True),
|
||||
(".//div[@class='code-block-caption']",
|
||||
'^List 2 should be List 2$', True),
|
||||
],
|
||||
'foo.html': [
|
||||
(".//div[@class='figure']/p[@class='caption']",
|
||||
'^Fig.1.1 should be Fig.1.1$', True),
|
||||
(".//div[@class='figure']/p[@class='caption']",
|
||||
'^Fig.1.2 should be Fig.1.2$', True),
|
||||
(".//div[@class='figure']/p[@class='caption']",
|
||||
'^Fig.1.3 should be Fig.1.3$', True),
|
||||
(".//div[@class='figure']/p[@class='caption']",
|
||||
'^Fig.1.4 should be Fig.1.4$', True),
|
||||
(".//table/caption", '^Table 1.1 should be Table 1.1$', True),
|
||||
(".//table/caption", '^Table 1.2 should be Table 1.2$', True),
|
||||
(".//table/caption", '^Table 1.3 should be Table 1.3$', True),
|
||||
(".//table/caption", '^Table 1.4 should be Table 1.4$', True),
|
||||
(".//div[@class='code-block-caption']",
|
||||
'^List 1.1 should be List 1.1$', True),
|
||||
(".//div[@class='code-block-caption']",
|
||||
'^List 1.2 should be List 1.2$', True),
|
||||
(".//div[@class='code-block-caption']",
|
||||
'^List 1.3 should be List 1.3$', True),
|
||||
(".//div[@class='code-block-caption']",
|
||||
'^List 1.4 should be List 1.4$', True),
|
||||
],
|
||||
'bar.html': [
|
||||
(".//div[@class='figure']/p[@class='caption']",
|
||||
'^Fig.2.1 should be Fig.2.1$', True),
|
||||
(".//div[@class='figure']/p[@class='caption']",
|
||||
'^Fig.2.3 should be Fig.2.3$', True),
|
||||
(".//div[@class='figure']/p[@class='caption']",
|
||||
'^Fig.2.4 should be Fig.2.4$', True),
|
||||
(".//table/caption", '^Table 2.1 should be Table 2.1$', True),
|
||||
(".//table/caption", '^Table 2.3 should be Table 2.3$', True),
|
||||
(".//table/caption", '^Table 2.4 should be Table 2.4$', True),
|
||||
(".//div[@class='code-block-caption']",
|
||||
'^List 2.1 should be List 2.1$', True),
|
||||
(".//div[@class='code-block-caption']",
|
||||
'^List 2.3 should be List 2.3$', True),
|
||||
(".//div[@class='code-block-caption']",
|
||||
'^List 2.4 should be List 2.4$', True),
|
||||
],
|
||||
'baz.html': [
|
||||
(".//div[@class='figure']/p[@class='caption']",
|
||||
'^Fig.2.2 should be Fig.2.2$', True),
|
||||
(".//table/caption", '^Table 2.2 should be Table 2.2$', True),
|
||||
(".//div[@class='code-block-caption']",
|
||||
'^List 2.2 should be List 2.2$', True),
|
||||
],
|
||||
}
|
||||
|
||||
for fname, paths in iteritems(expects):
|
||||
parser = NslessParser()
|
||||
parser.entity.update(html_entities.entitydefs)
|
||||
fp = open(os.path.join(app.outdir, fname), 'rb')
|
||||
try:
|
||||
etree = ET.parse(fp, parser)
|
||||
finally:
|
||||
fp.close()
|
||||
|
||||
for xpath, check, be_found in paths:
|
||||
yield check_xpath, etree, fname, xpath, check, be_found
|
||||
|
||||
|
||||
@gen_with_app(buildername='html', testroot='numfig',
|
||||
confoverrides={'numfig': True, 'numfig_prefix': {'figure': 'Figure:', 'table': 'Tab_', 'code-block': 'Code-'}})
|
||||
def test_numfig_with_prefix(app, status, warning):
|
||||
app.builder.build_all()
|
||||
|
||||
expects = {
|
||||
'index.html': [
|
||||
(".//div[@class='figure']/p[@class='caption']",
|
||||
'^Figure:1 should be Fig.1$', True),
|
||||
(".//div[@class='figure']/p[@class='caption']",
|
||||
'^Figure:2 should be Fig.2$', True),
|
||||
(".//table/caption", '^Tab_1 should be Table 1$', True),
|
||||
(".//table/caption", '^Tab_2 should be Table 2$', True),
|
||||
(".//div[@class='code-block-caption']",
|
||||
'^Code-1 should be List 1$', True),
|
||||
(".//div[@class='code-block-caption']",
|
||||
'^Code-2 should be List 2$', True),
|
||||
],
|
||||
'foo.html': [
|
||||
(".//div[@class='figure']/p[@class='caption']",
|
||||
'^Figure:1.1 should be Fig.1.1$', True),
|
||||
(".//div[@class='figure']/p[@class='caption']",
|
||||
'^Figure:1.2 should be Fig.1.2$', True),
|
||||
(".//div[@class='figure']/p[@class='caption']",
|
||||
'^Figure:1.3 should be Fig.1.3$', True),
|
||||
(".//div[@class='figure']/p[@class='caption']",
|
||||
'^Figure:1.4 should be Fig.1.4$', True),
|
||||
(".//table/caption", '^Tab_1.1 should be Table 1.1$', True),
|
||||
(".//table/caption", '^Tab_1.2 should be Table 1.2$', True),
|
||||
(".//table/caption", '^Tab_1.3 should be Table 1.3$', True),
|
||||
(".//table/caption", '^Tab_1.4 should be Table 1.4$', True),
|
||||
(".//div[@class='code-block-caption']",
|
||||
'^Code-1.1 should be List 1.1$', True),
|
||||
(".//div[@class='code-block-caption']",
|
||||
'^Code-1.2 should be List 1.2$', True),
|
||||
(".//div[@class='code-block-caption']",
|
||||
'^Code-1.3 should be List 1.3$', True),
|
||||
(".//div[@class='code-block-caption']",
|
||||
'^Code-1.4 should be List 1.4$', True),
|
||||
],
|
||||
'bar.html': [
|
||||
(".//div[@class='figure']/p[@class='caption']",
|
||||
'^Figure:2.1 should be Fig.2.1$', True),
|
||||
(".//div[@class='figure']/p[@class='caption']",
|
||||
'^Figure:2.3 should be Fig.2.3$', True),
|
||||
(".//div[@class='figure']/p[@class='caption']",
|
||||
'^Figure:2.4 should be Fig.2.4$', True),
|
||||
(".//table/caption", '^Tab_2.1 should be Table 2.1$', True),
|
||||
(".//table/caption", '^Tab_2.3 should be Table 2.3$', True),
|
||||
(".//table/caption", '^Tab_2.4 should be Table 2.4$', True),
|
||||
(".//div[@class='code-block-caption']",
|
||||
'^Code-2.1 should be List 2.1$', True),
|
||||
(".//div[@class='code-block-caption']",
|
||||
'^Code-2.3 should be List 2.3$', True),
|
||||
(".//div[@class='code-block-caption']",
|
||||
'^Code-2.4 should be List 2.4$', True),
|
||||
],
|
||||
'baz.html': [
|
||||
(".//div[@class='figure']/p[@class='caption']",
|
||||
'^Figure:2.2 should be Fig.2.2$', True),
|
||||
(".//table/caption", '^Tab_2.2 should be Table 2.2$', True),
|
||||
(".//div[@class='code-block-caption']",
|
||||
'^Code-2.2 should be List 2.2$', True),
|
||||
],
|
||||
}
|
||||
|
||||
for fname, paths in iteritems(expects):
|
||||
parser = NslessParser()
|
||||
parser.entity.update(html_entities.entitydefs)
|
||||
fp = open(os.path.join(app.outdir, fname), 'rb')
|
||||
try:
|
||||
etree = ET.parse(fp, parser)
|
||||
finally:
|
||||
fp.close()
|
||||
|
||||
for xpath, check, be_found in paths:
|
||||
yield check_xpath, etree, fname, xpath, check, be_found
|
||||
|
||||
|
||||
@gen_with_app(buildername='html', testroot='numfig',
|
||||
confoverrides={'numfig': True, 'numfig_secnum_depth': 2})
|
||||
def test_numfig_with_secnum_depth(app, status, warning):
|
||||
app.builder.build_all()
|
||||
|
||||
expects = {
|
||||
'index.html': [
|
||||
(".//div[@class='figure']/p[@class='caption']",
|
||||
'^Fig.1 should be Fig.1$', True),
|
||||
(".//div[@class='figure']/p[@class='caption']",
|
||||
'^Fig.2 should be Fig.2$', True),
|
||||
(".//table/caption", '^Table 1 should be Table 1$', True),
|
||||
(".//table/caption", '^Table 2 should be Table 2$', True),
|
||||
(".//div[@class='code-block-caption']",
|
||||
'^List 1 should be List 1$', True),
|
||||
(".//div[@class='code-block-caption']",
|
||||
'^List 2 should be List 2$', True),
|
||||
],
|
||||
'foo.html': [
|
||||
(".//div[@class='figure']/p[@class='caption']",
|
||||
'^Fig.1.1 should be Fig.1.1$', True),
|
||||
(".//div[@class='figure']/p[@class='caption']",
|
||||
'^Fig.1.1.1 should be Fig.1.2$', True),
|
||||
(".//div[@class='figure']/p[@class='caption']",
|
||||
'^Fig.1.1.2 should be Fig.1.3$', True),
|
||||
(".//div[@class='figure']/p[@class='caption']",
|
||||
'^Fig.1.2.1 should be Fig.1.4$', True),
|
||||
(".//table/caption", '^Table 1.1 should be Table 1.1$', True),
|
||||
(".//table/caption", '^Table 1.1.1 should be Table 1.2$', True),
|
||||
(".//table/caption", '^Table 1.1.2 should be Table 1.3$', True),
|
||||
(".//table/caption", '^Table 1.2.1 should be Table 1.4$', True),
|
||||
(".//div[@class='code-block-caption']",
|
||||
'^List 1.1 should be List 1.1$', True),
|
||||
(".//div[@class='code-block-caption']",
|
||||
'^List 1.1.1 should be List 1.2$', True),
|
||||
(".//div[@class='code-block-caption']",
|
||||
'^List 1.1.2 should be List 1.3$', True),
|
||||
(".//div[@class='code-block-caption']",
|
||||
'^List 1.2.1 should be List 1.4$', True),
|
||||
],
|
||||
'bar.html': [
|
||||
(".//div[@class='figure']/p[@class='caption']",
|
||||
'^Fig.2.1.1 should be Fig.2.1$', True),
|
||||
(".//div[@class='figure']/p[@class='caption']",
|
||||
'^Fig.2.1.3 should be Fig.2.3$', True),
|
||||
(".//div[@class='figure']/p[@class='caption']",
|
||||
'^Fig.2.2.1 should be Fig.2.4$', True),
|
||||
(".//table/caption", '^Table 2.1.1 should be Table 2.1$', True),
|
||||
(".//table/caption", '^Table 2.1.3 should be Table 2.3$', True),
|
||||
(".//table/caption", '^Table 2.2.1 should be Table 2.4$', True),
|
||||
(".//div[@class='code-block-caption']",
|
||||
'^List 2.1.1 should be List 2.1$', True),
|
||||
(".//div[@class='code-block-caption']",
|
||||
'^List 2.1.3 should be List 2.3$', True),
|
||||
(".//div[@class='code-block-caption']",
|
||||
'^List 2.2.1 should be List 2.4$', True),
|
||||
],
|
||||
'baz.html': [
|
||||
(".//div[@class='figure']/p[@class='caption']",
|
||||
'^Fig.2.1.2 should be Fig.2.2$', True),
|
||||
(".//table/caption", '^Table 2.1.2 should be Table 2.2$', True),
|
||||
(".//div[@class='code-block-caption']",
|
||||
'^List 2.1.2 should be List 2.2$', True),
|
||||
],
|
||||
}
|
||||
|
||||
for fname, paths in iteritems(expects):
|
||||
parser = NslessParser()
|
||||
parser.entity.update(html_entities.entitydefs)
|
||||
fp = open(os.path.join(app.outdir, fname), 'rb')
|
||||
try:
|
||||
etree = ET.parse(fp, parser)
|
||||
finally:
|
||||
fp.close()
|
||||
|
||||
for xpath, check, be_found in paths:
|
||||
yield check_xpath, etree, fname, xpath, check, be_found
|
||||
|
@ -91,3 +91,10 @@ def test_latex(app, status, warning):
|
||||
assert False, 'latex exited with return code %s' % p.returncode
|
||||
finally:
|
||||
os.chdir(cwd)
|
||||
|
||||
|
||||
@with_app(buildername='latex')
|
||||
def test_latex_add_latex_package(app, status, warning):
|
||||
app.add_latex_package('foo')
|
||||
app.builder.build_all()
|
||||
assert '\\usepackage{foo}' in (app.outdir / 'SphinxTests.tex').text()
|
||||
|
Loading…
Reference in New Issue
Block a user