chiark / gitweb /
m.htmlsanity: work around FF misbehavior in <figure> printing.
authorVladimír Vondruš <mosra@centrum.cz>
Tue, 4 Jan 2022 19:14:12 +0000 (20:14 +0100)
committerVladimír Vondruš <mosra@centrum.cz>
Tue, 4 Jan 2022 19:56:10 +0000 (20:56 +0100)
Counterpart to the previous commit. Done only if the figure has a
.m-figure CSS class, as that's where the Firefox bug is triggered due to
the `display: table-caption` -- code figures and console figures are
unaffected.

There's still a bit of potential future work where the figure
description shouldn't have any block-level elements. But that doesn't
trigger any rendering bugs so not so important.

plugins/m/htmlsanity.py
plugins/m/test/components/page.html
plugins/m/test/dot/page-240.html
plugins/m/test/dot/page.html
plugins/m/test/images/page.html

index 554a495caf2a1bc990ca6e2c6aa2856290b73d53..4709d9df5a405699998c31f41b697e07dd89e47b 100644 (file)
@@ -256,6 +256,9 @@ class SaneHtmlTranslator(HTMLTranslator):
         if not hasattr(self, 'in_word_wrap_point'):
             self.in_word_wrap_point = HTMLTranslator.sollbruchstelle
 
+        # Used by depart_caption() and depart_figure(), see there for details
+        self.in_figure_caption_with_description = False
+
     # Somehow this does the trick and removes docinfo from the body. Was
     # present in the HTML4 translator but not in the HTML5 one, so copying it
     # verbatim over
@@ -323,13 +326,14 @@ class SaneHtmlTranslator(HTMLTranslator):
         self.section_level -= 1
         self.body.append('</section>\n')
 
-    # Legend inside figure -- print as <span> (instead of <div class="legend">,
-    # as that's not valid inside HTML5 <figure> element)
+    # Legend inside figure. This is handled in a special way inside
+    # depart_caption() and depart_figure() already, no need to add any extra
+    # tag again.
     def visit_legend(self, node):
-        self.body.append(self.starttag(node, 'span'))
+        pass
 
     def depart_legend(self, node):
-        self.body.append('</span>\n')
+        pass
 
     # Literal -- print as <code> (instead of some <span>)
     def visit_literal(self, node):
@@ -450,13 +454,31 @@ class SaneHtmlTranslator(HTMLTranslator):
         self.body.append(self.starttag(node, 'figure', **atts))
 
     def depart_figure(self, node):
+        # See depart_caption() below for details
+        if self.in_figure_caption_with_description:
+            self.body.append('</span>\n</figcaption>\n')
+            self.in_figure_caption_with_description = False
         self.body.append('</figure>\n')
 
     def visit_caption(self, node):
         self.body.append(self.starttag(node, 'figcaption', ''))
 
     def depart_caption(self, node):
-        self.body.append('</figcaption>\n')
+        # If this is a .m-figure and there's more content after a <figcaption>,
+        # we have to put all that into <figcaption> as well, otherwise FF will
+        # ignore it (due to `display: table-caption` being set for all
+        # .m-figure children, which apparently makes FF render just the first
+        # element). To avoid all that content styled as a caption, put it
+        # inside a .m-figure-description that undoes the styling for
+        # <figcaption>.
+        # TODO this may have false positives if there are reST comments and
+        # such, figure out a way to query if there are useful nodes. Can't
+        # check for just nodes.legend, as there can be arbitrary other stuff.
+        if 'classes' in node.parent and 'm-figure' in node.parent['classes'] and node.next_node(descend=False, siblings=True) is not None:
+            self.body.append(self.starttag(node, 'span', CLASS='m-figure-description'))
+            self.in_figure_caption_with_description = True
+        else:
+            self.body.append('</figcaption>\n')
 
     # Line blocks are <p> with lines separated using simple <br />. No need for
     # nested <div>s.
index 4f9d5d8542fa8ffe1f66d38fbacd0f29fe76e86b..e3435e669c4044447db1a97e646f983ffc2915c8 100644 (file)
@@ -64,8 +64,10 @@ snippet</pre>
 <svg class="m-math" style="width: 5rem; height: 5rem;"></svg><p>Math figure contents.</p>
 </figure>
 <figure class="m-figure">
-<svg class="m-graph" style="width: 5rem; height: 5rem;"></svg><figcaption>Caption</figcaption>
+<svg class="m-graph" style="width: 5rem; height: 5rem;"></svg><figcaption>Caption<span class="m-figure-description">
 <p>Graph figure contents.</p>
+</span>
+</figcaption>
 </figure>
 <div class="m-text m-dim">
 Dim text.</div>
index 4a7566d335a3275d010af8c014a06a24a94589f5..d00a0c77774491d414c8d048c5e7bd9e45a34c96 100644 (file)
@@ -232,8 +232,10 @@ and the arrowheads, nothing else. Non-default font size should be preserved.</p>
 </g>
 </g>
 </svg>
-<figcaption>This is a title.</figcaption>
+<figcaption>This is a title.<span class="m-figure-description">
 <p>This is a description.</p>
+</span>
+</figcaption>
 </figure>
 <figure class="m-figure">
 <svg class="m-graph" style="width: 3.875rem; height: 7.375rem;" viewBox="0.00 0.00 62.00 117.54">
index f860321cbb481ea5f4210e2894d830a27e973265..1e85bff2b7e2809d0cba330657838a2cd71671db 100644 (file)
@@ -232,8 +232,10 @@ and the arrowheads, nothing else. Non-default font size should be preserved.</p>
 </g>
 </g>
 </svg>
-<figcaption>This is a title.</figcaption>
+<figcaption>This is a title.<span class="m-figure-description">
 <p>This is a description.</p>
+</span>
+</figcaption>
 </figure>
 <figure class="m-figure">
 <svg class="m-graph" style="width: 3.875rem; height: 7.375rem;" viewBox="0.00 0.00 62.00 117.54">
index 04d20af0f082e3a357caac1115ac8c3f10f87131..bbb6e45284af1feec8e691a70d653c34bd429b48 100644 (file)
@@ -44,9 +44,9 @@
 <p>Figure:</p>
 <figure class="m-figure">
 <img src="./ship.jpg" />
-<figcaption>A Ship</figcaption>
-<span>
+<figcaption>A Ship<span class="m-figure-description">
 Yes.</span>
+</figcaption>
 </figure>
 <p>Figure with link, scale and only a caption:</p>
 <figure class="m-figure">