27

Question

How can I get my grid lines to line up perfectly such that they correspond to the physical millimeters on the page.

Situation

I have a sheet of A4 paper. I want to draw grid lines on it with each millimeter labelled (obviously the numbering size is for digital use, realistically the centimeters would be labelled for the physical print).

Criteria

  • Works for any paper size (provided the \step maximum is adjusted)
  • Lines align with the physical dimensions
  • The overlay will cover any other tikz pictures (or anything else) regardless of where the command is called in the document (I can call the command on any page where I want the grid)

enter image description here

Problem

  • The lines do not start at the origin
  • The grid is not above the tikzpicture called within the document regardless of where \showgrid is called.

Example Code

\documentclass{article}
\usepackage{fontspec}
\usepackage{tikz}
\usetikzlibrary{calc}
\usepackage{anyfontsize}
\newcommand{\showgrid}{%
    \begin{tikzpicture}[overlay,remember picture,every node/.style={inner sep=0pt,outer sep=0pt}]%
        \draw[help lines,xstep=1mm,ystep=1mm,gray!25] (current page.north west) grid (current page.south east);
        \draw[help lines,xstep=10mm,ystep=10mm,color=gray] (current page.south west) grid (current page.north east);
        \foreach \step in {0,1,...,297} {
            \node [anchor=north] at ($ (current page.north west) + (\step mm,0cm) $) {\fontsize{1}{2}\selectfont \step};
            \node [anchor=west] at ($ (current page.north west) + (0cm,-\step mm) $) {\fontsize{1}{2}\selectfont \step};
        }
    \end{tikzpicture}
}%



\begin{document}
\thispagestyle{empty}
\showgrid{}

\begin{tikzpicture}[overlay,remember picture,every node/.style={fill=red,inner sep=0pt,outer sep=0pt}]%
   \node [minimum width=2cm,minimum height=2cm] at (current page.center) {};
\end{tikzpicture}%

\end{document}

Output

enter image description here


UPDATE: My Solution

This is a hybrid solution that utilizes cfr's approach combined with the automatic page size detection of esdd's answer.

\documentclass[a4paper]{article}
\usepackage{tikz}
\usepackage{tikzpagenodes}
\usetikzlibrary{calc}
\usetikzlibrary{backgrounds}
\usepackage{anyfontsize}
\usepackage{atbegshi}
\newcommand{\showgrid}{%
  \AtBeginShipoutNext{\AtBeginShipoutAddToBoxForeground{%
      \begin{tikzpicture}
        [
          overlay,
          remember picture,
          inner sep=0pt,
          outer sep=0pt,
          minor line/.style={help lines, draw=black!50, on background layer},
          major line/.style={help lines, draw=black},
          major number/.style={font=\fontsize{3}{5}\selectfont\bfseries},
          minor number/.style={font=\fontsize{1}{2}\selectfont},
        ]
        \pgfmathtruncatemacro\xmaxstep{\paperwidth/1mm}% calculate needed steps in x direction
        \pgfmathtruncatemacro\ymaxstep{\paperheight/1mm}% calculate needed steps in y direction
        \foreach \step in {0,1,...,\xmaxstep} {
          \pgfmathsetmacro\gridlineconfig{ifthenelse(equal(int(mod(\step,10)),0),"major line","minor line")}%
          \draw [\gridlineconfig] ($(current page.north west) + (\step mm,0)$) -- ($(current page.south west) + (\step mm,0)$);
        }
        \foreach \step in {0,1,...,\ymaxstep} {
          \pgfmathsetmacro\gridlineconfig{ifthenelse(equal(int(mod(\step,10)),0),"major line","minor line")}%
          \pgfmathsetmacro\numberconfig{ifthenelse(equal(int(mod(\step,10)),0),"major number","minor number")}%
          \draw [\gridlineconfig] ($(current page.north west) - (0,\step mm)$) -- ($(current page.north east) - (0,\step mm)$);
          \node [anchor=north,\numberconfig] at ($ (current page.north west) + (\step mm,0) $) {\step};
          \node [anchor=west,\numberconfig] at ($ (current page.north west) - (0,\step mm) $) {\step};
        }
      \end{tikzpicture}
    }%
  }%
}
\tikzset{% 
    myseg/.style={%
        red,very thick
    }
}


