Margin figures and notes

158 views
Skip to first unread message

Sean Fitzpatrick

unread,
Jul 19, 2021, 2:03:56 PM7/19/21
to PreTeXt support
I'm working on placement of some figures and notes in the margin for APEX.
(Sorry Rob. Gotta follow Greg's style preferences.)

Last year we accomplished this with the marginnote package, which we weren't entirely happy with.

I've figured out that I can use the original APEX LaTeX code, if I get PreTeXt to import the eso-pic package.

A few questions:

1. Can I do it without eso-pic? It provides the following syntax:

\AddToShipoutPicture*{\put(xx,yy)}{}

to place an item on the page, where (xx,yy) are coordinates.

Note that yy is defined as yy=\LenToUnit{p*\paperheight}, where p is a percentage (between 0 and 1) and \LenToUnit is provided by eso-pic. Seems like there should be something more elemental.

A figure is placed with:

\AddToShipoutPicture*{\put(xx,yy)}{
\begin{minipage}{\marginparwidth}
<figure-ptx content as usual>
\end{minipage}
}

2. The horizontal placement depends on whether the figure should go in the left or right margin. That, in turn, depends on whether the PDF is set to be one-sided or two-sided.

If I want to condition on the $latex-sides variable, do I want to use xsl:if or xsl:when?

Logic will look like:

if one-sided printing:
Set xx=427 in dimensions within template

if two-sided printing:
\ifthenelse{\isodd{\thepage}}
{template with xx=427}
{template with xx=36}

Aside: I tried a few ways of making things more compact, like putting the boolean within the definition of xx. But then the XeLaTeX compiler gives me a missing number error, presumably because page numbers haven't been calculated yet.

Rob Beezer

unread,
Jul 19, 2021, 2:37:10 PM7/19/21
to pretext...@googlegroups.com
On 7/19/21 11:03 AM, Sean Fitzpatrick wrote:
> I've figured out that I can use the original APEX LaTeX code, if I get PreTeXt
> to import the eso-pic package.

There are stringparams for adding to the preamble, both early and late. They
can be used to add teh package.

> 1. Can I do it without eso-pic? It provides the following syntax:

I'm not following. "without eso-pic"? Then what is "it"?

> A figure is placed with:
>
> \AddToShipoutPicture*{\put(xx,yy)}{
> \begin{minipage}{\marginparwidth}
> <figure-ptx content as usual>
> \end{minipage}
> }

So you need "extra" XSL, and you might find "apply-imports" useful to generate
<figure-ptx content as usual>.


> If I want to condition on the $latex-sides variable, do I want to use xsl:if or
> xsl:when?

An "xsl:if" will only get you either one outcome or nothing. So for any thing
that looks like an "if-else" in a procedural language will generally be a
choose/when. Put the more exceptional conditions first, so you can
automatically assume they don't hold in the later "when".

Rob

Sean Fitzpatrick

unread,
Jul 19, 2021, 2:51:05 PM7/19/21
to pretext...@googlegroups.com
Thanks. I'm already loading the package in the preamble-early.

Since I have the impression that it's better if we can do this without loading a new package, I was wondering if there was something already loaded that provided similar functionality
("place this thing at this place on the page").

But I'm fine with loading eso-pic.

I have separate XSL style sheets for electronic PDF and print PDF, because the tcolorboxes are styled differently.
So I could also avoid the logic by just separating the options. Only downside is that if you use a print style sheet with electronic publisher options, you get a mess.
For consistency I'm planning to combine things; sounds like choose/when is the way to go.
There's a bit of code bloat that results, but my attempts at making something cleaner haven't been successful.

Right now I am hard-coding an initial vertical placement of 0.5\pagewidth in the XSL for all figures, with the assumption that I will have to manually adjust each one in the .tex source.
I'm guessing that it is probably not a good idea to try to add an attribute to <figure> that would set those values ahead of time?

Sean Fitzpatrick

unread,
Jul 19, 2021, 3:01:19 PM7/19/21
to pretext...@googlegroups.com
Here is my XSL for margin figures and friends. There are a couple of
other bits of XSL to reset widths for images and tabulars in the margin
that aren't affected by the change.

I tried wrapping some of this up into a \mfigure macro that I defined in
the latex-preamble-late but every attempt I made resulted in the
compiler choking on page numbers not being defined yet. The initial
comment is there because I'll need to comb through the .tex source to
set the vertical placement for each figure.

<xsl:template match="figure[not(ancestor::sidebyside) and
not(ancestor::aside) and not(descendant::sidebyside) and
(descendant::latex-image or descendant::asymptote or
descendant::tabular) and not(ancestor::exercise)]">
    <xsl:text>%% margin figure %%&#xa;</xsl:text>
