4

I use this code (fixed by marmot :) ...), which worked perfectly until a point where my document got too many pages.
At a given point I get a "Dimension too large" error. It uses code that tests if a given tikzmark is on a page, so my hunch is that the problem lies there somewhere, that too many pages cause trouble... Alas, I have no clue whatsoever how to troubleshoot.

Given the nature of the problem, the following is an "as-minimal-as-it-gets-not-working-example" :) (If you delete two rows of the \repeatenoughtimes macro you will get it to work ... just to show that the problem has definitely to do with repeating it too often.)

% !TEX TS-program = xelatexmk
\documentclass{article}
%\usepackage[a6paper]{geometry}
\usepackage[paperwidth=4in,paperheight=3in]{geometry}
%\url{https://tex.stackexchange.com/q/483547/86}
\usepackage{tikz}
\usepackage{tikzpagenodes}
\usetikzlibrary{tikzmark}
\newcounter{tikzmarklines}\setcounter{tikzmarklines}{0} % 

%% Code added recently to the package which provides the \iftikzmarkoncurrentpage code: 
\makeatletter

\newif\iftikzmark@
\renewcommand\iftikzmark[3]{%
    \@ifundefined{save@pt@\tikzmark@pp@name{#1}}{%
      #3%
    }{%
      #2%
    }%
}%

\newcommand\iftikzmarkexists[1]{%
  \@ifundefined{save@pt@\tikzmark@pp@name{#1}}{%
    \tikzmark@false%
  }{%
    \tikzmark@true%
  }%
  \iftikzmark@
}%

\newcommand\iftikzmarkonpage[2]{%
  \@ifundefined{save@pt@\tikzmark@pp@name{#1}}{%
    \tikzmark@false
  }{%
    \@ifundefined{save@pg@\csname save@pt@\tikzmark@pp@name{#1}\endcsname}{%
      \tikzmark@false
    }{%
      \ifnum\csname save@pg@\csname save@pt@\tikzmark@pp@name{#1}\endcsname\endcsname=#2\relax%
      \tikzmark@true
      \else
      \tikzmark@false
      \fi
    }%
  }%
  \iftikzmark@
}

\newcommand\iftikzmarkoncurrentpage[1]{%
  \@ifundefined{save@pt@\tikzmark@pp@name{#1}}{%
    \tikzmark@false
  }{%
    \@ifundefined{save@pg@\csname save@pt@\tikzmark@pp@name{#1}\endcsname}{%
      \tikzmark@false
    }{%
      \ifnum\csname save@pg@\csname save@pt@\tikzmark@pp@name{#1}\endcsname\endcsname=\the\value{page}\relax%
      \tikzmark@true
      \else
      \tikzmark@false
      \fi
    }%
  }%
  \iftikzmark@
}
\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}}}

\newif\iffirstmark

\newcommand{\linestart}{%
  \stepcounter{tikzmarklines}%
  \tikzmark{a\thetikzmarklines}%
  \global\firstmarktrue
  \iftikzmarkoncurrentpage{b\thetikzmarklines}%
  \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\thetikzmarklines}{pic cs:b\thetikzmarklines}];
  \end{tikzpicture}%
  \fi
}

\newcommand{\linefinish}{%
  \iffirstmark
  \tikzmark{b\thetikzmarklines}%
  \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\thetikzmarklines}{0,0}];
  \end{tikzpicture}%
  }

\usepackage{lipsum}

\newcommand{\repeatenoughtimes}{
Text \linestart text text\par
Text text \linefinish text\par
Text \linestart text text\par
Text text \linefinish text\par
\lipsum[1-5]
}

\begin{document} 

\repeatenoughtimes\repeatenoughtimes\repeatenoughtimes\repeatenoughtimes
\repeatenoughtimes\repeatenoughtimes\repeatenoughtimes\repeatenoughtimes
\repeatenoughtimes\repeatenoughtimes\repeatenoughtimes\repeatenoughtimes
\repeatenoughtimes\repeatenoughtimes\repeatenoughtimes\repeatenoughtimes
\repeatenoughtimes\repeatenoughtimes\repeatenoughtimes\repeatenoughtimes

\end{document}
  • I am not convinced that the number of repetitions is the problem. If I use \lipsum[1-2] instead of \lipsum[1-5], the error goes away. – marmot Apr 15 at 16:03
  • @marmot But then if you add a few more \repeatenoughtimes, you get the error back :( ... hence my hunch it's the page count ??? ... but honestly I have no idea... – jan Apr 15 at 16:35
2

Here's my proposed fix. To try it out, put it between \makeatletter ... \makeatother in your preamble after loading the tikzmark library.

It's entirely possible that I don't understand how \numexpr or dimensions work, but the idea is sound.

\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}%
    }%
  }
  • It works up until page 3662, so definitely sufficient for my current purposes ;) but (using @UlrikeFischer 's example) with \setcounter{page}{3663} and higher it still fails ... – jan Apr 16 at 7:10
  • To make it work with more pages I'd need to reimplement the next page concept. I could add a warning that it only works with documents at most 3662 pages long ... I've added this to the tikzmark code on github. – Loop Space Apr 20 at 11:01
  • I think it's safe to assume that people with an over-3662-page document might need the iftikzmarkonpage up to page 3661 but I doubt they will need it on the next page ... just my feeling ;P – jan Apr 20 at 17:08
4

(To long for a comment). It is a bug in tikzmark and related to the next page option. It multiplies \pgf@y by the page number, and with a large enough page number it explodes.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{tikzmark}
\tikzset{
  next page=below,
 }
\begin{document}
\setcounter{page}{30}
\tikzmark{blub}\tikz[remember picture]\draw(pic cs:blub);
\end{document}
  • Oh, ok. I've emailed the developer. – jan Apr 15 at 18:36

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.