summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sphinx/environment.py71
-rw-r--r--sphinx/io.py16
-rw-r--r--sphinx/transforms/__init__.py223
-rw-r--r--sphinx/transforms/compact_bullet_list.py82
-rw-r--r--sphinx/transforms/i18n.py (renamed from sphinx/transforms.py)205
-rw-r--r--tests/roots/test-keep_warnings/conf.py4
-rw-r--r--tests/roots/test-keep_warnings/index.rst2
-rw-r--r--tests/roots/test-refonly_bullet_list/conf.py8
-rw-r--r--tests/roots/test-refonly_bullet_list/index.rst14
-rw-r--r--tests/test_markup.py37
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'