% !TeX spellcheck = en_US
% !TeX root = tikz-ext-manual.tex
% Copyright 2022 by Qrrbrbirlbel
%
% This file may be distributed and/or modified
%
% 1. under the LaTeX Project Public License and/or
% 2. under the GNU Free Documentation License.
%

\section{And a little bit more}
\begin{tikzlibrary}{ext.misc}
  This library adds miscellaneous utilities to \pgfname math, \pgfname\space or \tikzname.
  \inspiration{FullArc-Q}{FullArc-A}
\end{tikzlibrary}

\subsection{\pgfname math}

\begin{multicols}{2}\
\pgfkeys{/codeexample/every codeexample/.append style={width=3cm}}
\subsubsection{Postfix operator \texttt{R}}

Similar to |\segments[<num>]| in PSTricks, the postfix operator |R| allows the user
to use an arbitrary number of segments of a circle to be used instead of an angle.

\begin{key}{/\pgfext/full arc=\meta{num} (default |\{\}|)}\keycompat{pgf}
  The number \meta{num} of segments will be set up.
  Using |full arc| with an empty value disables the segmentation and |1R| equals $1^\circ$.
  
  The given value \meta{num} is evaluated when the key is used and doesn't change when
  \meta{num} contains variables that change.
\end{key}
The |R| operator can then be used.
\begin{math-operator}{R}{postfix}{extfullarc}
  Multiplies \mvar{x} with $\frac{360}{\meta{num}}$.
\end{math-operator}

\subsubsection{Functions}

\begin{math-function}{extstrrepeat("\mvar{Text}", \mvar{x})}\mathcompat{strrepeat}
\mathcommand
  Returns a string with \mvar{Text} repeated \mvar{x} times.

\begin{codeexample}[]
\pgfmathparse{extstrrepeat("foo", 5)}
\pgfmathresult
\end{codeexample}
\end{math-function}

\begin{math-function}{extisInString("\mvar{String}", "\mvar{Text}")}\mathcompat{isInString}
\mathcommand
  Returns |1| (true) if \mvar{Text} contains \mvar{String},
  otherwise |0| (false).

\begin{codeexample}[]
\pgfmathparse{extisInString("foo", "bar")}
\pgfmathresult \ and\ 
\pgfmathparse{extisInString("foo", "foobar")}
\pgfmathresult
\end{codeexample}
\end{math-function}

\begin{math-function}{extstrcat("\mvar{Text A}", "\mvar{Text B}", …)}\mathcompat{strcat}
\mathcommand
  Returns the concatenation of all given parameters.

\begin{codeexample}[]
\pgfmathparse{extstrcat("blue!", int(7*3), "!green")}
\pgfmathresult
\end{codeexample}
\end{math-function}


\begin{math-function}{extisEmpty("\mvar{Text}")}\mathcompat{isEmpty}
\mathcommand
  Returns |1| (true) if \mvar{Text} is empty, otherwise |0| (false).
  %
\begin{codeexample}[]
\pgfmathparse{extisEmpty("foo")} \pgfmathresult\ and\ 
\pgfmathparse{extisEmpty("")}    \pgfmathresult\ and\ 
\def\emptyText{}
\pgfmathparse{extisEmpty("\emptyText")} \pgfmathresult
\end{codeexample}
\end{math-function}

\begin{math-function}{extatanXY(\mvar{x},\mvar{y})}\mathcompat{atanXY}
\mathcommand
  Arctangent of $\mvar y\div \mvar x$ in degrees. This also takes into account the quadrant.
  This is just a argument-swapped version of |atan2|\indexMathFunctionO{atan2} which makes it easier to use
  the |\p| commands of the |calc|\indexLibraryO{calc} library.
  %
\begin{codeexample}[]
\pgfmathparse{extatanXY(3,4)} \pgfmathresult
\end{codeexample}
\end{math-function}
\begin{math-function}{extatanYX(\mvar{y},\mvar{x})}\mathcompat{atanYX}
\mathcommand
   Arctangent of $y\div x$ in degrees. This also takes into account the quadrant.