\begin{document}
\null
\showgrid

\begin{tikzpicture}[overlay,remember picture]
\draw [myseg] (current page text area.north west) -- (current page text area.north east) -- (current page text area.south east) -- (current page text area.south west) -- (current page text area.north west);
\draw [myseg] (current page header area.north west) -- (current page header area.north east) -- (current page header area.south east) -- (current page header area.south west) -- (current page header area.north west);
\draw [myseg] (current page footer area.north west) -- (current page footer area.north east) -- (current page footer area.south east) -- (current page footer area.south west) -- (current page footer area.north west);
\draw [myseg] (current page marginpar area.north west) -- (current page marginpar area.north east) -- (current page marginpar area.south east) -- (current page marginpar area.south west) -- (current page marginpar area.north west);
\end{tikzpicture}

\end{document}

Output

Note: When reverse engineering layouts, this grid can be printed over another PDF by using the scale to printer margins option on most printing menus, because both the PDF and the grid will be scaled at the same ratio, which means that a scaled-down millimeter will be the equivalent of a millimeter on the underlaying PDF. An example of drawing on images using this code can be found here: https://tex.stackexchange.com/a/269156/13552 enter image description here enter image description here

  • 3
    To have your grid over anything on the page just draw it at the end, using on preamble \AtEndDocument{\showgrid{}}, not on the document body. – Sigur Feb 20 '15 at 17:57
  • Doesn't that add it to every page or just the last page? What about just on the page where I added the \showgrid command? – Jonathan Komar Feb 20 '15 at 18:06
14
+50

Note that the line widths may not look even in the posted PNGS. This is an artefact of a small screen/PDF viewer combination and has nothing to do with the actual PDF. It just affects my PNG clippings.

I think this solution satisfies the various desiderata:

  • Can be adapted to other paper sizes by adjusting the definitions of the \steps.
  • The north-west corner of the paper is at the origin and the grid lines align with the physical dimensions of the page in the sense that the north-west corners of both a small square and a large square of the grid are aligned with the north-west corner of the page. page with grid north-west origin
  • The grid overlays other page contents, including tikzpictures, even if these use overlay, remember picture themselves. grid overlays image
  • \showgrid can be specified anywhere on the page where the grid is required, including before any tikzpictures, even if they themselves use overlay, remember picture.
  • The grid is shown only on the page(s) it is requested. No grid will be used for the following page. (But it would be easy to adapt this so that it was shown on every page or whatever. See the documentation of atbegshi.)

I drew the grid by hand, drawing the horizontal and vertical lines separately. I use the backgrounds library to ensure that the lighter lines are not drawn over the darker lines (which looks rather odd).

I use atbegshi to ensure the grid is placed above any and all page content.

