mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Merge branch '2.0' into 6798_autosummary_emits_skip_member_event
This commit is contained in:
13
CHANGES
13
CHANGES
@@ -18,6 +18,8 @@ Deprecated
|
|||||||
* ``sphinx.builders.gettext.POHEADER``
|
* ``sphinx.builders.gettext.POHEADER``
|
||||||
* ``sphinx.io.SphinxStandaloneReader.app``
|
* ``sphinx.io.SphinxStandaloneReader.app``
|
||||||
* ``sphinx.io.SphinxStandaloneReader.env``
|
* ``sphinx.io.SphinxStandaloneReader.env``
|
||||||
|
* ``sphinx.util.texescape.tex_escape_map``
|
||||||
|
* ``sphinx.util.texescape.tex_hl_escape_map_new``
|
||||||
|
|
||||||
Features added
|
Features added
|
||||||
--------------
|
--------------
|
||||||
@@ -31,9 +33,12 @@ Features added
|
|||||||
* #1331: Add new config variable: :confval:`user_agent`
|
* #1331: Add new config variable: :confval:`user_agent`
|
||||||
* #6000: LaTeX: have backslash also be an inline literal word wrap break
|
* #6000: LaTeX: have backslash also be an inline literal word wrap break
|
||||||
character
|
character
|
||||||
|
* #4186: LaTeX: Support upLaTeX as a new :confval:`latex_engine` (experimental)
|
||||||
* #6812: Improve a warning message when extensions are not parallel safe
|
* #6812: Improve a warning message when extensions are not parallel safe
|
||||||
* #6818: Improve Intersphinx performance for multiple remote inventories.
|
* #6818: Improve Intersphinx performance for multiple remote inventories.
|
||||||
|
* #2546: apidoc: .so file support
|
||||||
* #6798: autosummary: emit ``autodoc-skip-member`` event on generating stub file
|
* #6798: autosummary: emit ``autodoc-skip-member`` event on generating stub file
|
||||||
|
* #6483: i18n: make explicit titles in toctree translatable
|
||||||
|
|
||||||
Bugs fixed
|
Bugs fixed
|
||||||
----------
|
----------
|
||||||
@@ -44,8 +49,10 @@ Bugs fixed
|
|||||||
.. _latex3/latex2e#173: https://github.com/latex3/latex2e/issues/173
|
.. _latex3/latex2e#173: https://github.com/latex3/latex2e/issues/173
|
||||||
* #6618: LaTeX: Avoid section names at the end of a page
|
* #6618: LaTeX: Avoid section names at the end of a page
|
||||||
* #6738: LaTeX: Do not replace unicode characters by LaTeX macros on unicode
|
* #6738: LaTeX: Do not replace unicode characters by LaTeX macros on unicode
|
||||||
supported LaTeX engines
|
supported LaTeX engines: ¶, §, €, ∞, ±, →, ‣, –, superscript and subscript
|
||||||
|
digits go through "as is" (as default OpenType font supports them)
|
||||||
* #6704: linkcheck: Be defensive and handle newly defined HTTP error code
|
* #6704: linkcheck: Be defensive and handle newly defined HTTP error code
|
||||||
|
* #6806: linkcheck: Failure on parsing content
|
||||||
* #6655: image URLs containing ``data:`` causes gettext builder crashed
|
* #6655: image URLs containing ``data:`` causes gettext builder crashed
|
||||||
* #6584: i18n: Error when compiling message catalogs on Hindi
|
* #6584: i18n: Error when compiling message catalogs on Hindi
|
||||||
* #6718: i18n: KeyError is raised if section title and table title are same
|
* #6718: i18n: KeyError is raised if section title and table title are same
|
||||||
@@ -60,6 +67,10 @@ Bugs fixed
|
|||||||
code-block long enough not to fit on one page
|
code-block long enough not to fit on one page
|
||||||
* #6809: LaTeX: code-block in a danger type admonition can easily spill over
|
* #6809: LaTeX: code-block in a danger type admonition can easily spill over
|
||||||
bottom of page
|
bottom of page
|
||||||
|
* #6793: texinfo: Code examples broken following "sidebar"
|
||||||
|
* #6813: An orphan warning is emitted for included document on Windows. Thanks
|
||||||
|
to @drillan
|
||||||
|
* #6850: Fix smartypants module calls re.sub() with wrong options
|
||||||
|
|
||||||
Testing
|
Testing
|
||||||
--------
|
--------
|
||||||
|
|||||||
@@ -41,6 +41,16 @@ The following is a list of deprecated interfaces.
|
|||||||
- 4.0
|
- 4.0
|
||||||
- ``sphinx.io.SphinxStandaloneReader.setup()``
|
- ``sphinx.io.SphinxStandaloneReader.setup()``
|
||||||
|
|
||||||
|
* - ``sphinx.util.texescape.tex_escape_map``
|
||||||
|
- 2.3
|
||||||
|
- 4.0
|
||||||
|
- ``sphinx.util.texescape.escape()``
|
||||||
|
|
||||||
|
* - ``sphinx.util.texescape.tex_hl_escape_map_new``
|
||||||
|
- 2.3
|
||||||
|
- 4.0
|
||||||
|
- ``sphinx.util.texescape.hlescape()``
|
||||||
|
|
||||||
* - ``sphinx.domains.math.MathDomain.add_equation()``
|
* - ``sphinx.domains.math.MathDomain.add_equation()``
|
||||||
- 2.2
|
- 2.2
|
||||||
- 4.0
|
- 4.0
|
||||||
|
|||||||
@@ -1836,6 +1836,7 @@ These options influence LaTeX output.
|
|||||||
* ``'xelatex'`` -- XeLaTeX
|
* ``'xelatex'`` -- XeLaTeX
|
||||||
* ``'lualatex'`` -- LuaLaTeX
|
* ``'lualatex'`` -- LuaLaTeX
|
||||||
* ``'platex'`` -- pLaTeX (default if :confval:`language` is ``'ja'``)
|
* ``'platex'`` -- pLaTeX (default if :confval:`language` is ``'ja'``)
|
||||||
|
* ``'uplatex'`` -- upLaTeX (experimental)
|
||||||
|
|
||||||
``'pdflatex'``\ 's support for Unicode characters is limited.
|
``'pdflatex'``\ 's support for Unicode characters is limited.
|
||||||
|
|
||||||
@@ -1861,6 +1862,10 @@ These options influence LaTeX output.
|
|||||||
|
|
||||||
Use ``xelatex`` by default for Greek documents.
|
Use ``xelatex`` by default for Greek documents.
|
||||||
|
|
||||||
|
.. versionchanged:: 2.3
|
||||||
|
|
||||||
|
Add ``uplatex`` support.
|
||||||
|
|
||||||
Contrarily to :ref:`MathJaX math rendering in HTML output <math-support>`,
|
Contrarily to :ref:`MathJaX math rendering in HTML output <math-support>`,
|
||||||
LaTeX requires some extra configuration to support Unicode literals in
|
LaTeX requires some extra configuration to support Unicode literals in
|
||||||
:rst:dir:`math`: the only comprehensive solution (as far as we know) is to
|
:rst:dir:`math`: the only comprehensive solution (as far as we know) is to
|
||||||
|
|||||||
@@ -63,20 +63,38 @@ class toctree(nodes.General, nodes.Element, translatable):
|
|||||||
|
|
||||||
def preserve_original_messages(self):
|
def preserve_original_messages(self):
|
||||||
# type: () -> None
|
# type: () -> None
|
||||||
|
# toctree entries
|
||||||
|
rawentries = self.setdefault('rawentries', [])
|
||||||
|
for title, docname in self['entries']:
|
||||||
|
if title:
|
||||||
|
rawentries.append(title)
|
||||||
|
|
||||||
|
# :caption: option
|
||||||
if self.get('caption'):
|
if self.get('caption'):
|
||||||
self['rawcaption'] = self['caption']
|
self['rawcaption'] = self['caption']
|
||||||
|
|
||||||
def apply_translated_message(self, original_message, translated_message):
|
def apply_translated_message(self, original_message, translated_message):
|
||||||
# type: (str, str) -> None
|
# type: (str, str) -> None
|
||||||
|
# toctree entries
|
||||||
|
for i, (title, docname) in enumerate(self['entries']):
|
||||||
|
if title == original_message:
|
||||||
|
self['entries'][i] = (translated_message, docname)
|
||||||
|
|
||||||
|
# :caption: option
|
||||||
if self.get('rawcaption') == original_message:
|
if self.get('rawcaption') == original_message:
|
||||||
self['caption'] = translated_message
|
self['caption'] = translated_message
|
||||||
|
|
||||||
def extract_original_messages(self):
|
def extract_original_messages(self):
|
||||||
# type: () -> List[str]
|
# type: () -> List[str]
|
||||||
|
messages = [] # type: List[str]
|
||||||
|
|
||||||
|
# toctree entries
|
||||||
|
messages.extend(self.get('rawentries', []))
|
||||||
|
|
||||||
|
# :caption: option
|
||||||
if 'rawcaption' in self:
|
if 'rawcaption' in self:
|
||||||
return [self['rawcaption']]
|
messages.append(self['rawcaption'])
|
||||||
else:
|
return messages
|
||||||
return []
|
|
||||||
|
|
||||||
|
|
||||||
# domain-specific object descriptions (class, function etc.)
|
# domain-specific object descriptions (class, function etc.)
|
||||||
|
|||||||
@@ -427,8 +427,12 @@ def default_latex_engine(config: Config) -> str:
|
|||||||
def default_latex_docclass(config: Config) -> Dict[str, str]:
|
def default_latex_docclass(config: Config) -> Dict[str, str]:
|
||||||
""" Better default latex_docclass settings for specific languages. """
|
""" Better default latex_docclass settings for specific languages. """
|
||||||
if config.language == 'ja':
|
if config.language == 'ja':
|
||||||
return {'manual': 'jsbook',
|
if config.latex_engine == 'uplatex':
|
||||||
'howto': 'jreport'}
|
return {'manual': 'ujbook',
|
||||||
|
'howto': 'ujreport'}
|
||||||
|
else:
|
||||||
|
return {'manual': 'jsbook',
|
||||||
|
'howto': 'jreport'}
|
||||||
else:
|
else:
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
@@ -440,10 +444,12 @@ def default_latex_use_xindy(config: Config) -> bool:
|
|||||||
|
|
||||||
def default_latex_documents(config: Config) -> List[Tuple[str, str, str, str, str]]:
|
def default_latex_documents(config: Config) -> List[Tuple[str, str, str, str, str]]:
|
||||||
""" Better default latex_documents settings. """
|
""" Better default latex_documents settings. """
|
||||||
|
project = texescape.escape(config.project, config.latex_engine)
|
||||||
|
author = texescape.escape(config.author, config.latex_engine)
|
||||||
return [(config.master_doc,
|
return [(config.master_doc,
|
||||||
make_filename_from_project(config.project) + '.tex',
|
make_filename_from_project(config.project) + '.tex',
|
||||||
texescape.escape_abbr(texescape.escape(config.project)),
|
texescape.escape_abbr(project),
|
||||||
texescape.escape_abbr(texescape.escape(config.author)),
|
texescape.escape_abbr(author),
|
||||||
'manual')]
|
'manual')]
|
||||||
|
|
||||||
|
|
||||||
@@ -454,7 +460,7 @@ def setup(app: Sphinx) -> Dict[str, Any]:
|
|||||||
app.connect('config-inited', validate_config_values)
|
app.connect('config-inited', validate_config_values)
|
||||||
|
|
||||||
app.add_config_value('latex_engine', default_latex_engine, None,
|
app.add_config_value('latex_engine', default_latex_engine, None,
|
||||||
ENUM('pdflatex', 'xelatex', 'lualatex', 'platex'))
|
ENUM('pdflatex', 'xelatex', 'lualatex', 'platex', 'uplatex'))
|
||||||
app.add_config_value('latex_documents', default_latex_documents, None)
|
app.add_config_value('latex_documents', default_latex_documents, None)
|
||||||
app.add_config_value('latex_logo', None, None, [str])
|
app.add_config_value('latex_logo', None, None, [str])
|
||||||
app.add_config_value('latex_appendices', [], None)
|
app.add_config_value('latex_appendices', [], None)
|
||||||
|
|||||||
@@ -59,6 +59,9 @@ def check_anchor(response: requests.requests.Response, anchor: str) -> bool:
|
|||||||
# Read file in chunks. If we find a matching anchor, we break
|
# Read file in chunks. If we find a matching anchor, we break
|
||||||
# the loop early in hopes not to have to download the whole thing.
|
# the loop early in hopes not to have to download the whole thing.
|
||||||
for chunk in response.iter_content(chunk_size=4096, decode_unicode=True):
|
for chunk in response.iter_content(chunk_size=4096, decode_unicode=True):
|
||||||
|
if isinstance(chunk, bytes): # requests failed to decode
|
||||||
|
chunk = chunk.decode() # manually try to decode it
|
||||||
|
|
||||||
parser.feed(chunk)
|
parser.feed(chunk)
|
||||||
if parser.found:
|
if parser.found:
|
||||||
break
|
break
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import os
|
|||||||
import sys
|
import sys
|
||||||
import warnings
|
import warnings
|
||||||
from fnmatch import fnmatch
|
from fnmatch import fnmatch
|
||||||
|
from importlib.machinery import EXTENSION_SUFFIXES
|
||||||
from os import path
|
from os import path
|
||||||
from typing import Any, List, Tuple
|
from typing import Any, List, Tuple
|
||||||
|
|
||||||
@@ -45,7 +46,7 @@ else:
|
|||||||
]
|
]
|
||||||
|
|
||||||
INITPY = '__init__.py'
|
INITPY = '__init__.py'
|
||||||
PY_SUFFIXES = {'.py', '.pyx'}
|
PY_SUFFIXES = ('.py', '.pyx') + tuple(EXTENSION_SUFFIXES)
|
||||||
|
|
||||||
template_dir = path.join(package_dir, 'templates', 'apidoc')
|
template_dir = path.join(package_dir, 'templates', 'apidoc')
|
||||||
|
|
||||||
@@ -232,7 +233,7 @@ def recurse_tree(rootpath: str, excludes: List[str], opts: Any,
|
|||||||
for root, subs, files in os.walk(rootpath, followlinks=followlinks):
|
for root, subs, files in os.walk(rootpath, followlinks=followlinks):
|
||||||
# document only Python module files (that aren't excluded)
|
# document only Python module files (that aren't excluded)
|
||||||
py_files = sorted(f for f in files
|
py_files = sorted(f for f in files
|
||||||
if path.splitext(f)[1] in PY_SUFFIXES and
|
if f.endswith(PY_SUFFIXES) and
|
||||||
not is_excluded(path.join(root, f), excludes))
|
not is_excluded(path.join(root, f), excludes))
|
||||||
is_pkg = INITPY in py_files
|
is_pkg = INITPY in py_files
|
||||||
is_namespace = INITPY not in py_files and implicit_namespaces
|
is_namespace = INITPY not in py_files and implicit_namespaces
|
||||||
@@ -270,7 +271,7 @@ def recurse_tree(rootpath: str, excludes: List[str], opts: Any,
|
|||||||
assert root == rootpath and root_package is None
|
assert root == rootpath and root_package is None
|
||||||
for py_file in py_files:
|
for py_file in py_files:
|
||||||
if not is_skipped_module(path.join(rootpath, py_file), opts, excludes):
|
if not is_skipped_module(path.join(rootpath, py_file), opts, excludes):
|
||||||
module = path.splitext(py_file)[0]
|
module = py_file.split('.')[0]
|
||||||
create_module_file(root_package, module, opts, user_template_dir)
|
create_module_file(root_package, module, opts, user_template_dir)
|
||||||
toplevels.append(module)
|
toplevels.append(module)
|
||||||
|
|
||||||
|
|||||||
@@ -27,10 +27,9 @@ from sphinx.domains import Domain
|
|||||||
from sphinx.environment import BuildEnvironment
|
from sphinx.environment import BuildEnvironment
|
||||||
from sphinx.errors import NoUri
|
from sphinx.errors import NoUri
|
||||||
from sphinx.locale import _, __
|
from sphinx.locale import _, __
|
||||||
from sphinx.util import logging
|
from sphinx.util import logging, texescape
|
||||||
from sphinx.util.docutils import SphinxDirective
|
from sphinx.util.docutils import SphinxDirective
|
||||||
from sphinx.util.nodes import make_refnode
|
from sphinx.util.nodes import make_refnode
|
||||||
from sphinx.util.texescape import tex_escape_map
|
|
||||||
from sphinx.writers.html import HTMLTranslator
|
from sphinx.writers.html import HTMLTranslator
|
||||||
from sphinx.writers.latex import LaTeXTranslator
|
from sphinx.writers.latex import LaTeXTranslator
|
||||||
|
|
||||||
@@ -301,8 +300,10 @@ def latex_visit_todo_node(self: LaTeXTranslator, node: todo_node) -> None:
|
|||||||
if self.config.todo_include_todos:
|
if self.config.todo_include_todos:
|
||||||
self.body.append('\n\\begin{sphinxadmonition}{note}{')
|
self.body.append('\n\\begin{sphinxadmonition}{note}{')
|
||||||
self.body.append(self.hypertarget_to(node))
|
self.body.append(self.hypertarget_to(node))
|
||||||
|
|
||||||
title_node = cast(nodes.title, node[0])
|
title_node = cast(nodes.title, node[0])
|
||||||
self.body.append('%s:}' % title_node.astext().translate(tex_escape_map))
|
title = texescape.escape(title_node.astext(), self.config.latex_engine)
|
||||||
|
self.body.append('%s:}' % title)
|
||||||
node.pop(0)
|
node.pop(0)
|
||||||
else:
|
else:
|
||||||
raise nodes.SkipNode
|
raise nodes.SkipNode
|
||||||
|
|||||||
@@ -27,8 +27,7 @@ from sphinx.deprecation import RemovedInSphinx30Warning
|
|||||||
from sphinx.ext import doctest
|
from sphinx.ext import doctest
|
||||||
from sphinx.locale import __
|
from sphinx.locale import __
|
||||||
from sphinx.pygments_styles import SphinxStyle, NoneStyle
|
from sphinx.pygments_styles import SphinxStyle, NoneStyle
|
||||||
from sphinx.util import logging
|
from sphinx.util import logging, texescape
|
||||||
from sphinx.util.texescape import tex_hl_escape_map_new
|
|
||||||
|
|
||||||
if False:
|
if False:
|
||||||
# For type annotation
|
# For type annotation
|
||||||
@@ -68,9 +67,11 @@ class PygmentsBridge:
|
|||||||
html_formatter = HtmlFormatter
|
html_formatter = HtmlFormatter
|
||||||
latex_formatter = LatexFormatter
|
latex_formatter = LatexFormatter
|
||||||
|
|
||||||
def __init__(self, dest='html', stylename='sphinx', trim_doctest_flags=None):
|
def __init__(self, dest='html', stylename='sphinx', trim_doctest_flags=None,
|
||||||
# type: (str, str, bool) -> None
|
latex_engine=None):
|
||||||
|
# type: (str, str, bool, str) -> None
|
||||||
self.dest = dest
|
self.dest = dest
|
||||||
|
self.latex_engine = latex_engine
|
||||||
|
|
||||||
style = self.get_style(stylename)
|
style = self.get_style(stylename)
|
||||||
self.formatter_args = {'style': style} # type: Dict[str, Any]
|
self.formatter_args = {'style': style} # type: Dict[str, Any]
|
||||||
@@ -112,7 +113,7 @@ class PygmentsBridge:
|
|||||||
# first, escape highlighting characters like Pygments does
|
# first, escape highlighting characters like Pygments does
|
||||||
source = source.translate(escape_hl_chars)
|
source = source.translate(escape_hl_chars)
|
||||||
# then, escape all characters nonrepresentable in LaTeX
|
# then, escape all characters nonrepresentable in LaTeX
|
||||||
source = source.translate(tex_hl_escape_map_new)
|
source = texescape.escape(source, self.latex_engine)
|
||||||
return '\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n' + \
|
return '\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n' + \
|
||||||
source + '\\end{Verbatim}\n'
|
source + '\\end{Verbatim}\n'
|
||||||
|
|
||||||
@@ -192,7 +193,7 @@ class PygmentsBridge:
|
|||||||
if self.dest == 'html':
|
if self.dest == 'html':
|
||||||
return hlsource
|
return hlsource
|
||||||
else:
|
else:
|
||||||
return hlsource.translate(tex_hl_escape_map_new)
|
return texescape.hlescape(hlsource, self.latex_engine)
|
||||||
|
|
||||||
def get_stylesheet(self):
|
def get_stylesheet(self):
|
||||||
# type: () -> str
|
# type: () -> str
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import os
|
|||||||
from sphinx.locale import __
|
from sphinx.locale import __
|
||||||
from sphinx.util import get_matching_files
|
from sphinx.util import get_matching_files
|
||||||
from sphinx.util import logging
|
from sphinx.util import logging
|
||||||
|
from sphinx.util import path_stabilize
|
||||||
from sphinx.util.matching import compile_matchers
|
from sphinx.util.matching import compile_matchers
|
||||||
from sphinx.util.osutil import SEP, relpath
|
from sphinx.util.osutil import SEP, relpath
|
||||||
|
|
||||||
@@ -71,6 +72,7 @@ class Project:
|
|||||||
filename = relpath(filename, self.srcdir)
|
filename = relpath(filename, self.srcdir)
|
||||||
for suffix in self.source_suffix:
|
for suffix in self.source_suffix:
|
||||||
if filename.endswith(suffix):
|
if filename.endswith(suffix):
|
||||||
|
filename = path_stabilize(filename)
|
||||||
return filename[:-len(suffix)]
|
return filename[:-len(suffix)]
|
||||||
|
|
||||||
# the file does not have docname
|
# the file does not have docname
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ XINDYOPTS += -M LatinRules.xdy
|
|||||||
# format: pdf or dvi (used only by archive targets)
|
# format: pdf or dvi (used only by archive targets)
|
||||||
FMT = pdf
|
FMT = pdf
|
||||||
|
|
||||||
{% if latex_engine == 'platex' -%}
|
{% if latex_engine in ('platex', 'uplatex') -%}
|
||||||
# latexmkrc is read then overridden by latexmkjarc
|
# latexmkrc is read then overridden by latexmkjarc
|
||||||
LATEX = latexmk -r latexmkjarc -dvi
|
LATEX = latexmk -r latexmkjarc -dvi
|
||||||
PDFLATEX = latexmk -r latexmkjarc -pdfdvi -dvi- -ps-
|
PDFLATEX = latexmk -r latexmkjarc -pdfdvi -dvi- -ps-
|
||||||
@@ -49,7 +49,7 @@ PDFLATEX = latexmk -pdf -dvi- -ps-
|
|||||||
%.png %.gif %.jpg %.jpeg: FORCE_MAKE
|
%.png %.gif %.jpg %.jpeg: FORCE_MAKE
|
||||||
extractbb '$@'
|
extractbb '$@'
|
||||||
|
|
||||||
{% if latex_engine == 'platex' -%}
|
{% if latex_engine in ('platex', 'uplatex') -%}
|
||||||
%.dvi: %.tex $(ALLIMGS) FORCE_MAKE
|
%.dvi: %.tex $(ALLIMGS) FORCE_MAKE
|
||||||
for f in *.pdf; do extractbb "$$f"; done
|
for f in *.pdf; do extractbb "$$f"; done
|
||||||
$(LATEX) $(LATEXMKOPTS) '$<'
|
$(LATEX) $(LATEXMKOPTS) '$<'
|
||||||
@@ -62,7 +62,7 @@ PDFLATEX = latexmk -pdf -dvi- -ps-
|
|||||||
%.ps: %.dvi
|
%.ps: %.dvi
|
||||||
dvips '$<'
|
dvips '$<'
|
||||||
|
|
||||||
{% if latex_engine == 'platex' -%}
|
{% if latex_engine in ('platex', 'uplatex') -%}
|
||||||
%.pdf: %.tex $(ALLIMGS) FORCE_MAKE
|
%.pdf: %.tex $(ALLIMGS) FORCE_MAKE
|
||||||
for f in *.pdf; do extractbb "$$f"; done
|
for f in *.pdf; do extractbb "$$f"; done
|
||||||
{%- else -%}
|
{%- else -%}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
$latex = 'platex ' . $ENV{'LATEXOPTS'} . ' -kanji=utf8 %O %S';
|
$latex = '{{ latex_engine }} ' . $ENV{'LATEXOPTS'} . ' -kanji=utf8 %O %S';
|
||||||
$dvipdf = 'dvipdfmx %O -o %D %S';
|
$dvipdf = 'dvipdfmx %O -o %D %S';
|
||||||
$makeindex = 'internal mendex %S %B %D';
|
$makeindex = 'internal mendex %S %B %D';
|
||||||
sub mendex {
|
sub mendex {
|
||||||
@@ -155,7 +155,7 @@ def educateQuotes(text: str, language: str = 'en') -> str:
|
|||||||
|
|
||||||
# Special case for decade abbreviations (the '80s):
|
# Special case for decade abbreviations (the '80s):
|
||||||
if language.startswith('en'): # TODO similar cases in other languages?
|
if language.startswith('en'): # TODO similar cases in other languages?
|
||||||
text = re.sub(r"""'(?=\d{2}s)""", apostrophe, text, re.UNICODE)
|
text = re.sub(r"""'(?=\d{2}s)""", apostrophe, text, flags=re.UNICODE)
|
||||||
|
|
||||||
close_class = r"""[^\ \t\r\n\[\{\(\-]"""
|
close_class = r"""[^\ \t\r\n\[\{\(\-]"""
|
||||||
dec_dashes = r"""–|—"""
|
dec_dashes = r"""–|—"""
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
from functools import partial
|
||||||
from typing import Dict, List, Union
|
from typing import Dict, List, Union
|
||||||
|
|
||||||
from jinja2.loaders import BaseLoader
|
from jinja2.loaders import BaseLoader
|
||||||
@@ -69,8 +70,9 @@ class LaTeXRenderer(SphinxRenderer):
|
|||||||
super().__init__(template_path)
|
super().__init__(template_path)
|
||||||
|
|
||||||
# use texescape as escape filter
|
# use texescape as escape filter
|
||||||
self.env.filters['e'] = texescape.get_escape_func(latex_engine)
|
escape = partial(texescape.escape, latex_engine=latex_engine)
|
||||||
self.env.filters['escape'] = texescape.get_escape_func(latex_engine)
|
self.env.filters['e'] = escape
|
||||||
|
self.env.filters['escape'] = escape
|
||||||
self.env.filters['eabbr'] = texescape.escape_abbr
|
self.env.filters['eabbr'] = texescape.escape_abbr
|
||||||
|
|
||||||
# use JSP/eRuby like tagging instead because curly bracket; the default
|
# use JSP/eRuby like tagging instead because curly bracket; the default
|
||||||
|
|||||||
@@ -9,7 +9,10 @@
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import re
|
import re
|
||||||
from typing import Callable, Dict
|
from typing import Dict
|
||||||
|
|
||||||
|
from sphinx.deprecation import RemovedInSphinx40Warning, deprecated_alias
|
||||||
|
|
||||||
|
|
||||||
tex_replacements = [
|
tex_replacements = [
|
||||||
# map TeX special chars
|
# map TeX special chars
|
||||||
@@ -20,30 +23,26 @@ tex_replacements = [
|
|||||||
('_', r'\_'),
|
('_', r'\_'),
|
||||||
('{', r'\{'),
|
('{', r'\{'),
|
||||||
('}', r'\}'),
|
('}', r'\}'),
|
||||||
('[', r'{[}'),
|
|
||||||
(']', r'{]}'),
|
|
||||||
('`', r'{}`'),
|
|
||||||
('\\', r'\textbackslash{}'),
|
('\\', r'\textbackslash{}'),
|
||||||
('~', r'\textasciitilde{}'),
|
('~', r'\textasciitilde{}'),
|
||||||
|
('^', r'\textasciicircum{}'),
|
||||||
|
# map chars to avoid mis-interpretation in LaTeX
|
||||||
|
('[', r'{[}'),
|
||||||
|
(']', r'{]}'),
|
||||||
|
# map chars to avoid TeX ligatures
|
||||||
|
# 1. ' - and , not here for some legacy reason
|
||||||
|
# 2. no effect with lualatex (done otherwise: #5790)
|
||||||
|
('`', r'{}`'),
|
||||||
('<', r'\textless{}'),
|
('<', r'\textless{}'),
|
||||||
('>', r'\textgreater{}'),
|
('>', r'\textgreater{}'),
|
||||||
('^', r'\textasciicircum{}'),
|
|
||||||
# map special Unicode characters to TeX commands
|
# map special Unicode characters to TeX commands
|
||||||
('¶', r'\P{}'),
|
|
||||||
('§', r'\S{}'),
|
|
||||||
('€', r'\texteuro{}'),
|
|
||||||
('∞', r'\(\infty\)'),
|
|
||||||
('±', r'\(\pm\)'),
|
|
||||||
('→', r'\(\rightarrow\)'),
|
|
||||||
('‣', r'\(\rightarrow\)'),
|
|
||||||
('✓', r'\(\checkmark\)'),
|
('✓', r'\(\checkmark\)'),
|
||||||
('✔', r'\(\pmb{\checkmark}\)'),
|
('✔', r'\(\pmb{\checkmark}\)'),
|
||||||
# used to separate -- in options
|
# used to separate -- in options
|
||||||
('', r'{}'),
|
('', r'{}'),
|
||||||
# map some special Unicode characters to similar ASCII ones
|
# map some special Unicode characters to similar ASCII ones
|
||||||
|
# (even for Unicode LaTeX as may not be supported by OpenType font)
|
||||||
('⎽', r'\_'),
|
('⎽', r'\_'),
|
||||||
('–', r'\textendash{}'),
|
|
||||||
('|', r'\textbar{}'),
|
|
||||||
('ℯ', r'e'),
|
('ℯ', r'e'),
|
||||||
('ⅈ', r'i'),
|
('ⅈ', r'i'),
|
||||||
# Greek alphabet not escaped: pdflatex handles it via textalpha and inputenc
|
# Greek alphabet not escaped: pdflatex handles it via textalpha and inputenc
|
||||||
@@ -53,6 +52,15 @@ tex_replacements = [
|
|||||||
# A map Unicode characters to LaTeX representation
|
# A map Unicode characters to LaTeX representation
|
||||||
# (for LaTeX engines which don't support unicode)
|
# (for LaTeX engines which don't support unicode)
|
||||||
unicode_tex_replacements = [
|
unicode_tex_replacements = [
|
||||||
|
# map some more common Unicode characters to TeX commands
|
||||||
|
('¶', r'\P{}'),
|
||||||
|
('§', r'\S{}'),
|
||||||
|
('€', r'\texteuro{}'),
|
||||||
|
('∞', r'\(\infty\)'),
|
||||||
|
('±', r'\(\pm\)'),
|
||||||
|
('→', r'\(\rightarrow\)'),
|
||||||
|
('‣', r'\(\rightarrow\)'),
|
||||||
|
('–', r'\textendash{}'),
|
||||||
# superscript
|
# superscript
|
||||||
('⁰', r'\(\sp{\text{0}}\)'),
|
('⁰', r'\(\sp{\text{0}}\)'),
|
||||||
('¹', r'\(\sp{\text{1}}\)'),
|
('¹', r'\(\sp{\text{1}}\)'),
|
||||||
@@ -77,28 +85,38 @@ unicode_tex_replacements = [
|
|||||||
('₉', r'\(\sb{\text{9}}\)'),
|
('₉', r'\(\sb{\text{9}}\)'),
|
||||||
]
|
]
|
||||||
|
|
||||||
tex_escape_map = {} # type: Dict[int, str]
|
tex_replace_map = {} # type: Dict[int, str]
|
||||||
tex_escape_map_without_unicode = {} # type: Dict[int, str]
|
|
||||||
tex_replace_map = {}
|
_tex_escape_map = {} # type: Dict[int, str]
|
||||||
tex_hl_escape_map_new = {}
|
_tex_escape_map_without_unicode = {} # type: Dict[int, str]
|
||||||
|
_tex_hlescape_map = {} # type: Dict[int, str]
|
||||||
|
_tex_hlescape_map_without_unicode = {} # type: Dict[int, str]
|
||||||
|
|
||||||
|
|
||||||
def get_escape_func(latex_engine: str) -> Callable[[str], str]:
|
deprecated_alias('sphinx.util.texescape',
|
||||||
"""Get escape() function for given latex_engine."""
|
{
|
||||||
if latex_engine in ('lualatex', 'xelatex'):
|
'tex_escape_map': _tex_escape_map,
|
||||||
return escape_for_unicode_latex_engine
|
'tex_hl_escape_map_new': _tex_hlescape_map,
|
||||||
else:
|
},
|
||||||
return escape
|
RemovedInSphinx40Warning)
|
||||||
|
|
||||||
|
|
||||||
def escape(s: str) -> str:
|
def escape(s: str, latex_engine: str = None) -> str:
|
||||||
"""Escape text for LaTeX output."""
|
"""Escape text for LaTeX output."""
|
||||||
return s.translate(tex_escape_map)
|
if latex_engine in ('lualatex', 'xelatex'):
|
||||||
|
# unicode based LaTeX engine
|
||||||
|
return s.translate(_tex_escape_map_without_unicode)
|
||||||
|
else:
|
||||||
|
return s.translate(_tex_escape_map)
|
||||||
|
|
||||||
|
|
||||||
def escape_for_unicode_latex_engine(s: str) -> str:
|
def hlescape(s: str, latex_engine: str = None) -> str:
|
||||||
"""Escape text for unicode supporting LaTeX engine."""
|
"""Escape text for LaTeX highlighter."""
|
||||||
return s.translate(tex_escape_map_without_unicode)
|
if latex_engine in ('lualatex', 'xelatex'):
|
||||||
|
# unicode based LaTeX engine
|
||||||
|
return s.translate(_tex_hlescape_map_without_unicode)
|
||||||
|
else:
|
||||||
|
return s.translate(_tex_hlescape_map)
|
||||||
|
|
||||||
|
|
||||||
def escape_abbr(text: str) -> str:
|
def escape_abbr(text: str) -> str:
|
||||||
@@ -108,15 +126,19 @@ def escape_abbr(text: str) -> str:
|
|||||||
|
|
||||||
def init() -> None:
|
def init() -> None:
|
||||||
for a, b in tex_replacements:
|
for a, b in tex_replacements:
|
||||||
tex_escape_map[ord(a)] = b
|
_tex_escape_map[ord(a)] = b
|
||||||
tex_escape_map_without_unicode[ord(a)] = b
|
_tex_escape_map_without_unicode[ord(a)] = b
|
||||||
tex_replace_map[ord(a)] = '_'
|
tex_replace_map[ord(a)] = '_'
|
||||||
|
|
||||||
for a, b in unicode_tex_replacements:
|
for a, b in unicode_tex_replacements:
|
||||||
tex_escape_map[ord(a)] = b
|
_tex_escape_map[ord(a)] = b
|
||||||
tex_replace_map[ord(a)] = '_'
|
tex_replace_map[ord(a)] = '_'
|
||||||
|
|
||||||
for a, b in tex_replacements:
|
for a, b in tex_replacements:
|
||||||
if a in '[]{}\\':
|
if a in '[]{}\\':
|
||||||
continue
|
continue
|
||||||
tex_hl_escape_map_new[ord(a)] = b
|
_tex_hlescape_map[ord(a)] = b
|
||||||
|
_tex_hlescape_map_without_unicode[ord(a)] = b
|
||||||
|
|
||||||
|
for a, b in unicode_tex_replacements:
|
||||||
|
_tex_hlescape_map[ord(a)] = b
|
||||||
|
|||||||
@@ -28,11 +28,11 @@ from sphinx.deprecation import (
|
|||||||
from sphinx.domains.std import StandardDomain
|
from sphinx.domains.std import StandardDomain
|
||||||
from sphinx.errors import SphinxError
|
from sphinx.errors import SphinxError
|
||||||
from sphinx.locale import admonitionlabels, _, __
|
from sphinx.locale import admonitionlabels, _, __
|
||||||
from sphinx.util import split_into, logging
|
from sphinx.util import split_into, logging, texescape
|
||||||
from sphinx.util.docutils import SphinxTranslator
|
from sphinx.util.docutils import SphinxTranslator
|
||||||
from sphinx.util.nodes import clean_astext, get_prev_node
|
from sphinx.util.nodes import clean_astext, get_prev_node
|
||||||
from sphinx.util.template import LaTeXRenderer
|
from sphinx.util.template import LaTeXRenderer
|
||||||
from sphinx.util.texescape import get_escape_func, tex_replace_map
|
from sphinx.util.texescape import tex_replace_map
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from docutils.utils.roman import toRoman
|
from docutils.utils.roman import toRoman
|
||||||
@@ -221,6 +221,15 @@ ADDITIONAL_SETTINGS = {
|
|||||||
'fncychap': '',
|
'fncychap': '',
|
||||||
'geometry': '\\usepackage[dvipdfm]{geometry}',
|
'geometry': '\\usepackage[dvipdfm]{geometry}',
|
||||||
},
|
},
|
||||||
|
'uplatex': {
|
||||||
|
'latex_engine': 'uplatex',
|
||||||
|
'babel': '',
|
||||||
|
'classoptions': ',dvipdfmx',
|
||||||
|
'fontpkg': '\\usepackage{times}',
|
||||||
|
'textgreek': '',
|
||||||
|
'fncychap': '',
|
||||||
|
'geometry': '\\usepackage[dvipdfm]{geometry}',
|
||||||
|
},
|
||||||
|
|
||||||
# special settings for latex_engine + language_code
|
# special settings for latex_engine + language_code
|
||||||
('xelatex', 'fr'): {
|
('xelatex', 'fr'): {
|
||||||
@@ -500,9 +509,6 @@ class LaTeXTranslator(SphinxTranslator):
|
|||||||
self.compact_list = 0
|
self.compact_list = 0
|
||||||
self.first_param = 0
|
self.first_param = 0
|
||||||
|
|
||||||
# escape helper
|
|
||||||
self.escape = get_escape_func(self.config.latex_engine)
|
|
||||||
|
|
||||||
# sort out some elements
|
# sort out some elements
|
||||||
self.elements = self.builder.context.copy()
|
self.elements = self.builder.context.copy()
|
||||||
|
|
||||||
@@ -653,7 +659,8 @@ class LaTeXTranslator(SphinxTranslator):
|
|||||||
self.elements['classoptions'] += ',' + \
|
self.elements['classoptions'] += ',' + \
|
||||||
self.elements['extraclassoptions']
|
self.elements['extraclassoptions']
|
||||||
|
|
||||||
self.highlighter = highlighting.PygmentsBridge('latex', self.config.pygments_style)
|
self.highlighter = highlighting.PygmentsBridge('latex', self.config.pygments_style,
|
||||||
|
latex_engine=self.config.latex_engine)
|
||||||
self.context = [] # type: List[Any]
|
self.context = [] # type: List[Any]
|
||||||
self.descstack = [] # type: List[str]
|
self.descstack = [] # type: List[str]
|
||||||
self.table = None # type: Table
|
self.table = None # type: Table
|
||||||
@@ -735,6 +742,9 @@ class LaTeXTranslator(SphinxTranslator):
|
|||||||
# type: (str) -> str
|
# type: (str) -> str
|
||||||
return '\\autopageref*{%s}' % self.idescape(id)
|
return '\\autopageref*{%s}' % self.idescape(id)
|
||||||
|
|
||||||
|
def escape(self, s: str) -> str:
|
||||||
|
return texescape.escape(s, self.config.latex_engine)
|
||||||
|
|
||||||
def idescape(self, id):
|
def idescape(self, id):
|
||||||
# type: (str) -> str
|
# type: (str) -> str
|
||||||
return '\\detokenize{%s}' % str(id).translate(tex_replace_map).\
|
return '\\detokenize{%s}' % str(id).translate(tex_replace_map).\
|
||||||
@@ -1815,6 +1825,7 @@ class LaTeXTranslator(SphinxTranslator):
|
|||||||
value = value.replace('"', '""')
|
value = value.replace('"', '""')
|
||||||
value = value.replace('@', '"@')
|
value = value.replace('@', '"@')
|
||||||
value = value.replace('!', '"!')
|
value = value.replace('!', '"!')
|
||||||
|
value = value.replace('|', r'\textbar{}')
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def style(string):
|
def style(string):
|
||||||
@@ -2163,8 +2174,6 @@ class LaTeXTranslator(SphinxTranslator):
|
|||||||
node.rawsource, lang, opts=opts, linenos=linenos,
|
node.rawsource, lang, opts=opts, linenos=linenos,
|
||||||
location=(self.curfilestack[-1], node.line), **highlight_args
|
location=(self.curfilestack[-1], node.line), **highlight_args
|
||||||
)
|
)
|
||||||
# workaround for Unicode issue
|
|
||||||
hlcode = hlcode.replace('€', '@texteuro[]')
|
|
||||||
if self.in_footnote:
|
if self.in_footnote:
|
||||||
self.body.append('\n\\sphinxSetupCodeBlockInFootnote')
|
self.body.append('\n\\sphinxSetupCodeBlockInFootnote')
|
||||||
hlcode = hlcode.replace('\\begin{Verbatim}',
|
hlcode = hlcode.replace('\\begin{Verbatim}',
|
||||||
|
|||||||
@@ -1284,6 +1284,7 @@ class TexinfoTranslator(SphinxTranslator):
|
|||||||
title = cast(nodes.title, node[0])
|
title = cast(nodes.title, node[0])
|
||||||
self.visit_rubric(title)
|
self.visit_rubric(title)
|
||||||
self.body.append('%s\n' % self.escape(title.astext()))
|
self.body.append('%s\n' % self.escape(title.astext()))
|
||||||
|
self.depart_rubric(title)
|
||||||
|
|
||||||
def depart_topic(self, node):
|
def depart_topic(self, node):
|
||||||
# type: (nodes.Element) -> None
|
# type: (nodes.Element) -> None
|
||||||
|
|||||||
10
tests/roots/test-intl/toctree.txt
Normal file
10
tests/roots/test-intl/toctree.txt
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
i18n with toctree
|
||||||
|
=================
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:caption: caption
|
||||||
|
|
||||||
|
figure <figure>
|
||||||
|
table
|
||||||
|
https://www.sphinx-doc.org/
|
||||||
|
self
|
||||||
31
tests/roots/test-intl/xx/LC_MESSAGES/toctree.po
Normal file
31
tests/roots/test-intl/xx/LC_MESSAGES/toctree.po
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
# SOME DESCRIPTIVE TITLE.
|
||||||
|
# Copyright (C)
|
||||||
|
# This file is distributed under the same license as the Sphinx intl <Tests> package.
|
||||||
|
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||||
|
#
|
||||||
|
#, fuzzy
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: Sphinx intl <Tests> 2013.120\n"
|
||||||
|
"Report-Msgid-Bugs-To: \n"
|
||||||
|
"POT-Creation-Date: 2019-11-01 10:24+0900\n"
|
||||||
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
|
||||||
|
#: ../../toctree.txt:4
|
||||||
|
msgid "figure"
|
||||||
|
msgstr "FIGURE"
|
||||||
|
|
||||||
|
#: ../../toctree.txt:4
|
||||||
|
#: ../../toctree.txt:4
|
||||||
|
msgid "caption"
|
||||||
|
msgstr "CAPTION"
|
||||||
|
|
||||||
|
#: ../../toctree.txt:2
|
||||||
|
msgid "i18n with toctree"
|
||||||
|
msgstr "I18N WITH TOCTREE"
|
||||||
|
|
||||||
@@ -315,7 +315,7 @@ def test_numref_with_prefix2(app, status, warning):
|
|||||||
assert ('\\hyperref[\\detokenize{baz:table22}]'
|
assert ('\\hyperref[\\detokenize{baz:table22}]'
|
||||||
'{Table:\\ref{\\detokenize{baz:table22}}}') in result
|
'{Table:\\ref{\\detokenize{baz:table22}}}') in result
|
||||||
assert ('\\hyperref[\\detokenize{index:code-1}]{Code-\\ref{\\detokenize{index:code-1}} '
|
assert ('\\hyperref[\\detokenize{index:code-1}]{Code-\\ref{\\detokenize{index:code-1}} '
|
||||||
'\\textbar{} }') in result
|
'| }') in result
|
||||||
assert ('\\hyperref[\\detokenize{baz:code22}]'
|
assert ('\\hyperref[\\detokenize{baz:code22}]'
|
||||||
'{Code-\\ref{\\detokenize{baz:code22}}}') in result
|
'{Code-\\ref{\\detokenize{baz:code22}}}') in result
|
||||||
assert ('\\hyperref[\\detokenize{foo:foo}]'
|
assert ('\\hyperref[\\detokenize{foo:foo}]'
|
||||||
@@ -1414,6 +1414,7 @@ def test_default_latex_documents():
|
|||||||
'project': 'STASI™ Documentation',
|
'project': 'STASI™ Documentation',
|
||||||
'author': "Wolfgang Schäuble & G'Beckstein."})
|
'author': "Wolfgang Schäuble & G'Beckstein."})
|
||||||
config.init_values()
|
config.init_values()
|
||||||
|
config.add('latex_engine', None, True, None)
|
||||||
expected = [('index', 'stasi.tex', 'STASI™ Documentation',
|
expected = [('index', 'stasi.tex', 'STASI™ Documentation',
|
||||||
r"Wolfgang Schäuble \& G'Beckstein.\@{}", 'manual')]
|
r"Wolfgang Schäuble \& G'Beckstein.\@{}", 'manual')]
|
||||||
assert default_latex_documents(config) == expected
|
assert default_latex_documents(config) == expected
|
||||||
|
|||||||
@@ -465,6 +465,30 @@ def test_text_table(app):
|
|||||||
assert expect_msg.string in result
|
assert expect_msg.string in result
|
||||||
|
|
||||||
|
|
||||||
|
@sphinx_intl
|
||||||
|
@pytest.mark.sphinx('gettext')
|
||||||
|
@pytest.mark.test_params(shared_result='test_intl_gettext')
|
||||||
|
def test_gettext_toctree(app):
|
||||||
|
app.build()
|
||||||
|
# --- toctree
|
||||||
|
expect = read_po(app.srcdir / 'xx' / 'LC_MESSAGES' / 'toctree.po')
|
||||||
|
actual = read_po(app.outdir / 'toctree.pot')
|
||||||
|
for expect_msg in [m for m in expect if m.id]:
|
||||||
|
assert expect_msg.id in [m.id for m in actual if m.id]
|
||||||
|
|
||||||
|
|
||||||
|
@sphinx_intl
|
||||||
|
@pytest.mark.sphinx('text')
|
||||||
|
@pytest.mark.test_params(shared_result='test_intl_basic')
|
||||||
|
def test_text_toctree(app):
|
||||||
|
app.build()
|
||||||
|
# --- toctree
|
||||||
|
result = (app.outdir / 'toctree.txt').text()
|
||||||
|
expect = read_po(app.srcdir / 'xx' / 'LC_MESSAGES' / 'toctree.po')
|
||||||
|
for expect_msg in [m for m in expect if m.id]:
|
||||||
|
assert expect_msg.string in result
|
||||||
|
|
||||||
|
|
||||||
@sphinx_intl
|
@sphinx_intl
|
||||||
@pytest.mark.sphinx('gettext')
|
@pytest.mark.sphinx('gettext')
|
||||||
@pytest.mark.test_params(shared_result='test_intl_gettext')
|
@pytest.mark.test_params(shared_result='test_intl_gettext')
|
||||||
|
|||||||
@@ -312,6 +312,24 @@ def test_inline(get_verifier, type, rst, html_expected, latex_expected):
|
|||||||
verifier(rst, html_expected, latex_expected)
|
verifier(rst, html_expected, latex_expected)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.sphinx(confoverrides={'latex_engine': 'xelatex'})
|
||||||
|
@pytest.mark.parametrize('type,rst,html_expected,latex_expected', [
|
||||||
|
(
|
||||||
|
# in verbatim code fragments
|
||||||
|
'verify',
|
||||||
|
'::\n\n @Γ\\∞${}',
|
||||||
|
None,
|
||||||
|
('\\begin{sphinxVerbatim}[commandchars=\\\\\\{\\}]\n'
|
||||||
|
'@Γ\\PYGZbs{}∞\\PYGZdl{}\\PYGZob{}\\PYGZcb{}\n'
|
||||||
|
'\\end{sphinxVerbatim}'),
|
||||||
|
),
|
||||||
|
])
|
||||||
|
def test_inline_for_unicode_latex_engine(get_verifier, type, rst,
|
||||||
|
html_expected, latex_expected):
|
||||||
|
verifier = get_verifier(type)
|
||||||
|
verifier(rst, html_expected, latex_expected)
|
||||||
|
|
||||||
|
|
||||||
def test_samp_role(parse):
|
def test_samp_role(parse):
|
||||||
# no braces
|
# no braces
|
||||||
text = ':samp:`a{b}c`'
|
text = ':samp:`a{b}c`'
|
||||||
|
|||||||
Reference in New Issue
Block a user