11

Currently I am using an external PDF image to get a color gradient provide in the margins. See the output below. I achieve this by using command \ULCornerWallPaper{1}{./pictures/wallpaper_1.pdf}

However, this method is very inefficient because importing the external picture every time results in a long compilation time. Is there a better way of doing it?

The gradient is only applied to some of the pages so it would be ideal if you provided me with a solution which I can include in \ULCornerWallPaper{1}{} so I can undo gradient after a while using command \ClearWallPaper.

Could I achieve this using tikz? I'm not very familiar with it, but it looks like a possible tool for solving my problem.

two muppets

5
  • 3
    You could have a look on tikz and the current page node. This allows you to attach tikz graphics to a page and shading is fairly easy in tikz. Look for example here Oct 2, 2012 at 12:21
  • But i ll have to apply tikz picture for every single page. This is not an option.
    – 71GA
    Oct 2, 2012 at 17:09
  • I tried using tikz and i have a problem because my gradient goes over my marginal notes and not below them.
    – 71GA
    Oct 2, 2012 at 22:42
  • I think you can have a look to How to set colored ruled margins for different pages?: the answer automatically does not cover marginal notes and you can set the gradient easily. Notice that I think the background package allows you to choose the pages in which display the background. Oct 3, 2012 at 8:30
  • 2
    Pardon me, but the following quote just seemed appropriate. "...I have discovered a truly marvelous demonstration of this proposition that this margin is too narrow to contain." - Fermat :)
    – McGafter
    Mar 27, 2013 at 9:10

2 Answers 2

27

The solution below defines two alternative ways of drawing a coloured gradient in the margin background on a selection of pages:

  1. Invoke the \conditionalmarginbg (which takes no argument) at the beginning of your document and then toggle the margin background on/off in your document by using the \startdrawmarginbg and \stopdrawmarginbg macros.
  2. Invoke \marginbgpagelist at the beginning of your document; its only argument is a list of pages on which to draw a margin background. That list uses pgffor's \foreach syntax, so you can specify 10,...,20 to draw a margin back on pages 10 to 20.

In the example below, I used \conditionalmarginbg and, for visualisation, I emphasised (red, bold text) where \startdrawmarginbg and \stopdrawmarginbg are invoked.

Notes:

  • You'll need to run pdflatex no fewer than 3 times to get the correct output.
  • I presume you need(ed) this for a book, so I didn't bother making my solution compatible with the oneside class option. It works fine with twoside, though.

References:

enter image description here enter image description here

\documentclass[twoside]{book}

\usepackage{lipsum}                         % for filler text
\usepackage[margin=3cm]{geometry}           % for setting the dimensions
\usepackage{tikzpagenodes}                      
\usepackage{background}
    \backgroundsetup%
    {%
        contents    = {},%
        opacity     = 1,%
        scale       = 1,
    }
\usepackage{etoolbox}                       % defines the \ifnumodd macro
\usepackage{xcolor}



% Let's define some colours for this colour gradient
\definecolor{outercolor}{gray}{.7}
\definecolor{innercolor}{gray}{1}

% a switch for toggling margin background on/off
\newif\ifdrawmarginbg\drawmarginbgfalse
\newcommand\startdrawmarginbg{\drawmarginbgtrue}
\newcommand\stopdrawmarginbg{\drawmarginbgfalse}

% redefinition of \emph, just to show where
% my \startdrawmarginbg and \stopdrawmarginbg are invoked in the example
\renewcommand\emph[1]{\textcolor{red}{\bfseries#1}}


% ----- Two possible strategies -----

% --- \conditionalmarginbg ---
% Invoke the following macro at the beginning of the document and then
% use \startdrawmarginbg and \stopdrawmarginbg to toggle the margin background
% gradient on/off in the document.
\newcommand\conditionalmarginbg%
{%
    \AddEverypageHook%
    {%
        \ifdrawmarginbg%
            \thispagemarginbg%
        \fi%
    }%
}

% --- \marginbgpagelist ---
% Invoke the following macro at the beginning of the document.
% It's only (mandatory) argument is a list (using pgffor's \foreach syntax)
% corresponding to the pages on which a margin background gradient
% should be drawn.
\newcommand\marginbgpagelist[1]%
{%
    \AddEverypageHook%
    {%
        \foreach \p in {#1}%
        {%
            \ifnum\value{page}=\p%
                \thispagemarginbg%
            \fi
        }%
    }%
}


% ----- Auxiliary macros ----- 

% Auxiliary macro for both \conditionalmarginbg and \marginbgpagelist
\newcommand\thispagemarginbg
{%
    \ifnumodd{\value{page}}
        {\marginbgevenorodd{1}}
        {\marginbgevenorodd{0}}
    \BgMaterial
}%

% Auxiliary macro for \thispagemarginbg
\newcommand\marginbgevenorodd[1]%
{%
    \ifnum#1=1%
        \def\shadeangle{90}
        \def\marginrectangle
        {%
            (current page marginpar area.south west |- current page.south)%
            rectangle%
            (current page.north east)
        }
    \else%
        \ifnum#1=0%

            \def\shadeangle{-90}
            \def\marginrectangle
            {%
                (current page marginpar area.south east |- current page.south)%
                rectangle%
                (current page.north west)
            }
        \else%
            \errmessage{Incompatible value supplied to \string\marginbgevenorodd}   
        \fi%
    \fi%
    \backgroundsetup
    {%
        angle=0,%
        contents=%
        {%
            \tikz[remember picture,overlay]
            \shade
            [%
                bottom color    = outercolor,%
                top color       = innercolor,%
                shading angle   = \shadeangle,%
            ] \marginrectangle;%
        }%                  
    }%
}

% Use either...
% \marginbgpagelist{2,3,...,4}
% or...
\conditionalmarginbg

\begin{document} 

\lipsum[1-10]

\emph{A margin background gradient is drawn from this page onwards.}
\startdrawmarginbg

\lipsum[21-40]

\emph{No margin background gradient is drawn from this page onwards.}
\stopdrawmarginbg

\lipsum[41-50]

\end{document}
0
12

I will provide a solution which draws the gradient using MetaFun. It's drawn on the page layer, which means it is located underneath the text elements and margin notes. You can also use leftpage or rightpage to include different backgrounds on even and odd pages.

Since MetaPost is much faster than TikZ or including external figures you don't have worry about the compilation times. The uniqueMPgraphic ensures that the graphic is computed only once and reused. This enables to draw 1000 pages with gradient background in about 2.5s (on my machine).

The location is customisable via the option gradientmargin. Here's a complete example using ConTeXt.

\setuplayout [width=13cm]

\startuniqueMPgraphic{background:gradient}
  path p;
    p := OverlayBox leftenlarged -\framedparameter{gradientmargin};
    linear_shade(p, 0, white, OverlayColor);
  setbounds currentpicture to boundingbox OverlayBox;
\stopuniqueMPgraphic

\defineoverlay
  [background:gradient]
  [\uniqueMPgraphic{background:gradient}]

\setupbackgrounds
  [page]
  [background=background:gradient,
   gradientmargin=15cm,
   backgroundcolor=middlegray]

\starttext
  \dorecurse{10}{\input knuth}
\stoptext

Result:

result

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .