diff options
| -rw-r--r-- | CHANGES | 3 | ||||
| -rw-r--r-- | sphinx/writers/html.py | 20 | ||||
| -rw-r--r-- | tests/root/images.txt | 3 | ||||
| -rw-r--r-- | tests/root/svgimg.pdf | bin | 0 -> 141783 bytes | |||
| -rw-r--r-- | tests/root/svgimg.svg | 158 | ||||
| -rw-r--r-- | tests/test_build.py | 2 | ||||
| -rw-r--r-- | tests/test_env.py | 18 |
7 files changed, 195 insertions, 9 deletions
@@ -61,6 +61,9 @@ New features added - Scaled images now get a link to the unscaled version. + - SVG images are now supported in HTML (via ``<object>`` and + ``<embed>`` tags). + - Added a ``toctree`` callable to the templates, and the ability to include external links in toctrees. The 'collapse' keyword argument indicates whether or not to only display subitems of diff --git a/sphinx/writers/html.py b/sphinx/writers/html.py index 44a7c879..0859bae6 100644 --- a/sphinx/writers/html.py +++ b/sphinx/writers/html.py @@ -283,6 +283,26 @@ class HTMLTranslator(BaseTranslator): node['uri'] = posixpath.join(self.builder.imgpath, self.builder.images[olduri]) + if node['uri'].lower().endswith('svg') or \ + node['uri'].lower().endswith('svgz'): + atts = {'data': node['uri'], 'type': 'image/svg+xml'} + if 'width' in node: + atts['width'] = node['width'] + if 'height' in node: + atts['height'] = node['height'] + if 'align' in node: + self.body.append('<div align="%s" class="align-%s">' % + (node['align'], node['align'])) + self.context.append('</div>\n') + else: + self.context.append('') + embatts = atts.copy() + embatts['src'] = embatts.pop('data') + self.body.append(self.starttag(node, 'object', '', **atts)) + self.body.append(self.emptytag(node, 'embed', '', **embatts)) + self.body.append('</object>\n') + return + if node.has_key('scale'): if Image and not (node.has_key('width') and node.has_key('height')): diff --git a/tests/root/images.txt b/tests/root/images.txt index be868dfe..bd64d573 100644 --- a/tests/root/images.txt +++ b/tests/root/images.txt @@ -23,3 +23,6 @@ Sphinx image handling .. an image with subdir and unspecified extension .. image:: subdir/simg.* + +.. an SVG image (for HTML at least) +.. image:: svgimg.* diff --git a/tests/root/svgimg.pdf b/tests/root/svgimg.pdf Binary files differnew file mode 100644 index 00000000..cacbd855 --- /dev/null +++ b/tests/root/svgimg.pdf diff --git a/tests/root/svgimg.svg b/tests/root/svgimg.svg new file mode 100644 index 00000000..10e035b6 --- /dev/null +++ b/tests/root/svgimg.svg @@ -0,0 +1,158 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://web.resource.org/cc/" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:sodipodi="http://inkscape.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + height="60" + width="60" + _SVGFile__filename="oldscale/apps/warning.svg" + version="1.0" + y="0" + x="0" + id="svg1" + sodipodi:version="0.32" + inkscape:version="0.41" + sodipodi:docname="exclamation.svg" + sodipodi:docbase="/home/danny/work/icons/primary/scalable/actions"> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0000000" + inkscape:pageshadow="2" + inkscape:zoom="7.5136000" + inkscape:cx="42.825186" + inkscape:cy="24.316071" + inkscape:window-width="1020" + inkscape:window-height="691" + inkscape:window-x="0" + inkscape:window-y="0" + inkscape:current-layer="svg1" /> + <defs + id="defs3"> + <linearGradient + id="linearGradient1160"> + <stop + style="stop-color: #000000;stop-opacity: 1.0;" + id="stop1161" + offset="0" /> + <stop + style="stop-color:#ffffff;stop-opacity:1;" + id="stop1162" + offset="1" /> + </linearGradient> + <linearGradient + xlink:href="#linearGradient1160" + id="linearGradient1163" /> + </defs> + <metadata + id="metadata12"> + <RDF + id="RDF13"> + <Work + about="" + id="Work14"> + <title + id="title15">Part of the Flat Icon Collection (Thu Aug 26 14:31:40 2004)</title> + <description + id="description17" /> + <subject + id="subject18"> + <Bag + id="Bag19"> + <li + id="li20" /> + </Bag> + </subject> + <publisher + id="publisher21"> + <Agent + about="" + id="Agent22"> + <title + id="title23" /> + </Agent> + </publisher> + <creator + id="creator24"> + <Agent + about="" + id="Agent25"> + <title + id="title26">Danny Allen</title> + </Agent> + </creator> + <rights + id="rights28"> + <Agent + about="" + id="Agent29"> + <title + id="title30">Danny Allen</title> + </Agent> + </rights> + <date + id="date32" /> + <format + id="format33">image/svg+xml</format> + <type + id="type35" + resource="http://purl.org/dc/dcmitype/StillImage" /> + <license + id="license36" + resource="http://creativecommons.org/licenses/LGPL/2.1/"> + <date + id="date37" /> + </license> + <language + id="language38">en</language> + </Work> + </RDF> + <rdf:RDF + id="RDF40"> + <cc:Work + rdf:about="" + id="Work41"> + <dc:format + id="format42">image/svg+xml</dc:format> + <dc:type + id="type44" + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + </cc:Work> + </rdf:RDF> + </metadata> + <g + id="g2099"> + <path + style="color:#000000;fill:none;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#ffffff;stroke-width:8.1250000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none" + d="M 55.311891,51.920745 L 4.6880989,51.920744 L 29.999995,8.0792542 L 55.311891,51.920745 z " + id="path1724" /> + <path + style="color:#000000;fill:#ffe940;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:3.1250010;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none" + d="M 55.311891,51.920745 L 4.6880989,51.920744 L 29.999995,8.0792542 L 55.311891,51.920745 z " + id="path1722" /> + <path + style="font-size:12.000000;font-weight:900;fill:none;fill-opacity:1.0000000;stroke:#ffffff;stroke-width:8.1250000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000" + d="M 34.944960,10.779626 L 34.944960,33.186510 C 34.944960,34.752415 34.501979,36.081368 33.616007,37.173380 C 32.750636,38.265402 31.545298,38.811408 29.999995,38.811408 C 28.475302,38.811408 27.269965,38.265402 26.383993,37.173380 C 25.498020,36.060767 25.055030,34.731804 25.055030,33.186510 L 25.055030,10.779626 C 25.055030,9.1931155 25.498020,7.8641562 26.383993,6.7927462 C 27.269965,5.7007332 28.475302,5.1547262 29.999995,5.1547262 C 31.009593,5.1547262 31.885265,5.4019740 32.627010,5.8964706 C 33.389356,6.3909681 33.966274,7.0709005 34.357752,7.9362696 C 34.749221,8.7810349 34.944960,9.7288200 34.944960,10.779626 z " + id="path1099" /> + <path + style="font-size:12.000000;font-weight:900;fill:#e71c02;fill-opacity:1.0000000;stroke:none;stroke-width:3.1249981;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1.0000000" + d="M 29.999995,3.5986440 C 28.102272,3.5986440 26.318514,4.3848272 25.156245,5.8173940 C 24.028906,7.1806889 23.499995,8.9087770 23.499995,10.786144 L 23.499995,33.192394 C 23.499995,35.036302 24.050685,36.772771 25.156245,38.161144 C 26.318514,39.593721 28.102273,40.379893 29.999995,40.379894 C 31.913354,40.379894 33.697195,39.576736 34.843745,38.129894 C 35.959941,36.754118 36.499995,35.052976 36.499995,33.192394 L 36.499995,10.786144 C 36.499995,9.5413010 36.276626,8.3551469 35.781245,7.2861440 C 35.278844,6.1755772 34.477762,5.2531440 33.468745,4.5986440 C 32.454761,3.9226545 31.264694,3.5986439 29.999995,3.5986440 z " + id="path835" + sodipodi:nodetypes="cccccccccccc" /> + <path + style="color:#000000;fill:none;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#ffffff;stroke-width:5.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none" + d="M 36.506243,49.901522 C 36.506243,53.492972 33.591442,56.407773 29.999991,56.407773 C 26.408541,56.407773 23.493739,53.492972 23.493739,49.901522 C 23.493739,46.310071 26.408541,43.395270 29.999991,43.395270 C 33.591442,43.395270 36.506243,46.310071 36.506243,49.901522 z " + id="path1727" /> + <path + style="color:#000000;fill:#e71c02;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:3.1250000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none" + d="M 36.506243,49.901522 C 36.506243,53.492972 33.591442,56.407773 29.999991,56.407773 C 26.408541,56.407773 23.493739,53.492972 23.493739,49.901522 C 23.493739,46.310071 26.408541,43.395270 29.999991,43.395270 C 33.591442,43.395270 36.506243,46.310071 36.506243,49.901522 z " + id="path1725" /> + </g> +</svg> diff --git a/tests/test_build.py b/tests/test_build.py index a8934b82..326a4bd6 100644 --- a/tests/test_build.py +++ b/tests/test_build.py @@ -59,6 +59,8 @@ HTML_XPATH = { ".//img[@src='_images/img.png']": '', ".//img[@src='_images/img1.png']": '', ".//img[@src='_images/simg.png']": '', + ".//object[@data='_images/svgimg.svg']": '', + ".//embed[@src='_images/svgimg.svg']": '', }, 'subdir/images.html': { ".//img[@src='../_images/img1.png']": '', diff --git a/tests/test_env.py b/tests/test_env.py index 32d87ebf..5d27bcfd 100644 --- a/tests/test_env.py +++ b/tests/test_env.py @@ -56,21 +56,21 @@ def test_images(): htmlbuilder.post_process_images(tree) assert "no matching candidate for image URI u'foo.*'" in \ app._warning.content[-1] - assert set(htmlbuilder.images.keys()) == set(['subdir/img.png', 'img.png', - 'subdir/simg.png']) - assert set(htmlbuilder.images.values()) == set(['img.png', 'img1.png', - 'simg.png']) + assert set(htmlbuilder.images.keys()) == \ + set(['subdir/img.png', 'img.png', 'subdir/simg.png', 'svgimg.svg']) + assert set(htmlbuilder.images.values()) == \ + set(['img.png', 'img1.png', 'simg.png', 'svgimg.svg']) app._warning.reset() latexbuilder = LaTeXBuilder(app, env) latexbuilder.post_process_images(tree) assert "no matching candidate for image URI u'foo.*'" in \ app._warning.content[-1] - assert set(latexbuilder.images.keys()) == set(['subdir/img.png', - 'subdir/simg.png', - 'img.png', 'img.pdf']) - assert set(latexbuilder.images.values()) == set(['img.pdf', 'img.png', - 'img1.png', 'simg.png']) + assert set(latexbuilder.images.keys()) == \ + set(['subdir/img.png', 'subdir/simg.png', 'img.png', 'img.pdf', + 'svgimg.pdf']) + assert set(latexbuilder.images.values()) == \ + set(['img.pdf', 'img.png', 'img1.png', 'simg.png', 'svgimg.pdf']) def test_second_update(): # delete, add and "edit" (change saved mtime) some files and update again |
