mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
birkenfeld/sphinx を default にマージしました。
This commit is contained in:
commit
54ebc5e17a
11
CHANGES
11
CHANGES
@ -20,6 +20,8 @@ Incompatible changes
|
||||
templates directory.
|
||||
* Custom domains should implement the new `Domain.resolve_any_xref`
|
||||
method to make the `any` role work properly.
|
||||
* gettext builder: disable extracting/apply 'index' node by default. Please set
|
||||
'index' to :confval:`gettext_enables` to enable extracting index entries.
|
||||
|
||||
Features added
|
||||
--------------
|
||||
@ -44,6 +46,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 +87,10 @@ 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.
|
||||
* #1344: add :confval:`gettext_enables` to enable extracting 'index' to gettext
|
||||
catalog output / applying translation catalog to generated documentation.
|
||||
|
||||
Bugs fixed
|
||||
----------
|
||||
@ -147,6 +155,9 @@ Bugs fixed
|
||||
to avoid separation of caption and body. Thanks to Takeshi Komiya.
|
||||
* PR#295, #1520: ``make.bat latexpdf`` mechanism to ``cd`` back to the current
|
||||
directory. Thanks to Peter Suter.
|
||||
* PR#297, #1571: Add imgpath property to all builders. It make easier to
|
||||
develop builder extensions. Thanks to Takeshi Komiya.
|
||||
* #1584: Point to master doc in HTML "top" link.
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
|
@ -447,6 +447,16 @@ documentation on :ref:`intl` for details.
|
||||
|
||||
.. versionadded:: 1.3
|
||||
|
||||
.. confval:: gettext_enables
|
||||
|
||||
To specify names to enable gettext extracting and translation applying for
|
||||
i18n. You can specify below names:
|
||||
|
||||
:index: index terms
|
||||
|
||||
The default is ``[]``.
|
||||
|
||||
.. versionadded:: 1.3
|
||||
|
||||
.. _html-options:
|
||||
|
||||
|
@ -288,6 +288,18 @@ package.
|
||||
|
||||
.. versionadded:: 1.0
|
||||
|
||||
.. method:: Sphinx.add_latex_package(packagename, options=None)
|
||||
|
||||
Add *packagename* to the list of packages that LaTeX source code will include.
|
||||
If you provide *options*, it will be taken to `\usepackage` declaration.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
app.add_latex_package('mypackage') # => \usepackage{mypackage}
|
||||
app.add_latex_package('mypackage', 'foo,bar') # => \usepackage[foo,bar]{mypackage}
|
||||
|
||||
.. 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, options=None):
|
||||
self.debug('[app] adding latex package: %r', packagename)
|
||||
from sphinx.builders.latex import LaTeXBuilder
|
||||
LaTeXBuilder.usepackages.append((packagename, options))
|
||||
|
||||
def add_lexer(self, alias, lexer):
|
||||
self.debug('[app] adding lexer: %r', (alias, lexer))
|
||||
from sphinx.highlighting import lexers
|
||||
|
@ -70,6 +70,10 @@ class Builder(object):
|
||||
|
||||
# images that need to be copied over (source -> dest)
|
||||
self.images = {}
|
||||
# basename of images directory
|
||||
self.imagedir = ""
|
||||
# relative path to image directory from current docname (used at writing docs)
|
||||
self.imgpath = ""
|
||||
|
||||
# these get set later
|
||||
self.parallel_ok = False
|
||||
|
@ -404,7 +404,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
||||
The method tries to read and write the files with the PIL,
|
||||
converting the format and resizing the image if necessary/possible.
|
||||
"""
|
||||
ensuredir(path.join(self.outdir, '_images'))
|
||||
ensuredir(path.join(self.outdir, self.imagedir))
|
||||
for src in self.app.status_iterator(self.images, 'copying images... ',
|
||||
brown, len(self.images)):
|
||||
dest = self.images[src]
|
||||
@ -416,7 +416,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
||||
(path.join(self.srcdir, src), ))
|
||||
try:
|
||||
copyfile(path.join(self.srcdir, src),
|
||||
path.join(self.outdir, '_images', dest))
|
||||
path.join(self.outdir, self.imagedir, dest))
|
||||
except (IOError, OSError) as err:
|
||||
self.warn('cannot copy image file %r: %s' %
|
||||
(path.join(self.srcdir, src), err))
|
||||
@ -432,7 +432,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
||||
nh = (height * nw) / width
|
||||
img = img.resize((nw, nh), Image.BICUBIC)
|
||||
try:
|
||||
img.save(path.join(self.outdir, '_images', dest))
|
||||
img.save(path.join(self.outdir, self.imagedir, dest))
|
||||
except (IOError, OSError) as err:
|
||||
self.warn('cannot write image file %r: %s' %
|
||||
(path.join(self.srcdir, src), err))
|
||||
|
@ -108,15 +108,16 @@ class I18nBuilder(Builder):
|
||||
for node, msg in extract_messages(doctree):
|
||||
catalog.add(msg, node)
|
||||
|
||||
# Extract translatable messages from index entries.
|
||||
for node, entries in traverse_translatable_index(doctree):
|
||||
for typ, msg, tid, main in entries:
|
||||
for m in split_index_msg(typ, msg):
|
||||
if typ == 'pair' and m in pairindextypes.values():
|
||||
# avoid built-in translated message was incorporated
|
||||
# in 'sphinx.util.nodes.process_index_entry'
|
||||
continue
|
||||
catalog.add(m, node)
|
||||
if 'index' in self.env.config.gettext_enables:
|
||||
# Extract translatable messages from index entries.
|
||||
for node, entries in traverse_translatable_index(doctree):
|
||||
for typ, msg, tid, main in entries:
|
||||
for m in split_index_msg(typ, msg):
|
||||
if typ == 'pair' and m in pairindextypes.values():
|
||||
# avoid built-in translated message was incorporated
|
||||
# in 'sphinx.util.nodes.process_index_entry'
|
||||
continue
|
||||
catalog.add(m, node)
|
||||
|
||||
|
||||
# determine tzoffset once to remain unaffected by DST change during build
|
||||
|
@ -95,6 +95,8 @@ class StandaloneHTMLBuilder(Builder):
|
||||
# a hash of all config values that, if changed, cause a full rebuild
|
||||
self.config_hash = ''
|
||||
self.tags_hash = ''
|
||||
# basename of images directory
|
||||
self.imagedir = '_images'
|
||||
# section numbers for headings in the currently visited document
|
||||
self.secnumbers = {}
|
||||
# currently written docname
|
||||
@ -424,6 +426,7 @@ class StandaloneHTMLBuilder(Builder):
|
||||
doctree.settings = self.docsettings
|
||||
|
||||
self.secnumbers = self.env.toc_secnumbers.get(docname, {})
|
||||
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
|
||||
@ -436,7 +439,7 @@ class StandaloneHTMLBuilder(Builder):
|
||||
self.handle_page(docname, ctx, event_arg=doctree)
|
||||
|
||||
def write_doc_serialized(self, docname, doctree):
|
||||
self.imgpath = relative_uri(self.get_target_uri(docname), '_images')
|
||||
self.imgpath = relative_uri(self.get_target_uri(docname), self.imagedir)
|
||||
self.post_process_images(doctree)
|
||||
title = self.env.longtitles.get(docname)
|
||||
title = title and self.render_partial(title)['title'] or ''
|
||||
@ -534,13 +537,13 @@ class StandaloneHTMLBuilder(Builder):
|
||||
def copy_image_files(self):
|
||||
# copy image files
|
||||
if self.images:
|
||||
ensuredir(path.join(self.outdir, '_images'))
|
||||
ensuredir(path.join(self.outdir, self.imagedir))
|
||||
for src in self.app.status_iterator(self.images, 'copying images... ',
|
||||
brown, len(self.images)):
|
||||
dest = self.images[src]
|
||||
try:
|
||||
copyfile(path.join(self.srcdir, src),
|
||||
path.join(self.outdir, '_images', dest))
|
||||
path.join(self.outdir, self.imagedir, dest))
|
||||
except Exception as err:
|
||||
self.warn('cannot copy image file %r: %s' %
|
||||
(path.join(self.srcdir, src), err))
|
||||
@ -1028,6 +1031,7 @@ class SerializingHTMLBuilder(StandaloneHTMLBuilder):
|
||||
def init(self):
|
||||
self.config_hash = ''
|
||||
self.tags_hash = ''
|
||||
self.imagedir = '_images'
|
||||
self.theme = None # no theme necessary
|
||||
self.templates = None # no template bridge necessary
|
||||
self.init_translator_class()
|
||||
|
@ -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 = []
|
||||
|
@ -157,7 +157,7 @@ class QtHelpBuilder(StandaloneHTMLBuilder):
|
||||
olen = len(outdir)
|
||||
projectfiles = []
|
||||
staticdir = path.join(outdir, '_static')
|
||||
imagesdir = path.join(outdir, '_images')
|
||||
imagesdir = path.join(outdir, self.imagedir)
|
||||
for root, dirs, files in os.walk(outdir):
|
||||
resourcedir = root.startswith(staticdir) or \
|
||||
root.startswith(imagesdir)
|
||||
|
@ -58,7 +58,8 @@ class WebSupportBuilder(PickleHTMLBuilder):
|
||||
doctree.settings = self.docsettings
|
||||
|
||||
self.secnumbers = self.env.toc_secnumbers.get(docname, {})
|
||||
self.imgpath = '/' + posixpath.join(self.virtual_staticdir, '_images')
|
||||
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
|
||||
self.docwriter.write(doctree, destination)
|
||||
@ -70,7 +71,7 @@ class WebSupportBuilder(PickleHTMLBuilder):
|
||||
self.handle_page(docname, ctx, event_arg=doctree)
|
||||
|
||||
def write_doc_serialized(self, docname, doctree):
|
||||
self.imgpath = '/' + posixpath.join(self.virtual_staticdir, '_images')
|
||||
self.imgpath = '/' + posixpath.join(self.virtual_staticdir, self.imagedir)
|
||||
self.post_process_images(doctree)
|
||||
title = self.env.longtitles.get(docname)
|
||||
title = title and self.render_partial(title)['title'] or ''
|
||||
@ -148,7 +149,7 @@ class WebSupportBuilder(PickleHTMLBuilder):
|
||||
PickleHTMLBuilder.handle_finish(self)
|
||||
|
||||
# move static stuff over to separate directory
|
||||
directories = ['_images', '_static']
|
||||
directories = [self.imagedir, '_static']
|
||||
for directory in directories:
|
||||
src = path.join(self.outdir, directory)
|
||||
dst = path.join(self.staticdir, directory)
|
||||
|
@ -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'),
|
||||
@ -205,6 +211,7 @@ class Config(object):
|
||||
gettext_location = (True, 'gettext'),
|
||||
gettext_uuid = (True, 'gettext'),
|
||||
gettext_auto_build = (True, 'env'),
|
||||
gettext_enables = ([], 'env'),
|
||||
|
||||
# XML options
|
||||
xml_pretty = (True, 'env'),
|
||||
|
@ -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."""
|
||||
|
@ -146,14 +146,8 @@ def render_dot(self, code, options, format, prefix='graphviz'):
|
||||
).encode('utf-8')
|
||||
|
||||
fname = '%s-%s.%s' % (prefix, sha1(hashkey).hexdigest(), format)
|
||||
if hasattr(self.builder, 'imgpath'):
|
||||
# HTML
|
||||
relfn = posixpath.join(self.builder.imgpath, fname)
|
||||
outfn = path.join(self.builder.outdir, '_images', fname)
|
||||
else:
|
||||
# LaTeX
|
||||
relfn = fname
|
||||
outfn = path.join(self.builder.outdir, fname)
|
||||
relfn = posixpath.join(self.builder.imgpath, fname)
|
||||
outfn = path.join(self.builder.outdir, self.builder.imagedir, fname)
|
||||
|
||||
if path.isfile(outfn):
|
||||
return relfn, outfn
|
||||
|
@ -86,7 +86,7 @@ def render_math(self, math):
|
||||
|
||||
shasum = "%s.png" % sha1(latex.encode('utf-8')).hexdigest()
|
||||
relfn = posixpath.join(self.builder.imgpath, 'math', shasum)
|
||||
outfn = path.join(self.builder.outdir, '_images', 'math', shasum)
|
||||
outfn = path.join(self.builder.outdir, self.builder.imagedir, 'math', shasum)
|
||||
if path.isfile(outfn):
|
||||
depth = read_png_depth(outfn)
|
||||
return relfn, depth
|
||||
|
@ -139,7 +139,7 @@
|
||||
{%- if hasdoc('copyright') %}
|
||||
<link rel="copyright" title="{{ _('Copyright') }}" href="{{ pathto('copyright') }}" />
|
||||
{%- endif %}
|
||||
<link rel="top" title="{{ docstitle|e }}" href="{{ pathto('index') }}" />
|
||||
<link rel="top" title="{{ docstitle|e }}" href="{{ pathto(master_doc) }}" />
|
||||
{%- if parents %}
|
||||
<link rel="up" title="{{ parents[-1].title|striptags|e }}" href="{{ parents[-1].link|e }}" />
|
||||
{%- endif %}
|
||||
|
@ -244,13 +244,13 @@ cite, code, tt {
|
||||
letter-spacing: 0.01em;
|
||||
}
|
||||
|
||||
tt {
|
||||
code {
|
||||
background-color: #F2F2F2;
|
||||
border-bottom: 1px solid #ddd;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
tt.descname, tt.descclassname, tt.xref {
|
||||
code.descname, code.descclassname, code.xref {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
@ -259,12 +259,12 @@ hr {
|
||||
margin: 2em;
|
||||
}
|
||||
|
||||
a tt {
|
||||
a code {
|
||||
border: 0;
|
||||
color: #CA7900;
|
||||
}
|
||||
|
||||
a tt:hover {
|
||||
a code:hover {
|
||||
color: #2491CF;
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
@ -437,22 +462,23 @@ class Locale(Transform):
|
||||
node.children = patch.children
|
||||
node['translated'] = True
|
||||
|
||||
# Extract and translate messages for index entries.
|
||||
for node, entries in traverse_translatable_index(self.document):
|
||||
new_entries = []
|
||||
for type, msg, tid, main in entries:
|
||||
msg_parts = split_index_msg(type, msg)
|
||||
msgstr_parts = []
|
||||
for part in msg_parts:
|
||||
msgstr = catalog.gettext(part)
|
||||
if not msgstr:
|
||||
msgstr = part
|
||||
msgstr_parts.append(msgstr)
|
||||
if 'index' in env.config.gettext_enables:
|
||||
# Extract and translate messages for index entries.
|
||||
for node, entries in traverse_translatable_index(self.document):
|
||||
new_entries = []
|
||||
for type, msg, tid, main in entries:
|
||||
msg_parts = split_index_msg(type, msg)
|
||||
msgstr_parts = []
|
||||
for part in msg_parts:
|
||||
msgstr = catalog.gettext(part)
|
||||
if not msgstr:
|
||||
msgstr = part
|
||||
msgstr_parts.append(msgstr)
|
||||
|
||||
new_entries.append((type, ';'.join(msgstr_parts), tid, main))
|
||||
new_entries.append((type, ';'.join(msgstr_parts), tid, main))
|
||||
|
||||
node['raw_entries'] = entries
|
||||
node['entries'] = new_entries
|
||||
node['raw_entries'] = entries
|
||||
node['entries'] = new_entries
|
||||
|
||||
|
||||
class RemoveTranslatableInline(Transform):
|
||||
|
@ -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,14 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
||||
self.elements['fncychap'] = ''
|
||||
else:
|
||||
self.elements['classoptions'] += ',english'
|
||||
if getattr(builder, 'usepackages', None):
|
||||
def declare_package(packagename, options=None):
|
||||
if options:
|
||||
return '\\usepackage[%s]{%s}' % (options, packagename)
|
||||
else:
|
||||
return '\\usepackage{%s}' % (packagename,)
|
||||
usepackages = (declare_package(*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']:
|
||||
|
@ -6,3 +6,4 @@ keep_warnings = True
|
||||
templates_path = ['_templates']
|
||||
html_additional_pages = {'index': 'index.html'}
|
||||
release = version = '2013.120'
|
||||
gettext_enables = ['index']
|
||||
|
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 |
@ -113,6 +113,38 @@ def test_gettext_index_entries(app, status, warning):
|
||||
"Exception",
|
||||
"Statement",
|
||||
"Builtin",
|
||||
]
|
||||
for expect in expected_msgids:
|
||||
assert expect in msgids
|
||||
msgids.remove(expect)
|
||||
|
||||
# unexpected msgid existent
|
||||
assert msgids == []
|
||||
|
||||
|
||||
@with_app('gettext', testroot='intl',
|
||||
confoverrides={'gettext_compact': False, 'gettext_enables': []})
|
||||
def test_gettext_disable_index_entries(app, status, warning):
|
||||
# regression test for #976
|
||||
app.builder.build(['index_entries'])
|
||||
|
||||
_msgid_getter = re.compile(r'msgid "(.*)"').search
|
||||
|
||||
def msgid_getter(msgid):
|
||||
m = _msgid_getter(msgid)
|
||||
if m:
|
||||
return m.groups()[0]
|
||||
return None
|
||||
|
||||
pot = (app.outdir / 'index_entries.pot').text(encoding='utf-8')
|
||||
msgids = [_f for _f in map(msgid_getter, pot.splitlines()) if _f]
|
||||
|
||||
expected_msgids = [
|
||||
"i18n with index entries",
|
||||
"index target section",
|
||||
"this is :index:`Newsletter` target paragraph.",
|
||||
"various index entries",
|
||||
"That's all.",
|
||||
]
|
||||
for expect in expected_msgids:
|
||||
assert expect in msgids
|
||||
|
@ -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,13 @@ 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.add_latex_package('bar', 'baz')
|
||||
app.builder.build_all()
|
||||
result = (app.outdir / 'SphinxTests.tex').text(encoding='utf8')
|
||||
assert '\\usepackage{foo}' in result
|
||||
assert '\\usepackage[baz]{bar}' in result
|
||||
|
Loading…
Reference in New Issue
Block a user