#! /usr/bin/env python3 # $Id: test_html4css1_parts.py 10005 2024-12-18 22:03:27Z milde $ # Author: reggie dugard # Maintainer: docutils-develop@lists.sourceforge.net # Copyright: This module has been placed in the public domain. """ Test `core.publish_parts()`__ with the html4css1 writer. __ https://docutils.sourceforge.io/docs/api/publisher.html#publish-parts """ 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.writers import html4css1 # 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() # Parts returned by `publish_parts()` for the HTML5 writer by default: # * empty input string # * default configuration settings. # See format_parts() below for the substitution of unresolved format markers. default_parts = { 'body': '{fragment}', 'body_pre_docinfo': '', 'body_prefix': '\n\n{header}
\n', 'body_suffix': '
\n{footer}\n\n', 'docinfo': '', 'encoding': 'utf-8', 'errors': 'xmlcharrefreplace', 'footer': '', 'fragment': '', 'head': '{meta}{metatitle}\n', 'head_prefix': '\n' '\n' '\n' '\n', 'header': '', 'html_body': '{header}
\n{fragment}
\n{footer}', 'html_head': '{meta}{metatitle}\n', 'html_prolog': '\n' '\n', 'html_subtitle': '', 'html_title': '', 'meta': '\n' f'\n', 'stylesheet': '', 'subtitle': '', 'title': '', 'version': f'{docutils.__version__}', 'whole': '{head_prefix}\n' '{head}\n' '{stylesheet}\n' '{body_prefix}\n' '{body_pre_docinfo}\n' '{docinfo}\n' '{body}\n' '{body_suffix}\n', } def format_parts(parts): # fill in part values that depend on other parts # https://docutils.sourceforge.io/docs/api/publisher.html#html4-writer # metadata title: either the visible title or document['source'] metatitle = parts['title'] or '<string>' # "html_head" leaves the encoding unresolved, as "%s": parts['html_head'] = parts['html_head'].format(metatitle=metatitle, **parts) # now resolve encoding: try: parts['meta'] = parts['meta'] % parts['encoding'] except TypeError: # charset- missing if encoding is 'unicode' pass parts['head'] = parts['head'].format(metatitle=metatitle, **parts) parts['body_prefix'] = parts['body_prefix'].format(**parts) parts['body'] = parts['body'].format(**parts) parts['body_suffix'] = parts['body_suffix'].format(**parts) parts['html_body'] = parts['html_body'].format(**parts) # newlines are stripped when parts are used to expand the template file parts['whole'] = parts['whole'].format(**{k: v.rstrip('\n') for k, v in parts.items()}) return parts class Html4WriterPublishPartsTestCase(unittest.TestCase): """Test "html4css1" writer `publish_parts()` interface.""" maxDiff = None def test_publish_parts(self): for name, (settings_overrides, cases) in totest.items(): for casenum, (case_input, expected_parts) in enumerate(cases): _stgns = {'_disable_config': True, 'strict_visitor': True, 'stylesheet_path': '', 'section_self_link': True, **settings_overrides, } parts = docutils.core.publish_parts(source=case_input, writer=html4css1.Writer(), settings_overrides=_stgns, ) expected = format_parts(default_parts | expected_parts) for key in parts.keys(): with self.subTest(id=f'totest[{name!r}][{casenum}][{key}]'): self.assertEqual(f'{expected[key]}', f'{parts[key]}') totest = {} totest['standard'] = ({}, [ ['', # empty input string {} # results in default parts ], ['Simple String with *markup*', {'fragment': '

Simple String with markup

\n'} ], ['.. header:: custom document header\n\n' 'A paragraph.', {'header': '
\ncustom document header\n' '
\n
\n', 'body_prefix': '\n' '\n' '
\n' 'custom document header\n' '
\n' '
\n' '
\n', 'fragment': '

A paragraph.

\n', } ], ['.. footer:: custom document footer\n\n' 'A paragraph.', {'footer': '\n', 'fragment': '

A paragraph.

\n', } ], ["""\ +++++ Title +++++ Subtitle ======== Some stuff Section ------- Some more stuff Another Section ............... And even more stuff """, {'body_pre_docinfo': '

Title

\n' '

Subtitle

\n', 'body_prefix': '\n\n
\n', 'fragment': """\

Some stuff

Section

Some more stuff

Another Section

And even more stuff

""", 'html_body': """\

Title

Subtitle

Some stuff

Section

Some more stuff

Another Section

And even more stuff

""", 'html_subtitle': '

Subtitle

\n', 'html_title': '

Title

\n', 'subtitle': 'Subtitle', 'title': 'Title' }], ["""\ +++++ Title +++++ :author: me Some stuff """, {'body_pre_docinfo': '

Title

\n', 'body_prefix': '\n\n
\n', 'docinfo': """\
Author: me
""", 'fragment': '

Some stuff

\n', 'html_body': """\

Title

Author: me

Some stuff

""", 'html_title': '

Title

\n', 'meta': default_parts['meta'] + '\n', 'title': 'Title' }], ]) totest['no_title_promotion'] = ({'doctitle_xform': False}, [ ["""\ +++++ Title +++++ Not A Subtitle ============== Some stuff Section ------- Some more stuff Another Section ............... And even more stuff """, {'fragment': """\

Title

Not A Subtitle

Some stuff

Section

Some more stuff

Another Section

And even more stuff

"""}, ], ]) totest['unknown-encoding'] = ({'output_encoding': 'unicode'}, [ ['Simple String\n', {'encoding': 'unicode', 'fragment': '

Simple String

\n', 'head_prefix': '\n' '\n' '\n' '\n', 'html_head': f'{default_parts["meta"]}{{metatitle}}\n', 'meta': f'\n', }], ]) if __name__ == '__main__': unittest.main()