4

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}%
    \advance\pgf@x by -\pgf@xa
    \advance\pgf@y by -\pgf@ya
    \pgf@xa=\pgf@x
    \pgf@ya=\pgf@y
    \pgf@process%
    {\pgfpointorigin\csname save@pt@\tmk@label @offset\endcsname}%
    \advance\pgf@xa by \pgf@x
    \advance\pgf@ya by \pgf@y
      \@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}%
        \advance \pgf@xa by %
        \tmk@pg\pgf@x\relax
        \advance \pgf@ya by %
        \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
2

(I'm getting quite curious about this document ...)

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.

This is implemented in the latest version on github.

The reason why tikzmark thinks there's a huge difference between the current page and the tikzmark page is that it keeps track of the information by linking data to the picture id (which keeps count of the pictures in the document). Changing the number of tikz pictures in the document will mean that tikzmarks might be associated with the wrong pictures (until a new run has been done and they get back in sync again) and so the page numbers will be wrongly calculated (and, in your case, get very large).

Once the document stabilises, your tikzmarks are associated with the correct pages which is why the error goes away on the second run even without the fix.

  • 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
  • Oh, I get it, yes of course. Fantastic thanks so much! All working. Will you add these changes to the package on CTAN eventually with a future update? – jan May 26 at 9:34
  • 1
    Yes, I'll send these off to CTAN once I've tested to make sure that nothing else has broken. – Loop Space May 27 at 9:47

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.