1

I want to define a tikz node called current grid area based on the nodes defined by the tikzpagenodes package. This node is a rectangle that contains the 4 nodes defined in the package; current page footer, current page header, current page text area and current page marginpar:

The north of the grid area should be the north of the header; the south should be the south of the footer. The east and west depend of the recto/verso page. In odd pages the west should be west of the text area and the east of the marginpar. In the even pages the west is the west of marginpar and the east the is the east of the text area.

I extract the coordinate values of the corners of each area save them in global macros like \gl@globalgridareaw, \gl@globalgridareae .... Then I build the node using the code to build current page in pgfmoduleshapes.code.tex. Is part I don't understand very well :-),

% Special  current grid area bounding box rectangle:
\expandafter\def\csname pgf@sh@ns@current grid area\endcsname{rectangle}
\expandafter\def\csname pgf@sh@np@current grid area\endcsname{%
  \def\southwest{\pgfqpoint{\gl@globalgridareaw}{\gl@globalgridareas}}%
  \def\northeast{\pgfqpoint{\gl@globalgridareae}{\gl@globalgridarean}}%
}
% % TODO: Should I redefine this?
 \expandafter\def\csname pgf@sh@nt@current grid area\endcsname{{1}{0}{0}{1}{0pt}{0pt}}
 \expandafter\def\csname pgf@sh@pi@current grid area\endcsname{pgfpageorigin}
}

As the example bellow show the the node is not correctly defined. It seems that some offset should be added.

\documentclass{article}
\usepackage{geometry}
\usepackage{tikzpagenodes}
\usetikzlibrary{calc}

\makeatletter
\newcommand{\calculateparameters}{
    \noindent\tikz[remember picture,overlay]{\path (current page header area.north);%
    \pgfgetlastxy{\gl@discard}{\gl@gridarean}
    \path (current page footer area.south);
    \pgfgetlastxy{\gl@discard}{\gl@gridareas}
    \global\let\gl@globalgridareas\gl@gridareas%
    \global\let\gl@globalgridarean\gl@gridarean%
  }
    \checkoddpage

    \ifoddpage
    \noindent\tikz[remember picture,overlay]{
      \path (current page marginpar area.east);
      \pgfgetlastxy{\gl@gridareae}{\gl@discard}
      \path (current page text area.west);
      \pgfgetlastxy{\gl@gridareaw}{\gl@discard}
      \global\let\gl@globalgridareaw\gl@gridareaw%
      \global\let\gl@globalgridareae\gl@gridareae%
    }
    \else
    \tikz[remember picture,overlay]{
      \path (current page marginpar area.west);
      \pgfgetlastxy{\gl@gridareaw}{\gl@discard}
      \path (current page text area.east);
      \pgfgetlastxy{\gl@gridareae}{\gl@discard}
      \global\let\gl@globalgridareaw\gl@gridareaw%
      \global\let\gl@globalgridareae\gl@gridareae%
    }
    \fi

% Special  current grid area bounding box rectangle:
\expandafter\def\csname pgf@sh@ns@current grid area\endcsname{rectangle}
\expandafter\def\csname pgf@sh@np@current grid area\endcsname{%
  \def\southwest{\pgfqpoint{\gl@globalgridareaw}{\gl@globalgridareas}}%
  \def\northeast{\pgfqpoint{\gl@globalgridareae}{\gl@globalgridarean}}%
}
% % TODO: Should I redefine this?
 \expandafter\def\csname pgf@sh@nt@current grid area\endcsname{{1}{0}{0}{1}{0pt}{0pt}}
 \expandafter\def\csname pgf@sh@pi@current grid area\endcsname{pgfpageorigin}
}

\makeatother

\begin{document}
\calculateparameters%
\noindent\tikz[<-,remember picture,overlay] {%
  \draw[red] (current grid area.south west) rectangle (current grid area.north);
}%


\tikz[remember picture,overlay] {%
\draw [blue,line width=2mm]
(current page.south west)
rectangle
(current page.north east);
\draw [green]
(current page text area.south west)
rectangle
(current page text area.north east);
\draw [yellow]
(current page marginpar area.south west)
rectangle
(current page marginpar area.north east);
\draw [red]
(current page header area.south west)
rectangle
(current page header area.north east);
\draw [orange]
(current page footer area.south west)
rectangle
(current page footer area.north east);
}%
\end{document}
1

The coordinate values you extract there (you could also use \pgfpointanchor{<node name>}{<anchor>} and then you would have the coordinates in the dimens \pgf@x and \pgf@y without the need to use TikZ) are the coordinates in the current TikZ picture (relative to that’s origin).

But in \northeast and \southwest (the \savedanchors of a rectangle shape), the coordinates are needed in the local coordinate system of the node itself (which is in these cases the original coordinate system of the page {1}{0}{0}{1}{0pt}{0pt}).

If the \pgfpictureid of the current TikZ picture (where you access a node) is not the same as in the \pgf@sh@pi@<node name> macro (here pgfpageorigin) the difference between the current TikZ picture and the node’s is added to the coordinates (this is where remember picture and the .aux file comes in play).

If you would extract all the needed coordinates in one TikZ picture, you could your definition of the current grid area node and use then

\expandafter\edef\csname pgf@sh@pi@current grid area\endcsname{\pgfpictureid}

(the transformation matrix will be the same anyway).

But then you could just use the fit library and do

\node[fit=(current page marginpar area)(current page footer area)(current page header area),
      inner sep=+0pt] (current grid area) {};

(there is still the need for doing this on every page do sort out even and odd ones).

Long story short:

I’d just use the values for the coordinate of the original page nodes from tikzpagenodes. These consist of a few calculations that consider the widths and heights of certain areas as well as separators between these areas.


I removed the geometry package from your example as it did bad things to the margin width (at least without any settings) in a two sided document.

Code

\documentclass[two side]{article}
\usepackage{lipsum,tikzpagenodes}
\makeatletter
\@newtikzpagenode{current grid area}{%
 \def\southwest{\pgfpoint
  {\current@textarea@left\ifoddpageoroneside\else-\marginparsep-\marginparwidth\fi}
  {\paperheight-\current@textarea@top-\textheight-\footskip}}%
 \def\northeast{\pgfpoint
  {\current@textarea@left+\textwidth\ifoddpageoroneside+\marginparsep+\marginparwidth\fi}
  {\paperheight-\current@textarea@top+\headsep+\headheight}}%
}
\makeatother
\newcommand*\drawAreas[1][]{%
\tikz[
  remember picture, overlay,
  nodes={fill=white, fill opacity=.8, text opacity=1, inner ysep=+1pt},
  RECT/.style={to path={(\tikztostart.south west) rectangle
    node[##1] {\tikztostart} (\tikztostart.north east)}},
  #1] {%
  \draw [blue,line width=2mm](current page)                to[RECT] ();
  \draw [green]              (current page text area)      to[RECT] ();
  \draw [yellow!70!black]    (current page marginpar area) to[RECT={rotate=90}] ();
  \draw [red]                (current page header area)    to[RECT] ();
  \draw [orange]             (current page footer area)    to[RECT] ();
  \draw [black, ultra thick] (current grid area)           to[RECT] ();
}}
\begin{document}
\marginpar{\color{gray}\raggedleft\lipsum[2]}
\drawAreas

\vfill\pagebreak
\marginpar{\color{gray}\raggedright\lipsum[2]}
\drawAreas
\end{document}

Output

enter image description here

enter image description here

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.