13

Below is my example. I'd like to use a global style for all my tikz pictures to set up the line width. It is working well until I use a clip. I guess that it is not possible to pass some style option to clip. The code below gives the error msg

Package tikz Error: Extra options not allowed for clipping path command. \clip (2,0) circle (2cm);

Here is the MWE.

\documentclass{article}
\usepackage{tikz}
\tikzset{every path/.style={line width=2pt}}
\begin{document}
\begin{tikzpicture}
\clip (2,0) circle (2cm);
\draw (0,0) circle (3cm);
\end{tikzpicture}
\end{document}

Any help?

Sigur
  • 37,330

2 Answers2

11

Here are three solutions.

1) If you necessarily need every path/.style, choose this excellent answer from Matthew Leingang (but the TeX group around \clip prevents the propagation of the bounding box):

\documentclass{article}
\usepackage{tikz}

\tikzset{every path/.style={draw=blue,line width=2pt}}
\begin{document}
\begin{tikzpicture}
  {
    \tikzset{every path/.style={}}
    \clip (2,0) circle (2cm);
  }
  \draw (0,0) circle (3cm);
\end{tikzpicture}
\end{document}

2) Most of the time, you can avoid to use every path/.style. Here, you can use every picture/.style instead of every path/.style:

\documentclass{article}
\usepackage{tikz}
\tikzset{every picture/.style={line width=2pt}}
\begin{document}
\begin{tikzpicture}
\clip (2,0) circle (2cm);
\draw (0,0) circle (3cm);
\end{tikzpicture}
\end{document}

3) The third solution redefines the clip option :

\documentclass{article}
\usepackage{tikz}

\makeatletter
\tikzset{clip/.code={%
    \let\tikz@mode=\pgfutil@empty%
    \let\tikz@preactions=\pgfutil@empty%
    \let\tikz@postactions=\pgfutil@empty%
    \let\tikz@options=\pgfutil@empty%
    \tikz@addmode{\tikz@mode@cliptrue}%
  },
}
\makeatother

\tikzset{every path/.style={line width=2pt}}
\begin{document}
\begin{tikzpicture}
  \clip (2,0) circle (2cm);
  \draw (0,0) circle (3cm);
\end{tikzpicture}
\end{document}
Paul Gaborit
  • 70,770
  • 10
  • 176
  • 283
  • Well, if you’re proposing the second solution, do \tikzset{clip/.code={\tikz@addmode{\tikz@mode@cliptrue}\let\tikz@options=\pgfutil@empty}} and you can use the original \path[clip] and \clip. – Qrrbrbirlbel Dec 26 '12 at 18:44
  • @Qrrbrbirlbel Thanks for your suggestion: I edited my answer. – Paul Gaborit Dec 26 '12 at 18:58
  • Of these three, Matthew's is the most reliable and robust. It really should be the first version given. – Andrew Stacey Dec 26 '12 at 23:13
  • @AndrewStacey The first solution is simpler: every picture can replace every path in the majority of cases! – Paul Gaborit Dec 26 '12 at 23:20
  • Disagree. In simple cases, maybe, but it's not difficult to come up with examples where the behaviour is radically different. every scope comes in between, for example. – Andrew Stacey Dec 26 '12 at 23:32
  • @AndrewStacey I misspoke: Most of the time, you can avoid using every path (replacing it by every picture, every scope, or global options for example). For the current question, the solution is every picture. – Paul Gaborit Dec 26 '12 at 23:39
  • @AndrewStacey I edited my answer... – Paul Gaborit Dec 27 '12 at 00:01
  • @AndrewStacey Matthews's solution prevents the correct calculation of the bounding box.... – Paul Gaborit Dec 27 '12 at 12:04
  • @PaulGaborit The bounding box issue is, in my view, a bug in how clip interacts with subsequent bounding box calculations (it is confined to the group, not the scope). I've edited some fixes into Matthew's solution. – Andrew Stacey Dec 27 '12 at 21:53
5

This is a crude method. Instead of changing the path style, you can define a my path and use it.

\documentclass{article}
\usepackage{tikz}
\tikzset{my path/.style={line width=2pt}}
\begin{document}
\begin{tikzpicture}
\clip (2,0) circle (2cm);
\draw [my path] (0,0) circle (3cm);
\end{tikzpicture}
\end{document}

enter image description here

Or define tikzset after clip (if needed put it inside a scope):

\documentclass{article}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\clip (2,0) circle (2cm);
\begin{scope}
\tikzset{every path/.style={line width=2pt}}
\draw  (0,0) circle (3cm);
\end{scope}
\end{tikzpicture}
\end{document}
  • Thanks for your help. But with you suggestion I would have to use the my style on every picture. I'd like to set up global line width to change on the whole document. – Sigur Dec 26 '12 at 12:29
  • 1
    @Sigur Unfortunately yes. But second option is somewhat less brutal. For using it globally, one has to patch the \clip command. Let us wait for tikz gurus. :-) –  Dec 26 '12 at 12:41