mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Fix #7610: incorrectly renders consecutive backslashes
This commit is contained in:
parent
6ce265dc81
commit
71b653719d
1
CHANGES
1
CHANGES
@ -89,6 +89,7 @@ Bugs fixed
|
||||
* #7536: sphinx-autogen: crashes when template uses i18n feature
|
||||
* #2785: html: Bad alignment of equation links
|
||||
* #7581: napoleon: bad parsing of inline code in attribute docstrings
|
||||
* #7610: incorrectly renders consecutive backslashes for docutils-0.16
|
||||
|
||||
Testing
|
||||
--------
|
||||
|
@ -23,6 +23,7 @@ from sphinx import addnodes
|
||||
from sphinx.config import Config
|
||||
from sphinx.deprecation import RemovedInSphinx40Warning, deprecated_alias
|
||||
from sphinx.locale import _, __
|
||||
from sphinx.util import docutils
|
||||
from sphinx.util import logging
|
||||
from sphinx.util.docutils import new_document
|
||||
from sphinx.util.i18n import format_date
|
||||
@ -360,12 +361,18 @@ class SphinxSmartQuotes(SmartQuotes, SphinxTransform):
|
||||
def get_tokens(self, txtnodes: List[Text]) -> Generator[Tuple[str, str], None, None]:
|
||||
# A generator that yields ``(texttype, nodetext)`` tuples for a list
|
||||
# of "Text" nodes (interface to ``smartquotes.educate_tokens()``).
|
||||
|
||||
texttype = {True: 'literal', # "literal" text is not changed:
|
||||
False: 'plain'}
|
||||
for txtnode in txtnodes:
|
||||
notsmartquotable = not is_smartquotable(txtnode)
|
||||
yield (texttype[notsmartquotable], txtnode.astext())
|
||||
if is_smartquotable(txtnode):
|
||||
if docutils.__version_info__ >= (0, 16):
|
||||
# SmartQuotes uses backslash escapes instead of null-escapes
|
||||
text = re.sub(r'(?<=\x00)([-\\\'".`])', r'\\\1', str(txtnode))
|
||||
else:
|
||||
text = txtnode.astext()
|
||||
|
||||
yield ('plain', text)
|
||||
else:
|
||||
# skip smart quotes
|
||||
yield ('literal', txtnode.astext())
|
||||
|
||||
|
||||
class DoctreeReadEvent(SphinxTransform):
|
||||
|
@ -13,7 +13,6 @@ import re
|
||||
import pytest
|
||||
from docutils import frontend, utils, nodes
|
||||
from docutils.parsers.rst import Parser as RstParser
|
||||
from docutils.transforms.universal import SmartQuotes
|
||||
|
||||
from sphinx import addnodes
|
||||
from sphinx.builders.html.transforms import KeyboardTransform
|
||||
@ -21,6 +20,8 @@ from sphinx.builders.latex import LaTeXBuilder
|
||||
from sphinx.builders.latex.theming import ThemeFactory
|
||||
from sphinx.roles import XRefRole
|
||||
from sphinx.testing.util import Struct, assert_node
|
||||
from sphinx.transforms import SphinxSmartQuotes
|
||||
from sphinx.util import docutils
|
||||
from sphinx.util import texescape
|
||||
from sphinx.util.docutils import sphinx_domains
|
||||
from sphinx.writers.html import HTMLWriter, HTMLTranslator
|
||||
@ -67,7 +68,7 @@ def parse(new_document):
|
||||
document = new_document()
|
||||
parser = RstParser()
|
||||
parser.parse(rst, document)
|
||||
SmartQuotes(document, startnode=None).apply()
|
||||
SphinxSmartQuotes(document, startnode=None).apply()
|
||||
for msg in document.traverse(nodes.system_message):
|
||||
if msg['level'] == 1:
|
||||
msg.replace_self([])
|
||||
@ -349,6 +350,21 @@ def test_inline(get_verifier, type, rst, html_expected, latex_expected):
|
||||
verifier(rst, html_expected, latex_expected)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('type,rst,html_expected,latex_expected', [
|
||||
(
|
||||
'verify',
|
||||
r'4 backslashes \\\\',
|
||||
r'<p>4 backslashes \\</p>',
|
||||
None,
|
||||
),
|
||||
])
|
||||
@pytest.mark.skipif(docutils.__version_info__ < (0, 16),
|
||||
reason='docutils-0.16 or above is required')
|
||||
def test_inline_docutils16(get_verifier, type, rst, html_expected, latex_expected):
|
||||
verifier = get_verifier(type)
|
||||
verifier(rst, html_expected, latex_expected)
|
||||
|
||||
|
||||
@pytest.mark.sphinx(confoverrides={'latex_engine': 'xelatex'})
|
||||
@pytest.mark.parametrize('type,rst,html_expected,latex_expected', [
|
||||
(
|
||||
|
Loading…
Reference in New Issue
Block a user