9

How can I prevent the definition of a .pic from adding an additional space to the typeset output, where the .pic is defined in a \tikzset{} within the document body, rather than either in the preamble or within a tikzpicture environment?

Here's an MWE:

\documentclass{standalone}
\usepackage{tikz}
\begin{document}
\tikzset{make me/.pic={\node{#1};}}%
\begin{tikzpicture}
  \node {a};
  \draw (current bounding box.south west) rectangle (current bounding box.north east);
\end{tikzpicture}
\end{document}

unwanted space

A slightly-less-M WE shows that the additional space is added with a standard class also.

\documentclass{article}
\usepackage{showframe}
\usepackage{tikz}
\parindent=0pt
\begin{document}
x%
\begin{tikzpicture}
  \node {a};
  \draw (current bounding box.south west) rectangle (current bounding box.north east);
\end{tikzpicture}

x\tikzset{make me/.pic={\node{#1};}}%
\begin{tikzpicture}
  \node {a};
  \draw (current bounding box.south west) rectangle (current bounding box.north east);
\end{tikzpicture}
\end{document}

unwanted space in standard class

I want that the \tikzset{} line makes no difference to the typeset output whatsoever. As far as I'm concerned, it is just defining something. It should only affect the output if that something actually gets used. Otherwise, it should just marginally increase the compilation time.

Note that I know this can be avoided by defining the .pic in the preamble or inside the tikzpicture environment. I specifically need to prevent it when the .pic is defined in the document but outside a tikzpicture. The remainder of this post just briefly explains why I want to do it this way.

I not uncommonly want to say something like

\documentclass{standalone}
\begin{document}
\input{img-group-common}%
\begin{tikzpicture}
  ...
\end{tikzpicture}
\end{document}

I cannot put the \input in the preamble because the picture will be included using the standalone package, thus everything in the preamble will be ignored.

I do not want to include the \input in the preamble of my main document, because I want to keep the settings in img-group-common local to a group of closely related images. Usually, these are pictures with a common structure or which require common elements.

Typically, all img-group.common.tex does is \tikzset{...}. The problem is, that if \tikzset{...} defines a pic, a space is added to the typeset output before the tikzpicture is typeset.

4
  • 1
    I wanted to ask 'What is the best way ...' but the system told me that was too subjective and would be closed. Then I tried 'What is the correct way ...' but it said that was too long. So the 'How should I ...' is SE-speak for 'what is the best way ...?' – cfr May 6 '17 at 22:40
  • Can this be reproduced using \documentclass{article}? – Symbol 1 May 6 '17 at 22:55
  • @Symbol1 Yes, but you need a letter or something before i.e. if the \tikzset and tikzpicture are right after the document begins, the space vanishes. But if you insert an x first, you can see the space. Hang on, I'll add that as a second slightly-less-MWE. – cfr May 6 '17 at 23:05
  • @Symbol1 Please see additional example above. It is also not \tikzset itself. I went through a file of settings for a group of pictures and most of the definitions did nothing. The .pic was obviously (in light of Sod's Law) right at the end, last but one. – cfr May 6 '17 at 23:10
8

This is how .pic is defined in tikz.code.tex line 4636-4640

\pgfkeysdef{/handlers/.pic}{%
  \edef\pgf@temp{\pgfkeyscurrentpath}%
  \edef\pgf@temp{\expandafter\tikz@smuggle@pics@in\pgf@temp\pgf@stop}%
  \expandafter\pgfkeys\expandafter{\pgf@temp/.style={code={#1}}}
}

The author missed a % at the end of line 4639.


I reported it as a bug here: https://sourceforge.net/p/pgf/bugs/426/.

9
  • Nice space-hunting. So would it be best to redefine it myself or should I workaround it some other way? Right now, I'm putting \unskip before \endinput for the inputted file, but will be a pain to remember to do this - these spaces are troublesome to track down. (At least, for me, they are.) – cfr May 6 '17 at 23:19
  • I will simply copy this piece of code and paste it after \usepackage{tikz} with % added. (Do not forget \makeatletter; I usually do.) – Symbol 1 May 6 '17 at 23:22
  • If you really want backward-compatibility, I will suggest \pgfkeysdef{/handlers/.pic fix}{ basically the same thing }. But honestly I had never cared about it. – Symbol 1 May 6 '17 at 23:30
  • Could one of you report this to get it fixed at source? – David Carlisle May 6 '17 at 23:31
  • @DavidCarlisle That's very optimistic. The pic code has so many bugs in it, is could occupy a considerable team of naturalists for some centuries. I'm not quite sure why as this doesn't seem true of PGF/TikZ generally. – cfr May 6 '17 at 23:36
1

In case it is useful to anybody, here's a supplement to Symbol 1's answer, tex/latex/tikz-pic-fix/tikz-pic-fix.sty:

\ProvidesPackage{tikz-pic-fix}[fix pic handler to eliminate spurious space]
\RequirePackage{tikz}
% ateb Symbol 1: https://tex.stackexchange.com/a/368531/
\pgfkeysdef{/handlers/.pic}{% tikz.code.tex: llinellau 4636-4640
  \edef\pgf@temp{\pgfkeyscurrentpath}%
  \edef\pgf@temp{\expandafter\tikz@smuggle@pics@in\pgf@temp\pgf@stop}%
  \expandafter\pgfkeys\expandafter{\pgf@temp/.style={code={#1}}}% collir % yn y côd gwreiddiol
}

\endinput

The advantage of this is that you can easily remove the patching code or change it if necessary and then any documents which use tikz-pic-fix will just load the standard tikz and you don't have to hunt through them to change every application of the fix.

EDIT

Or a TikZ library, if you've forgotten what you did with the code ....

\ProvidesFile{tikzlibrarypicfix.code.tex}
\pgfkeysdef{/handlers/.pic}{% ateb Symbol 1: https://tex.stackexchange.com/a/368531/
  \edef\pgf@temp{\pgfkeyscurrentpath}%
  \edef\pgf@temp{\expandafter\tikz@smuggle@pics@in\pgf@temp\pgf@stop}%
  \expandafter\pgfkeys\expandafter{\pgf@temp/.style={code={#1}}}%
}
\endinput

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.