From: <mi...@us...> - 2024-08-21 13:44:51
|
Revision: 9913 http://sourceforge.net/p/docutils/code/9913 Author: milde Date: 2024-08-21 13:44:48 +0000 (Wed, 21 Aug 2024) Log Message: ----------- Refactor HTML5 writer tests. New test script "test_html5_polyglot.py": Split basic output tests (which happen to use the "fragment" returned by `publish_parts()` to get the interesting part of the output) from other tests of `publish_parts()` Really test all returned parts in "test_html5_polyglot_parts.py". Fill in parts that are built out of other parts in a helper function instead of pruning parts. Add test cases for input that goes to special parts. Disable default style sheet ("stylesheet_path" setting) by for tests not requiring a stylesheet. Modified Paths: -------------- trunk/docutils/docs/api/publisher.rst trunk/docutils/test/test_writers/test_html5_polyglot_misc.py trunk/docutils/test/test_writers/test_html5_polyglot_parts.py Added Paths: ----------- trunk/docutils/test/test_writers/test_html5_polyglot.py Modified: trunk/docutils/docs/api/publisher.rst =================================================================== --- trunk/docutils/docs/api/publisher.rst 2024-08-21 13:44:37 UTC (rev 9912) +++ trunk/docutils/docs/api/publisher.rst 2024-08-21 13:44:48 UTC (rev 9913) @@ -603,7 +603,7 @@ Default: "restructuredtext". -_`writer` : str | docutils.parsers.Writer +_`writer` : str | docutils.writers.Writer `Writer component name`_ or instance. [#component-names]_ Default: "pseudoxml". Copied: trunk/docutils/test/test_writers/test_html5_polyglot.py (from rev 9912, trunk/docutils/test/test_writers/test_html5_polyglot_parts.py) =================================================================== --- trunk/docutils/test/test_writers/test_html5_polyglot.py (rev 0) +++ trunk/docutils/test/test_writers/test_html5_polyglot.py 2024-08-21 13:44:48 UTC (rev 9913) @@ -0,0 +1,672 @@ +#! /usr/bin/env python3 + +# $Id$ +# Author: reggie dugard <re...@us...> +# Copyright: This module has been placed in the public domain. + +"""Test HTML5 writer output ("fragment" part). + +This is the document body (not HTML <body>). +""" + +from pathlib import Path +import re +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 + +if with_pygments: + import pygments + _pv = re.match(r'^([0-9]+)\.([0-9]*)', pygments.__version__) + if (int(_pv[1]), int(_pv[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: + REQUIRES_PIL = '' + ONLY_LOCAL = 'Can only read local images.' + DUMMY_PNG_NOT_FOUND = "[Errno 2] No such file or directory: 'dummy.png'" + # Pillow reports the absolute path since version 10.3.0 (cf. [bugs: 485]) + if (tuple(int(i) for i in PIL.__version__.split('.')) >= (10, 3)): + DUMMY_PNG_NOT_FOUND = ("[Errno 2] No such file or directory: '%s'" + % Path('dummy.png').resolve()) + SCALING_OUTPUT = 'style="width: 32.0px; height: 32.0px;" ' + NO_PIL_SYSTEM_MESSAGE = '' +else: + REQUIRES_PIL = '\n Requires Python Imaging Library.' + ONLY_LOCAL = 'Requires Python Imaging Library.' + DUMMY_PNG_NOT_FOUND = 'Requires Python Imaging Library.' + SCALING_OUTPUT = '' + NO_PIL_SYSTEM_MESSAGE = ( + '<aside class="system-message">\n' + '<p class="system-message-title">System Message:' + ' WARNING/2 (<span class="docutils literal">' + '<string></span>, line 1)</p>\n' + '<p>Cannot scale image!\n' + ' Could not get size from "/data/blue%20square.png":\n' + ' Requires Python Imaging Library.</p>\n' + '</aside>\n') + + +class Html5WriterPublishPartsTestCase(unittest.TestCase): + """Test case for HTML5 writer via the publish_parts() interface.""" + + maxDiff = None + + def test_publish(self): + if not with_pygments: + del totest['syntax_highlight'] + writer = 'html5' + for name, (settings_overrides, cases) in totest.items(): + 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=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 +""", +'<p>Simple String</p>\n', +], +["""\ +Simple String with *markup* +""", +'<p>Simple String with <em>markup</em></p>\n', +], +["""\ +Simple String with an even simpler ``inline literal`` +""", +'<p>Simple String with an even simpler <span class="docutils literal">inline literal</span></p>\n', +], +["""\ +A simple `anonymous reference`__ + +__ http://www.test.com/test_url +""", +'<p>A simple <a class="reference external" href="http://www.test.com/test_url">anonymous reference</a></p>\n', +], +["""\ +One paragraph. + +Two paragraphs. +""", +"""\ +<p>One paragraph.</p> +<p>Two paragraphs.</p> +""", +], +["""\ +A simple `named reference`_ with stuff in between the +reference and the target. + +.. _`named reference`: http://www.test.com/test_url +""", +"""\ +<p>A simple <a class="reference external" href="http://www.test.com/test_url">named reference</a> with stuff in between the +reference and the target.</p> +""", +], +["""\ +.. [CIT2022] A citation. +""", +"""\ +<div role="list" class="citation-list"> +<div class="citation" id="cit2022" role="doc-biblioentry"> +<span class="label"><span class="fn-bracket">[</span>CIT2022<span class="fn-bracket">]</span></span> +<p>A citation.</p> +</div> +</div> +""", +], +]) + + +totest['no_title_promotion'] = ({'doctitle_xform': False}, [ +["""\ ++++++ +Title ++++++ + +Not A Subtitle +============== + +Some stuff + +Section +------- + +Some more stuff + +Another Section +............... + +And even more stuff +""", +"""\ +<section id="title"> +<h2>Title<a class="self-link" title="link to this section" href="#title"></a></h2> +<section id="not-a-subtitle"> +<h3>Not A Subtitle<a class="self-link" title="link to this section" href="#not-a-subtitle"></a></h3> +<p>Some stuff</p> +<section id="section"> +<h4>Section<a class="self-link" title="link to this section" href="#section"></a></h4> +<p>Some more stuff</p> +<section id="another-section"> +<h5>Another Section<a class="self-link" title="link to this section" href="#another-section"></a></h5> +<p>And even more stuff</p> +</section> +</section> +</section> +</section> +""", +], +["""\ +* bullet +* list +""", +"""\ +<ul class="simple"> +<li><p>bullet</p></li> +<li><p>list</p></li> +</ul> +""", +], +["""\ +.. table:: + :align: right + + +-----+-----+ + | 1 | 2 | + +-----+-----+ + | 3 | 4 | + +-----+-----+ +""", +"""\ +<table class="align-right"> +<tbody> +<tr><td><p>1</p></td> +<td><p>2</p></td> +</tr> +<tr><td><p>3</p></td> +<td><p>4</p></td> +</tr> +</tbody> +</table> +""", +], +["""\ +Not a docinfo. + +:This: .. _target: + + is +:a: +:simple: +:field: list +""", +"""\ +<p>Not a docinfo.</p> +<dl class="field-list simple"> +<dt>This<span class="colon">:</span></dt> +<dd><p id="target">is</p> +</dd> +<dt>a<span class="colon">:</span></dt> +<dd><p></p></dd> +<dt>simple<span class="colon">:</span></dt> +<dd><p></p></dd> +<dt>field<span class="colon">:</span></dt> +<dd><p>list</p> +</dd> +</dl> +""", +], +["""\ +Not a docinfo. + +:This is: a +:simple field list with loooong field: names +""", +"""\ +<p>Not a docinfo.</p> +<dl class="field-list simple"> +<dt>This is<span class="colon">:</span></dt> +<dd><p>a</p> +</dd> +<dt>simple field list with loooong field<span class="colon">:</span></dt> +<dd><p>names</p> +</dd> +</dl> +""", +], +["""\ +Not a docinfo. + +.. class:: field-indent-200 + +:This: is a +:simple: field list with custom indent. +""", +"""\ +<p>Not a docinfo.</p> +<dl class="field-list simple" style="--field-indent: 200px;"> +<dt>This<span class="colon">:</span></dt> +<dd><p>is a</p> +</dd> +<dt>simple<span class="colon">:</span></dt> +<dd><p>field list with custom indent.</p> +</dd> +</dl> +""", +], +["""\ +Not a docinfo. + +.. class:: field-indent-200uf + +:This: is a +:simple: field list without custom indent, + because the unit "uf" is invalid. +""", +"""\ +<p>Not a docinfo.</p> +<dl class="field-indent-200uf field-list simple"> +<dt>This<span class="colon">:</span></dt> +<dd><p>is a</p> +</dd> +<dt>simple<span class="colon">:</span></dt> +<dd><p>field list without custom indent, +because the unit "uf" is invalid.</p> +</dd> +</dl> +""", +], +["""\ +.. figure:: dummy.png + + The figure's caption. + + A legend. + + The legend's second paragraph. +""", +"""\ +<figure> +<img alt="dummy.png" src="dummy.png" /> +<figcaption> +<p>The figure's caption.</p> +<div class="legend"> +<p>A legend.</p> +<p>The legend's second paragraph.</p> +</div> +</figcaption> +</figure> +""", +], +["""\ +.. figure:: dummy.png + + The figure's caption, no legend. +""", +"""\ +<figure> +<img alt="dummy.png" src="dummy.png" /> +<figcaption> +<p>The figure's caption, no legend.</p> +</figcaption> +</figure> +""", +], +["""\ +.. figure:: dummy.png + + .. + + A legend without caption. +""", +"""\ +<figure> +<img alt="dummy.png" src="dummy.png" /> +<figcaption> +<div class="legend"> +<p>A legend without caption.</p> +</div> +</figcaption> +</figure> +""", +], +["""\ +.. figure:: dummy.png + +No caption nor legend. +""", +"""\ +<figure> +<img alt="dummy.png" src="dummy.png" /> +</figure> +<p>No caption nor legend.</p> +""", +], +[f"""\ +.. include:: {DATA_ROOT}/multiple-term-definition.xml + :parser: xml +""", +"""\ +<dl> +<dt>New in Docutils 0.22</dt> +<dd><p>A definition list item may contain several +terms with optional classifier(s).</p> +<p>However, there is currently no corresponding +reStructuredText syntax.</p> +</dd> +<dt>term 2a</dt> +<dt>term 2b</dt> +<dd><p>definition 2</p> +</dd> +<dt>term 3a<span class="classifier">classifier 3a</span><span class="classifier">classifier 3aa</span><dt>term 3b<span class="classifier">classifier 3b</span></dt> +<dd><p>definition 3</p> +</dd> +</dl> +""", +], +]) + + +totest['lazy_loading'] = ({'image_loading': 'lazy', + 'report_level': 4}, [ +["""\ +Lazy loading by default, overridden by :loading: option +("cannot embed" warning ignored). + +.. image:: dummy.png +.. image:: dummy.png + :loading: link +.. figure:: dummy.png +.. figure:: dummy.png + :loading: embed +""", +"""\ +<p>Lazy loading by default, overridden by :loading: option +("cannot embed" warning ignored).</p> +<img alt="dummy.png" loading="lazy" src="dummy.png" /> +<img alt="dummy.png" src="dummy.png" /> +<figure> +<img alt="dummy.png" loading="lazy" src="dummy.png" /> +</figure> +<figure> +<img alt="dummy.png" src="dummy.png" /> +</figure> +""", +], +]) + + +totest['root_prefix'] = ({'root_prefix': ROOT_PREFIX, + 'image_loading': 'embed', + 'warning_stream': '', + }, [ +["""\ +.. image:: /data/blue%20square.png + :scale: 100% +.. figure:: /data/blue%20square.png +""", +'<img alt="/data/blue%20square.png" src="data:image/png;base64,' +'iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAALElEQVR4nO3NMQ' +'EAMAjAsDFjvIhHFCbgSwU0kdXvsn96BwAAAAAAAAAAAIsNnEwBk52VRuMAAAAA' +'SUVORK5CYII="' +f' {SCALING_OUTPUT}/>\n{NO_PIL_SYSTEM_MESSAGE}' +'<figure>\n' +'<img alt="/data/blue%20square.png" src="data:image/png;base64,' +'iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAALElEQVR4nO3NMQ' +'EAMAjAsDFjvIhHFCbgSwU0kdXvsn96BwAAAAAAAAAAAIsNnEwBk52VRuMAAAAA' +'SUVORK5CYII=" />\n' +'</figure>\n', +], +]) + + +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 +""", +"""\ +<p>Two footnotes <a class="brackets" href="#f1" id="footnote-reference-1" role="doc-noteref"><span class="fn-bracket">[</span>1<span class="fn-bracket">]</span></a> <a class="brackets" href="#f2" id="footnote-reference-2" role="doc-noteref"><span class="fn-bracket">[</span>2<span class="fn-bracket">]</span></a> and two citations <a class="citation-reference" href="#once" id="citation-reference-1" role="doc-biblioref">[once]</a> <a class="citation-reference" href="#twice" id="citation-reference-2" role="doc-biblioref">[twice]</a>.</p> +<p>The latter are referenced a second time <a class="brackets" href="#f2" id="footnote-reference-3" role="doc-noteref"><span class="fn-bracket">[</span>2<span class="fn-bracket">]</span></a> <a class="citation-reference" href="#twice" id="citation-reference-3" role="doc-biblioref">[twice]</a>.</p> +<aside class="footnote-list brackets"> +<aside class="footnote brackets" id="f1" role="doc-footnote"> +<span class="label"><span class="fn-bracket">[</span>1<span class="fn-bracket">]</span></span> +<p>referenced once</p> +</aside> +<aside class="footnote brackets" id="f2" role="doc-footnote"> +<span class="label"><span class="fn-bracket">[</span>2<span class="fn-bracket">]</span></span> +<p>referenced twice</p> +</aside> +</aside> +<div role="list" class="citation-list"> +<div class="citation" id="once" role="doc-biblioentry"> +<span class="label"><span class="fn-bracket">[</span>once<span class="fn-bracket">]</span></span> +<p>citation referenced once</p> +</div> +<div class="citation" id="twice" role="doc-biblioentry"> +<span class="label"><span class="fn-bracket">[</span>twice<span class="fn-bracket">]</span></span> +<p>citation referenced twice</p> +</div> +</div> +""", +], +]) + + +totest['syntax_highlight'] = ({'syntax_highlight': 'short', + }, [ +["""\ +.. code:: shell + + cat <<EOF + Hello World + EOF +""", +"""\ +<pre class="code shell literal-block"><code>cat <span class="s"><<EOF +Hello World +EOF</span></code></pre> +""", +], +["""\ +.. role:: shell(code) + :language: shell + +:shell:`cat <<EOF Hello World EOF` +""", +"""\ +<p><code class="shell">cat <span class="s"><<EOF Hello World EOF</span></code></p> +""", +], +]) + + +totest['system_messages'] = ({'math_output': 'mathml', + 'warning_stream': '', + }, [ +["""\ +.. image:: https://dummy.png + :loading: embed +""", +"""\ +<img alt="https://dummy.png" src="https://dummy.png" /> +<aside class="system-message"> +<p class="system-message-title">System Message: ERROR/3 \ +(<span class="docutils literal"><string></span>, line 1)</p> +<p>Cannot embed image "https://dummy.png": + Can only read local images.</p> +</aside> +""", +], +[f"""\ +.. image:: {DATA_ROOT.as_uri()}/circle-broken.svg + :loading: embed +""", +f"""\ +<svg xmlns="http://www.w3.org/2000/svg" + viewBox="0 0 10 10"> + <circle cx="5" cy="5" r="4" fill="lightblue" x/> +</svg> + +<aside class="system-message"> +<p class="system-message-title">System Message: ERROR/3 (<span class="docutils literal"><string></span>, line 1)</p> +<p>Cannot parse SVG image "{DATA_ROOT.as_uri()}/circle-broken.svg": + not well-formed (invalid token): line 3, column 48</p> +</aside> +""" +], +[r"""Broken :math:`\sin \my`. +""", +"""\ +<p>Broken <span class="math problematic">\\sin \\my</span>.</p> +<aside class="system-message"> +<p class="system-message-title">System Message: WARNING/2 (<span class="docutils literal"><string></span>, line 1)</p> +<p>Unknown LaTeX command "\\my".</p> +</aside> +"""], +]) + +totest['system_messages-PIL'] = ({'math_output': 'mathml', + 'warning_stream': '', + }, [ +["""\ +.. image:: dummy.png + :scale: 100% + :loading: embed +""", +f"""\ +<img alt="dummy.png" src="dummy.png" /> +<aside class="system-message"> +<p class="system-message-title">System Message: WARNING/2 \ +(<span class="docutils literal"><string></span>, line 1)</p> +<p>Cannot scale image! + Could not get size from "dummy.png": + {DUMMY_PNG_NOT_FOUND}</p> +</aside> +<aside class="system-message"> +<p class="system-message-title">System Message: ERROR/3 \ +(<span class="docutils literal"><string></span>, line 1)</p> +<p>Cannot embed image "dummy.png": + [Errno 2] No such file or directory: 'dummy.png'</p> +</aside> +""", +], +["""\ +.. image:: dummy.mp4 + :scale: 100% +""", +f"""\ +<video src="dummy.mp4" title="dummy.mp4"> +<a href="dummy.mp4">dummy.mp4</a> +</video> +<aside class="system-message"> +<p class="system-message-title">System Message: WARNING/2 \ +(<span class="docutils literal"><string></span>, line 1)</p> +<p>Cannot scale image! + Could not get size from "dummy.mp4":{REQUIRES_PIL} + PIL cannot read video images.</p> +</aside> +""", +], +["""\ +.. image:: https://dummy.png + :scale: 100% + :loading: embed +""", +f"""\ +<img alt="https://dummy.png" src="https://dummy.png" /> +<aside class="system-message"> +<p class="system-message-title">System Message: WARNING/2 \ +(<span class="docutils literal"><string></span>, line 1)</p> +<p>Cannot scale image! + Could not get size from "https://dummy.png": + {ONLY_LOCAL}</p> +</aside> +<aside class="system-message"> +<p class="system-message-title">System Message: ERROR/3 \ +(<span class="docutils literal"><string></span>, line 1)</p> +<p>Cannot embed image "https://dummy.png": + Can only read local images.</p> +</aside> +""", +], +]) + +totest['no_system_messages'] = ({'math_output': 'mathml', + 'report_level': 4, + 'warning_stream': '', + }, [ +["""\ +.. image:: dummy.png + :scale: 100% + :loading: embed + +.. image:: dummy.mp4 + :scale: 100% +""", +"""\ +<img alt="dummy.png" src="dummy.png" /> +<video src="dummy.mp4" title="dummy.mp4"> +<a href="dummy.mp4">dummy.mp4</a> +</video> +""", +], +[f"""\ +.. image:: {DATA_ROOT.as_uri()}/circle-broken.svg + :loading: embed +""", +"""\ +<svg xmlns="http://www.w3.org/2000/svg" + viewBox="0 0 10 10"> + <circle cx="5" cy="5" r="4" fill="lightblue" x/> +</svg> + +"""], +[r'Broken :math:`\sin \my`.', +'<p>Broken <tt class="math">\\sin \\my</tt>.</p>\n' +], +]) + + +if __name__ == '__main__': + unittest.main() Property changes on: trunk/docutils/test/test_writers/test_html5_polyglot.py ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Author Date Id Revision \ No newline at end of property Modified: trunk/docutils/test/test_writers/test_html5_polyglot_misc.py =================================================================== --- trunk/docutils/test/test_writers/test_html5_polyglot_misc.py 2024-08-21 13:44:37 UTC (rev 9912) +++ trunk/docutils/test/test_writers/test_html5_polyglot_misc.py 2024-08-21 13:44:48 UTC (rev 9913) @@ -36,7 +36,7 @@ # error handler. settings_overrides = { 'output_encoding': 'latin1', - 'stylesheet': '', + 'stylesheet_path': '', '_disable_config': True} result = core.publish_string( 'EUR = \u20ac', writer='html5_polyglot', @@ -49,7 +49,6 @@ class MovingArgsTestCase(unittest.TestCase): mys = {'stylesheet_path': '', - # 'embed_stylesheet': False, '_disable_config': True, } @@ -99,8 +98,8 @@ mys = {'_disable_config': True} styles = core.publish_parts(self.data, writer='html5_polyglot', settings_overrides=mys)['stylesheet'] - self.assertIn('Minimal style sheet ' - 'for the HTML output of Docutils.', styles) + self.assertIn('Minimal style sheet for the HTML output of Docutils.', + styles) def test_default_stylesheet_linked(self): # default style sheet, linked @@ -141,7 +140,8 @@ styles = core.publish_parts(self.data, writer='html5_polyglot', settings_overrides=mys)['stylesheet'] if (TEST_ROOT / '../docutils/writers/html5_polyglot/').is_dir(): - self.assertIn('docutils/writers/html5_polyglot/minimal.css', styles) + self.assertIn('docutils/writers/html5_polyglot/minimal.css', + styles) self.assertIn(f'href="{ham_css}"', styles) def test_custom_stylesheet_dir_embedded(self): Modified: trunk/docutils/test/test_writers/test_html5_polyglot_parts.py =================================================================== --- trunk/docutils/test/test_writers/test_html5_polyglot_parts.py 2024-08-21 13:44:37 UTC (rev 9912) +++ trunk/docutils/test/test_writers/test_html5_polyglot_parts.py 2024-08-21 13:44:48 UTC (rev 9913) @@ -5,15 +5,12 @@ # Copyright: This module has been placed in the public domain. """ -Test for fragment code in HTML writer. +Test `core.publish_parts()`__ with the HTML5 writer. -Note: the 'body' and 'whole' entries have been removed from the parts -dictionaries (redundant), along with 'meta' and 'stylesheet' entries with -standard values, and any entries with empty values. +__ https://docutils.sourceforge.io/docs/api/publisher.html#publish-parts """ from pathlib import Path -import re import sys import unittest @@ -24,182 +21,136 @@ 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 html5_polyglot -if with_pygments: - import pygments - _pv = re.match(r'^([0-9]+)\.([0-9]*)', pygments.__version__) - if (int(_pv[1]), int(_pv[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: - REQUIRES_PIL = '' - ONLY_LOCAL = 'Can only read local images.' - DUMMY_PNG_NOT_FOUND = "[Errno 2] No such file or directory: 'dummy.png'" - # Pillow reports the absolute path since version 10.3.0 (cf. [bugs: 485]) - if (tuple(int(i) for i in PIL.__version__.split('.')) >= (10, 3)): - DUMMY_PNG_NOT_FOUND = ("[Errno 2] No such file or directory: '%s'" - % Path('dummy.png').resolve()) - SCALING_OUTPUT = 'style="width: 32.0px; height: 32.0px;" ' - NO_PIL_SYSTEM_MESSAGE = '' -else: - REQUIRES_PIL = '\n Requires Python Imaging Library.' - ONLY_LOCAL = 'Requires Python Imaging Library.' - DUMMY_PNG_NOT_FOUND = 'Requires Python Imaging Library.' - SCALING_OUTPUT = '' - NO_PIL_SYSTEM_MESSAGE = ( - '<aside class="system-message">\n' - '<p class="system-message-title">System Message:' - ' WARNING/2 (<span class="docutils literal">' - '<string></span>, line 1)</p>\n' - '<p>Cannot scale image!\n' - ' Could not get size from "/data/blue%20square.png":\n' - ' Requires Python Imaging Library.</p>\n' - '</aside>\n') +# 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': '</head>\n<body>\n{header}<main>\n', + 'body_suffix': '</main>\n{footer}</body>\n</html>\n', + 'docinfo': '', + 'encoding': 'utf-8', + 'errors': 'xmlcharrefreplace', + 'footer': '', + 'fragment': '', + 'head': '{meta}<title>{metatitle}</title>\n', + 'head_prefix': + '<!DOCTYPE html>\n' + '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">\n' + '<head>\n', + 'header': '', + 'html_body': '{header}<main>\n{fragment}</main>\n{footer}', + 'html_head': '{meta}<title>{metatitle}</title>\n', + 'html_prolog': '<!DOCTYPE html>\n', + 'html_subtitle': '', + 'html_title': '', + 'meta': '<meta charset="%s" />\n' + f'<meta name="generator" content="Docutils {docutils.__version__}: https://docutils.sourceforge.io/" />\n' + '<meta name="viewport" content="width=device-width, initial-scale=1" />\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-<meta> 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 Html5WriterPublishPartsTestCase(unittest.TestCase): - """Test case for HTML writer via the publish_parts interface.""" + """Test HTML5 writer `publish_parts()` interface.""" maxDiff = None - def test_publish(self): - if not with_pygments: - del totest['syntax_highlight'] - writer = 'html5' + def test_publish_parts(self): for name, (settings_overrides, cases) in totest.items(): - 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=writer, - settings_overrides={ - '_disable_config': True, - 'strict_visitor': True, - 'stylesheet_path': '', - 'section_self_link': True, - **settings_overrides, - } - ) - # if the formatted output is a just single fragment, - # compare the text directly for a nicer diff on failure - formatted = self.format_output(parts) - if len(formatted) == 1 and 'fragment' in formatted: - fragment = formatted['fragment'] - self.assertEqual(case_expected, fragment) - else: - self.assertEqual(case_expected, formatted) + 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=html5_polyglot.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]}') - standard_content_type_template = '<meta charset="%s" />\n' - standard_generator_template = ( - '<meta name="generator"' - f' content="Docutils {docutils.__version__}: ' - 'https://docutils.sourceforge.io/" />\n') - standard_viewport_value = ( - '<meta name="viewport"' - ' content="width=device-width, initial-scale=1" />\n') - standard_html_meta_value = (standard_content_type_template - + standard_generator_template - + standard_viewport_value) - standard_meta_value = standard_html_meta_value % 'utf-8' - standard_html_prolog = '<!DOCTYPE html>\n' - standard_html_body_template = '<main>\n%s</main>\n' - def format_output(self, parts): - """Minimize & standardize the output.""" - # remove redundant parts & uninteresting parts: - del parts['whole'] - assert parts['body'] == parts['fragment'] - del parts['body'] - del parts['body_pre_docinfo'] - del parts['body_prefix'] - del parts['body_suffix'] - del parts['head'] - del parts['head_prefix'] - del parts['encoding'] - del parts['errors'] - del parts['version'] - # remove standard portions: - parts['meta'] = parts['meta'].replace(self.standard_meta_value, '') - parts['html_head'] = parts['html_head'].replace( - self.standard_html_meta_value, '...') - parts['html_head'] = parts['html_head'].replace( - '...<title><string></title>\n', '') - parts['html_prolog'] = parts['html_prolog'].replace( - self.standard_html_prolog, '') - parts['html_body'] = parts['html_body'].replace( - self.standard_html_body_template % parts['fragment'], '') - # remove empty keys and return - return {k: v for k, v in parts.items() if v} - - totest = {} totest['standard'] = ({}, [ -["""\ -Simple String -""", -'<p>Simple String</p>\n', -], -["""\ -Simple String with *markup* -""", -'<p>Simple String with <em>markup</em></p>\n', -], -["""\ -Simple String with an even simpler ``inline literal`` -""", -'<p>Simple String with an even simpler <span class="docutils literal">inline literal</span></p>\n', -], -["""\ -A simple `anonymous reference`__ - -__ http://www.test.com/test_url -""", -'<p>A simple <a class="reference external" href="http://www.test.com/test_url">anonymous reference</a></p>\n', -], -["""\ -One paragraph. - -Two paragraphs. -""", -"""\ -<p>One paragraph.</p> -<p>Two paragraphs.</p> -""", -], -["""\ -A simple `named reference`_ with stuff in between the -reference and the target. - -.. _`named reference`: http://www.test.com/test_url -""", -"""\ -<p>A simple <a class="reference external" href="http://www.test.com/test_url">named reference</a> with stuff in between the -reference and the target.</p> -""", -], -["""\ -.. [CIT2022] A citation. -""", -"""\ -<div role="list" class="citation-list"> -<div class="citation" id="cit2022" role="doc-biblioentry"> -<span class="label"><span class="fn-bracket">[</span>CIT2022<span class="fn-bracket">]</span></span> -<p>A citation.</p> -</div> -</div> -""", -], -["""\ + ['', # empty input string + {} # results in default parts + ], + ['Simple String with *markup*', + {'fragment': '<p>Simple String with <em>markup</em></p>\n'} + ], + ['.. header:: custom document header\n\n' + 'A paragraph.', + {'header': '<header>\n<p>custom document header</p>\n</header>\n', + 'body_prefix': '</head>\n' + '<body>\n' + '<header>\n' + '<p>custom document header</p>\n</header>\n' + '<main>\n', + 'fragment': '<p>A paragraph.</p>\n', + } + ], + ['.. footer:: custom document footer\n\n' + 'A paragraph.', + {'footer': '<footer>\n<p>custom document footer</p>\n</footer>\n', + 'fragment': '<p>A paragraph.</p>\n', + } + ], + ["""\ +++++ Title +++++ @@ -219,7 +170,10 @@ And even more stuff """, -{'fragment': """\ + {'body_pre_docinfo': '<h1 class="title">Title</h1>\n' + '<p class="subtitle" id="subtitle">Subtitle</p>\n', + 'body_prefix': '</head>\n<body>\n<main id="title">\n', + 'fragment': """\ <p>Some stuff</p> <section id="section"> <h2>Section<a class="self-link" title="link to this section" href="#section"></a></h2> @@ -230,7 +184,7 @@ </section> </section> """, - 'html_body': """\ + 'html_body': """\ <main id="title"> <h1 class="title">Title</h1> <p class="subtitle" id="subtitle">Subtitle</p> @@ -245,13 +199,12 @@ </section> </main> """, - 'html_head': '...<title>Title</title>\n', - 'html_subtitle': '<p class="subtitle" id="subtitle">Subtitle</p>\n', - 'html_title': '<h1 class="title">Title</h1>\n', - 'subtitle': 'Subtitle', - 'title': 'Title' -}], -["""\ + 'html_subtitle': '<p class="subtitle" id="subtitle">Subtitle</p>\n', + 'html_title': '<h1 class="title">Title</h1>\n', + 'subtitle': 'Subtitle', + 'title': 'Title' + }], + ["""\ +++++ Title +++++ @@ -260,14 +213,16 @@ Some stuff """, -{'docinfo': """\ + {'body_pre_docinfo': '<h1 class="title">Title</h1>\n', + 'body_prefix': '</head>\n<body>\n<main id="title">\n', + 'docinfo': """\ <dl class="docinfo simple"> <dt class="author">Author<span class="colon">:</span></dt> <dd class="author"><p>me</p></dd> </dl> """, - 'fragment': '<p>Some stuff</p>\n', - 'html_body': """\ + 'fragment': '<p>Some stuff</p>\n', + 'html_body': """\ <main id="title"> <h1 class="title">Title</h1> <dl class="docinfo simple"> @@ -277,63 +232,14 @@ <p>Some stuff</p> </main> """, - 'html_head': """\ -...<meta name="author" content="me" /> -<title>Title</title> -""", - 'html_title': '<h1 class="title">Title</h1>\n', - 'meta': '<meta name="author" content="me" />\n', - 'title': 'Title' -}], -]) + 'html_title': '<h1 class="title">Title</h1>\n', + 'meta': default_parts['meta'] + '<meta name="author" content="me" />\n', + 'title': 'Title' + }], + ]) -totest['standard'] = ({'output_encoding': 'unicode'}, [ -["""\ -Simple String -""", -{'fragment': '<p>Simple String</p>\n', - 'meta': """\ -<meta name="generator" content="Docutils 0.22b.dev: https://docutils.sourceforge.io/" /> -<meta name="viewport" content="width=device-width, initial-scale=1" /> -""", -}], -]) - totest['no_title_promotion'] = ({'doctitle_xform': False}, [ -["""\ -Simple String -""", -'<p>Simple String</p>\n', -], -["""\ -Simple String with *markup* -""", -'<p>Simple String with <em>markup</em></p>\n', -], -["""\ -Simple String with an even simpler ``inline literal`` -""", -'<p>Simple String with an even simpler <span class="docutils literal">inline literal</span></p>\n', -], -["""\ -A simple `anonymous reference`__ - -__ http://www.test.com/test_url -""", -'<p>A simple <a class="reference external" href="http://www.test.com/test_url">anonymous reference</a></p>\n', -], -["""\ -A simple `named reference`_ with stuff in between the -reference and the target. - -.. _`named reference`: http://www.test.com/test_url -""", -"""\ -<p>A simple <a class="reference external" href="http://www.test.com/test_url">named reference</a> with stuff in between the -reference and the target.</p> -""", -], -["""\ + ["""\ +++++ Title +++++ @@ -353,7 +259,7 @@ And even more stuff """, -"""\ + {'fragment': """\ <section id="title"> <h2>Title<a class="self-link" title="link to this section" href="#title"></a></h2> <section id="not-a-subtitle"> @@ -369,486 +275,19 @@ </section> </section> </section> -""", -], -["""\ -* bullet -* list -""", -"""\ -<ul class="simple"> -<li><p>bullet</p></li> -<li><p>list</p></li> -</ul> -""", -], -["""\ -.. table:: - :align: right +"""}, + ], + ]) - +-----+-----+ - | 1 | 2 | - +-----+-----+ - | 3 | 4 | - +-----+-----+ -""", -"""\ -<table class="align-right"> -<tbody> -<tr><td><p>1</p></td> -<td><p>2</p></td> -</tr> -<tr><td><p>3</p></td> -<td><p>4</p></td> -</tr> -</tbody> -</table> -""", -], -["""\ -Not a docinfo. +totest['unknown-encoding'] = ({'output_encoding': 'unicode'}, [ + ['Simple String\n', + {'encoding': 'unicode', + 'fragment': '<p>Simple String</p>\n', + 'html_head': f'{default_parts["meta"]}<title>{{metatitle}}</title>\n', + 'meta': default_parts['meta'].removeprefix('<meta charset="%s" />\n'), + }], + ]) -:This: .. _target: - is -:a: -:simple: -:field: list -""", -"""\ -<p>Not a docinfo.</p> -<dl class="field-list simple"> -<dt>This<span class="colon">:</span></dt> -<dd><p id="target">is</p> -</dd> -<dt>a<span class="colon">:</span></dt> -<dd><p></p></dd> -<dt>simple<span class="colon">:</span></dt> -<dd><p></p></dd> -<dt>field<span class="colon">:</span></dt> -<dd><p>list</p> -</dd> -</dl> -""", -], -["""\ -Not a docinfo. - -:This is: a -:simple field list with loooong field: names -""", -"""\ -<p>Not a docinfo.</p> -<dl class="field-list simple"> -<dt>This is<span class="colon">:</span></dt> -<dd><p>a</p> -</dd> -<dt>simple field list with loooong field<span class="colon">:</span></dt> -<dd><p>names</p> -</dd> -</dl> -""", -], -["""\ -Not a docinfo. - -.. class:: field-indent-200 - -:This: is a -:simple: field list with custom indent. -""", -"""\ -<p>Not a docinfo.</p> -<dl class="field-list simple" style="--field-indent: 200px;"> -<dt>This<span class="colon">:</span></dt> -<dd><p>is a</p> -</dd> -<dt>simple<span class="colon">:</span></dt> -<dd><p>field list with custom indent.</p> -</dd> -</dl> -""", -], -["""\ -Not a docinfo. - -.. class:: field-indent-200uf - -:This: is a -:simple: field list without custom indent, - because the unit "uf" is invalid. -""", -"""\ -<p>Not a docinfo.</p> -<dl class="field-indent-200uf field-list simple"> -<dt>This<span class="colon">:</span></dt> -<dd><p>is a</p> -</dd> -<dt>simple<span class="colon">:</span></dt> -<dd><p>field list without custom indent, -because the unit "uf" is invalid.</p> -</dd> -</dl> -""", -], -["""\ -.. figure:: dummy.png - - The figure's caption. - - A legend. - - The legend's second paragraph. -""", -"""\ -<figure> -<img alt="dummy.png" src="dummy.png" /> -<figcaption> -<p>The figure's caption.</p> -<div class="legend"> -<p>A legend.</p> -<p>The legend's second paragraph.</p> -</div> -</figcaption> -</figure> -""", -], -["""\ -.. figure:: dummy.png - - The figure's caption, no legend. -""", -"""\ -<figure> -<img alt="dummy.png" src="dummy.png" /> -<figcaption> -<p>The figure's caption, no legend.</p> -</figcaption> -</figure> -""", -], -["""\ -.. figure:: dummy.png - - .. - - A legend without caption. -""", -"""\ -<figure> -<img alt="dummy.png" src="dummy.png" /> -<figcaption> -<div class="legend"> -<p>A legend without caption.</p> -</div> -</figcaption> -</figure> -""", -], -["""\ -.. figure:: dummy.png - -No caption nor legend. -""", -"""\ -<figure> -<img alt="dummy.png" src="dummy.png" /> -</figure> -<p>No caption nor legend.</p> -""", -], -[f"""\ -.. include:: {DATA_ROOT}/multiple-term-definition.xml - :parser: xml -""", -"""\ -<dl> -<dt>New in Docutils 0.22</dt> -<dd><p>A definition list item may contain several -terms with optional classifier(s).</p> -<p>However, there is currently no corresponding -reStructuredText syntax.</p> -</dd> -<dt>term 2a</dt> -<dt>term 2b</dt> -<dd><p>definition 2</p> -</dd> -<dt>term 3a<span class="classifier">classifier 3a</span><span class="classifier">classifier 3aa</span><dt>term 3b<span class="classifier">classifier 3b</span></dt> -<dd><p>definition 3</p> -</dd> -</dl> -""", -], -]) - - -totest['lazy_loading'] = ({'image_loading': 'lazy', - 'report_level': 4}, [ -["""\ -Lazy loading by default, overridden by :loading: option -("cannot embed" warning ignored). - -.. image:: dummy.png -.. image:: dummy.png - :loading: link -.. figure:: dummy.png -.. figure:: dummy.png - :loading: embed -""", -"""\ -<p>Lazy loading by default, overridden by :loading: option -("cannot embed" warning ignored).</p> -<img alt="dummy.png" loading="lazy" src="dummy.png" /> -<img alt="dummy.png" src="dummy.png" /> -<figure> -<img alt="dummy.png" loading="lazy" src="dummy.png" /> -</figure> -<figure> -<img alt="dummy.png" src="dummy.png" /> -</figure> -""", -], -]) - - -totest['root_prefix'] = ({'root_prefix': ROOT_PREFIX, - 'image_loading': 'embed', - 'warning_stream': '', - }, [ -["""\ -.. image:: /data/blue%20square.png - :scale: 100% -.. figure:: /data/blue%20square.png -""", -'<img alt="/data/blue%20square.png" src="data:image/png;base64,' -'iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAALElEQVR4nO3NMQ' -'EAMAjAsDFjvIhHFCbgSwU0kdXvsn96BwAAAAAAAAAAAIsNnEwBk52VRuMAAAAA' -'SUVORK5CYII="' -f' {SCALING_OUTPUT}/>\n{NO_PIL_SYSTEM_MESSAGE}' -'<figure>\n' -'<img alt="/data/blue%20square.png" src="data:image/png;base64,' -'iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAALElEQVR4nO3NMQ' -'EAMAjAsDFjvIhHFCbgSwU0kdXvsn96BwAAAAAAAAAAAIsNnEwBk52VRuMAAAAA' -'SUVORK5CYII=" />\n' -'</figure>\n', -], -]) - - -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 -""", -"""\ -<p>Two footnotes <a class="brackets" href="#f1" id="footnote-reference-1" role="doc-noteref"><span class="fn-bracket">[</span>1<span class="fn-bracket">]</span></a> <a class="brackets" href="#f2" id="footnote-reference-2" role="doc-noteref"><span class="fn-bracket">[</span>2<span class="fn-bracket">]</span></a> and two citations <a class="citation-reference" href="#once" id="citation-reference-1" role="doc-biblioref">[once]</a> <a class="citation-reference" href="#twice" id="citation-reference-2" role="doc-biblioref">[twice]</a>.</p> -<p>The latter are referenced a second time <a class="brackets" href="#f2" id="footnote-reference-3" role="doc-noteref"><span class="fn-bracket">[</span>2<span class="fn-bracket">]</span></a> <a class="citation-reference" href="#twice" id="citation-reference-3" role="doc-biblioref">[twice]</a>.</p> -<aside class="footnote-list brackets"> -<aside class="footnote brackets" id="f1" role="doc-footnote"> -<span class="label"><span class="fn-bracket">[</span>1<span class="fn-bracket">]</span></span> -<p>referenced once</p> -</aside> -<aside class="footnote brackets" id="f2" role="doc-footnote"> -<span class="label"><span class="fn-bracket">[</span>2<span class="fn-bracket">]</span></span> -<p>referenced twice</p> -</aside> -</aside> -<div role="list" class="citation-list"> -<div class="citation" id="once" role="doc-biblioentry"> -<span class="label"><span class="fn-bracket">[</span>once<span class="fn-bracket">]</span></span> -<p>citation referenced once</p> -</div> -<div class="citation" id="twice" role="doc-biblioentry"> -<span class="label"><span class="fn-bracket">[</span>twice<span class="fn-bracket">]</span></span> -<p>citation referenced twice</p> -</div> -</div> -""", -], -]) - - -totest['syntax_highlight'] = ({'syntax_highlight': 'short', - }, [ -["""\ -.. code:: shell - - cat <<EOF - Hello World - EOF -""", -"""\ -<pre class="code shell literal-block"><code>cat <span class="s"><<EOF -Hello World -EOF</span></code></pre> -""", -], -["""\ -.. role:: shell(code) - :language: shell - -:shell:`cat <<EOF Hello World EOF` -""", -"""\ -<p><code class="shell">cat <span class="s"><<EOF Hello World EOF</span></code></p> -""", -], -]) - - -totest['system_messages'] = ({'math_output': 'mathml', - 'warning_stream': '', - }, [ -["""\ -.. image:: https://dummy.png - :loading: embed -""", -"""\ -<img alt="https://dummy.png" src="https://dummy.png" /> -<aside class="system-message"> -<p class="system-message-title">System Message: ERROR/3 \ -(<span class="docutils literal"><string></span>, line 1)</p> -<p>Cannot embed image "https://dummy.png": - Can only read local images.</p> -</aside> -""", -], -[f"""\ -.. image:: {DATA_ROOT.as_uri()}/circle-broken.svg - :loading: embed -""", -f"""\ -<svg xmlns="http://www.w3.org/2000/svg" - viewBox="0 0 10 10"> - <circle cx="5" cy="5" r="4" fill="lightblue" x/> -</svg> - -<aside class="system-message"> -<p class="system-message-title">System Message: ERROR/3 (<span class="docutils literal"><string></span>, line 1)</p> -<p>Cannot parse SVG image "{DATA_ROOT.as_uri()}/circle-broken.svg": - not well-formed (invalid token): line 3, column 48</p> -</aside> -""" -], -[r"""Broken :math:`\sin \my`. -""", -"""\ -<p>Broken <span class="math problematic">\\sin \\my</span>.</p> -<aside class="system-message"> -<p class="system-message-title">System Message: WARNING/2 (<span class="docutils literal"><string></span>, line 1)</p> -<p>Unknown LaTeX command "\\my".</p> -</aside> -"""], -]) - -totest['system_messages-PIL'] = ({'math_output': 'mathml', - 'warning_stream': '', - }, [ -["""\ -.. image:: dummy.png - :scale: 100% - :loading: embed -""", -f"""\ -<img alt="dummy.png" src="dummy.png" /> -<aside class="system-message"> -<p class="system-message-title">System Message: WARNING/2 \ -(<span class="docutils literal"><string></span>, line 1)</p> -<p>Cannot scale image! - Could not get size from "dummy.png": - {DUMMY_PNG_NOT_FOUND}</p> -</aside> -<aside class="system-message"> -<p class="system-message-title">System Message: ERROR/3 \ -(<span class="docutils literal"><string></span>, line 1)</p> -<p>Cannot embed image "dummy.png": - [Errno 2] No such file or directory: 'dummy.png'</p> -</aside> -""", -], -["""\ -.. image:: dummy.mp4 - :scale: 100% -""", -f"""\ -<video src="dummy.mp4" title="dummy.mp4"> -<a href="dummy.mp4">dummy.mp4</a> -</video> -<aside class="system-message"> -<p class="system-message-title">System Message: WARNING/2 \ -(<span class="docutils literal"><string></span>, line 1)</p> -<p>Cannot scale image! - Could not get size from "dummy.mp4":{REQUIRES_PIL} - PIL cannot read video images.</p> -</aside> -""", -], -["""\ -.. image:: https://dummy.png - :scale: 100% - :loading: embed -""", -f"""\ -<img alt="https://dummy.png" src="https://dummy.png" /> -<aside class="system-message"> -<p class="system-message-title">System Message: WARNING/2 \ -(<span class="docutils literal"><string></span>, line 1)</p> -<p>Cannot scale image! - Could not get size from "https://dummy.png": - {ONLY_LOCAL}</p> -</aside> -<aside class="system-message"> -<p class="system-message-title">System Message: ERROR/3 \ -(<span class="docutils literal"><string></span>, line 1)</p> -<p>Cannot embed image "https://dummy.png": - Can only read local images.</p> -</aside> -""", -], -]) - -totest['no_system_messages'] = ({'math_output': 'mathml', - 'report_level': 4, - 'warning_stream': '', - }, [ -["""\ -.. image:: dummy.png - :scale: 100% - :loading: embed - -.. image:: dummy.mp4 - :scale: 100% -""", -"""\ -<img alt="dummy.png" src="dummy.png" /> -<video src="dummy.mp4" title="dummy.mp4"> -<a href="dummy.mp4">dummy.mp4</a> -</video> -""", -], -[f"""\ -.. image:: {DATA_ROOT.as_uri()}/circle-broken.svg - :loading: embed -""", -"""\ -<svg xmlns="http://www.w3.org/2000/svg" - viewBox="0 0 10 10"> - <circle cx="5" cy="5" r="4" fill="lightblue" x/> -</svg> - -"""], -[r'Broken :math:`\sin \my`.', -'<p>Broken <tt class="math">\\sin \\my</tt>.</p>\n' -], -]) - - if __name__ == '__main__': unittest.main() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |