3

Using the code from Background margin fill for (first line of) section titles?, I have this MWE:

\documentclass[10pt,twoside,openright]{book}

\usepackage[
  paperwidth=15cm,
  paperheight=20cm,
  outer=2.5cm,
  inner=2.5cm,
  top=2.5cm,
  bottom=2.5cm
  ]{geometry}
% \usepackage[a4,center]{crop}   % `crop` line
% \crop[cam,info]                % `crop` line

\usepackage{titlesec}
\usepackage{tikz}
\usetikzlibrary{external,calc}
\usepackage{tikzpagenodes}

\titleformat{\section}[hang]{\normalfont\Large\bfseries\color{black!90}}{\thesection}{1.5em}{\tikzexternaldisable\sectioncolouration{\Alph{section}}}[\tikzexternalenable]

\newcommand*\sectioncolouration[1]{%
  \begin{tikzpicture}[baseline=(a.base), overlay, remember picture, inner xsep=0pt, outer sep=0pt]
    \node  (a) {\phantom{\normalfont\Large\bfseries Xy}};
    \path [fill=blue, fill opacity=.2, even odd rule] (current page.west |- a.north) -| (current page.east |- a.south) -| cycle (current page text area.west |- a.north) -| (current page text area.east |- a.south) -| cycle;
    \ifodd\value{page}
    \node at (a -| {$(current page text area.east)!1/2!(current page.east)$}) {#1};
    \else
    \node at (a -| {$(current page text area.west)!1/2!(current page.west)$}) {#1};
    \fi
  \end{tikzpicture}}

\begin{document}
  \frontmatter
  \mainmatter

  \part{Introduction}
  \chapter*{The first chapter - without thinking anything else}

  \newpage

  \section{The first section - and some more text inside; and some more text inside; and some more text inside}

  Blah, blah, blah...

  \begin{tikzpicture}[remember picture,overlay]
  \draw[thick] (current page text area.north east) rectangle (current page text area.south west) ;
  \end{tikzpicture}

  \newpage
  \section{This section starts on an even page}
  Some text\dots

\end{document}

With the crop lines commented, as posted, everything is fine (after texing twice - click for full res):

test.png

But if I uncomment the crop lines, and recompile, then the output is corrupt:

test1.png

It's as if current page text area (and even \ifodd\value{page}) cannot be determined if crop is active?!

Is there any way to get this code to work, even if crop is active?

6
  • 1
    You are using a custom paper size?
    – cfr
    Commented Mar 29, 2015 at 23:24
  • Thanks @cfr: Yes, I am - I shuffled the values shown in this MWE a bit, just to "genericize", but I still have a custom paper size in my actual doc...
    – sdaau
    Commented Mar 29, 2015 at 23:28
  • 1
    You need to tell geometry. It thinks that your paper is 15x20cm when it is really 21x29.7cm. However, I'm losing the crop marks when I do this.
    – cfr
    Commented Mar 29, 2015 at 23:37
  • 1
    You know that geometry has a showcrop of its own? That works fine...
    – cfr
    Commented Mar 29, 2015 at 23:40
  • Thanks for that @cfr - good to know about the problems with geometry and losing cropmarks; had no idea about geometry's showcrop - but I'd prefer to get this working with the crop package (it was used in the original template I'm using).
    – sdaau
    Commented Mar 29, 2015 at 23:44

4 Answers 4

1

Here's a third answer. As the image shows, this does not correct the placement of the nodes added by tikzpagenodes. Rather, it compensates for the lies crop tells within the limited context of the section thumbs configuration.

section thumbs despite the lies

\documentclass[10pt,twoside,openright]{book}

\usepackage[
  paperwidth=15cm,
  paperheight=20cm,
  outer=2.5cm,
  inner=2.5cm,
  top=2.5cm,
  bottom=2.5cm
  ]{geometry}
\usepackage[a4,center]{crop}   % `crop` line
\crop[cam,info]                % `crop` line

\usepackage{titlesec}
\usepackage{tikz}
\usetikzlibrary{external,calc}
\usepackage{tikzpagenodes}

\titleformat{\section}[hang]{\normalfont\Large\bfseries\color{black!90}}{\thesection}{1.5em}{\tikzexternaldisable\sectioncolouration{\Alph{section}}}[\tikzexternalenable]

\newcommand*\sectioncolouration[1]{%
  \begin{tikzpicture}[baseline=(a.base), overlay, remember picture, inner xsep=0pt, outer sep=0pt]
    \node  (a) {\phantom{\normalfont\Large\bfseries Xy}};
    \ifx\stockwidth\undefined
    \coordinate (b) at (0,0);
    \else
    \coordinate (b) at (.5\paperwidth-.5\stockwidth,.5\stockheight-.5\paperheight);
    \fi
    \begin{scope}
      \path [fill=blue, fill opacity=.2, even odd rule] (current page.west |- a.north) -| (current page.east |- a.south) -| cycle ({$(current page text area.west) + (b)$} |- a.north) -| ({$(current page text area.east) + (b)$} |- a.south) -| cycle;
      \ifodd\value{page}
      \node at (a -| {$(current page text area.east)!1/2!(current page.east) + .5*(b)$}) {#1};
      \else
      \node at (a -| {$(current page text area.west)!1/2!(current page.west) + .5*(b)$}) {#1};
      \fi
    \end{scope}
  \end{tikzpicture}}

\begin{document}
  \frontmatter
  \mainmatter

  \part{Introduction}
  \chapter*{The first chapter - without thinking anything else}

  \newpage

  \section{The first section - and some more text inside; and some more text inside; and some more text inside}

  Blah, blah, blah...

  \begin{tikzpicture}[remember picture,overlay]
  \draw[thick] (current page text area.north east) rectangle (current page text area.south west) ;
  \end{tikzpicture}

  \newpage
  \section{This section starts on an even page}
  Some text\dots

\end{document}
2
  • 1
    Thanks @cfr - I like this one the best; I just added an \ifx conditional, so the same code works if just the crop lines are commented. Btw, I also tried to work with \stockwidth, but as it can be seen from my answer below, couldn't really figure it out, so I took a different approach (via redef of top and left). Cheers!
    – sdaau
    Commented Mar 30, 2015 at 2:52
  • 1
    @sdaau Note that this relies on the fact that you are passing center to crop, I think. Otherwise, you'd need to adjust the 0.5 appropriately in defining (b).
    – cfr
    Commented Mar 30, 2015 at 2:53
2

Ok, I think I have something, but am not exactly sure of it; the fix seems to be this:

\ifx\CROP@size\undefined
  \typeout{CROP@size undefined}
\else
  \typeout{CROP@size defined}
  % must set via newlength so it survives descent into tikzpicture!
  \setlength\gparindent{\parindent}
  \setlength\gbaselineskip{\baselineskip}
  \def\current@textarea@left{(1in+\hoffset+\currentsidemargin-\Gm@lmargin-\gparindent)}
  \def\current@textarea@top{(1in+\voffset+\topmargin+\headheight+\headsep)+2*\[email protected]\gbaselineskip}
\fi

... that is, if crop is loaded, redefine \current@textarea@left and \current@textarea@top from tikzpagenodes, so the left is adjusted by \Gm@lmargin-\gparindent and the right by 2*\[email protected]\gbaselineskip - where \Gm@l/tmargin are margins via the geometry package.

The \gparindent and \gbaselineskip are "globalised" versions of parindent/baselineskip - as lengths - otherwise they won't propagate when the above definitions run inside tikzpicture (which resets parindent/baselineskip). The Gm@ margins make sense, but I have no idea why there is this displacement in there to begin with - I found the fix values via trial/error, so caveat emptor.

The code below has some extra debug stuff, and it outputs something like this:

/tmp/test.png

Seems there is a tiny amount of bleed too - which is nice; also, all seems to work if you just comment the crop lines, as well.

The code:

\documentclass[10pt,twoside,openright]{book}

\usepackage[
  paperwidth=15cm,
  paperheight=20cm,
  outer=3.5cm,
  inner=2.5cm,
  top=2.5cm,
  bottom=3.5cm
  ]{geometry}
\usepackage[a4,center]{crop}
\crop[cam,info]

\usepackage{lipsum}

\usepackage{titlesec}
\usepackage{tikz}
\usetikzlibrary{external,calc}
\usepackage{tikzpagenodes}
\makeatletter
\newlength\gparindent
\newlength\gbaselineskip
\ifx\CROP@size\undefined
  \typeout{CROP@size undefined}
\else
  \typeout{CROP@size defined}
  % from tikzpagenodes:
  % NB: \parindent, \baselineskip seem to dissapear inside \sectioncolouration
%   \let\gparindent\parindent% NO
%   \xdef\gparindent{\parindent}% NO!
  % must set via newlength so it survives descent into tikzpicture!
  \setlength\gparindent{\parindent}
  \setlength\gbaselineskip{\baselineskip}
  \typeout{gparindent-Start \the\gparindent}%
  \def\current@textarea@left{(1in+\hoffset+\currentsidemargin-\Gm@lmargin-\gparindent)}
  \def\current@textarea@top{(1in+\voffset+\topmargin+\headheight+\headsep)+2*\[email protected]\gbaselineskip}
  % no need to repeat this:
%   \@newtikzpagenode{current page text area}{%
%     \def\southwest{\pgfpoint{\current@textarea@left}{\paperheight-\current@textarea@top-\textheight}}%
%     \def\northeast{\pgfpoint{\current@textarea@left+\textwidth}{\paperheight-\current@textarea@top}}%
%   }
\fi
\makeatother


\newcommand*\sectioncolouration[1]{%
  \begin{tikzpicture}[baseline=(a.base), overlay, remember picture, inner xsep=0pt, outer sep=0pt]%
    \typeout{gparindent-In-Sect-Col \the\gparindent}%
    \node  (a) {\phantom{\normalfont\Large\bfseries Xy}};
    \path [fill=blue, fill opacity=.2, even odd rule]
      (current page.west |- a.north) -| (current page.east |- a.south) -| cycle
      (current page text area.west |- a.north) -| (current page text area.east |- a.south) -| cycle;
%     (current page text area.south west) -| (current page text area.north east) -| cycle; % debug
    \draw[red] (current page text area.north east) rectangle (current page text area.south west); % debug
    \ifodd\value{page}
    \node at (a -| {$(current page text area.east)!1/2!(current page.east)$}) {#1};
    \else
    \node at (a -| {$(current page text area.west)!1/2!(current page.west)$}) {#1};
    \fi
  \end{tikzpicture}}

\titleformat{\section}[hang]{%
  \typeout{gparindent-Sect \the\gparindent}%
  \setlength\gparindent{\parindent}%
  \setlength\gbaselineskip{\baselineskip}%
  \normalfont\Large\bfseries\color{black!90}%
}{\thesection}{1.5em}{\tikzexternaldisable\sectioncolouration{\Alph{section}}}[\tikzexternalenable]


\begin{document}
  \frontmatter
  \mainmatter


  \part{Introduction}
  \chapter*{The first chapter - without thinking anything else}

  \newpage

  \section{The first section - and some more text inside; and some more text inside; and some more text inside}

  % debug
  \begin{tikzpicture}[remember picture,overlay]
  \draw[thick] (current page text area.north east) rectangle (current page text area.south west) ;
  \draw[thick] (current page text area.east) rectangle ($(current page text area.west)+(0,1)$) ;
  \end{tikzpicture}

  \noindent
  Blah, blah, blah... \lipsum[1-3]

%   \newpage
  \section{This section starts on an odd page}
  Some text\dots

\end{document}
0
1

crop appears to fundamentally disagree with tikzpagenodes. Or, rather, lying about your page layout, as crop requires, appears to fundamentally disagree with it. This is not terribly surprising. If the text area is not where you say, it isn't that surprising that things go haywire.

If geometry's crop marks are an option, these work fine:

crop marks with fancy sections

\documentclass[10pt,twoside,openright]{book}
\usepackage[
  paper=a4paper,
  layoutsize={15cm,20cm},
  layoutoffset={30mm,48.5mm},
  outer=2.5cm,
  inner=2.5cm,
  top=2.5cm,
  bottom=2.5cm,
  showcrop,
  ]{geometry}
\usepackage{titlesec}
\usepackage{tikz}
\usetikzlibrary{external,calc}
\usepackage{tikzpagenodes}

\titleformat{\section}[hang]{\normalfont\Large\bfseries\color{black!90}}{\thesection}{1.5em}{\tikzexternaldisable\sectioncolouration{\Alph{section}}}[\tikzexternalenable]

\newcommand*\sectioncolouration[1]{%
  \begin{tikzpicture}[baseline=(a.base), overlay, remember picture, inner xsep=0pt, outer sep=0pt]
    \node  (a) {\phantom{\normalfont\Large\bfseries Xy}};
    \path [fill=blue, fill opacity=.2, even odd rule] (current page.west |- a.north) -| (current page.east |- a.south) -| cycle (current page text area.west |- a.north) -| (current page text area.east |- a.south) -| cycle;
    \ifodd\value{page}
    \node at (a -| {$(current page text area.east)!1/2!(current page.east)$}) {#1};
    \else
    \node at (a -| {$(current page text area.west)!1/2!(current page.west)$}) {#1};
    \fi
  \end{tikzpicture}}

\begin{document}
  \frontmatter
  \mainmatter

  \part{Introduction}
  \chapter*{The first chapter - without thinking anything else}

  \newpage

  \section{The first section - and some more text inside; and some more text inside; and some more text inside}

  Blah, blah, blah...

  \begin{tikzpicture}[remember picture,overlay]
    \draw[thick] (current page text area.north east) rectangle (current page text area.south west) ;
  \end{tikzpicture}

  \newpage
  \section{This section starts on an even page}
  Some text\dots

\end{document}
1
  • Thanks for that @cfr; I'm trying to mess a bit with redefining tikzpagenodes if crop is loaded (I'm not progressing much though); if everything else fails, I'll eventually accept this answer... Cheers!
    – sdaau
    Commented Mar 29, 2015 at 23:46
1

I've been working on this problem from a more general angle.

From scanning the documentation of the crop package, it would seem like the most relevant values that we'd want to pull out are \stockwidth and \stockheight, which are used to store the ultimate paper size.

All we really need to do is redefine the main macros for tikzpagenodes to account for the difference between \stock* and \paper*. The code for this is

\def\current@textarea@left{%
  (1in+\hoffset+\currentsidemargin+.5*(\paperwidth-\stockwidth))%
}
\def\current@textarea@top{%
  (1in+\voffset+\topmargin+\headheight+\headsep-.5*(\stockheight-\paperheight))%
}

Which just adds half of the difference between the \stock and \paper values to acccount for the offset. We only need half the value b/c the logical page is centered in the physical page, thus offset by half the difference.

To make a generic version of this, we'll do the following:

%fix the crop issue with tikzpagenodes
\@ifpackageloaded{crop}{
  \@ifpackagewith{crop}{center}
    {
    \def\current@textarea@left{%
      (1in+\hoffset+\currentsidemargin+.5*(\paperwidth-\stockwidth))}
    \def\current@textarea@top{%
      (1in+\voffset+\topmargin+\headheight+\headsep-.5*(\stockheight-\paperheight))}
    }
    {
    \def\current@textarea@top{%
      (1in+\voffset+\topmargin+\headheight+\headsep-(\stockheight-\paperheight))}
    }
  }
  {%
}

Now we can automatically adjust for the offset if the crop package is loaded. I also made a different adjustment for when the center option isn't used, where the \hoffset is fine and thus doesn't need adjustment, and the \voffset needs twice the adjustment (seeing as we're at the top left corner of the page).

I tested this both while typesetting RTL and LTR texts, using XeTeX.

It's actually interesting, because the center option actually sets \hoffset and \voffset to values which would be correct for our needs, but investigating that isn't necessary.

You must log in to answer this question.

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