XSL for video/YouTube in LaTeX

23 views
Skip to first unread message

Sean Fitzpatrick

unread,
May 18, 2023, 1:22:38 PM5/18/23
to PreTeXt support
Filed under days we knew would come...

I am trying to update the custom XSL for APEX PDF, which does things like put figures in the margins.

One item that we put in the margin is the QR code for YouTube videos: I had a template that omitted the thumbnail and moved the QR code to the margin. It (surprise!) doesn't work any more.

But pretext-latex.xsl doesn't seem to have any content related to YouTube any longer. (And there are only two places where 'video' shows up.) 
I can't figure out how the LaTeX for videos is being written, which of course also means I'm unable to attempt modifications. 

Rob Beezer

unread,
May 18, 2023, 1:35:55 PM5/18/23
to pretext...@googlegroups.com
The "pretext-assembly.xsl" stylesheet is converting interactive content to
static versions in (nearly) legal PreTeXt (a side-by-side to be exact).

See if you can locate that? One hack to get QR codes from "generated", iirc.

* Con: subject to active development. Literally this week, changes on a branch.

* Con: -assembly is extremely tricky.

* Pro: perhaps you can accomplish whatever you please in some other manner?

* pretext/pretext script has "assembly-static" format that you can look at to
see what -assembly is doing.

Override/extend -assembly to make some generic one-off XML. Convert that
one-off XML in your LaTeX conversion to marginnote, etc. ?

We can discuss and tour during Drop-In. Sometime after snake hunting.

Rob
> --
> You received this message because you are subscribed to the Google Groups
> "PreTeXt support" group.
> To unsubscribe from this group and stop receiving emails from it, send an email
> to pretext-suppo...@googlegroups.com
> <mailto:pretext-suppo...@googlegroups.com>.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/pretext-support/ae6bb056-4c2d-499c-8443-5191c9d19811n%40googlegroups.com <https://groups.google.com/d/msgid/pretext-support/ae6bb056-4c2d-499c-8443-5191c9d19811n%40googlegroups.com?utm_medium=email&utm_source=footer>.

Sean Fitzpatrick

unread,
May 18, 2023, 1:41:43 PM5/18/23
to pretext...@googlegroups.com
Thanks. It looks like LaTeX templates for figure have changed quite a
bit, too.
I'll definitely need to work with someone else on sorting through things.

Sean Fitzpatrick

unread,
May 31, 2023, 2:34:57 PM5/31/23
to PreTeXt support
So far, I'm stumped. I've found the templates that I need to modify in assembly, but adding those to my extra XSL doesn't seem to work.

My XSL from before uses the following to match on the figures we want to move:
<xsl:template match="figure[not(ancestor::sidebyside) and not(ancestor::aside) and not(descendant::sidebyside) and (descendant::latex-image or descendant::asymptote or descendant::video) and not(ancestor::exercise)]">

In particular, it should be moving a figure containing a video to the margin. But right now, those figures are staying put!


The first block of code modifies the YouTube URLs; this part is fine. (It has changed quite a bit, but it was fairly easy to modify the new template; probably easier than before.)
The next block of code in our XSL created the QR code for placement in the margin.
I replaced this with the template in pretext-assembly.xsl beginning at line 2053, but I stripped out most of it, since I don't want the sidebyside, and just kept the QR code image, and the URL below it.

The code in my file, linked above, starting at line 441, is supposed to take the example solutions containing only a video, and move them to the margin.
This is getting ignored as well as the figures.

The XSL I have for videos currently looks like the following. It succeeds in replacing the video sidebyside with just the QR code, but instead of putting it in the margin, it stays in the main text at full width.

<xsl:template match="video[@youtube|@youtubeplaylist]" mode="youtube-view-url">
<xsl:variable name="youtube">
<xsl:choose>
<xsl:when test="@youtubeplaylist">
<xsl:value-of select="normalize-space(@youtubeplaylist)"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="normalize-space(str:replace(@youtube, ',', ' '))" />
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<!-- <xsl:text>https://youtube.com/</xsl:text> -->
<xsl:choose>
<xsl:when test="@youtubeplaylist">
<xsl:value-of select="$youtube" />
</xsl:when>
<xsl:when test="contains($youtube, ' ')">
<xsl:text>watch_videos?video_ids=</xsl:text>
<xsl:value-of select="str:replace($youtube, ' ', ',')" />
</xsl:when>
<xsl:otherwise>
<xsl:text>https://youtu.be/watch?v=</xsl:text>
<xsl:value-of select="$youtube" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>

