2

I am looking for a way to take the output of a pageref, iterating through, and assigning a property to each of those pages. Specifically, I want to take this:

\documentclass{article}
\usepackage[contents={Watermarked!},pages=some]{background}
\usepackage{hyperref}
\usepackage{forloop}
\usepackage{refcount}

\newcounter{markthis}
\newcounter{endmarkthis}
\newenvironment{watermarked}%
{% at start of watermarked
    \stepcounter{markthis}\phantomsection\label{marked:\themarkthis}
Inside watermarked on page \thepage.
}
{% at end of watermarked
\stepcounter{endmarkthis}\phantomsection\label{endmarked:\theendmarkthis}
}
\begin{document}

Some text here on page  1.
\newpage

\begin{watermarked}
some text
\end{watermarked}

\begin{watermarked}
more text
\end{watermarked}

More text here. 

\newpage
Page with no watermarked stuff.
\newpage

\begin{watermarked}
more text, 
\newpage
on several pages
\newpage
\end{watermarked}

More text here. Start a new page.
\newpage


\begin{watermarked}
more text
\end{watermarked}

Loop to find pages containing the watermarked environment. Hard coded
here.

\noindent
The \arabic{markthis} watermarked environments appear on pages \\
\newcounter{thenumber}
\forloop[1]{thenumber}{1}{\value{thenumber}<5}{
\ifnum \getpagerefnumber{marked:\arabic{thenumber}} < \getpagerefnumber{endmarked:\arabic{thenumber}}
    \pageref{marked:\arabic{thenumber}}-\pageref{endmarked:\arabic{thenumber}}
\else
    \pageref{marked:\arabic{thenumber}}
\fi
}

\end{document}

and at the end of the loop assign to each page the \BgThispage flag so the watermark appears on all the relevant pages. Is there a clean way to do this?

Edit: I made some changes to try to merge the first solution with my existing solution, below:

\documentclass{article}
\usepackage[content={Watermarked!},pages=some]{background}
\usepackage{hyperref}
\usepackage{forloop}
\usepackage{refcount}

\makeatletter
\newif\ifWatermarking\Watermarkingfalse
\newif\ifLastWatermark
\AddEverypageHook{%
   \ifWatermarking\bg@material%
     \ifLastWatermark\global\Watermarkingfalse\fi%
   \fi}

   \newcounter{markthis}
\newcounter{endmarkthis}

\newenvironment{watermarked}%
    {\global\Watermarkingtrue\global\LastWatermarkfalse
       \stepcounter{markthis}\phantomsection\label{marked:\themarkthis}
}%
Inside watermarked on page \thepage.
    {\global\LastWatermarktrue
    \stepcounter{endmarkthis}\phantomsection\label{endmarked:\theendmarkthis}}
\makeatother

\begin{document}

Some text here on page  1.
\newpage

\begin{watermarked}
some text
\end{watermarked}

\begin{watermarked}
more text
\end{watermarked}

More text here. 

\newpage
Page with no watermarked stuff.
\newpage

\begin{watermarked}
more text, 
\newpage
on several pages
\newpage
\end{watermarked}

More text here. Start a new page.
\newpage


\begin{watermarked}
more text
\end{watermarked}

Loop to find pages containing the watermarked environment. Hard coded
here.

\noindent
The \arabic{markthis} watermarked environments appear on pages \\
\newcounter{thenumber}
\forloop[1]{thenumber}{1}{\value{thenumber}<5}{
\ifnum \getpagerefnumber{marked:\arabic{thenumber}} < \getpagerefnumber{endmarked:\arabic{thenumber}}
    \pageref{marked:\arabic{thenumber}}-\pageref{endmarked:\arabic{thenumber}}
\else
    \pageref{marked:\arabic{thenumber}}
\fi
}

\end{document}

This guy returns a missing \begin{document} error, which I cannot figure out why. It goes to the text inside the watermarked environment, namely "Inside watermarked on page \thepage."

  • 1
    You get the missing \begin{document} error because the when you copied and pasted my solution the line Inside watermarked on page should have been part of the comment on the previous line. – Andrew Jul 26 '14 at 14:09
  • Yep, that'd do it. Thank you! Once I sort out how to make sure I don't post page 2 twice, I'll post the solution. – webb Jul 26 '14 at 19:53
  • With my solution it doesn't matter if you have two watermarked environments on the same page. Is this what you meant? Also, you don't need to re-post the solution as part of your question – Andrew Jul 27 '14 at 0:00
3

EDIT II

Here is a fully functional solution. The MWE example is yours. My code puts the watermarks on pages 2,4,5,6 and 7 and adds hyperlinks back to them at the end of the document. I'll make some comments below.

\documentclass{article}
\usepackage[contents={Watermarked!},pages=some]{background}
\usepackage[colorlinks]{hyperref}
\pagenumbering{arabic}

\newcounter{watermark}

