% !TeX TS-program = lualatex
% !TeX spellcheck = en_US
% !TeX root = tikz-ext-manual.tex
% Copyright 2023 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{Arrow Pics}
\label{tikzlibrary:arrows}
\tikzset{external/export/.try=false}%
\begin{tikzlibrary}{ext.arrows-plus}
  This library defines pics and keys
  that can be used to place (bended) arrow tips on paths.
\end{tikzlibrary}

\begin{multicols}{2}
The \referenceDecorationandIndexO{markings} decoration
already provides the functionality to place arrow tips along the path.
The pics and keys provided by this library serve as an alternative.

Many of the pics and keys share various keys that specify
where and how the arrow tips are placed.
\begin{key}{/\tikzext/pos <=\meta{value} (initially 0.0)}
If the pic type supports it and a start arrow tip sequence is provided
this specifies the position of that sequence.
\end{key}
\begin{key}{/\tikzext/pos >=\meta{value} (initially 0.5)}
This is an alias for \referenceKeyandIndex{pos},
if an end arrow tip sequence is provided, it is placed at this position.
\end{key}
\begin{key}{/\tikzext/pos < angle=\meta{angle}}
For tips along an arc the angle along that arc can be specified for the start tip sequence.
\end{key}
\begin{key}{/\tikzext/pos > angle=\meta{angle}}
For tips along an arc the angle along that arc can be specified for the end tip sequence.
\end{key}
\begin{key}{/\tikzext/arrow shift mode=\meta{shift mode} (initially total length)}
This key is used to set the \meta{shift mode} for the arrow tip.
It can be one of the following.
\begin{description}
\item[|arrow shift mode|=\declare{|off|}]

  This disables the shifting.
\item[|arrow shift mode|=\declare{|total length|}]

  The total length of the whole arrow tip sequence will be used.
\item[|arrow shift mode|=\declare{|total|}]

  This is an alias for |total length|.
\item[|arrow shift mode|=\declare{|length until line end|}]

  The length of the whole arrow tip until the line end will be used --
  as reported by \pgfname\ which might not always be the expected one.
\item[|arrow shift mode|=\declare{|line end|}]

  This is an alias for |length until line end|.
\end{description}
\begin{codeexample}[preamble=\usetikzlibrary{ext.arrows-plus}]
\begin{tikzpicture}[>={Straight Barb[color=red]}, ultra thick]
\ttfamily
\foreach[count=\y] \shiftmode in {off, total length, length until line end}
  \draw[ext/arrow shift mode=\shiftmode] (0, -\y  )
                -- pic {ext/arrow=>}    ++(right:2)
                -- pic {ext/arrow=>.>>} ++(right:2) node[below right] {\shiftmode}
    ++(down:.4) -- pic {ext/arrow=>.>>} ++( left:2)
                -- pic {ext/arrow=>}    ++( left:2);
\draw[thin, gray] (1,-.75) -- +(down:3) (3,-.75) -- +(down:3);
\end{tikzpicture}
\end{codeexample}

For single arrow tips it might be better to use the Centered arrow tip variants
of the \referenceLibraryandIndex{ext.arrows} library (see sec~\ref{pgflibrary:arrows})
and disabled |arrow shift mode|.
\end{key}

When an arrow tip sequence is to be drawn depending on the shift mode
its total length or its length until the line end will be determined
and multiplied with the |arrow shift factor|.
The result of this evaluation is used to shift the arrow tip sequence
in the tip's direction.

\begin{key}{/\tikzext/arrow shift factor start=\meta{value} (initially 0.5)}
  This determines the shift factor for the start tip sequence.
  
  The default value is probably good for most cases.
\end{key}
\begin{key}{/\tikzext/arrow shift factor end=\meta{value} (initially 0.5)}
  This determines the shift factor for the start tip sequence.
  
  The default value is probably good for most cases.
\end{key}
\begin{key}{/\tikzext/arrow shift factor=\meta{value}}
  This sets both the start and end shift factor.
\end{key}
\subsection{Arrow pic types}