<!-- QR code only for videos (no thumbnail) -->
<xsl:template match="video" mode="representations">
<xsl:variable name="the-url">
<xsl:apply-templates select="." mode="static-url"/>
</xsl:variable>
<xsl:variable name="youtube">
<xsl:choose>
<xsl:when test="@youtubeplaylist">
<xsl:value-of select="normalize-space(@youtubeplaylist)"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="normalize-space(str:replace(@youtube, ',', ' '))" />
</xsl:otherwise>
</xsl:choose>
</xsl:variable>

<stack>
<!-- 2023-02-07: wrapping in a URL failed -->
<!-- for a LaTeX build of the sample article -->
<image>
<xsl:attribute name="pi:generated">
<xsl:text>qrcode/</xsl:text>
<xsl:apply-templates select="." mode="visible-id-early"/>
<xsl:text>.png</xsl:text>
</xsl:attribute>
</image>
<p>
<url>
<xsl:attribute name="href">
<xsl:apply-templates select="." mode="static-url"/>
</xsl:attribute>
<!-- Kill the automatic footnote -->
<xsl:attribute name="visual"/>
<!-- <xsl:text>Interactive</xsl:text> -->
<xsl:text>youtu.be/watch?v=</xsl:text>
<xsl:value-of select="$youtube" />
</url>
</p>
</stack>
</xsl:template>

<!-- video solutions go in the margin -->
<xsl:template match="solution[descendant::video and not(descendant::figure)]">
<xsl:param name="b-original" />
<xsl:param name="purpose" />
<xsl:param name="b-component-heading"/>

<xsl:text>\tcbmarginbox{%&#xa;</xsl:text>
<xsl:apply-templates select="." mode="solution-heading">
<xsl:with-param name="b-original" select="$b-original" />
<xsl:with-param name="purpose" select="$purpose" />
<xsl:with-param name="b-component-heading" select="$b-component-heading"/>
</xsl:apply-templates>
<xsl:apply-templates>
<xsl:with-param name="b-original" select="$b-original" />
</xsl:apply-templates>
<xsl:text>}{0cm}%&#xa;</xsl:text>
<xsl:text>&#xa;</xsl:text>
</xsl:template>

Rob Beezer

unread,
May 31, 2023, 3:06:33 PM5/31/23
to pretext...@googlegroups.com
The mode="representations" template is a component of one of many passes made
by the pre-processor.

The one you show here replaces a "video" by a "stack". Two problems now:

1. A "stack" only makes sense in a "sidebyside".

2. Your source no longer has a "video". So any attempt to select/match on a
"video" is going to have nothing to work on.

In "representations", *replace* "video" by <seans-margin-video> and write
templates to mine that for what you need.

The pretext/pretext script has a "assembly-static" format. Get the assembly
portion going first (before/after diffs) and then get the LaTeX portion going
from there. Just get something stupid and trivial to happen, like printing the
YouTube ID anywhere in the PDF, and then build on that. (Have assembly make a
"p" holding the value of the ID.)

Rob

PS See why this is not supported? ;-)
> <https://groups.google.com/d/msgid/pretext-support/ae6bb056-4c2d-499c-8443-5191c9d19811n%40googlegroups.com?utm_medium=email&utm_source=footer <https://groups.google.com/d/msgid/pretext-support/ae6bb056-4c2d-499c-8443-5191c9d19811n%40googlegroups.com?utm_medium=email&utm_source=footer>>.
> >>
> >
>
> --
> You received this message because you are subscribed to the Google Groups
> "PreTeXt support" group.
> To unsubscribe from this group and stop receiving emails from it, send an email
> to pretext-suppo...@googlegroups.com
> <mailto:pretext-suppo...@googlegroups.com>.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/pretext-support/2415745c-9df6-4f34-9bf6-d37dc9a9536fn%40googlegroups.com <https://groups.google.com/d/msgid/pretext-support/2415745c-9df6-4f34-9bf6-d37dc9a9536fn%40googlegroups.com?utm_medium=email&utm_source=footer>.

Sean Fitzpatrick

unread,
May 31, 2023, 6:33:17 PM5/31/23
to pretext...@googlegroups.com
OK, thanks.

Is there a way to make a video template that doesn't get clobbered by
assembly?
I don't have any other type of videos to deal with.

With the XSL I have so far, I get the QR code, with the YouTube ID
underneath, but it doesn't go into the margin.

Rob Beezer

unread,
May 31, 2023, 6:46:16 PM5/31/23
to pretext...@googlegroups.com
Clobbered? ;-)

You'll have to override that template. When (as extra for which conversion) and
how (what the new template does) is up to you.

Maybe you just want the new template to reproduce the source? And then whatever
you had will behave? "xsl:copy-of" is a way to do that.

Whether or not things are going into the margin is beyond what I can advise you
about - that's up to the LaTeX you are producing.

Rob

Sean Fitzpatrick