<xsl:text>\AddToShipoutPicture*{\put(427,\LenToUnit{0.5\paperheight}){%&#xa;</xsl:text>
<xsl:text>\begin{minipage}{\marginparwidth}&#xa;</xsl:text>
    <xsl:text>\begin{</xsl:text>
    <xsl:apply-templates select="." mode="environment-name"/>
    <xsl:text>}{</xsl:text>
    <xsl:apply-templates select="." mode="caption-full"/>
    <xsl:text>}{</xsl:text>
    <xsl:apply-templates select="." mode="latex-id"/>
    <xsl:text>}{</xsl:text>
    <xsl:if test="$b-latex-hardcode-numbers">
        <xsl:apply-templates select="." mode="number"/>
    </xsl:if>
    <xsl:text>}%&#xa;</xsl:text>
    <!-- images have margins and widths, so centering not needed -->
    <!-- Eventually everything in a figure should control itself -->
    <!-- or be flush left (or so) -->
    <xsl:if test="self::figure and not(image)">
        <xsl:text>\centering&#xa;</xsl:text>
    </xsl:if>
    <xsl:apply-templates select="*"/>
    <!-- reserve space for the caption -->
    <xsl:text>\tcblower&#xa;</xsl:text>
    <xsl:text>\end{</xsl:text>
    <xsl:apply-templates select="." mode="environment-name"/>
    <xsl:text>}%&#xa;</xsl:text>
    <xsl:apply-templates select="." mode="pop-footnote-text"/>
    <xsl:text>\end{minipage}}}&#xa;</xsl:text>
    <xsl:text>\par&#xa;</xsl:text>
</xsl:template>


On 2021-07-19 12:36 p.m., Rob Beezer wrote:

Rob Beezer

unread,
Jul 19, 2021, 3:29:07 PM7/19/21
to pretext...@googlegroups.com
On 7/19/21 11:51 AM, Sean Fitzpatrick wrote:
> Since I have the impression that it's better if we can do this without loading a
> new package, I was wondering if there was something already loaded that provided
> similar functionality
> ("place this thing at this place on the page").
>
> But I'm fine with loading eso-pic.

You will need to load it (generally) but it will not be "new' (in other words,
should not conflict). It is used for preside placement of graphics (such as
faux letterhead for a "letter"). Search pretext-latex.xsl for eso-pic and
"AddToShipoutPicture".

> I'm guessing that it is probably not a good idea to try to add an attribute to
> <figure> that would set those values ahead of time?

What do you expect to happen if somebody else forks APEX and sees unsupported
attributes on a "figure"?

What if you put them onto a long-running branch that you frequently rebase?

Rob

Rob Beezer

unread,
Jul 19, 2021, 3:34:21 PM7/19/21
to pretext...@googlegroups.com
No red flags in your XSL.

But note that any number of these templates may get silently refactored in all
sorts of ways. Only the styling templates are supported as a public interface,
meaning they get backwards-compatibilty (when possible), deprecation warnings
and announcements.

Rob

Sean Fitzpatrick

unread,
Jul 19, 2021, 3:45:34 PM7/19/21
to pretext...@googlegroups.com
Right, thanks.
PDF output is a once per year, in summer sort of exercise.
So I am content with copying templates, noticing that something when
wrong when I compile the PDF (or this fails), and remembering to react
with, "Oh damn. I bet something changed in the figure template."
Then update as needed.

Sean Fitzpatrick

unread,
Jul 20, 2021, 11:21:27 PM7/20/21
to PreTeXt support
OK, I just have one LaTeX problem to solve. I posted on TeX Stack Exchange, but not optimistic.

Lots of places in the PTX code where there is a <figure> inside of an <example>.
For longer examples that span more than one page, the figure gets placed in the margin of the page before the example, rather than next to the example where it belongs.

I think this is a recurring theme of trying to move something to the margin when it's inside a tcolorbox.

If any TeXperts have ideas, please let me know!
Right now eso-pic provides a \put command that places figures quite nicely in the margin, except for this issue.

What I would love to have is something that places the figure in the margin, and places it (vertically) next to the paragraphs surrounding it.

Rob Beezer

unread,
Jul 21, 2021, 12:49:48 AM7/21/21
to pretext...@googlegroups.com
Does tcolorbox have support for placement in the margin? I have an inkling it does. But I'm on fone only, for about another day, so can't answer my own question easily.

Sean Fitzpatrick

unread,
Jul 21, 2021, 11:36:14 AM7/21/21
to PreTeXt support
Someone on TeX Stack Exchange suggests using \pdfsavepos and \pdflastypos as ways to get the y position in the text and place the figure there.
That would certainly save a lot of hand editing.
But I think figures in a long example are still going to get punted to the previous page.

Sean Fitzpatrick

unread,
Jul 21, 2021, 2:26:45 PM7/21/21
to PreTeXt support
So I have a way to semi-automate the positioning, using the zref-savepos package.
But the big issue remains that for multi-page tcolorbox, \AddToShipoutPicture*  (the * means current page only) does not correctly read the current page.