This library provides the following pics:
\begin{description}
\item[|ext/arrow|]
  This is the simplest implementation to place an arrow tip along a path.
  It uses the current timer that is also used to place nodes.
  
  It can be used without any adjustment for every path operation that provides such a timer.
  These do \emph{not} include
  \referencePathOperationandIndexO{circle},
  \referencePathOperationandIndexO{ellipse},
  \referencePathOperationandIndexO{plot} and
  \referencePathOperationandIndexO{grid}.
  For \referencePathOperationandIndexO{rectangle},
      \referencePathOperationandIndexO{parabola},
      \referencePathOperationandIndexO{sin} and
      \referencePathOperationandIndexO{cos},
  the \referenceLibraryandIndex{ext.paths.timer} library is recommended or even necessary
  (see section~\ref{library:timer}).
  
  The arrow tips will never be bended. For this the following pic types
  or the \referenceKeyandIndex[/\tikzext/]{arc arrows} key will be necessary.

  Due to \cite{PgfIssueSloped} with an active transformation,
  the arrow tips won't be placed correctly in many cases.
  For this \emph{and} bended arrow tips the following pics are necessary.
  
\item[|ext/softpath arrows|]
  This pic type places a possible bended arrow tip on the last segment of the path.
  
%  For the path operators \referencePathOperationandIndexO{--},
%  {\catcode`\|=12 \referencePathOperationandIndexO{|-}
%              and \referencePathOperationandIndexO{-|}}
%  this works even with a non-identity transformation.
%  If possible, the current timer will be used to take more segments into account so
%  that the arrow tip can be placed along the recent path operation.
  
  This won't work for \referencePathOperationandIndexO{arc}s,
  for this the \referenceKeyandIndex[/\tikzext/]{arc arrows} key will be necessary.
  
  This pic type can place two tip specification,
  one at |pos >| and one at |pos <| in the reversed direction.

\item[|ext/softpath arrow|]
  This is an alias for |softpath arrows| with an empty start arrow tip specification.

\end{description}
\begin{pictype}{ext/arrow}{\opt{|=|\meta{\rmfamily arrow tip specification}}}
  This pic draws the given \meta{arrow tip specification}
  (defaults to the end tip specification of the path).
  
  
  This obviously is best used as a pic along a path segment that supports it.
  It \emph{does not} support bended arrow tips.
\begin{codeexample}[preamble=\usetikzlibrary{arrows.meta, bending, ext.arrows-plus}]
\begin{tikzpicture}[>={Triangle[color=red]}, arrows={[bend]}, ultra thick]
\ttfamily
\foreach[count=\y] \shiftmode in {off, total length, length until line end}
  \draw[ext/arrow shift mode=\shiftmode] (0, -\y  )
                to[bend  left] pic {ext/arrow=>}    ++(right:2)
                to[bend  left] pic {ext/arrow=>>.>} ++(right:2)
                                             node[below right] {\shiftmode}
    ++(down:.4) to[bend right] pic {ext/arrow=>>.>} ++( left:2)
                to[bend right] pic {ext/arrow=>}    ++( left:2);
\draw[thin, gray] (1,-.5) -- +(down:3) (3,-.5) -- +(down:3);
\end{tikzpicture}
\end{codeexample}
\end{pictype}

\begin{pictype}{ext/softpath arrows}{\opt{|=|\meta{\rmfamily start tip specification}|-|\meta{\rmfamily end tip specification}}}
  This pic draws the given arrow tip specification
  (defaults to the already present tip specification of the path)
  along the previous path segment (a curve or a line).
  It supports the |pos <| key.
  
  \paragraph{Note:} For arcs with an angle greater than 90${}^\circ$
    this will not work as expected. Use the |/tikz/ext/arc arrows| key instead.
\end{pictype}
\begin{pictype}{ext/softpath arrow}{\opt{|=|\meta{\rmfamily end tip specification}}}
  This pic type is an alias for |softpath arrows = -|\meta{end tip specification}.

\begin{codeexample}[preamble=\usetikzlibrary{arrows.meta, bending, ext.arrows-plus}]
\begin{tikzpicture}[>={Triangle[color=red]}, arrows={[bend]}, ultra thick]
\ttfamily
\foreach[count=\y] \shiftmode in {off, total length, length until line end}
  \draw[ext/arrow shift mode=\shiftmode] (0, -\y  )
                to[bend  left] pic {ext/softpath arrow=>}    ++(right:2)
                to[bend  left] pic {ext/softpath arrow=>>.>} ++(right:2)
                                             node[below right] {\shiftmode}
    ++(down:.4) to[bend right] pic {ext/softpath arrow=>>.>} ++( left:2)
                to[bend right] pic {ext/softpath arrow=>}    ++( left:2);
\draw[thin, gray] (1,-.5) -- +(down:3) (3,-.5) -- +(down:3);
\end{tikzpicture}
\end{codeexample}
\end{pictype}

\subsection{Arrow keys}
The last pic type |softpath arrows| is also available as a key
which is the preferred version.
\begin{key}{/\tikzext/softpath arrows=\opt{\meta{options}} (default ->)}
This key adds arrow tips to the previous path segment (a curve or a line).

\begin{stylekey}{/\tikzext/every softpath arrows (initially \{\})}
This style will be applied for every instance of |softpath arrows| (key version, not the pic).
It also sets up forwarding
\begin{itemize}
  \item from |/tikz/pos >| to |/tikz/ext/pos >| and
  \item from |/tikz/pos <| to |/tikz/ext/pos >|.
\end{itemize}
\end{stylekey}
\end{key}

For |arc|s the following key needs to be used directly after the |arc| path operation.
\begin{key}{/\tikzext/arc arrows=\opt{\meta{options}} (default ->)}
This key adds arrow tips to the previous arc segment.
\begin{stylekey}{/\tikzext/every arc arrows (initially \{\})}
This style will be applied for every instance of |arc arrows|.
It also sets up forwarding
\begin{itemize}
  \item from |/tikz/pos >| to |/tikz/ext/pos >|,
  \item from |/tikz/pos <| to |/tikz/ext/pos >| as well as
  \item from |/tikz/pos > angle| to |/tikz/ext/pos > angle| and
  \item from |/tikz/pos < angle| to |/tikz/ext/pos < angle|.
\end{itemize}
\begin{codeexample}[preamble=\usetikzlibrary{arrows.meta, ext.arrows-plus}]
\begin{tikzpicture}
\draw (0,0) -- (135:1)
      (0,0) -- (225:1) [help lines];
\draw[arrows={[bend] Stealth-Latex}]
  (120:1) arc[start angle=120,
                end angle=240, radius=1]
  [ext/arc arrows={pos < angle=135,
                   pos > angle=225,
                   arrows=[red]}];
\end{tikzpicture}
\end{codeexample}
\end{stylekey}


\paragraph{Tip:}
Use an arc with the full 360${}^\circ$ to place bended arrow tips along a circle or an ellipse.
\end{key}
\subsection{Shifted and bended arrows for the \texttt{decorations.markings} library}
Many paths are not properly accessible by the previous methods.
If this library is loaded \emph{after}
the \referenceLibraryandIndexO{decorations.markings} library,
both the |\arrow| and
the |\arrowreversed| macros are enhanced.

\begin{command}{\arrow\opt{|**|\oarg{options}}\marg{arrow end tip}}
  This macro works the same as before but the one-starred version
  applies the shifting as specified
  by |arrow shift mode| and |arrow shift factor|
  where as the two-starred version also bends the arrow tip.
\end{command}
\begin{command}{\arrowreversed\opt{|**|\oarg{options}}\marg{arrow end tip}}
  As above, only the arrow end tip is flipped and points in the other direction.
\end{command}
\begin{codeexample}[width=2cm,preamble=\usetikzlibrary{bending, decorations.markings, ext.arrows-plus}]
\tikzset{
  arr/.style={
    postaction=decorate,
    decoration={
      name=markings,
      mark={between positions .25 and 1 step .25 with
        \arrow#1[red]{> _ < _ >}}}}}
\tikz[y=1.5cm, >=Stealth, arrows={[round]}, nodes={circle, draw}]
  \path   node[arr=  ]{Ti\emph kZ} % \arrow
   (0,-1) node[arr=* ]{Ti\emph kZ} % \arrow*
   (0,-2) node[arr=**]{Ti\emph kZ} % \arrow**
  ;
\end{codeexample}
\end{multicols}
\endinput