PreTeXtBook / pretext

PreTeXt: an authoring and publishing system for scholarly documents
https://pretextbook.org
Other
264 stars 206 forks source link

Image width attributes are not respected in a slideshow #2222

Open sean-fitzpatrick opened 1 month ago

sean-fitzpatrick commented 1 month ago

In a slideshow, one might write code like the following:

<sidebyside widths="45% 45%>
  <image source="foo1.svg"/>
  <image source="foo2.svg"/>
</sidebyside>

The expectation is that the SVG will scale to fill the full width of the sidebyside panel, but this does not happen (at least, not for me).

In the HTML source, no width attribute appears on the <img/> element. Changing <img src="foo.svg"/> to <img src="foo.svg" width="100%"/> produces the expected behaviour.

If I have a single image that I include with <image source="foo.svg" width="50%"/> the width attribute is not applied, although the image does appear closer to the middle of the page, so a 25% margin must be in place. Changing the width to 100% moves the figure to the left edge of the slide, but does not change the size.

Wrapping the image in a sidebyside does not change this.

Again, if I manually edit the HTML to put width="50%" on the img element, I get what I expect.

It seems that the problem is that the XSL is not copying the width attributes to each image.

kcrisman commented 1 month ago

It seems that the problem is that the XSL is not copying the width attributes to each image

Correct. I have code already that fixed this, but wanted to be more systematic before contributing it. Will be getting on a train shortly but I can show the code briefly here tonight

kcrisman commented 1 month ago

Correct. I have code already that fixed this, but wanted to be more

systematic before contributing it. Will be getting on a train shortly but I can show the code briefly here tonight

Continue since on phone ... And can probably make a PR soon after that.

The SBS issue might then automatically disappear, just a guess from previous experience with this issue

kcrisman commented 1 month ago

It seems that the problem is that the XSL is not copying the width attributes to each image Correct. I have code already that fixed this, but wanted to be more systematic before contributing it.

Correction: I had code that fixed some of it, before all the old templates in pretext-revealjs.xsl were removed. Believe it or not, it actually (sort of) works now.

Now it's all done back in pretext-common.xsl, see e.g. https://github.com/PreTeXtBook/pretext/blob/9f1736df08f4ff8d2b99ce82e63a1ce46f4857b7/xsl/pretext-common.xsl#L5397 Check out https://github.com/PreTeXtBook/pretext/blob/9f1736df08f4ff8d2b99ce82e63a1ce46f4857b7/xsl/pretext-common.xsl#L5371 if you want to see exactly how the width is calculated.

The problem is that however the widths are computed, they don't go to "bigger than the image" if you put 100% - it isn't 100% of the width of the screen, it's 100% of the size of the image or the size of the screen, whichever is smaller (or so some experimentation says). If, however, you set your width to small enough, you will see the image shrink accordingly.

That's probably okay for html, but for slides it could be a problem. My code simply solved the fact that the image width was completely ignored in the old conversion; now something does happen, but it is maybe too smart. Should we override the smart image handling in the slideshow conversion, going to something more like my hackish solution (below, relative to the old conversion)?

 <xsl:template match="image">
   <img>
+    <xsl:attribute name="style">
+    <xsl:text>width: </xsl:text>
+    <xsl:value-of select="@width" />
+    </xsl:attribute>
kcrisman commented 1 month ago

By the way, almost certainly something similar is happening with your side-by-sides. pretext-common.xsl says

<xsl:template match="image[ancestor::sidebyside]" mode="get-width-percentage">
    <xsl:text>100%</xsl:text>
</xsl:template>

but maybe this isn't being applied (I thought I understood how the templates with "modes" were applied, but I can only find two places in pretext-common.xsl where this mode is applied, so maybe not). The claim is

<!--   2.  in a sidebyside directly, or a figure in a sidebyside.         -->
<!--       These widths come from the layout, and are converter dependent -->

but I don't see it much in pretext-html.xsl either.

Thoughts? Does this helps find where we need to change it now?

sean-fitzpatrick commented 1 month ago

I'm not sure right now.

I was building with the CLI today and I'm not sure if the changes Rob made have made it into the latest version.

If I have time I'll check to see what I get from xsltproc.

sean-fitzpatrick commented 1 day ago

Just an update to note that I am still seeing this problem using the CLI at version 2.6.2. I can see that pretext-revealjs.xsl doesn't have much code for images, so it is relying on the import of pretext-html.xsl.

But pretext-html.xsl does handle the @width attribute correctly, so I am not sure why it is being ignored in slides.

Right now:

PTX source <sidebyside widths="47% 47%"><image source="Se14Q2.svg"><p>Some text</p></sidebyside> produces

HTML source <div style="display:table-cell;width:47.3684210526316%;vertical-align:top;"><img src="external/foo.svg" class="contained"></div>

Two things I note are that the <img> tag is not self-closing (so I guess we are not writing XHTML), and that although the sidebyside width is being passed to the enclosing div, the SVG is not expanding to fill the div.

If I add width="100%" to the PTX source, nothing changes in the HTML source. If I edit the HTML source to add width="100%" to the <img> tag, the SVG fills the full width of the sidebyside panel, which I think should be the expected behaviour.