\begin{codeexample}[]
\pgfmathparse{extatanYX(4,3)} \pgfmathresult
\end{codeexample}
\end{math-function}

\subsubsection{Functions: using coordinates}
The following functions can only be used with \pgfname\space and/or \tikzname.
Since the arguments are usually plain text (and not numbers) one has to wrap
them in |"|.
\begin{math-function}{extanglebetween("\mvar{p1}", "\mvar{p2}")}\mathcompat{anglebetween}\mathcommand
  Return the angle between the centers of the nodes \mvar{p1} and \mvar{p2}.
\end{math-function}
\begin{math-function}{extqanglebetween("\mvar{p}")}\mathcompat{qanglebetween}\mathcommand
  Return the angle between the origin and the center of the node \mvar{p}.
\end{math-function}
\begin{math-function}{extdistancebetween("\mvar{p1}", "\mvar{p2}")}\mathcompat{distancebetween}\mathcommand
  Return the distance (in pt) between the centers of the nodes \mvar{p1} and \mvar{p2}.
\end{math-function}
\begin{math-function}{extqdistancebetween("\mvar{p}")}\mathcompat{qdistancebetween}\mathcommand
  Return the distance (in pt) between the origin and the center of the node \mvar{p}.
\end{math-function}

\end{multicols}

\begin{codeexample}[width=6cm,preamble=\usetikzlibrary{calc,ext.misc,through}]
\begin{tikzpicture}
\path (0,0) coordinate (A) + (0:4) coordinate (B) +(75:4) coordinate (C);
\draw (A) -- (B) -- (C) -- cycle;
\foreach \cnt in {1,...,4}{
  \pgfmathsetmacro\triA{extdistancebetween("B","C")}
  \pgfmathsetmacro\triB{extdistancebetween("C","A")}
  \pgfmathsetmacro\triC{extdistancebetween("A","B")}
  \path (barycentric cs:A=\triA,B=\triB,C=\triC) coordinate (M)
       node [draw, circle through=($(A)!(M)!(C)$)] (M) {};
  \draw ($(C)-(A)$) coordinate (vecB)
      (M.75-90) coordinate (@)
      (intersection of @--[shift=(vecB)]@ and B--C) coordinate (C) -- 
      (intersection of @--[shift=(vecB)]@ and B--A) coordinate (A);}
\end{tikzpicture}
\end{codeexample}

\subsection{\pgfname for}

This library loads also most of the functions of the
\referencePackageandIndex{pgffor-ext} of section~\ref{pkg:pgffor-ext}
on page~\pageref{pkg:pgffor-ext}.

\subsection{\pgfname keys}
\begin{pgfkeyslibrary}{ext.pgfkeys-plus}
  This extends \pgfname keys and adds helpful |/utils| keys as well as handlers.
  This library gets loaded by the |ext.misc| library.
\end{pgfkeyslibrary}

\begin{multicols}{2}
\subsubsection{Conditionals}

\begin{key}{/\utilsext/pgfmath if=\marg{cond}\marg{true}\opt{\marg{false}}}{\def\myname{if}\keycompat{utils}}
  This key checks the conditional \meta{cond} and applies the styles \meta{true}
  if \meta{cond} is true, otherwise \meta{false}.
  \meta{cond} can be anything that \pgfname math understands.
  
  As a side effect on how \pgfname keys parses argument, the \meta{false} argument is
  actually optional.
\end{key}

The following keys use \TeX' macros |\if|, |\ifx|, |\ifnum| and |\ifdim| for faster
executions.

\begin{key}{/\utilsext/if=\meta{token A}\meta{token B}\marg{true}\opt{\marg{false}}}\keycompat{utils/TeX}
  This key checks via |\if| if \meta{token A} matches \meta{token B}
  and applies the styles \meta{true} if it does, otherwise \meta{false}.
  
  As a side effect on how \pgfname keys parses argument, the \meta{false} argument is
  actually optional.