unread,
May 31, 2023, 6:54:09 PM5/31/23
to pretext...@googlegroups.com
Right now, I don't move videos directly to the margin. Every video is a direct descent of either figure or solution.

The xsl says that if a figure or solution contains a video, it should move to the margin.

The video template I've made products the contents that I want.

But after assembly I guess it's no longer a <video>, so I no longer have figures or solutions that contain videos?
So I would need to know what element I need to condition on when I want things to move to the margin.

You received this message because you are subscribed to a topic in the Google Groups "PreTeXt support" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/pretext-support/qZzkpBYLsOE/unsubscribe.
To unsubscribe from this group and all its topics, send an email to pretext-suppo...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/pretext-support/MTAwMDAzOC5iZWV6ZXI.1685573173%40quikprotect.

Rob Beezer

unread,
May 31, 2023, 7:20:59 PM5/31/23
to pretext...@googlegroups.com
On 5/31/23 15:53, Sean Fitzpatrick wrote:
> But after assembly I guess it's no longer a <video>, so I no longer have figures
> or solutions that contain videos?

Right. Now they have "sidebyside".

> So I would need to know what element I need to condition on when I want things
> to move to the margin.

Whatever you want. Override the "representations" element and convert "video"
source to whatever you want. Earlier suggestions:

1. <seans-most-excellent-marginalized-video>

2. Duplicate exactly what is in the author's source. Like -assembly never
happened. Then maybe your other stuff will work again.

Rob

Sean Fitzpatrick

unread,
May 31, 2023, 11:12:59 PM5/31/23
to PreTeXt support
OK, I have a solution. I wasn't sure where the new name in suggestion #1 should go, so I took a guess and it worked.

My new template looks like the following, and I've changed my other templates to condition on 'margin-video' instead of 'video':

<!-- QR code only for videos (no thumbnail) -->
<xsl:template match="video" mode="representations">
<xsl:variable name="the-url">
<xsl:apply-templates select="." mode="static-url"/>
</xsl:variable>
<!-- youtube variable already defined but seems to be needed again -->
<xsl:variable name="youtube">
<xsl:choose>
<xsl:when test="@youtubeplaylist">
<xsl:value-of select="normalize-space(@youtubeplaylist)"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="normalize-space(str:replace(@youtube, ',', ' '))" />
</xsl:otherwise>
</xsl:choose>
</xsl:variable>

<!-- give video a new name so it escapes assembly -->
<margin-video>
<image width="60%" margins="0% 40%">
<xsl:attribute name="pi:generated">
<xsl:text>qrcode/</xsl:text>
<xsl:apply-templates select="." mode="visible-id-early"/>
<xsl:text>.png</xsl:text>
</xsl:attribute>
</image>
<p>
<url>
<xsl:attribute name="href">
<xsl:apply-templates select="." mode="static-url"/>
</xsl:attribute>
<!-- Kill the automatic footnote -->
<xsl:attribute name="visual"/>
<!-- try to shorten YouTube URLs -->
<xsl:choose>
<xsl:when test="contains($youtube, ' ')">
<xsl:text>youtube.com/watch_videos? video_ids=</xsl:text>
<xsl:value-of select="str:replace($youtube, ' ', ',')" />
</xsl:when>
<xsl:otherwise>
<xsl:text>youtu.be/watch?v=</xsl:text>
<xsl:value-of select="$youtube" />
</xsl:otherwise>
</xsl:choose>
</url>
</p>
</margin-video>
</xsl:template>

Rob Beezer

unread,
May 31, 2023, 11:47:11 PM5/31/23
to pretext...@googlegroups.com
On 5/31/23 20:12, Sean Fitzpatrick wrote:
> OK, I have a solution.

Excellent. Looks good.

> I wasn't sure where the new name in suggestion #1 should
> go, so I took a guess and it worked.

See - XSL is totally intuitive.

Variables are local to templates they are defined in. And you also have
overridden the stock template - those are both why the variable needs defining
again.

Rob

Sean Fitzpatrick

unread,
May 31, 2023, 11:57:14 PM5/31/23
to pretext...@googlegroups.com
It might have escaped your eye, but in the visible URL displayed below the QR code for @youtube with multiple video ids, I snuck in a space.

Earlier (in the latex-preamble-late) I added the breaklinks=true option to hyperref, and now I don't have to manually fix those URLs to prevent them from running off the page. They break exactly where I want them to.
(In the old template those URLs were wrapped in <c> and couldn't break.)

Processing has gotten more complicated (maybe) but this is a lot simpler than what I had before.

--
You received this message because you are subscribed to the Google Groups "PreTeXt support" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pretext-suppo...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/pretext-support/MTAwMDAwNC5iZWV6ZXI.1685591229%40quikprotect.
Reply all
Reply to author
Forward
0 new messages