From 06648a3157d19cb2a5fa6992b5ff8f87732b22b9 Mon Sep 17 00:00:00 2001 From: Yves Chevallier Date: Sat, 3 Aug 2019 13:03:16 +0200 Subject: [PATCH] Fix annotations --- sphinx/writers/html5.py | 12 ++++-- tests/test_build_html.py | 85 +++++++++++++++++++++++++--------------- 2 files changed, 62 insertions(+), 35 deletions(-) diff --git a/sphinx/writers/html5.py b/sphinx/writers/html5.py index f37647189..aae588e6b 100644 --- a/sphinx/writers/html5.py +++ b/sphinx/writers/html5.py @@ -279,10 +279,11 @@ class HTML5Translator(SphinxTranslator, BaseTranslator): self.depart_admonition(node) def get_secnumber(self, node): - # type: (nodes.Element) -> None + # type: (nodes.Element) -> Tuple[int, ...] if node.get('secnumber'): return node['secnumber'] - elif isinstance(node.parent, nodes.section): + + if isinstance(node.parent, nodes.section): if self.builder.name == 'singlehtml': docname = self.docnames[-1] anchorname = "%s/#%s" % (docname, node.parent['ids'][0]) @@ -292,15 +293,18 @@ class HTML5Translator(SphinxTranslator, BaseTranslator): anchorname = '#' + node.parent['ids'][0] if anchorname not in self.builder.secnumbers: anchorname = '' # try first heading which has no anchor + if self.builder.secnumbers.get(anchorname): return self.builder.secnumbers[anchorname] + return None def add_secnumber(self, node): + # type: (nodes.Element) -> None secnumber = self.get_secnumber(node) if secnumber: - self.body.append('%s' % - '.'.join(map(str, secnumber)) + self.secnumber_suffix) + self.body.append('%s' % + ('.'.join(map(str, secnumber)) + self.secnumber_suffix)) def add_fignumber(self, node): # type: (nodes.Element) -> None diff --git a/tests/test_build_html.py b/tests/test_build_html.py index 3255bb71e..2521ea68d 100644 --- a/tests/test_build_html.py +++ b/tests/test_build_html.py @@ -17,7 +17,7 @@ import pytest from html5lib import HTMLParser from sphinx.builders.html import validate_html_extra_path, validate_html_static_path -from sphinx.errors import ConfigError +from sphinx .errors import ConfigError from sphinx.testing.util import strip_escseq from sphinx.util import docutils from sphinx.util.inventory import InventoryFile @@ -82,6 +82,7 @@ def tail_check(check): def check_xpath(etree, fname, path, check, be_found=True): nodes = list(etree.findall(path)) + if check is None: assert nodes == [], ('found any nodes matching xpath ' '%r in file %s' % (path, fname)) @@ -96,15 +97,15 @@ def check_xpath(etree, fname, path, check, be_found=True): pass else: def get_text(node): - if node.text is not None: - return node.text - else: - # Since pygments-2.1.1, empty tag is inserted at top of - # highlighting block - if len(node) == 1 and node[0].tag == 'span' and node[0].text is None: - if node[0].tail is not None: - return node[0].tail - return '' + """ Get all text inside an HTML tag: + My 1dog 1likes bones --> My dog likes bones + """ + return ''.join( + filter( + lambda x: x and not re.match(r'^\s+$', x), + [node.text] + [n.tail for n in node.getchildren()] + ) + ) rex = re.compile(check) if be_found: @@ -116,7 +117,7 @@ def check_xpath(etree, fname, path, check, be_found=True): assert False, ('%r not found in any node matching ' 'path %s in %s: %r' % (check, path, fname, - [node.text for node in nodes])) + [get_all_text(node) for node in nodes])) @pytest.mark.sphinx('html', testroot='warnings') @@ -491,28 +492,40 @@ def test_html_translator(app): (".//li[@class='toctree-l3']/a", '2.2.1. Bar B1', False), ], 'foo.html': [ - (".//h1", '1. Foo', True), - (".//h2", '1.1. Foo A', True), - (".//h3", '1.1.1. Foo A1', True), - (".//h2", '1.2. Foo B', True), - (".//h3", '1.2.1. Foo B1', True), + (".//h1", 'Foo', True), + (".//h2", 'Foo A', True), + (".//h3", 'Foo A1', True), + (".//h2", 'Foo B', True), + (".//h3", 'Foo B1', True), + + (".//h1//span[@class='section-number']", '1. ', True), + (".//h2//span[@class='section-number']", '1.1. ', True), + (".//h3//span[@class='section-number']", '1.1.1. ', True), + (".//h2//span[@class='section-number']", '1.2. ', True), + (".//h3//span[@class='section-number']", '1.2.1. ', True), + (".//div[@class='sphinxsidebarwrapper']//li/a", '1.1. Foo A', True), (".//div[@class='sphinxsidebarwrapper']//li/a", '1.1.1. Foo A1', True), (".//div[@class='sphinxsidebarwrapper']//li/a", '1.2. Foo B', True), (".//div[@class='sphinxsidebarwrapper']//li/a", '1.2.1. Foo B1', True), ], 'bar.html': [ - (".//h1", '2. Bar', True), - (".//h2", '2.1. Bar A', True), - (".//h2", '2.2. Bar B', True), - (".//h3", '2.2.1. Bar B1', True), + (".//h1", 'Bar', True), + (".//h2", 'Bar A', True), + (".//h2", 'Bar B', True), + (".//h3", 'Bar B1', True), + (".//h1//span[@class='section-number']", '2. ', True), + (".//h2//span[@class='section-number']", '2.1. ', True), + (".//h2//span[@class='section-number']", '2.2. ', True), + (".//h3//span[@class='section-number']", '2.2.1. ', True), (".//div[@class='sphinxsidebarwrapper']//li/a", '2. Bar', True), (".//div[@class='sphinxsidebarwrapper']//li/a", '2.1. Bar A', True), (".//div[@class='sphinxsidebarwrapper']//li/a", '2.2. Bar B', True), (".//div[@class='sphinxsidebarwrapper']//li/a", '2.2.1. Bar B1', False), ], 'baz.html': [ - (".//h1", '2.1.1. Baz A', True), + (".//h1", 'Baz A', True), + (".//h1//span[@class='section-number']", '2.1.1. ', True), ], })) @pytest.mark.skipif(docutils.__version_info__ < (0, 13), @@ -536,20 +549,30 @@ def test_tocdepth(app, cached_etree_parse, fname, expect): (".//h1", 'test-tocdepth', True), # foo.rst - (".//h2", '1. Foo', True), - (".//h3", '1.1. Foo A', True), - (".//h4", '1.1.1. Foo A1', True), - (".//h3", '1.2. Foo B', True), - (".//h4", '1.2.1. Foo B1', True), + (".//h2", 'Foo', True), + (".//h3", 'Foo A', True), + (".//h4", 'Foo A1', True), + (".//h3", 'Foo B', True), + (".//h4", 'Foo B1', True), + (".//h2//span[@class='section-number']", '1. ', True), + (".//h3//span[@class='section-number']", '1.1. ', True), + (".//h4//span[@class='section-number']", '1.1.1. ', True), + (".//h3//span[@class='section-number']", '1.2. ', True), + (".//h4//span[@class='section-number']", '1.2.1. ', True), # bar.rst - (".//h2", '2. Bar', True), - (".//h3", '2.1. Bar A', True), - (".//h3", '2.2. Bar B', True), - (".//h4", '2.2.1. Bar B1', True), + (".//h2", 'Bar', True), + (".//h3", 'Bar A', True), + (".//h3", 'Bar B', True), + (".//h4", 'Bar B1', True), + (".//h2//span[@class='section-number']", '2. ', True), + (".//h3//span[@class='section-number']", '2.1. ', True), + (".//h3//span[@class='section-number']", '2.2. ', True), + (".//h4//span[@class='section-number']", '2.2.1. ', True), # baz.rst - (".//h4", '2.1.1. Baz A', True), + (".//h4", 'Baz A', True), + (".//h4//span[@class='section-number']", '2.1.1. ', True), ], })) @pytest.mark.skipif(docutils.__version_info__ < (0, 13),