\end{key}

\begin{key}{/\utilsext/ifx=\meta{token A}\meta{token B}\marg{true}\opt{\marg{false}}}\keycompat{utils/TeX}
  As above but via |\ifx|.
\end{key}

\begin{key}{/\utilsext/ifnum=\marg{num cond}\marg{true}\opt{\marg{false}}}\keycompat{utils/TeX}
  This key checks |\ifnum|\meta{num cond}
  and applies the styles \meta{true} if true, otherwise \meta{false}.
  A delimiting |\relax| will be inserted after \meta{num cond}.
  
  As a side effect on how \pgfname keys parses arguments, the \meta{false} argument is
  actually optional.
\end{key}

\begin{key}{/\utilsext/ifdim=\meta{dim cond}\meta{true}\opt{\meta{false}}}\keycompat{utils/TeX}
  As above but with |\ifdim|.
\end{key}

\begin{key}{/\utilsext/ifempty=\meta{Text}\meta{true}\opt{\meta{false}}}\keycompat{utils/TeX}
  This checks whether \meta{Text} is empty and applies styles \meta{true} if true,
  otherwise \meta{false}.
\end{key}
\begin{key}{/\utilsext/ifxempty=\meta{Text}\meta{true}\opt{\meta{false}}}\keycompat{utils/TeX}
  This checks whether fully expanded \meta{Text} is empty and applies styles \meta{true} if true,
  otherwise \meta{false}.
\end{key}

\subsubsection{Handlers}

While already a lot of values given to keys are evaluated by \pgfname math at some point,
not all of them are.

\begin{ext_handler}{{pgfmath}|=|\meta{eval}}\handlercompat{.pgfmath}
  This handler evaluates \meta{eval} before it is handed to the key.
  
  This handler works almost the same as the |.evaluated|\indexHandlerO{.evaluated}
  handler but it does its evaluation in a group so that the result will 
  not overwrite any other results.
\end{ext_handler}

\begin{ext_handler}{{pgfmath int}|=|\meta{eval}}\handlercompat{.pgfmath int}
  As above but truncates the result.
\end{ext_handler}

\begin{ext_handler}{{pgfmath wrap}|=|\marg{wrapper}\marg{eval}}\handlercompat{.pgfmath wrap}
  This feeds the result of \meta{eval} as |#1| to \meta{wrapper}.
  
  In the example below, one could have used the \referenceKeyandIndexO[/pgf/foreach/]{evaluate}
  key from the |\foreach| loop.
