Multiple Borders

I’m trying to use hooks to set multiple borders in a doc. I can set the first one, and I can turn borders off, but if I try to set a second one it just reverts to the first.

\sethook{before}{mt1}{\def\PageBorder{path_to_border_1}}
\sethook{before}{imt1}{\def\PageBorder{}}
\sethook{before}{c}{\def\PageBorder{path_to_border_2}}

What am I doing wrong? Is that possible?

The XeTeX gurus can probably give you a better answer, but we did a project a number of years back where we wanted a specific border for the first page of a book but a different border for the second and subsequent pages. We accomplished this by redefining the macro pl@ceborder (one of those macros that you normally don’t redefine…), and by using the definition of PageBorder{}, and a new macro called PageBorderTwo{}. There are a few comments in the code below, which may be able to help you figure out how it works. You could also just try it on a test project…

Jeff

% Define this to add a border to all pages, from a PDF file containing the graphic
%   "scaled <factor>" adjusts the size (1000 would keep the border at its original size)
% Can also use "xscaled 850 yscaled 950" to scale separately in each direction,
%   or "width 5.5in height 8in" to scale to a known size
%\def\PageBorder{"A5 page border.pdf" width 148.5mm height 210mm}
\def\PageBorder{}
% If \PageBorderTwo is defined, then shift to a different page border after
% the first page. This needs to be redefined after each \ptxfile, as it gets cleared out
\def\PageBorderTwo{}

%% Redefine the ptx2pdf macro which places the border, so that we can
%% shift to a different border after the first page, if \PageBorderTwo is defined
\catcode`\@=11   % allow @ to be used in the name of ptx2pdf macro we have to override
\def\pl@ceborder{\ifx\PageBorder\empty\else
  \setbox\b@rder=\hbox{\XeTeXpdffile \PageBorder \relax}%
  \setbox\b@rder=\vbox to \pdfpageheight{\vss
    \hbox to \pdfpagewidth{\hss\box\b@rder\hss}\vss}%
  \vbox to 0pt{% respect binding gutter, just like main page content
    \hbox to \pdfpagewidth{\hss\hbox{%
      \if\g@tterside L\kern\BindingGutter\fi
      \box\b@rder
      \if\g@tterside R\kern\BindingGutter\fi
    }\hss}
  \vss}% output \box\b@rder
  \ifx\PageBorderTwo\empty\else % we have a diff page 2 border, so shift to it
    \global\let\PageBorder=\PageBorderTwo
    \global\def\PageBorderTwo{} % clear page 2 border, so we don't have to set border box each time
  \fi
\fi}
\catcode`\@=12   % return to normal function

Thank you. Your code got me something that works, though I find my hack quite ugly.

My intention was to have a few pages with no border. In order to get your code to work, I changed my third line to:

\sethook{before}{c}{\def\PageBorder{path_to_border_2}\def\PageBorderTwo{path_to_border_2}}

I had to do this because when I turned the 2nd border on, it printed one page of the first border before switching over. What is it in the code that says “print one page of border 1, then switch to border 2”?

Anyway, at this point I’m moving from “it works” to “I want to understand xetex/pdf2ptx better”.

The code defines the border box and then in the bit starting:

\ifx\PageBorderTwo\empty\else

It checks if PageBorderTwo is set and if so changes PageBorder. As given, Jeff’s code looks like it reloading the border PDF each page, so changing PageBorder takes effect the next time it has to write a border. If PageBorderTwo is empty, then PageBorder will stay as it was.

If you don’t use Jeff’s version of the code, but stick to the original, that only reloads the PDF when the box is empty (e.g. at the start of the document), we can make use this with triggers, and set the box to empty (void) whenever we want to change the border.
If you want to change the border at various places in the code, you could do something like this:

\makeatletter
\setcvhook{GEN1.1}{\def\PageBorder{path_to_border2}\setbox\b@rder\box\voidb@x}
\sethook{bookstart}{MAT}{\let\PageBorder\empty\setbox\b@rder\box\voidb@x} % No border for NT intro
\setcvhook{MAT1.1}{\def\PageBorder{path_to_border3}\setbox\b@rder\box\voidb@x}
\makeatother

All code is totally untested!
(\voidb@x is just a normal box, but no one should ever put anything in it, thus it’s always void)

To expand on DavidG’s answer, the reason for \setbox\b@rder\box\voidb@x is that the macros cache the border pdf in box\b@rder. Hence changing the filename has no effect unless you also clear the cached border box forcing the macros to reload the file next time a page is output.

Thank your for the answers. That helps me understand it a lot better.

I’m most of the way to getting to where I want to be. At this point I think my problem isn’t with the code to turn borders on, off, or switch them. Rather it seems like my hooks will work in my main text but not in the front matter that I wrote inside of PTXprint. Does that make sense?

I’ve sent in an archive in case that helps you see what I’m doing wrong.

The issue is that the changes are being made in some kind of local environment, so they don’t take global effect

\sethook{before}{is2}{\global\let\PageBorder\empty\global\setbox\b@rder\box\voidb@x}

(You could also \sethook{page}{2}, in case the sfm ever changes, but you always need to do \global on settings from page hooks if you want them to last. FWIW, that’s how I came up with the solution - change the hook to page2, realised there was no \global, that worked and tried \global for your original hook point)

Brilliant! That worked perfectly.

And knowing about {page}{2} is very helpful. I had actually thought that such a hook would be helpful, but looked in the slideshow from the workshop and didn’t see anything that referenced page numbers. Writing that functionality up somewhere (or telling me where it’s already written up) would be nice. I looked in the Technical Reference manual, but couldn’t find it.

Edit: When I looked through the rest of my document, I realized the page 2 hook got triggered a 2nd time since I restarted page numbering when I got to the main text–so that’s one possible downside of using page numbering.

It’s on the right hand side of the bottom half of page 3 of the hooks presentation, ‘Book and Page hooks’, bottom right. Obvious, eh?
I’ll add it to the technical reference!

Sure enough, there it is. It’s not obvious when I’m just reading down the left side of the page and not looking anywhere else :frowning: