8

I'm trying to debug the error in "Dimension too large" error with too many tikzmarks which involves getting a Dimension too large error (duh). I have my suspicions as to what is causing it, and also a suspicion that there will be situations that mean that I can't eliminate the possibility of it occurring altogether.

Is there any way to defend against this error? What I would really like is something like a try ... except ... block. Does that exist?

Here's a MWE to play around with:

\documentclass{article}

\newdimen\ad
\newdimen\bd

\ad=16383pt\relax
\bd=2\ad

\showthe\ad
\showthe\bd

\begin{document}
\end{document}

Essentially, I would like to be able to wrap the \bd=2\ad in something that allows me to define an alternative if it threatens to trigger the dreaded Dimension too large error.

Andrew Stacey
  • 153,724
  • 43
  • 389
  • 751

1 Answers1

8

Using l3fp to make a wrapper macro which checks if the dimension exceeds \c_max_dim (or \maxdimen or 16383.99999pt) and uses a fallback value (which I set to \c_max_dim itself) in case the assignment exceeds it:

\documentclass{article}
\usepackage{expl3}
\ExplSyntaxOn
\cs_new:Npn \trydim #1
  {
    \exp_args:Nf
      \__loopspace_try_dim:nn { \fp_eval:n {#1} } {#1}
  }
\cs_new:Npn \__loopspace_try_dim:nn #1 #2
  {
    \fp_compare:nNnTF { abs(#1) } > \c_max_dim
      {
        % Exception code
        \dim_use:N \c_max_dim
      }
      {
        % Success code
        % Using \dim_eval:n to maintain TeX's behaviour,
        % but you can replace by #1, which is the result of \fp_eval:n
        \dim_eval:n {#2}
      }
  }
\ExplSyntaxOff

\newdimen\ad
\newdimen\bd

\ad=\trydim{16383pt}
\bd=\trydim{2\ad}

\showthe\ad
\showthe\bd

\begin{document}
\end{document}

This prints to the terminal:

> 16383.0pt.
l.31 \showthe\ad

?
> 16383.99998pt.
l.32 \showthe\bd

?

The "exception code" is what you intend to do if the value exceeds \c_max_dim. I used the \dim_use:N \c_max_dim to get the maximum value possible.

The "success code", you guessed, is when the value is within the allowed range. I used \dim_eval:n {#2} because there are controversies on the accuracy of l3fp, so the result obeys TeX's rules as long as they are valid. Of course you can change that to \fp_eval:n {#2} (or, for the matter, #1, which is the \fp_eval:n'ed dimension).


Or, if you prefer, an inline fallback value:

\documentclass{article}
\usepackage{expl3}
\ExplSyntaxOn
\cs_new:Npn \trydim #1 #2
  {
    \exp_args:Nf
      \__loopspace_try_dim:nnTF { \fp_eval:n {#1} }
        {#1} {#2}
  }
\prg_new_conditional:Npnn \__loopspace_try_dim:nn #1 { T, F, TF }
  {
    \fp_compare:nNnTF { abs(#1) } > \c_max_dim
      { \prg_return_false: }
      { \prg_return_true: }
  }
\ExplSyntaxOff

\newdimen\ad
\newdimen\bd

\ad=\trydim{16383pt}{0pt}

\bd=\trydim{2\ad}{10pt}

\showthe\ad
\showthe\bd

\begin{document}
\end{document}

Which prints:

> 16383.0pt.
l.31 \showthe\ad

?
> 10.0pt.
l.32 \showthe\bd

?