\begin{codeexample}[width=3.7cm,preamble=\usepgfkeyslibrary{ext.pgfkeys-plus}]
\tikz\foreach \i in {0,10,...,100}
\draw[
  line width=+.25cm,
  % needs ## because its inside the \foreach body
  color/.ext_pgfmath wrap={red!##1!blue}{sqrt(\i)*10}
]
  (0,\i/40) -- +(right:3);
\end{codeexample}
\end{ext_handler}

\begin{ext_handler}{{pgfmath if}|=|\marg{cond}\marg{true}\opt{\marg{false}}}\handlercompat{.pgfmath if}
  Evaluates \meta{cond} with \pgfname Math and returns \meta{true} or \meta{false} to the used key respectively.
\end{ext_handler}
\begin{ext_handler}{{if}|=|\meta{token A}\meta{token B}\marg{true}\opt{\marg{false}}}\handlercompat{.if}
  Checks via |\if| if \meta{token A} matches \meta{token B}
  and applies the value \meta{true} if it does, otherwise \meta{false}.
\end{ext_handler}
\begin{ext_handler}{{ifx}|=|\meta{token A}\meta{token B}\marg{true}\opt{\marg{false}}}\handlercompat{.ifx}
  As above but via |\ifx|.
\end{ext_handler}
\begin{ext_handler}{{ifnum}|=|\marg{ifnum cond}\marg{true}\opt{\marg{false}}}\handlercompat{.ifnum}
  Checks via |\ifnum| if \meta{ifnum cond}
  and applies the value \meta{true} if it does, otherwise \meta{false}.
\end{ext_handler}
\begin{ext_handler}{{ifdim}|=|\marg{ifdim cond}\marg{true}\opt{\marg{false}}}\handlercompat{.ifdim}
  As above but via |\ifdim|.
\end{ext_handler}
\begin{ext_handler}{{ifxempty}|=|\marg{Text}\marg{true}\opt{\marg{false}}}\handlercompat{.ifxempty}
  Checks whether a fully expanded \meta{Text} is empty
  and applies the value \meta{true} if it does, otherwise \meta{false}.
\end{ext_handler}
\begin{ext_handler}{{ifempty}|=|\marg{Text}\marg{true}\opt{\marg{false}}}
  Checks whether \meta{Text} is empty
  and applies the value \meta{true} if it does, otherwise \meta{false}.
\end{ext_handler}
\begin{ext_handler}{{List}|=|\marg{\meta{e1}, \meta{e2}, \dots, \meta{en}}}\handlercompat{.List}
  This handler evaluates the given list with |\foreach| and concatenates the element and
  the result is then given to the used key.
\end{ext_handler}
\end{multicols}
\begin{codeexample}[width=6cm,preamble=\usetikzlibrary{fit,ext.misc}]
\begin{tikzpicture}[nodes={draw, dashed, inner sep=+10pt}]
  \foreach \point [count=\cnt] in {(0,0), (0,2), (2,0), (2,2), (3,3), (-1,-1)}
    \node[circle, fill, inner sep=1pt, text=white] (point-\cnt) at \point {\cnt};
  \node[gray, fit/.ext_List={(point-1),(point-...),(point-4)}] {}; 
  \node[red,  fit/.ext_List={(point-1),(point-...),(point-5)}] {}; 
  \node[blue, fit/.ext_List={(point-1),(point-...),(point-6)}] {};
\end{tikzpicture}
\end{codeexample}

\pagebreak
\subsection{\tikzname}
\begin{multicols}{2}
\begin{key}{/\tikzext/reverse clip=\meta{direction} (default counter clockwise)}\keycompat{tikz}
This key installs a very big rectangle which is either constructed
\texttt{counter clockwise} (like the \referencePathOperationandIndexO{circle}
path operation) or |clockwise|.
\end{key}
\begin{key}{/\tikzext/clip rule=\meta{direction} (default even odd)}\keycompat{tikz}
This key switches directly\footnote{%
  Meaning, it directly executes
  \referenceCommandandIndexO{\pgfseteorule}/%
  \referenceCommandandIndexO{\pgfsetnonzerorule}
  and doesn't accumulates where \tikzname\space
  throws an error.}
to the specified rule which is
either |even odd| or |nonzero|.
This corresponds to the \referenceKeyandIndexO{even odd rule} and
\referenceKeyandIndexO{nonzero rule} keys.
\end{key}
\end{multicols}
\begingroup\catcode`\&=\active
\begin{codeexample}[preamble=\usetikzlibrary{ext.misc},width=6cm]
\newcommand*\myDiagram[1]{
  \fill[left color=blue, right color=green] (0, 0) rectangle (2, 1);
  \clip (1, .5) #1 [ext/reverse clip];
  \fill[left color=green, right color=blue] (0, 0) rectangle (2, 1);
}
\begin{tikzpicture}[radius=.4, row sep=5mm, column sep=5mm]
\matrix[
  row 2/.append style={ext/clip rule=even odd},
  column 1/.append style={ext/reverse clip/.default=clockwise}
]{
  \myDiagram{circle[]} &
  \myDiagram{+(0:.4) arc[start angle=0, delta angle=-360] -- cycle}
\\
  \myDiagram{circle[]} &
  \myDiagram{+(0:.4) arc[start angle=0, delta angle=-360] -- cycle}
\\};
\end{tikzpicture}
\end{codeexample}
\endgroup
\endinput