5

A graphics application creates tikz picture files. There is no control on the surrounding document. How to make sure that the picture compiles, regardless whether the fpu library is loaded or not, and is active or not? The code below throws the error,

! Illegal unit of measure (pt inserted).
<to be read again>
               Y
l.7 \tikzpicture\node(1,0){A};
                          \endtikzpicture

here is the code:

\documentclass{minimal}
\usepackage{tikz}
\usepgflibrary{fpu}         %
                            %  no control over the document
\begin{document}            %
\pgfkeys{/pgf/fpu}          %
% what to do here?                          %  generated code
\tikzpicture\node(1,0){A};\endtikzpicture   % 
\end{document}

1 Answer 1

4

Explanation of the error

When activated via /pgf/fpu, the PGF floating point unit (FPU) changes the output format for PGF calculations, in particular the output format of the \pgfmathresult command. The default format when the FPU is active, which corresponds to setting /pgf/fpu/output format to the value float, outputs numbers in a form such as 1Y2.0e0] (1 is a flag that stands for “positive number”, 2.0 is the mantissa and e0 specifies an exponent of 0; thus, 1Y2.0e0] represents 2x100 in this format, i.e., the number 2).

This number format is great for calculations, as it allows representing large data ranges at reasonable accuracy, however the TikZ code in general doesn't expect numbers in this format (nor does pgfplots, as far as I know). When TikZ tries to read a coordinate and finds 1Y2.0e0] as a result of a computation performed with PGF, it causes TeX to parse that as a length (a 〈dimen〉, most probably), which fails because Y isn't a unit of measure recognized by TeX—if it were, that would result in a mess, anyway. This explains the error message you quoted:

! Illegal unit of measure (pt inserted).
<to be read again>
               Y
l.7 \tikzpicture\node(1,0){A};
                          \endtikzpicture

(TeX tries to be helpful, as usual when it encounters errors, and takes the initiative of inserting a pt unit in the place where he expected a unit of measure, in order to go on with the compilation... which often isn't very helpful nowadays with fast computers.)

How to solve it

You could temporarily switch off the PGF floating point unit inside a group where your picture is typeset.

First method

In this method, we set /pgf/fpu to false inside a group, only if this key exists (otherwise, pgfkeys will throw an error if we try to set this key when the fpu library isn't loaded). Many thanks to Ulrike Fischer for the hint concerning .try=!

\documentclass{article}
\usepackage{tikz}
\usepgflibrary{fpu}         %
                            % no control over the document
                            %
\begin{document}            % no control over the document
\pgfkeys{/pgf/fpu}          %

{\pgfkeys{/pgf/fpu/.try=false}% switch the FPU off inside this group
 \tikzpicture\node(1,0){A};\endtikzpicture
}

\bigskip
% Show that the FPU state is restored to “on” after the group has ended
\pgfmathparse{1+1}\pgfmathresult

\end{document}

Second method

In this second method, we set /pgf/fpu to false inside the group only if we detect that the fpu PGF library is loaded.

\documentclass{article}
\usepackage{tikz}
\usepgflibrary{fpu}         %
                            % no control over the document
                            %
\begin{document}            % no control over the document
\pgfkeys{/pgf/fpu}          %

{\makeatletter
 \ifcsname pgf@library@fpu@loaded\endcsname
   \pgfkeys{/pgf/fpu=false}% switch the FPU off inside this group
 \fi
 \makeatother
%
 \tikzpicture\node(1,0){A};\endtikzpicture
}

\bigskip
% Show that the FPU state is restored to “on” after the group has ended
\pgfmathparse{1+1}\pgfmathresult

\end{document}

What precedes was written under the assumption that you can't add code before \begin{document} and that you may have to programmatically include several such fragments. If this is not the case, another option is to define an \IfPGFLibraryLoaded command (similar to \IfTikzLibraryLoaded from this answer) and set /pgf/fpu to false inside the group only if this command detects that the fpu PGF library is loaded. This can be done by using this before \begin{document}:

\makeatletter
\newcommand*{\IfPGFLibraryLoaded}[1]{%
  \ifcsname pgf@library@#1@loaded\endcsname
    \expandafter\@firstoftwo
  \else
    \expandafter\@secondoftwo
  \fi
}%
\makeatother

and what follows after \begin{document}:

{\IfPGFLibraryLoaded{fpu}{%
   \pgfkeys{/pgf/fpu=false}% switch the FPU off inside this group
 }{}%
 \tikzpicture\node(1,0){A};\endtikzpicture
}

Output

The sample documents given above produce the following output:

Screenshot

If you comment out \usepgflibrary{fpu} and \pgfkeys{/pgf/fpu}, the output becomes:

Screenshot

4
  • If the fpu library is not loaded at all, which is the most probable situation in foreign documents, the line pgfkeys{/pgf/fpu=false} throws another error. The document compiles, but the user is left with a little understandable error message.
    – tkl
    Jun 21, 2019 at 8:46
  • 5
    @tkl you can use \pgfkeys{/pgf/fpu/.try=false} . Jun 21, 2019 at 9:15
  • @UlrikeFischer Great tip, thanks! I had found another solution meanwhile, but yours is much simpler. Please see the updated answer.
    – frougon
    Jun 21, 2019 at 9:26
  • 1
    @siracusa Done, please see the last edit.
    – frougon
    Jun 25, 2019 at 15:54

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.