# “Dimension too large” error with too many tikzmarks

This is a follow up to the discussion here. Andrew provided a patch for the problem that when the page number go too large it created the problem (see his and Ulrike's answers in the linked question).

However, even with his patch (included in the MWE below), I am now running again into the "dimension too large" problem, this time definitely not caused by the page count, but by the number of tikzmarks (or so I presume). It only fails on the second run, so it might have to do with values changing.

I also observed that when I run it once with less iterations, and then keep slowly increasing the number it doesn't fail at all (unless I delete the aux files) and I can even go until I get TeX capacity exceeded. So it seems to have to do with rerunning it, but I have no clue.

% !TEX TS-program = xelatexmk
\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{tikzmark}

% Fix for error when pagenumber too large,
% from: https://tex.stackexchange.com/questions/484980/dimension-too-large-error-with-tikz-graphic-using-tikzmark-when-document-gets
\makeatletter
\tikzdeclarecoordinatesystem{pic}{%
\pgfutil@in@,{#1}%
\ifpgfutil@in@%
\tmk@labeldef#1\@nil
\else
\tmk@labeldef#1,(0pt,0pt)\@nil
\fi
\@ifundefined{save@pt@\tmk@label}{%
\tikz@scan@one@point\pgfutil@firstofone\tmk@def
}{%
\pgfsys@getposition{\csname save@pt@\tmk@label\endcsname}%
\save@orig@pic%
\pgfsys@getposition{\pgfpictureid}\save@this@pic%
\pgf@process{\pgfpointorigin\save@this@pic}%
\pgf@xa=\pgf@x
\pgf@ya=\pgf@y
\pgf@process{\pgfpointorigin\save@orig@pic}%
\pgf@xa=\pgf@x
\pgf@ya=\pgf@y
\pgf@process%
{\pgfpointorigin\csname save@pt@\tmk@label @offset\endcsname}%
\@ifundefined{save@pg@\csname save@pt@\tmk@label\endcsname}{}{%
\@ifundefined{save@pg@\pgfpictureid}{}{%
\pgfkeysvalueof{/tikz/next page vector}%
\edef\tmk@pg{\the\numexpr \csname save@pg@\csname save@pt@\tmk@label\endcsname\endcsname - \csname save@pg@\pgfpictureid\endcsname\relax}%
\tmk@pg\pgf@x\relax
\tmk@pg\pgf@y\relax
}%
}%
\pgf@x=\pgf@xa
\pgf@y=\pgf@ya
\pgftransforminvert
\pgf@pos@transform{\pgf@x}{\pgf@y}%
}%
}
\makeatother

\tikzset{
next page=below,
brace/.style n args={2}{insert path={%
([xshift=0.15em,yshift=0.1pt+.5ex]#1) --
([xshift=-0.3pt,yshift=0.1pt+.5ex]#1) --
([xshift=-0.3pt,yshift=-0.1pt+.5ex]#2) --
([xshift=0.15em,yshift=-0.1pt+.5ex]#2) --
([xshift=0.15em,yshift=0.1pt+.5ex]#2) --
([xshift=0.3pt,yshift=0.1pt+.5ex]#2) --
([xshift=0.3pt,yshift=-0.1pt+.5ex]#1) --
([xshift=0.15em,yshift=-0.1pt+.5ex]#1) --
cycle}}}

% Setup for regular brackets:
\newcounter{tikzmkcnt}\setcounter{tikzmkcnt}{0} % counter to automatically set tikzmarks

\newif\iffirstmark

\newcommand{\bracketstart}{%
\stepcounter{tikzmkcnt}%
\tikzmark{a\thetikzmkcnt}%
\global\firstmarktrue
\iftikzmarkoncurrentpage{b\thetikzmkcnt}%
\else
\begin{tikzpicture}[remember picture,overlay,next page=below]%
%  \clip (current page text area.south west) rectangle (current page text area.north east);
\fill[overlay,brace={pic cs:a\thetikzmkcnt}{pic cs:b\thetikzmkcnt}];
\end{tikzpicture}%
\fi
}

\newcommand{\bracketend}{%
\iffirstmark
\tikzmark{b\thetikzmkcnt}%
\global\firstmarkfalse
\fi
\begin{tikzpicture}[remember picture,overlay]%
%  \clip (current page text area.south west) rectangle (current page text area.north east);
\fill[overlay,brace={pic cs:a\thetikzmkcnt}{0,0}];
\end{tikzpicture}%
}

%% First I thought it had to do with some weird interaction with zref as it was part of this code:
%\RequirePackage[user,savepos]{zref}
%\newcommand{\offset}[1]{ % setting offset
%\dimexpr\zposx{#1}sp-(\oddsidemargin+1in)\relax}
%\newcommand{\offsetmk}[1]{\leavevmode\zsaveposx{#1}} % defining offset point
%\newcounter{offsetmkcnt}\setcounter{offsetmkcnt}{0} % counter for automatic marks
%\newcommand{\onsetmark}{\bracketstart\stepcounter{offsetmkcnt}\offsetmk{\theoffsetmkcnt}\hspace{.15em}}
%\newcommand{\offsetline}{\hspace{\dimexpr\offset{\theoffsetmkcnt}\relax}\bracketend\hspace{.15em}}
%
%\newcommand{\Zftest}{test \onsetmark{}test\par \offsetline{}test \onsetmark{}test\par \offsetline{}test \par}
%\newcommand{\Tentests}{\Zftest\Zftest\Zftest\Zftest\Zftest\Zftest\Zftest\Zftest\Zftest\Zftest}

%% But then I realized that even this one produces the error:
\newcommand{\Tktest}{test \bracketstart{}test\par test  \bracketend{}test \bracketstart{}test \par test test  \bracketend{}test \par}
\newcommand{\Tentests}{\Tktest\Tktest\Tktest\Tktest\Tktest\Tktest\Tktest\Tktest\Tktest\Tktest}

\newcommand{\Hundredtests}{\Tentests\Tentests\Tentests\Tentests\Tentests\Tentests\Tentests\Tentests\Tentests\Tentests}

\parindent0pt
\begin{document}
%\Zftest
%\Tktest

\Hundredtests\Hundredtests\Hundredtests\Hundredtests\Hundredtests
\Hundredtests\Hundredtests\Hundredtests\Hundredtests\Hundredtests
\Hundredtests\Hundredtests\Hundredtests\Hundredtests\Hundredtests

\end{document}

• Your MWE is a little strange. I agree that on the first run through you get a Dimension too large error. However, if you ask latex (xelatex, pdflatex ,...) to finish compiling the document and then recompile then it works. – Andrew May 18 at 0:33
• @Andrew Apologies for the weird MWE :P The actual document runs over hundreds of pages, so first I ran into the error when the page numbers got too large, but then the fix from the other thread solved that. But then it happened again when it got even larger. The actual document doesn't have tikz graphics on every line, there's text in between, but after many trial and errors, first with the original document and then trying to construct an MWE it seems that it fails with a given number of tikzmarks. Maybe I'm wrong. I'm just trying to figure out what the error is. – jan May 18 at 8:59
• @Andrew You're right that ignoring errors and running again finishes eventually. But I'm worried if the document gets even larger I don't want to have unstable code. – jan May 18 at 9:00

Here's a more compact MWE:

% !TEX TS-program = xelatexmk
\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{tikzmark}

\tikzset{
next page=below,
}

% Setup for regular brackets:
\newcounter{tikzmkcnt}\setcounter{tikzmkcnt}{0} % counter to automatically set tikzmarks

\newif\iffirstmark

\newcommand{\dotikzmark}{%
\stepcounter{tikzmkcnt}%
\tikzmark{a\thetikzmkcnt}%
TikZMark \thetikzmkcnt%
\newpage
\tikzmark{b\thetikzmkcnt}%
\tikz[remember picture, overlay] {\draw (pic cs:b\thetikzmkcnt) -- (pic cs:a\thetikzmkcnt);}
}
%% But then I realized that even this one produces the error:
\newcommand{\Tktest}{\dotikzmark}
\newcommand{\Tentests}{\Tktest\Tktest\Tktest\Tktest\Tktest\Tktest\Tktest\Tktest\Tktest\Tktest}

\newcommand{\Hundredtests}{\Tentests\Tentests\Tentests\Tentests\Tentests\Tentests\Tentests\Tentests\Tentests\Tentests}

\parindent0pt
\begin{document}

\Hundredtests\Hundredtests\Hundredtests\Hundredtests\Hundredtests
\Hundredtests\Hundredtests\Hundredtests\Hundredtests\Hundredtests
\Hundredtests\Hundredtests\Hundredtests\Hundredtests\Hundredtests

\end{document}


The issue is that when a tikzmark is on a different page then the package tries to put it in the "correct" place by imagining the pages laid out according to the next page specification and calculating the correct displacement. The issue that you are facing is that due to a reason I'll explain in a moment, the current page and the tikzmark page are far, far apart and the displacement exceeds the dimension limit.

My proposed fix is to stop trying to be so clever. If the tikzmark is on a page ahead, it now calculates the displacement as if it were on the immediate next page. I don't think that there's anything really to be gained by doing otherwise. This is where the perfect is the enemy of the good.

• Thank you for that explanation, I've learned a lot!! :) — I've downloaded the new version from github, alas, tex doesn't generate tikzmark.sty for some reason?? – jan May 25 at 11:04
• ... and pdflatex also throws an error ./tikzmark.dtx:693: LaTeX Error: File tikzrefextnodes' not found. – jan May 25 at 11:06
• It's a TikZ library, so tex tikzmark.dtx generates the file tikzlibrarytikzmark.code.tex` which is what you need. – Loop Space May 26 at 9:19