\documentclass[a4paper]{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\usetikzlibrary{backgrounds}
\usepackage{anyfontsize}
\newcommand{\showgrid}{%
  \AtBeginShipoutNext{\AtBeginShipoutAddToBoxForeground{%
      \begin{tikzpicture}
        [
          overlay,
          remember picture,
          inner sep=0pt,
          outer sep=0pt,
          minor line/.style={help lines, draw=gray!25, on background layer},
          major line/.style={help lines, draw=gray},
        ]
        \foreach \step in {0,...,210} {
          \pgfmathsetmacro\gridlineconfig{ifthenelse(equal(int(mod(\step,10)),0),"major line","minor line")}%
          \draw [\gridlineconfig] ($(current page.north west) + (\step mm,0)$) -- ($(current page.south west) + (\step mm,0)$);
        }
        \foreach \step in {0,...,297} {
          \pgfmathsetmacro\gridlineconfig{ifthenelse(equal(int(mod(\step,10)),0),"major line","minor line")}%
          \draw [\gridlineconfig] ($(current page.north west) - (0,\step mm)$) -- ($(current page.north east) - (0,\step mm)$);
          \node [anchor=north] at ($ (current page.north west) + (\step mm,0) $) {\fontsize{1}{2}\selectfont \step};
          \node [anchor=west] at ($ (current page.north west) - (0,\step mm) $) {\fontsize{1}{2}\selectfont \step};
        }
      \end{tikzpicture}
    }%
  }%
}
\usepackage{atbegshi}

\begin{document}
  \thispagestyle{empty}
  \showgrid
  \begin{tikzpicture}[overlay,remember picture,every node/.style={fill=red,inner sep=0pt,outer sep=0pt}]%
    \node [minimum width=2cm,minimum height=2cm] at (current page.center) {};
  \end{tikzpicture}
\end{document}
  • Awesome! I learned a little about the \pgfmathsetmacro! I am not sure I completely understand what is happening there, but I added the following styles to emphasize the major lines and removed the font code from the text input of the nodes: major number/.style={font=\fontsize{3}{5}\selectfont}, minor number/.style={font=\fontsize{1}{2}\selectfont}, \pgfmathsetmacro\numberconfig{ifthenelse(equal(int(mod(\step,10)),0),"major number","minor number")}% – Jonathan Komar Feb 24 '15 at 21:05
  • @macmadness86 It is just checking if \step is divisible by 10. So the major and minor lines are drawn in one step - if not divisible by 10, minor; if divisible, major. – cfr Feb 24 '15 at 22:06
  • OK. Yes I get that, but I am not sure how it is doing that check. On step 19, mod would be doing 19/10 = 1 (is that correct?) and int would be doing 1 ≠ 0, therefore minor? What I don't get is why you need the int if mod will always yield integers... – Jonathan Komar Feb 24 '15 at 22:11
  • 1
    @macmadness86 Yes. that's right. You need int because you will get things like 0.00... which will come out as not equal to 0. [It is to do with the way the library/TeX handles numbers.] – cfr Feb 24 '15 at 22:12
9

The command \AddToShipoutPictureFG* defined by the package eso-pic sets its contents on top of the current page. Additionally, it is possible to calculate the needed numbers of labels in x and y direction depending on the paper size.

\documentclass[a5paper]{article}
%\usepackage{fontspec} % commented to speed up compilation
\usepackage{blindtext}% dummy text
\usepackage{tikz}
\usepackage{anyfontsize}
\usepackage{eso-pic}

\newcommand{\showgrid}{%
  \AddToShipoutPictureFG*{%
    \begin{tikzpicture}[overlay,remember picture,
        thin,nodes={font=\fontsize{1}{2}\selectfont},
        yshift=\paperheight% origin is in the upper left corner
        ]
      \draw[gray!25,step=1mm](current page.south west)grid(current page.north east);
      \draw[blue!30!gray,step=10mm](current page.south west) grid(current page.north east);
      \pgfmathtruncatemacro\xmaxstep{\paperwidth/1mm}% calculate needed steps in x direction
      \pgfmathtruncatemacro\ymaxstep{\paperheight/1mm}% calculate needed steps in y direction
      \foreach \step in {0,1,...,\xmaxstep}
        \node [anchor=north] at ([xshift=\step mm]current page.north west) {\step};
      \foreach \step in {0,1,...,\ymaxstep}
        \node [anchor=west] at ([yshift=-\step mm]current page.north west) {\step};
%        \node[fill=red]at(0,0){};% to show the origin
    \end{tikzpicture}%
  }%
}

\begin{document}
\blindtext[2]
\showgrid
\tikz[overlay,remember picture]\node[minimum size=2cm,fill=red] at (current page.center) {};
\blinddocument
\showgrid
\blinddocument
\end{document}

enter image description here

enter image description here

enter image description here


With package scrlayer you can define the grid as a new pagestyle.

\documentclass[a5paper]{article}
%\usepackage{fontspec} % commented to speed up compilation
\usepackage{blindtext}% dummy text
\usepackage{tikz}
\usepackage{anyfontsize}

\usepackage{scrlayer}
\DeclareNewLayer[foreground,page,
  contents={%
  \begin{tikzpicture}[thin,nodes={font=\fontsize{1}{2}\selectfont}]
    \useasboundingbox(0,0)rectangle(\layerwidth,-\layerheight);
    \draw[gray!25,step=1mm](0,0)grid(\layerwidth,-\layerheight);
    \draw[orange!30!gray,step=10mm](0,0)grid(\layerwidth,-\layerheight);
    \pgfmathtruncatemacro\xmaxstep{\layerwidth/1mm}% calculate needed steps in x direction
    \pgfmathtruncatemacro\ymaxstep{\layerheight/1mm}% calculate needed steps in y direction
    \foreach \step in {0,1,...,\xmaxstep}
      \node [anchor=north] at (\step mm,0) {\step};
    \foreach \step in {0,1,...,\ymaxstep}
      \node [anchor=west] at (0,-\step mm){\step};
  \end{tikzpicture}%
  }
]{grid.fg}
\DeclareNewPageStyleByLayers{grid}{grid.fg}

\pagestyle{headings}

\begin{document}
\blindtext[2]
\thispagestyle{grid}
\tikz[overlay,remember picture]\node[minimum size=2cm,fill=red] at (current page.center) {};
\blinddocument
\thispagestyle{grid}
\blinddocument
\end{document}

enter image description here

enter image description here

  • (+1) for the automation. But I think the shipout command is from atbegshi so it would be more efficient to load this directly (since you don't need eso-pic itself as far as I can tell). Loading eso-pic works because it loads atbegshi. – cfr Feb 24 '15 at 16:15
  • +1 and almost the best answer for your automation. Ingenious! However, I noticed that the measurements are incorrect for the origin when switching to a4 paper. To clarify, the first y axis bold line starts on the seventh millimeter, but should be on the tenth. – Jonathan Komar Feb 24 '15 at 20:46
  • @macmadness86 Thank your for the note. There was yshift=\paperheight missing in the optional argument of the tikzpicture in the first code. Now the origin is in the upper left corner. – esdd Feb 25 '15 at 9:44
7

Partial solution

The code below has some minor problems.

  1. the origin to the grid is at the lower left corner of the page (the OP wants the upper left one)

  2. the use of \AddToShipoutPicture makes the origin as 1. but also makes the grid under the page contents. Removing it, the grid goes under but the origin becomes crazy.

With \AddToShipoutPicture

enter image description here

enter image description here

Without \AddToShipoutPicture

enter image description here

MW(?)E

\documentclass[a5paper]{article} % a5 just to example
%\usepackage{fontspec} % commented to speed up compilation
\usepackage{tikz}
\usetikzlibrary{shapes.misc}
\usetikzlibrary{calc}
\usepackage{anyfontsize}
\usepackage{eso-pic}

  \newcommand{\showgrid}{%
%    \AddToShipoutPicture{%
      \begin{tikzpicture}[overlay,remember picture]
        \draw[blue!30!white]
          (current page.south west) grid[step=1mm]
          (current page.north east);
        \draw[blue!80!white]
          (current page.south west) grid[step=10mm]
          (current page.north east);
        \foreach \step in {0,1,...,297} {
                      \node [anchor=north] at ($ (current page.north west) + (\step mm,0cm) $) {\fontsize{1}{2}\selectfont \step};
                      \node [anchor=west] at ($ (current page.north west) + (0cm,-\step mm) $) {\fontsize{1}{2}\selectfont \step};
                  }
      \end{tikzpicture}
%    }%
  }


\begin{document}
\thispagestyle{empty}
\begin{tikzpicture}[overlay,remember picture,every node/.style={fill=red,inner sep=0pt,outer sep=0pt}]%
   \node [minimum width=2cm,minimum height=2cm] at (current page.center) {};
\end{tikzpicture}%
\showgrid
\end{document}
  • Looks like we need to have TikZ create the paths of the grid during the shipout stage, and then have some kind of post action to actually draw the paths. – Jonathan Komar Feb 21 '15 at 16:37
  • 1
    (+1) I didn't realise that you'd mentioned atbegshi and that this solved the grid alignment issue. If you combine the atbegshi code from my answer with your use of grid, this would fix everything except, I think, the origin being at the lower left rather than the top left? If I've understood your comments correctly? (My answer gets the origin right as well, as I understand it, but only at a price....) – cfr Feb 24 '15 at 2:27
7

The answer is based on my answer at What are the ways to position things absolutely on the page?, except that I am using atbegshi rather than everypage, in order to get the grid to overlay, rather than underlay.

Then, I developed \grid{delta}{x-size}{y-size} to stack lines and inset them (rotated 90 degrees) over a second stack of lines to form the grid.

EDITED to include the grid lines at "0pt" offset. Also, give demo on p.3 of MWE that shows how to start grid mid page, rather than at page boundary.

\documentclass{article}
\usepackage{atbegshi}
\usepackage{xcolor,stackengine,ifthen,graphicx}
\usepackage{lipsum}
% THESE ARE LaTeX DEFAULTS; CAN CHANGE IF NEEDED.
\def\PageTopMargin{1in}
\def\PageLeftMargin{1in}
\newcommand\atxy[3]{%
 \AtBeginShipoutNext{\AtBeginShipoutAddToBoxForeground{%
  \smash{\hspace*{\dimexpr-\PageLeftMargin-\hoffset+#1\relax}%
  \raisebox{\dimexpr\PageTopMargin+\voffset-#2\relax}{\textcolor{red!80}{#3}}}}}}
\newlength\coord
\def\rlwd{.1pt}
\newcommand\grid[3]{%
  \setlength\coord{0pt}%
  \savestack\tmpboxy{\ooalign{\rule{#2}{\rlwd}\cr \linelabel}}%
  \whiledo{\lengthtest{\coord<\dimexpr#3-.01pt}}{%
    \addtolength\coord{#1}%
    \savestack\tmpboxy{\stackunder[\dimexpr#1-\rlwd\relax]{\tmpboxy}%
      {\ooalign{\rule{#2}{\rlwd}\cr \linelabel}}}%
  }%
  \setlength\coord{0pt}%
  \savestack\tmpboxx{\ooalign{\rule{#3}{\rlwd}\cr\linelabel}}%
  \whiledo{\lengthtest{\coord<\dimexpr#2-.01pt}}{%
    \addtolength\coord{#1}%
    \savestack\tmpboxx{\stackunder[\dimexpr#1-\rlwd\relax]{\tmpboxx}%
      {\ooalign{\rule{#3}{\rlwd}\cr\linelabel}}}%
  }%
  \stackinset{l}{}{t}{}{\rotatebox{90}{\tmpboxx}}{\tmpboxy}%
}
\newcommand\linelabel{\scalebox{.5}{\tiny\smash{\the\coord}}}
\begin{document}
\atxy{0pt}{0pt}{\grid{.1in}{8.5in}{11in}}
\lipsum[1-7]
\atxy{0pt}{0pt}{\grid{.2in}{5in}{7in}}
\lipsum[8-12]
\atxy{120pt}{120pt}{\grid{.1in}{5in}{2.3in}}
\end{document}

Here is a full page grid, of 0.1in gradation, invoked with \atxy{0pt}{0pt}{\grid{.1in}{8.5in}{11in}}, meaning start in the upper left of the paper (the first two arguments to \atxy are the x, y coordinates where to begin the overlay), while the three arguments to \grid are the gradation, the x-size and the y-size.

enter image description here

Here is a grid over a portion of the paper, using the invocation \atxy{0pt}{0pt}{\grid{.2in}{5in}{7in}}.

enter image description here

The fact that the grid overlays the document material is show here

enter image description here

The measurements are shown here

enter image description here

And here, I show with \atxy{120pt}{120pt}{\grid{.1in}{5in}{2.3in}} how to confine the grid to a region of interest.

enter image description here

  • (+1) I agree that's a nice option, too. The flexibility is great. – cfr Feb 24 '15 at 21:56
4

Here a solution that use afterpage package and redefine \@outputpage command. May be some one can patch this command using etoolbox. It doesn't use current page.

\documentclass{article}
\usepackage{tikz}
\usepackage{afterpage}
\usetikzlibrary{calc}
\usepackage{anyfontsize}
\makeatletter
\newcommand{\showgrid}{%
\let\grid@outputpage\@outputpage
\def\@outputpage{%
\begingroup           % the \endgroup is put in by \aftergroup
  \let \protect \noexpand
  \@resetactivechars
  \global\let\@@if@newlist\if@newlist
  \global\@newlistfalse
  \@parboxrestore
  \shipout \vbox{%
    \set@typeset@protect
    \aftergroup \endgroup
    \aftergroup \set@typeset@protect
                                % correct? or just restore by ending
                                % the group?
  \if@specialpage
    \global\@specialpagefalse\@nameuse{ps@\@specialstyle}%
  \fi
  \if@twoside
    \ifodd\count\z@ \let\@thehead\@oddhead \let\@thefoot\@oddfoot
         \let\@themargin\oddsidemargin
    \else \let\@thehead\@evenhead
       \let\@thefoot\@evenfoot \let\@themargin\evensidemargin
    \fi
  \fi
  \reset@font
  \normalsize
  \normalsfcodes
  \let\label\@gobble
  \let\index\@gobble
  \let\glossary\@gobble
  \baselineskip\z@skip \lineskip\z@skip \lineskiplimit\z@
    \@begindvi
    \vskip \topmargin
    \moveright\@themargin \vbox {%
      \setbox\@tempboxa \vbox to\headheight{%
        \vfil
        \color@hbox
          \normalcolor
          \hb@xt@\textwidth{\@thehead}%
        \color@endbox
        }%                        %% 22 Feb 87
      \dp\@tempboxa \z@
      \box\@tempboxa
      \vskip \headsep
      \box\@outputbox
      \baselineskip \footskip
      \color@hbox
        \normalcolor
        \hb@xt@\textwidth{\@thefoot}%
      \color@endbox
      }%
\vskip-\dimexpr\textheight+\topmargin+\headheight+\headsep+\footskip+1in\relax%
\hspace*{-1in}%
\begin{tikzpicture}[every node/.style={inner sep=0pt,outer sep=0pt}]%
   \draw[help lines,gray!25] (0,0) grid[step=1mm] (\paperwidth,-\paperheight);
   \draw[help lines,gray] (0,0) grid[step=10mm] (\paperwidth,-\paperheight);
   \foreach \step in {0,1,...,297} {
        \node [anchor=north] at ($ (0,0) + (\step mm,0cm) $) {\fontsize{1}{2}\selectfont \step};
        \node [anchor=west] at ($ (0,0) + (0cm,-\step mm) $) {\fontsize{1}{2}\selectfont \step};
    }
    \end{tikzpicture}
    }%
  \global\let\if@newlist\@@if@newlist
  \global \@colht \textheight
  \stepcounter{page}%
  \let\firstmark\botmark
}\afterpage{\global\let\@outputpage\grid@outputpage}}
\makeatother



\begin{document}
\thispagestyle{empty}
test 

\showgrid

and test

\begin{tikzpicture}[overlay,remember picture,every node/.style={fill=red,inner sep=0pt,outer sep=0pt}]%
   \node [minimum width=2cm,minimum height=2cm] at (current page.center) {};
\end{tikzpicture}%

\newpage

test

\newpage

test 

\showgrid

and test

\end{document}

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.