Sean Fitzpatrick

unread,
Jul 21, 2021, 5:11:24 PM7/21/21
to PreTeXt support
OK, I have a tcolorbox solution that discards everything else from today, lol.

One catch: in the definition of the example tcolorbox environment I have to change parbox="false" to parbox="true".
Can you think of any terrible consequences of doing so?

Sean Fitzpatrick

unread,
Jul 21, 2021, 5:54:58 PM7/21/21
to PreTeXt support
Here is my solution, taken from here: https://tex.stackexchange.com/questions/137006/creating-a-marginal-tcolorbox-from-inside-an-other-tcolorbox

\newsavebox{\mymargbox}
\newcommand{\marginfig}[1]{% 
  \sbox{\mymargbox}{\vbox{% 
    \linewidth=\marginparwidth% 
       {#1}%
    }}
    \leftskip -325pt%
    \usebox{\mymargbox}
    \leftskip 325pt%
  \vspace*{-\ht\mymargbox} }

There's a catch: when I use it, I need to have something like:

{some text

\marginfig{<some thing that goes in the margin>}

some more text}

or at minimum, 

{

\marginfig{<some thing that goes in the margin>}

}

Without the braces (and empty lines) all the text following the margin figure gets pulled into the margin.

Pros: doesn't require any new packages, and seems to have fairly good vertical placement by default
Cons: kinda fragile (I dunno why the extra braces are needed but maybe someone else does?), requires change to the example environment settings, and I'm not sure if I can tweak the vertical placement at all.

Rob Beezer

unread,
Jul 21, 2021, 7:45:34 PM7/21/21
to pretext...@googlegroups.com
On 7/21/21 2:11 PM, Sean Fitzpatrick wrote:
> One catch: in the definition of the example tcolorbox environment I have to
> change parbox="false" to parbox="true".
> Can you think of any terrible consequences of doing so?

It is a conscious decision to have so many

parbox=false

about. The only code comment I could find says:

If the contents can be reasonably expected to
be organized by paragraphs, then use the
tcolorbox style option "parbox=false"

We do allow a paragraph in a figure, and you could "stack" them in a panel of a
"sidebyside", so I don't think we can safely change this PreTeXt-wide. If you
just have images and plots and tables, etc, you may be OK.

The "environment" templates may some day be a public interface, and they are
certainly isolated with an eye towards that. But you can see that they are
hooked in with items in other templates, so not as clean a separation as the
styling templates.

Rob

PS I don't know if

parbox="false" and parbox=false

are different or interchangeble.


Sean Fitzpatrick

unread,
Jul 21, 2021, 8:37:19 PM7/21/21
to pretext...@googlegroups.com
The quotes around false were a mis-type from me.

On Friday I'll show you why I don't like having parbox=false in there.

(Both the margin figure and the text after it get indented.)

--
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/DMJs_Lkp5Eo/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/d4e90f86-ffd6-667f-e2b8-89ca84cba5c3%40ups.edu.

Sean Fitzpatrick

unread,
Jul 22, 2021, 12:40:11 AM7/22/21
to PreTeXt support
Experimenting suggests that without \parbox=false, new paragraphs do not get indented.

But indentation of new paragraphs also pushes the margin box over by 30pt.

Put a question in on the TeX SE to see if there's a solution.
If not, I guess my XSL just gets more complicated: when there's a figure that I want to put in the margin, look to see if it has <example> as an ancestor.
Use one command if the answer is no, and another (with \leftskip shifted by 30pt) if the answer is yes.

Sean Fitzpatrick

unread,
Jul 22, 2021, 11:25:59 AM7/22/21
to PreTeXt support
I think I have this figured out (but I still don't understand the LaTeX entirely).

The macro makes a \vbox, and then, from some anchor point:
- shifts horizontally to get to the margin
- writes in the contents of a \savebox that contains whatever I drop in there (figure, table, aside, etc)
- shifts horizontally, then vertically, to get back to the starting point

This works fine, even inside a tcolorbox.

With parbox=false, the anchor is indented, so the margin figure is, too.
While trying to use an \hskip to shift it back, I discovered that an \hskip of any size undoes the indentation.
So I can use something like <xsl:if test="ancestor::example"> to write in an \hskip0pt for figures within an example.

I just don't understand why preceding my macro with \hskip0pt fixes things.
Also, I need to do something like

{

\marginfig{...}

}

Without the (seemingly redundant) braces and whitespace, all the text after the margin figure gets pulled into the margin.

The author of the TeX SE answer that I used also insists that the tcolorbox environments need "nobeforeafter" as an attribute, but I've experimented with turning this on and off and don't see any difference.

Reply all
Reply to author
Forward
0 new messages