#! /usr/bin/env python3
# $Id: test_html4css1.py 10102 2025-04-23 15:54:44Z milde $
# Author: reggie dugard
# Copyright: This module has been placed in the public domain.
"""Test HTML4 writer output ("fragment" part).
This is the document body (not HTML ).
"""
from pathlib import Path
import sys
import unittest
if __name__ == '__main__':
# prepend the "docutils root" to the Python library path
# so we import the local `docutils` package.
sys.path.insert(0, str(Path(__file__).resolve().parents[2]))
import docutils
import docutils.core
from docutils.parsers.rst.directives.images import PIL
from docutils.utils.code_analyzer import with_pygments
from docutils.writers import html4css1
if with_pygments:
import pygments
if tuple(map(int, pygments.__version__.split('.')[:2])) >= (2, 14):
# pygments output changed in version 2.14
with_pygments = False
# TEST_ROOT is ./test/ from the docutils root
TEST_ROOT = Path(__file__).parents[1]
DATA_ROOT = TEST_ROOT / 'data'
ROOT_PREFIX = (TEST_ROOT / 'functional/input').as_posix()
# Pillow/PIL is optional:
if PIL:
SCALING_OUTPUT = 'style="width: 32.0px; height: 32.0px;" '
else:
SCALING_OUTPUT = ''
class Html4WriterPublishPartsTestCase(unittest.TestCase):
"""Test case for "html4css1" writer via the publish_parts() interface."""
maxDiff = None
def test_publish(self):
for name, (settings_overrides, cases) in totest.items():
if name == 'syntax_highlight' and not with_pygments:
self.skipTest('syntax highlight requires pygments')
for casenum, (case_input, case_expected) in enumerate(cases):
with self.subTest(id=f'totest[{name!r}][{casenum}]'):
parts = docutils.core.publish_parts(
source=case_input,
writer=html4css1.Writer(),
settings_overrides={
'_disable_config': True,
'strict_visitor': True,
'stylesheet_path': '',
'section_self_link': True,
**settings_overrides,
}
)
self.assertEqual(case_expected, parts['body'])
totest = {}
totest['standard'] = ({}, [
["""\
Simple String
""",
'
Simple String
\n',
],
["""\
Simple String with *markup*
""",
'
Simple String with markup
\n',
],
["""\
Simple String with an even simpler ``inline literal``
""",
'
\n',
],
["""\
One paragraph.
Two paragraphs.
""",
"""\
One paragraph.
Two paragraphs.
""",
],
["""\
A simple `named reference`_ with stuff in between the
reference and the target.
.. _`named reference`: http://www.test.com/test_url
""",
"""\
A simple named reference with stuff in between the
reference and the target.
""",
],
["""\
.. [CIT2022] A citation.
""",
"""\
[CIT2022]
A citation.
""",
],
])
totest['no_title_promotion'] = ({'doctitle_xform': False}, [
["""\
+++++
Title
+++++
Not A Subtitle
==============
Some stuff
Section
-------
Some more stuff
Another Section
...............
And even more stuff
""",
"""\
""",
],
["""\
Not a docinfo.
:This: .. _target:
is
:a:
:simple:
:field: list
""",
"""\
Not a docinfo.
This:
is
a:
simple:
field:
list
""",
],
["""\
Not a docinfo.
:This is: a
:simple field list with loooong field: names
""",
"""\
Not a docinfo.
This is:
a
simple field list with loooong field:
names
""",
],
["""\
Not a docinfo.
.. class:: field-indent-200
:This: is a
:simple: field list with custom indent.
""",
"""\
Not a docinfo.
This:
is a
simple:
field list with custom indent.
""",
],
["""\
Not a docinfo.
.. class:: field-indent-200uf
:This: is a
:simple: field list without custom indent,
because the unit "uf" is invalid.
""",
"""\
Not a docinfo.
This:
is a
simple:
field list without custom indent,
because the unit "uf" is invalid.
""",
],
["""\
.. figure:: dummy.png
:figname: fig:dummy
The figure's caption.
A legend.
The legend's second paragraph.
""",
"""\
The figure's caption.
A legend.
The legend's second paragraph.
""",
],
["""\
.. figure:: dummy.png
The figure's caption, no legend.
""",
"""\
The figure's caption, no legend.
""",
],
["""\
.. figure:: dummy.png
..
A legend without caption.
""",
"""\
A legend without caption.
""",
],
["""\
.. figure:: dummy.png
No caption nor legend.
""",
"""\
No caption nor legend.
""",
],
[f"""\
.. include:: {DATA_ROOT}/multiple-term-definition.xml
:parser: xml
""",
"""\
New in Docutils 0.22
A definition list item may contain several
terms with optional classifier(s).
However, there is currently no corresponding
reStructuredText syntax.
"""
],
])
totest['no_backlinks'] = ({'footnote_backlinks': False}, [
["""\
Two footnotes [#f1]_ [#f2]_ and two citations [once]_ [twice]_.
The latter are referenced a second time [#f2]_ [twice]_.
.. [#f1] referenced once
.. [#f2] referenced twice
.. [once] citation referenced once
.. [twice] citation referenced twice
""",
"""\