diff options
| -rw-r--r-- | sphinx/environment.py | 71 | ||||
| -rw-r--r-- | sphinx/io.py | 16 | ||||
| -rw-r--r-- | sphinx/transforms/__init__.py | 223 | ||||
| -rw-r--r-- | sphinx/transforms/compact_bullet_list.py | 82 | ||||
| -rw-r--r-- | sphinx/transforms/i18n.py (renamed from sphinx/transforms.py) | 205 | ||||
| -rw-r--r-- | tests/roots/test-keep_warnings/conf.py | 4 | ||||
| -rw-r--r-- | tests/roots/test-keep_warnings/index.rst | 2 | ||||
| -rw-r--r-- | tests/roots/test-refonly_bullet_list/conf.py | 8 | ||||
| -rw-r--r-- | tests/roots/test-refonly_bullet_list/index.rst | 14 | ||||
| -rw-r--r-- | tests/test_markup.py | 37 |
10 files changed, 387 insertions, 275 deletions
diff --git a/sphinx/environment.py b/sphinx/environment.py index 61df10237..e2d446acc 100644 --- a/sphinx/environment.py +++ b/sphinx/environment.py @@ -728,12 +728,10 @@ class BuildEnvironment(object): doctree = pub.document # post-processing - self.filter_messages(doctree) self.process_dependencies(docname, doctree) self.process_images(docname, doctree) self.process_downloads(docname, doctree) self.process_metadata(docname, doctree) - self.process_refonly_bullet_lists(docname, doctree) self.create_title_from(docname, doctree) self.note_indexentries_from(docname, doctree) self.build_toc_from(docname, doctree) @@ -851,14 +849,6 @@ class BuildEnvironment(object): # post-processing of read doctrees - def filter_messages(self, doctree): - """Filter system messages from a doctree.""" - filterlevel = self.config.keep_warnings and 2 or 5 - for node in doctree.traverse(nodes.system_message): - if node['level'] < filterlevel: - self.app.debug('%s [filtered system message]', node.astext()) - node.parent.remove(node) - def process_dependencies(self, docname, doctree): """Process docutils-generated dependency info.""" cwd = getcwd() @@ -986,67 +976,6 @@ class BuildEnvironment(object): del doctree[0] - def process_refonly_bullet_lists(self, docname, doctree): - """Change refonly bullet lists to use compact_paragraphs. - - Specifically implemented for 'Indices and Tables' section, which looks - odd when html_compact_lists is false. - """ - if self.config.html_compact_lists: - return - - class RefOnlyListChecker(nodes.GenericNodeVisitor): - """Raise `nodes.NodeFound` if non-simple list item is encountered. - - Here 'simple' means a list item containing only a paragraph with a - single reference in it. - """ - - def default_visit(self, node): - raise nodes.NodeFound - - def visit_bullet_list(self, node): - pass - - def visit_list_item(self, node): - children = [] - for child in node.children: - if not isinstance(child, nodes.Invisible): - children.append(child) - if len(children) != 1: - raise nodes.NodeFound - if not isinstance(children[0], nodes.paragraph): - raise nodes.NodeFound - para = children[0] - if len(para) != 1: - raise nodes.NodeFound - if not isinstance(para[0], addnodes.pending_xref): - raise nodes.NodeFound - raise nodes.SkipChildren - - def invisible_visit(self, node): - """Invisible nodes should be ignored.""" - pass - - def check_refonly_list(node): - """Check for list with only references in it.""" - visitor = RefOnlyListChecker(doctree) - try: - node.walk(visitor) - except nodes.NodeFound: - return False - else: - return True - - for node in doctree.traverse(nodes.bullet_list): - if check_refonly_list(node): - for item in node.traverse(nodes.list_item): - para = item[0] - ref = para[0] - compact_para = addnodes.compact_paragraph() - compact_para += ref - item.replace(para, compact_para) - def create_title_from(self, docname, document): """Add a title node to the document (just copy the first section title), and store that title in the environment. diff --git a/sphinx/io.py b/sphinx/io.py index bc14d59aa..f1386c9a8 100644 --- a/sphinx/io.py +++ b/sphinx/io.py @@ -14,9 +14,13 @@ from docutils.writers import UnfilteredWriter from six import string_types, text_type from sphinx.transforms import ( - ApplySourceWorkaround, ExtraTranslatableNodes, PreserveTranslatableMessages, Locale, - CitationReferences, DefaultSubstitutions, MoveModuleTargets, HandleCodeBlocks, - AutoNumbering, AutoIndexUpgrader, SortIds, RemoveTranslatableInline + ApplySourceWorkaround, ExtraTranslatableNodes, CitationReferences, + DefaultSubstitutions, MoveModuleTargets, HandleCodeBlocks, SortIds, + AutoNumbering, AutoIndexUpgrader, FilterSystemMessages, +) +from sphinx.transforms.compact_bullet_list import RefOnlyBulletListTransform +from sphinx.transforms.i18n import ( + PreserveTranslatableMessages, Locale, RemoveTranslatableInline, ) from sphinx.util import import_object, split_docinfo @@ -62,7 +66,8 @@ class SphinxStandaloneReader(SphinxBaseReader): transforms = [ApplySourceWorkaround, ExtraTranslatableNodes, PreserveTranslatableMessages, Locale, CitationReferences, DefaultSubstitutions, MoveModuleTargets, HandleCodeBlocks, AutoNumbering, AutoIndexUpgrader, SortIds, - RemoveTranslatableInline, PreserveTranslatableMessages] + RemoveTranslatableInline, PreserveTranslatableMessages, FilterSystemMessages, + RefOnlyBulletListTransform] class SphinxI18nReader(SphinxBaseReader): @@ -75,7 +80,8 @@ class SphinxI18nReader(SphinxBaseReader): transforms = [ApplySourceWorkaround, ExtraTranslatableNodes, CitationReferences, DefaultSubstitutions, MoveModuleTargets, HandleCodeBlocks, - AutoNumbering, SortIds, RemoveTranslatableInline] + AutoNumbering, SortIds, RemoveTranslatableInline, + FilterSystemMessages, RefOnlyBulletListTransform] def __init__(self, *args, **kwargs): SphinxBaseReader.__init__(self, *args, **kwargs) diff --git a/sphinx/transforms/__init__.py b/sphinx/transforms/__init__.py new file mode 100644 index 000000000..79ac99c9f --- /dev/null +++ b/sphinx/transforms/__init__.py @@ -0,0 +1,223 @@ +# -*- coding: utf-8 -*- +""" + sphinx.transforms + ~~~~~~~~~~~~~~~~~ + + Docutils transforms used by Sphinx when reading documents. + + :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +from docutils import nodes +from docutils.transforms import Transform +from docutils.transforms.parts import ContentsFilter + +from sphinx import addnodes +from sphinx.locale import _ +from sphinx.util.i18n import format_date +from sphinx.util.nodes import apply_source_workaround + +default_substitutions = set([ + 'version', + 'release', + 'today', +]) + + +class DefaultSubstitutions(Transform): + """ + Replace some substitutions if they aren't defined in the document. + """ + # run before the default Substitutions + default_priority = 210 + + def apply(self): + env = self.document.settings.env + config = self.document.settings.env.config + # only handle those not otherwise defined in the document + to_handle = default_substitutions - set(self.document.substitution_defs) + for ref in self.document.traverse(nodes.substitution_reference): + refname = ref['refname'] + if refname in to_handle: + text = config[refname] + if refname == 'today' and not text: + # special handling: can also specify a strftime format + text = format_date(config.today_fmt or _('%b %d, %Y'), + language=config.language, warn=env.warn) + ref.replace_self(nodes.Text(text, text)) + + +class MoveModuleTargets(Transform): + """ + Move module targets that are the first thing in a section to the section + title. + + XXX Python specific + """ + default_priority = 210 + + def apply(self): + for node in self.document.traverse(nodes.target): + if not node['ids']: + continue + if ('ismod' in node and + node.parent.__class__ is nodes.section and + # index 0 is the section title node + node.parent.index(node) == 1): + node.parent['ids'][0:0] = node['ids'] + node.parent.remove(node) + + +class HandleCodeBlocks(Transform): + """ + Several code block related transformations. + """ + default_priority = 210 + + def apply(self): + # move doctest blocks out of blockquotes + for node in self.document.traverse(nodes.block_quote): + if all(isinstance(child, nodes.doctest_block) for child + in node.children): + node.replace_self(node.children) + # combine successive doctest blocks + # for node in self.document.traverse(nodes.doctest_block): + # if node not in node.parent.children: + # continue + # parindex = node.parent.index(node) + # while len(node.parent) > parindex+1 and \ + # isinstance(node.parent[parindex+1], nodes.doctest_block): + # node[0] = nodes.Text(node[0] + '\n\n' + + # node.parent[parindex+1][0]) + # 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): + domain = self.document.settings.env.domains['std'] + + for node in self.document.traverse(nodes.Element): + if domain.is_enumerable_node(node) and domain.get_numfig_title(node) is not None: + self.document.note_implicit_target(node) + + +class SortIds(Transform): + """ + Sort secion IDs so that the "id[0-9]+" one comes last. + """ + default_priority = 261 + + def apply(self): + for node in self.document.traverse(nodes.section): + if len(node['ids']) > 1 and node['ids'][0].startswith('id'): + node['ids'] = node['ids'][1:] + [node['ids'][0]] + + +class CitationReferences(Transform): + """ + Replace citation references by pending_xref nodes before the default + docutils transform tries to resolve them. + """ + default_priority = 619 + + def apply(self): + for citnode in self.document.traverse(nodes.citation_reference): + cittext = citnode.astext() + refnode = addnodes.pending_xref(cittext, refdomain='std', reftype='citation', + reftarget=cittext, refwarn=True, + ids=citnode["ids"]) + refnode.source = citnode.source or citnode.parent.source + refnode.line = citnode.line or citnode.parent.line + refnode += nodes.Text('[' + cittext + ']') + citnode.parent.replace(citnode, refnode) + + +TRANSLATABLE_NODES = { + 'literal-block': nodes.literal_block, + 'doctest-block': nodes.doctest_block, + 'raw': nodes.raw, + 'index': addnodes.index, + 'image': nodes.image, +} + + +class ApplySourceWorkaround(Transform): + """ + update source and rawsource attributes + """ + default_priority = 10 + + def apply(self): + for n in self.document.traverse(): + if isinstance(n, nodes.TextElement): + apply_source_workaround(n) + + +class AutoIndexUpgrader(Transform): + """ + Detect old style; 4 column based indices and automatically upgrade to new style. + """ + default_priority = 210 + + def apply(self): + env = self.document.settings.env + for node in self.document.traverse(addnodes.index): + if 'entries' in node and any(len(entry) == 4 for entry in node['entries']): + msg = ('4 column based index found. ' + 'It might be a bug of extensions you use: %r' % node['entries']) + env.warn_node(msg, node) + for i, entry in enumerate(node['entries']): + if len(entry) == 4: + node['entries'][i] = entry + (None,) + + +class ExtraTranslatableNodes(Transform): + """ + make nodes translatable + """ + default_priority = 10 + + def apply(self): + targets = self.document.settings.env.config.gettext_additional_targets + target_nodes = [v for k, v in TRANSLATABLE_NODES.items() if k in targets] + if not target_nodes: + return + + def is_translatable_node(node): + return isinstance(node, tuple(target_nodes)) + + for node in self.document.traverse(is_translatable_node): + node['translatable'] = True + + +class FilterSystemMessages(Transform): + """Filter system messages from a doctree.""" + default_priority = 999 + + def apply(self): + env = self.document.settings.env + filterlevel = env.config.keep_warnings and 2 or 5 + for node in self.document.traverse(nodes.system_message): + if node['level'] < filterlevel: + env.app.debug('%s [filtered system message]', node.astext()) + node.parent.remove(node) + + +class SphinxContentsFilter(ContentsFilter): + """ + Used with BuildEnvironment.add_toc_from() to discard cross-file links + within table-of-contents link nodes. + """ + def visit_pending_xref(self, node): + text = node.astext() + self.parent.append(nodes.literal(text, text)) + raise nodes.SkipNode + + def visit_image(self, node): + raise nodes.SkipNode diff --git a/sphinx/transforms/compact_bullet_list.py b/sphinx/transforms/compact_bullet_list.py new file mode 100644 index 000000000..61b23f382 --- /dev/null +++ b/sphinx/transforms/compact_bullet_list.py @@ -0,0 +1,82 @@ +# -*- coding: utf-8 -*- +""" + sphinx.transforms.compact_bullet_list + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Docutils transforms used by Sphinx when reading documents. + + :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +from docutils import nodes +from docutils.transforms import Transform + +from sphinx import addnodes + + +class RefOnlyListChecker(nodes.GenericNodeVisitor): + """Raise `nodes.NodeFound` if non-simple list item is encountered. + + Here 'simple' means a list item containing only a paragraph with a + single reference in it. + """ + + def default_visit(self, node): + raise nodes.NodeFound + + def visit_bullet_list(self, node): + pass + + def visit_list_item(self, node): + children = [] + for child in node.children: + if not isinstance(child, nodes.Invisible): + children.append(child) + if len(children) != 1: + raise nodes.NodeFound + if not isinstance(children[0], nodes.paragraph): + raise nodes.NodeFound + para = children[0] + if len(para) != 1: + raise nodes.NodeFound + if not isinstance(para[0], addnodes.pending_xref): + raise nodes.NodeFound + raise nodes.SkipChildren + + def invisible_visit(self, node): + """Invisible nodes should be ignored.""" + pass + + +class RefOnlyBulletListTransform(Transform): + """Change refonly bullet lists to use compact_paragraphs. + + Specifically implemented for 'Indices and Tables' section, which looks + odd when html_compact_lists is false. + """ + default_priority = 100 + + def apply(self): + env = self.document.settings.env + if env.config.html_compact_lists: + return + + def check_refonly_list(node): + """Check for list with only references in it.""" + visitor = RefOnlyListChecker(self.document) + try: + node.walk(visitor) + except nodes.NodeFound: + return False + else: + return True + + for node in self.document.traverse(nodes.bullet_list): + if check_refonly_list(node): + for item in node.traverse(nodes.list_item): + para = item[0] + ref = para[0] + compact_para = addnodes.compact_paragraph() + compact_para += ref + item.replace(para, compact_para) diff --git a/sphinx/transforms.py b/sphinx/transforms/i18n.py index 9f2aeb8d1..38c5aef25 100644 --- a/sphinx/transforms.py +++ b/sphinx/transforms/i18n.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- """ - sphinx.transforms - ~~~~~~~~~~~~~~~~~ + sphinx.transforms.i18n + ~~~~~~~~~~~~~~~~~~~~~~ Docutils transforms used by Sphinx when reading documents. @@ -15,198 +15,19 @@ from docutils import nodes from docutils.io import StringInput from docutils.utils import relative_path from docutils.transforms import Transform -from docutils.transforms.parts import ContentsFilter from sphinx import addnodes -from sphinx.locale import _, init as init_locale from sphinx.util import split_index_msg +from sphinx.util.i18n import find_catalog from sphinx.util.nodes import ( - traverse_translatable_index, extract_messages, LITERAL_TYPE_NODES, IMAGE_TYPE_NODES, - apply_source_workaround, is_pending_meta, + LITERAL_TYPE_NODES, IMAGE_TYPE_NODES, + extract_messages, is_pending_meta, traverse_translatable_index, ) -from sphinx.util.i18n import find_catalog, format_date from sphinx.util.pycompat import indent +from sphinx.locale import init as init_locale from sphinx.domains.std import make_glossary_term, split_term_classifiers -default_substitutions = set([ - 'version', - 'release', - 'today', -]) - - -class DefaultSubstitutions(Transform): - """ - Replace some substitutions if they aren't defined in the document. - """ - # run before the default Substitutions - default_priority = 210 - - def apply(self): - env = self.document.settings.env - config = self.document.settings.env.config - # only handle those not otherwise defined in the document - to_handle = default_substitutions - set(self.document.substitution_defs) - for ref in self.document.traverse(nodes.substitution_reference): - refname = ref['refname'] - if refname in to_handle: - text = config[refname] - if refname == 'today' and not text: - # special handling: can also specify a strftime format - text = format_date(config.today_fmt or _('%b %d, %Y'), - language=config.language, warn=env.warn) - ref.replace_self(nodes.Text(text, text)) - - -class MoveModuleTargets(Transform): - """ - Move module targets that are the first thing in a section to the section - title. - - XXX Python specific - """ - default_priority = 210 - - def apply(self): - for node in self.document.traverse(nodes.target): - if not node['ids']: - continue - if ('ismod' in node and - node.parent.__class__ is nodes.section and - # index 0 is the section title node - node.parent.index(node) == 1): - node.parent['ids'][0:0] = node['ids'] - node.parent.remove(node) - - -class HandleCodeBlocks(Transform): - """ - Several code block related transformations. - """ - default_priority = 210 - - def apply(self): - # move doctest blocks out of blockquotes - for node in self.document.traverse(nodes.block_quote): - if all(isinstance(child, nodes.doctest_block) for child - in node.children): - node.replace_self(node.children) - # combine successive doctest blocks - # for node in self.document.traverse(nodes.doctest_block): - # if node not in node.parent.children: - # continue - # parindex = node.parent.index(node) - # while len(node.parent) > parindex+1 and \ - # isinstance(node.parent[parindex+1], nodes.doctest_block): - # node[0] = nodes.Text(node[0] + '\n\n' + - # node.parent[parindex+1][0]) - # 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): - domain = self.document.settings.env.domains['std'] - - for node in self.document.traverse(nodes.Element): - if domain.is_enumerable_node(node) and domain.get_numfig_title(node) is not None: - self.document.note_implicit_target(node) - - -class SortIds(Transform): - """ - Sort secion IDs so that the "id[0-9]+" one comes last. - """ - default_priority = 261 - - def apply(self): - for node in self.document.traverse(nodes.section): - if len(node['ids']) > 1 and node['ids'][0].startswith('id'): - node['ids'] = node['ids'][1:] + [node['ids'][0]] - - -class CitationReferences(Transform): - """ - Replace citation references by pending_xref nodes before the default - docutils transform tries to resolve them. - """ - default_priority = 619 - - def apply(self): - for citnode in self.document.traverse(nodes.citation_reference): - cittext = citnode.astext() - refnode = addnodes.pending_xref(cittext, refdomain='std', reftype='citation', - reftarget=cittext, refwarn=True, - ids=citnode["ids"]) - refnode.source = citnode.source or citnode.parent.source - refnode.line = citnode.line or citnode.parent.line - refnode += nodes.Text('[' + cittext + ']') - citnode.parent.replace(citnode, refnode) - - -TRANSLATABLE_NODES = { - 'literal-block': nodes.literal_block, - 'doctest-block': nodes.doctest_block, - 'raw': nodes.raw, - 'index': addnodes.index, - 'image': nodes.image, -} - - -class ApplySourceWorkaround(Transform): - """ - update source and rawsource attributes - """ - default_priority = 10 - - def apply(self): - for n in self.document.traverse(): - if isinstance(n, nodes.TextElement): - apply_source_workaround(n) - - -class AutoIndexUpgrader(Transform): - """ - Detect old style; 4 column based indices and automatically upgrade to new style. - """ - default_priority = 210 - - def apply(self): - env = self.document.settings.env - for node in self.document.traverse(addnodes.index): - if 'entries' in node and any(len(entry) == 4 for entry in node['entries']): - msg = ('4 column based index found. ' - 'It might be a bug of extensions you use: %r' % node['entries']) - env.warn_node(msg, node) - for i, entry in enumerate(node['entries']): - if len(entry) == 4: - node['entries'][i] = entry + (None,) - - -class ExtraTranslatableNodes(Transform): - """ - make nodes translatable - """ - default_priority = 10 - - def apply(self): - targets = self.document.settings.env.config.gettext_additional_targets - target_nodes = [v for k, v in TRANSLATABLE_NODES.items() if k in targets] - if not target_nodes: - return - - def is_translatable_node(node): - return isinstance(node, tuple(target_nodes)) - - for node in self.document.traverse(is_translatable_node): - node['translatable'] = True - - def publish_msgstr(app, source, source_path, source_line, config, settings): """Publish msgstr (single line) into docutils document @@ -595,17 +416,3 @@ class RemoveTranslatableInline(Transform): if 'translatable' in inline: inline.parent.remove(inline) inline.parent += inline.children - - -class SphinxContentsFilter(ContentsFilter): - """ - Used with BuildEnvironment.add_toc_from() to discard cross-file links - within table-of-contents link nodes. - """ - def visit_pending_xref(self, node): - text = node.astext() - self.parent.append(nodes.literal(text, text)) - raise nodes.SkipNode - - def visit_image(self, node): - raise nodes.SkipNode diff --git a/tests/roots/test-keep_warnings/conf.py b/tests/roots/test-keep_warnings/conf.py new file mode 100644 index 000000000..d0db3db83 --- /dev/null +++ b/tests/roots/test-keep_warnings/conf.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- + +master_doc = 'index' +keep_warnings = True diff --git a/tests/roots/test-keep_warnings/index.rst b/tests/roots/test-keep_warnings/index.rst new file mode 100644 index 000000000..1e2d5977f --- /dev/null +++ b/tests/roots/test-keep_warnings/index.rst @@ -0,0 +1,2 @@ +keep_warnings +===== diff --git a/tests/roots/test-refonly_bullet_list/conf.py b/tests/roots/test-refonly_bullet_list/conf.py new file mode 100644 index 000000000..68357c9a4 --- /dev/null +++ b/tests/roots/test-refonly_bullet_list/conf.py @@ -0,0 +1,8 @@ +# -*- coding: utf-8 -*- + +master_doc = 'index' +html_compact_lists = False + +latex_documents = [ + (master_doc, 'test.tex', 'The basic Sphinx documentation for testing', 'Sphinx', 'report') +] diff --git a/tests/roots/test-refonly_bullet_list/index.rst b/tests/roots/test-refonly_bullet_list/index.rst new file mode 100644 index 000000000..9d8539dba --- /dev/null +++ b/tests/roots/test-refonly_bullet_list/index.rst @@ -0,0 +1,14 @@ +test-refonly_bullet_list +======================== + +List A: + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` + +List B: + +* Hello +* Sphinx +* World diff --git a/tests/test_markup.py b/tests/test_markup.py index 60390bc09..133f187d3 100644 --- a/tests/test_markup.py +++ b/tests/test_markup.py @@ -15,6 +15,7 @@ import pickle from docutils import frontend, utils, nodes from docutils.parsers import rst +from sphinx import addnodes from sphinx.util import texescape from sphinx.writers.html import HTMLWriter, SmartyPantsHTMLTranslator from sphinx.writers.latex import LaTeXWriter, LaTeXTranslator @@ -170,3 +171,39 @@ def test_rst_prolog(app, status, warning): # rst_prolog & rst_epilog on exlucding reST parser assert not md.rawsource.startswith('*Hello world*.') assert not md.rawsource.endswith('*Good-bye world*.\n') + + +@with_app(buildername='dummy', testroot='keep_warnings') +def test_keep_warnings_is_True(app, status, warning): + app.builder.build_all() + doctree = pickle.loads((app.doctreedir / 'index.doctree').bytes()) + assert_node(doctree[0], nodes.section) + assert len(doctree[0]) == 2 + assert_node(doctree[0][1], nodes.system_message) + + +@with_app(buildername='dummy', testroot='keep_warnings', + confoverrides={'keep_warnings': False}) +def test_keep_warnings_is_False(app, status, warning): + app.builder.build_all() + doctree = pickle.loads((app.doctreedir / 'index.doctree').bytes()) + assert_node(doctree[0], nodes.section) + assert len(doctree[0]) == 1 + + +@with_app(buildername='dummy', testroot='refonly_bullet_list') +def test_compact_refonly_bullet_list(app, status, warning): + app.builder.build_all() + doctree = pickle.loads((app.doctreedir / 'index.doctree').bytes()) + assert_node(doctree[0], nodes.section) + assert len(doctree[0]) == 5 + + assert doctree[0][1].astext() == 'List A:' + assert_node(doctree[0][2], nodes.bullet_list) + assert_node(doctree[0][2][0][0], addnodes.compact_paragraph) + assert doctree[0][2][0][0].astext() == 'genindex' + + assert doctree[0][3].astext() == 'List B:' + assert_node(doctree[0][4], nodes.bullet_list) + assert_node(doctree[0][4][0][0], nodes.paragraph) + assert doctree[0][4][0][0].astext() == 'Hello' |