\makeatletter
\newif\ifWatermarkPage\WatermarkPagefalse% true if page should be watermarked
\newif\ifStillWatermarking\StillWatermarkingfalse% true if we want a watermark on the next page
\AddEverypageHook{%
  \ifWatermarkPage%
    \bg@material%
  \else%
    \ifStillWatermarking%
      \global\WatermarkPagefalse%
      \AddWatermarkLabels\bg@material%
    \fi%
  \fi%
  \global\WatermarkPagefalse%
}
% will hold a comma separated list of labels for the watermarked pages
\def\@watermarkedPages{\@gobble}  % gobble will eat an initial comma
% add a watermark and create a label - unless we've already done this for this page
\newcommand\AddWatermarkLabels{%
  \ifWatermarkPage%  already have label, so do nothing
  \else%
    \global\WatermarkPagetrue
    \refstepcounter{watermark}% increment number of watermarked pages
    % NB. Using \label{watermark:\thepage} doesn't write to the aux file 
    % when this is called via \AddEverypageHook, so we do it ourselves:
    \immediate\write\@auxout{\string\newlabel{watermark:\thepage}{{\thewatermark}{\thepage}{}{watermark.\thewatermark}{}}}
    \global\edef\@watermarkedPages{\@watermarkedPages,watermark:\thepage}% add label
  \fi
}
\newenvironment{watermarked}%
    {\global\StillWatermarkingtrue\AddWatermarkLabels}
    {\global\StillWatermarkingfalse\AddWatermarkLabels} % this page still needs a watermark

% The next macros pass the labels in \@watermarkedPages to \pageref taking
% care to add commas between references and an "and" between the last two.
\def\@printWatermarkedPage#1,#2{\pageref{#1}%
  \ifx#2@\let\@nextWatermark\relax%
  \else\let\@nextWatermark\@printWatermarkedPages%
  \fi%
  \@nextWatermark#2%
  }
\def\@printWatermarkedPages#1,#2{%
  \ifx#2@ and \let\@nextWatermark\@gobble\else ,\fi%
  \pageref{#1}%
  \@nextWatermark#2%
}
\newcommand\WatermarkedPages{\expandafter\@printWatermarkedPage\@watermarkedPages,@}
\makeatother

\begin{document}
% watermarks on pages 2,4,5,6,7
Some text here on page  1.
\newpage

\begin{watermarked}
some text
\end{watermarked}

\begin{watermarked}
more text
\end{watermarked}

More text here.

\newpage
Page with no watermarked stuff.
\newpage

\begin{watermarked}
more text,
\newpage
on several pages
\newpage
\end{watermarked}

More text here. Start a new page.
\newpage

\begin{watermarked}
more text
\end{watermarked}

\newpage
Loop to find pages containing the watermarked environment. Hard coded
here.

The \arabic{watermark} watermarked environments appear on the following
pages \WatermarkedPages.

\end{document}

Some comments:

  1. By way of explanation, the background package uses the everypage package to decorate the pages by defining \bg@material using PGF/TikZ. So this is why the code above has \bg@material inside the \AddEverypageHook. (In particular, you can don't need to add any more packages to your file because background already loads everything that I use.)

  2. Roughly half of the code is then devoted to defining \WatermarkedPages which extracts the list of references from \@watermarkedPages and hands them to \pageref so that it can create hyperlinks back to the corresponding pages. Quite possibly there is a more efficient way of doing this.

  3. The problem with my previous solution was that the hyperlinks all pointed back to the first page of the document rather than to the corresponding page, this was even though the page number displayed in the PDF file and reference itself were correct. [Edit: this issue is described in incorrect-target-of-label-link-produced-by-hyperref]. The solution was simply to \refstepcounter the counter for the number of watermarked pages (of course, as I write the aux file entry myself I could have just fudged this).

  4. I had problems in writing the labels to the aux files because not all of the \label commands executed resulted in an entry being written the aux file. I think that there might be an issue in using \label inside \shipout. To get around this I explicitly write the \newlabel commands to the aux file using an \immediate\write, which is perhaps a little OTT.

  • The goal is indeed to stick the watermark on everything with the watermark environment. Your full example almost works, except it doesn't seem to give the right page numbers, or a full list. Just a pointer to the page where it starts. But this is a great start, thank you! – webb Jul 25 '14 at 16:22
  • @webb Funny, I thought this was working but I agree that it wasn't. I've just edited the code and now it works. Part of the problem was that it seems(?) that \newlabel doesn't write to the aux file when called inside \shipout. To get around this I have had to explicitly write the label to the aux file myself. As I'll explain the links are still wrong. – Andrew Jul 26 '14 at 4:01
  • @webb I think it works now. – Andrew Jul 26 '14 at 14:00
  • It looks like I need to have this at the top of my document instead of at the end, which means multi-pass compilation. Any clue how to adapt this solution to that? – webb Sep 15 '15 at 16:32
  • @webb For the hyperlinked references the easiest way is to use hyperref, which uses (a super-up version of) latex standard referencing mechanism and hence requires two compilations. In theory it would be possible to do it without using hyperref but I suspect that this would take a fair amount of work. Certainly, I don't know how to do this off the top of my head. – Andrew Sep 18 '15 at 1:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.