summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTakeshi KOMIYA <i.tkomiya@gmail.com>2019-11-16 17:51:41 +0900
committerGitHub <noreply@github.com>2019-11-16 17:51:41 +0900
commitaf9a404de84c98a4ae94f4e4e77c6aacec5ea3fc (patch)
treeb981f88e92573fe2ed479d5469d96c4b671ea8a4
parentef09ea23feaf1d21faa3d5fd990a49fb14642bfa (diff)
parent660e746cf801b9fce867a35a1ad3b65ae9ef43c5 (diff)
downloadsphinx-git-af9a404de84c98a4ae94f4e4e77c6aacec5ea3fc.tar.gz
Merge pull request #6832 from tk0miya/6738_new_hlescape_for_unicode_latex_engine
Fix #6738: latex: literal_block does not support raw unicode characters
-rw-r--r--sphinx/highlighting.py11
-rw-r--r--sphinx/util/texescape.py28
-rw-r--r--sphinx/writers/latex.py3
-rw-r--r--tests/test_markup.py18
4 files changed, 53 insertions, 7 deletions
diff --git a/sphinx/highlighting.py b/sphinx/highlighting.py
index 977b71f28..0a6cf8d6e 100644
--- a/sphinx/highlighting.py
+++ b/sphinx/highlighting.py
@@ -28,7 +28,7 @@ from sphinx.ext import doctest
from sphinx.locale import __
from sphinx.pygments_styles import SphinxStyle, NoneStyle
from sphinx.util import logging
-from sphinx.util.texescape import tex_hl_escape_map_new
+from sphinx.util.texescape import get_hlescape_func, tex_hl_escape_map_new
if False:
# For type annotation
@@ -68,9 +68,11 @@ class PygmentsBridge:
html_formatter = HtmlFormatter
latex_formatter = LatexFormatter
- def __init__(self, dest='html', stylename='sphinx', trim_doctest_flags=None):
- # type: (str, str, bool) -> None
+ def __init__(self, dest='html', stylename='sphinx', trim_doctest_flags=None,
+ latex_engine=None):
+ # type: (str, str, bool, str) -> None
self.dest = dest
+ self.latex_engine = latex_engine
style = self.get_style(stylename)
self.formatter_args = {'style': style} # type: Dict[str, Any]
@@ -192,7 +194,8 @@ class PygmentsBridge:
if self.dest == 'html':
return hlsource
else:
- return hlsource.translate(tex_hl_escape_map_new)
+ escape = get_hlescape_func(self.latex_engine)
+ return escape(hlsource)
def get_stylesheet(self):
# type: () -> str
diff --git a/sphinx/util/texescape.py b/sphinx/util/texescape.py
index 4e7055119..c3231d3d3 100644
--- a/sphinx/util/texescape.py
+++ b/sphinx/util/texescape.py
@@ -32,7 +32,6 @@ tex_replacements = [
('¶', r'\P{}'),
('§', r'\S{}'),
('€', r'\texteuro{}'),
- ('∞', r'\(\infty\)'),
('±', r'\(\pm\)'),
('→', r'\(\rightarrow\)'),
('‣', r'\(\rightarrow\)'),
@@ -53,6 +52,8 @@ tex_replacements = [
# A map Unicode characters to LaTeX representation
# (for LaTeX engines which don't support unicode)
unicode_tex_replacements = [
+ # map special Unicode characters to TeX commands
+ ('∞', r'\(\infty\)'),
# superscript
('⁰', r'\(\sp{\text{0}}\)'),
('¹', r'\(\sp{\text{1}}\)'),
@@ -80,7 +81,8 @@ unicode_tex_replacements = [
tex_escape_map = {} # type: Dict[int, str]
tex_escape_map_without_unicode = {} # type: Dict[int, str]
tex_replace_map = {}
-tex_hl_escape_map_new = {}
+tex_hl_escape_map_new = {} # type: Dict[int, str]
+tex_hl_escape_map_new_without_unicode = {} # type: Dict[int, str]
def get_escape_func(latex_engine: str) -> Callable[[str], str]:
@@ -101,6 +103,24 @@ def escape_for_unicode_latex_engine(s: str) -> str:
return s.translate(tex_escape_map_without_unicode)
+def get_hlescape_func(latex_engine: str) -> Callable[[str], str]:
+ """Get hlescape() function for given latex_engine."""
+ if latex_engine in ('lualatex', 'xelatex'):
+ return hlescape_for_unicode_latex_engine
+ else:
+ return hlescape
+
+
+def hlescape(s: str) -> str:
+ """Escape text for LaTeX highlighter."""
+ return s.translate(tex_hl_escape_map_new)
+
+
+def hlescape_for_unicode_latex_engine(s: str) -> str:
+ """Escape text for unicode supporting LaTeX engine."""
+ return s.translate(tex_hl_escape_map_new_without_unicode)
+
+
def escape_abbr(text: str) -> str:
"""Adjust spacing after abbreviations. Works with @ letter or other."""
return re.sub(r'\.(?=\s|$)', r'.\@{}', text)
@@ -120,3 +140,7 @@ def init() -> None:
if a in '[]{}\\':
continue
tex_hl_escape_map_new[ord(a)] = b
+ tex_hl_escape_map_new_without_unicode[ord(a)] = b
+
+ for a, b in unicode_tex_replacements:
+ tex_hl_escape_map_new[ord(a)] = b
diff --git a/sphinx/writers/latex.py b/sphinx/writers/latex.py
index 29367a79e..5facdc40c 100644
--- a/sphinx/writers/latex.py
+++ b/sphinx/writers/latex.py
@@ -653,7 +653,8 @@ class LaTeXTranslator(SphinxTranslator):
self.elements['classoptions'] += ',' + \
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.descstack = [] # type: List[str]
self.table = None # type: Table
diff --git a/tests/test_markup.py b/tests/test_markup.py
index b8c9b66d9..94d1af951 100644
--- a/tests/test_markup.py
+++ b/tests/test_markup.py
@@ -312,6 +312,24 @@ def test_inline(get_verifier, type, 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):
# no braces
text = ':samp:`a{b}c`'