From 2b32ddeea7bc09a1579c7a500d1bc51f71cac3d6 Mon Sep 17 00:00:00 2001 From: Andrew Stacey Date: Fri, 31 May 2024 15:09:51 +0100 Subject: [PATCH] Arrow shortening via boolean The code to disable arrow shortening is now controlled by a boolean. Also, documentation updated accordingly. --- spath3.tex | 69 +++++++++++++++++++++++++++++++++++++------------ spath3_code.dtx | 45 +++++++++++++++++++------------- 2 files changed, 79 insertions(+), 35 deletions(-) diff --git a/spath3.tex b/spath3.tex index 1a5274d..897f5f7 100644 --- a/spath3.tex +++ b/spath3.tex @@ -1,5 +1,5 @@ \RequirePackage{shellesc} -\immediate\write18{tex spath3_code.dtx} +%\immediate\write18{tex spath3_code.dtx} \documentclass{l3doc} \usepackage{tikz} \usetikzlibrary{ @@ -50,27 +50,29 @@ \title{The \textsf{spath3} Package: Documentation} \author{Andrew Stacey \\ \url{loopspace@mathforge.org}} - \date{\fileversion~from \filedate} +\date{\fileversion~from \filedate} - \begin{document} +\let\OriginalBar=| - \maketitle +\begin{document} + +\maketitle \tableofcontents - \section{Introduction} +\section{Introduction} - The \texttt{spath3} package was originally designed as a low-level package for manipulating the \emph{soft paths} defined by PGF/TikZ. - Soft paths form one stage of the stack of translations between what the author writes in the \texttt{tikzpicture} environments in their \LaTeX\ document and what is eventually written to the output file. - Most of the complicated processing has been done by the time a soft path is constructed, but it is still very definitely a \TeX\ object and there has not, for example, been any consideration as to what the eventual output file format is (such as PDF, DVI, or SVG). - So it is very amenable to being modified at this stage and this package provides a set of routines for doing so. +The \texttt{spath3} package was originally designed as a low-level package for manipulating the \emph{soft paths} defined by PGF/TikZ. +Soft paths form one stage of the stack of translations between what the author writes in the \texttt{tikzpicture} environments in their \LaTeX\ document and what is eventually written to the output file. +Most of the complicated processing has been done by the time a soft path is constructed, but it is still very definitely a \TeX\ object and there has not, for example, been any consideration as to what the eventual output file format is (such as PDF, DVI, or SVG). +So it is very amenable to being modified at this stage and this package provides a set of routines for doing so. - The original purpose was to provide a common core on which other packages would be built. - Indeed, the packages \texttt{calligraphy}, \texttt{knots}, and \texttt{penrose} all use this package. - However, over time I've found myself wanting to use the routines of this package at a higher level and so have designed some user-level interfaces. - This document documents those. +The original purpose was to provide a common core on which other packages would be built. +Indeed, the packages \texttt{calligraphy}, \texttt{knots}, and \texttt{tilings} all use this package. +However, over time I've found myself wanting to use the routines of this package at a higher level and so have designed some user-level interfaces. +This document documents those. - To clarify some terminology used in this document (and more generally, this package), I regard paths as being composed of \emph{segments} and \emph{components}. +To clarify some terminology used in this document (and more generally, this package), I regard paths as being composed of \emph{segments} and \emph{components}. A \emph{segment} is a minimal drawing piece. Thus it might be a straight line or a B\'ezier curve. A \emph{component} is a minimal connected section of the path. @@ -142,7 +144,7 @@ \subsection{Path Names} \begin{verbatim} at end path construction={code} \end{verbatim} - +% This invokes the |code| right after the path has finished being built. \end{variable} @@ -634,6 +636,24 @@ \subsection{Shortening and Splitting Paths} \end{function} +\begin{function}{ + arrow shortening +} +\begin{syntax} +|arrow shortening| +|arrow shortening=|\marg{true{\OriginalBar}false} +\end{syntax} + +When an arrow is added to a path then the path is shortened so that the arrow tip is at the end of where the path should end up. +Placing an arrow, therefore, has two effects: modifying the path and rendering the arrow. +The former should happen before a soft path is manipulated, the latter afterwards. +This key allows for the necessary separation to occur. +Invoking it when the path is used disables the shortening at that juncture. + +Note that if the path (or its last segment) is very short then when the arrow is eventually placed it may end up pointing backwards. +Fixing this is on the \emph{ToDo} list! +\end{function} + \subsection{Exporting Paths} There are two keys to export a path. @@ -662,8 +682,8 @@ \subsection{Knots} draft mode } \begin{syntax} -|knot=|\meta{path}\meta{gap}\meta{components} -|global knot=|\meta{path}\meta{gap}\meta{components} +|knot=|\marg{path}\marg{gap}\marg{components} +|global knot=|\marg{path}\marg{gap}\marg{components} \end{syntax} This style combines various of the above to make it simpler to draw knots and links. @@ -908,6 +928,21 @@ \section{Examples} \end{tikzpicture} \end{example} +\begin{example} +\begin{tikzpicture}[>=Latex, line width=5pt] +% Just a simple line +\draw (0,1) to[bend left] +(5,0); +% Same line but with arrows, also save the path +\draw[->.>, spath/save=arrow] (0,0) to[bend left] +(5,0); +% Let's redraw that path without the arrows - it's short! But also distorted +\draw[spath/use={arrow,transform={yshift=-1cm}}]; +% So if we redraw it with arrows it gets doubly shortened +\draw[->.>,spath/use={arrow,transform={yshift=-2cm}}]; +% If we disable the shortening, the arrows end up in the right place +\draw[->.>,spath/use={arrow,transform={yshift=-3cm}}, spath/arrow shortening=false]; +\end{tikzpicture} +\end{example} + \item Intersections. One of the main motivations for implementing the intersection routines was to provide a different way of drawing knots and links and similar diagrams. diff --git a/spath3_code.dtx b/spath3_code.dtx index 09969d5..aa35314 100644 --- a/spath3_code.dtx +++ b/spath3_code.dtx @@ -5,7 +5,7 @@ %<*readme> ---------------------------------------------------------------- spath3 --- LaTeX3 functions for manipulating PGF soft paths -E-mail: loopspace@mathforge.org +E-mail: Andrew Stacey loopspace@mathforge.org Released under the LaTeX Project Public License v1.3c or later See http://www.latex-project.org/lppl.txt ---------------------------------------------------------------- @@ -27,7 +27,7 @@ As applications of its use, included are a package for drawing calligraphic path \preamble ---------------------------------------------------------------- spath3 --- Functions for manipulating PGF soft paths -E-mail: loopspace@mathforge.org +E-mail: Andrew Stacey loopspace@mathforge.org Released under the LaTeX Project Public License v1.3c or later See http://www.latex-project.org/lppl.txt ---------------------------------------------------------------- @@ -35,7 +35,7 @@ See http://www.latex-project.org/lppl.txt \endpreamble \postamble -Copyright (C) 2011-2021 by Andrew Stacey +Copyright (C) 2011-2024 by Andrew Stacey This work may be distributed and/or modified under the conditions of the LaTeX Project Public License (LPPL), either @@ -143,7 +143,7 @@ and the derived files spath3.ins, % % \fi % -% \CheckSum{10272} +% \CheckSum{10278} % % \CharacterTable % {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z @@ -171,6 +171,7 @@ and the derived files spath3.ins, % \changes{2.4}{2021/02/21}{Rejigged how the routines for using paths were implemented, added some more routines for joining paths.} % \changes{2.6}{2021/11/23}{Modified core routines to cope with a "true rectangle" path; added routines for splitting at a parametrised point.} % \changes{2.7}{2022/08/24}{Bug fixes} +% \changes{2.8}{2024/05/31}{Routine to disable arrow shortening, bug fixes} % % \DoNotIndex{\newcommand,\newenvironment} % @@ -198,7 +199,7 @@ and the derived files spath3.ins, % It was originally not really intended for use by end users but as a foundation on which other packages can be built. % However, over the years I've found myself using it at ever higher levels and so a set of interfaces has been designed using TikZ keys. % -% It also provides the engine that drives a few other packages, such as the \Verb+calligraphy+, \Verb+knot+, and \Verb+penrose+ packages. +% It also provides the engine that drives a few other packages, such as the \Verb+calligraphy+, \Verb+knot+, and \Verb+tilings+ (formerly, \Verb+penrose+) packages. % The first two of these are subpackages of this one. % The \Verb+calligraphy+ package simulates a calligraphic pen stroking a path. % The \Verb+knots+ package can be used to draw knot (and similar) diagrams. @@ -208,7 +209,7 @@ and the derived files spath3.ins, % \begin{itemize} % \item \Verb+calligraphy+ % \item \Verb+knots+ -% \item \Verb+penrose+ +% \item \Verb+tilings+ % \item \Verb+spath3+ (\emph{this} document is the code, there's another which focusses on usage) % \end{itemize} % @@ -259,7 +260,7 @@ and the derived files spath3.ins, \NeedsTeXFormat{LaTeX2e} \RequirePackage{expl3} \RequirePackage{pgf} -\ProvidesExplPackage {spath3} {2022/08/24} {2.7} {Functions for +\ProvidesExplPackage {spath3} {2024/05/31} {2.8} {Functions for manipulating PGF soft paths} \RequirePackage{xparse} % \end{macrocode} @@ -375,6 +376,13 @@ manipulating PGF soft paths} \bool_new:N \l_spath_movetorelevant_bool % \end{macrocode} % +% When manipulating soft paths, we might need to separate the shortening due to an arrow from when the path is rendered. +% +% \begin{macrocode} +\bool_new:N \l_spath_arrow_shortening_bool +\bool_set_true:N \l_spath_arrow_shortening_bool +% \end{macrocode} +% % The intersection routine can't happen inside a group so we need two token lists to hold the paths that we'll intersect. % % \begin{macrocode} @@ -3070,12 +3078,17 @@ manipulating PGF soft paths} % Then \verb+\pgf@xb+ is the length of the arrow head which is used to position the arrow and so before zeroing \verb+\pgf@xa+ we subtract it from \verb+\pgf@xb+ so that the arrow is placed so that its back point is at the current position. % % \begin{macrocode} -\cs_new_nopar:Npn \@@_arrow_disable_shortening:n #1 +\cs_new_nopar:Npn \@@_arrow_compute_shortening:n #1 { \@@_pgf_arrow_compute_shortening:n {#1} - \dim_sub:cn {pgf@xb} {\dim_use:c {pgf@xa}} - \dim_zero:c {pgf@xa} + \bool_if:NF \l_spath_arrow_shortening_bool + { + \dim_sub:cn {pgf@xb} {\dim_use:c {pgf@xa}} + \dim_zero:c {pgf@xa} + } } + +\cs_set_eq:cN {pgf@arrow@compute@shortening} \@@_arrow_compute_shortening:n % \end{macrocode} % % \end{macro} @@ -9055,12 +9068,8 @@ manipulating PGF soft paths} % This puts a conditional around the \texttt{spot weld} key because when figuring out a knot drawing then we will initially want to render it without the spot weld to keep the number of components constant. % % \begin{macrocode} - draft~ mode/.is~ choice, - draft~ mode/true/.code={ - \bool_set_true:N \l_@@_draft_bool - }, - draft~ mode/false/.code={ - \bool_set_false:N \l_@@_draft_bool + draft~ mode/.code={ + \@@_set_bool:Nn \l_@@_draft_bool {#1} }, maybe~ spot~ weld/.code={ \bool_if:NF \l_@@_draft_bool @@ -9142,8 +9151,8 @@ manipulating PGF soft paths} % \end{macrocode} % % \begin{macrocode} - disable~ arrow~ shortening/.code={ - \cs_set_eq:cN {pgf@arrow@compute@shortening} \__spath_arrow_disable_shortening:n + arrow~ shortening/.code={ + \@@_set_bool:Nn \l_spath_arrow_shortening_bool {#1} }, % \end{macrocode} %