texlive[67354] Master/texmf-dist: string-diagrams (13jun23)

commits+karl at tug.org commits+karl at tug.org
Tue Jun 13 22:17:59 CEST 2023


Revision: 67354
          http://tug.org/svn/texlive?view=revision&revision=67354
Author:   karl
Date:     2023-06-13 22:17:59 +0200 (Tue, 13 Jun 2023)
Log Message:
-----------
string-diagrams (13jun23)

Modified Paths:
--------------
    trunk/Master/texmf-dist/doc/latex/string-diagrams/README.md
    trunk/Master/texmf-dist/doc/latex/string-diagrams/string-diagrams.pdf
    trunk/Master/texmf-dist/source/latex/string-diagrams/string-diagrams.dtx
    trunk/Master/texmf-dist/source/latex/string-diagrams/string-diagrams.ins
    trunk/Master/texmf-dist/tex/latex/string-diagrams/string-diagrams.sty

Modified: trunk/Master/texmf-dist/doc/latex/string-diagrams/README.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/string-diagrams/README.md	2023-06-13 16:08:38 UTC (rev 67353)
+++ trunk/Master/texmf-dist/doc/latex/string-diagrams/README.md	2023-06-13 20:17:59 UTC (rev 67354)
@@ -31,28 +31,6 @@
 
 ### Usage
 
-After including the package in your preamble, you can craft your string diagrams in a `tikzpicture` environment:
-
-```latex
-\usepackage{string-diagrams}
-
-%...
-
-\begin{tikzpicture}
-  \node[box] (a) {a};
-  \node[box] (b) at (0,-2) {b};
-  \node[dot] (x) at (1,-1) {};
-  \node[dot] (y) at (-1,-1) {};
-  \wires[]{
-    a = { east = x.north },
-    b = { east0 = x.south },
-    y = { north = a.west1, south = b.west },
-  }{
-    a.west0, b.east1, x.east, y.west
-  }
-\end{tikzpicture}
-```
-
 Detailed instructions are available in the [documentation](http://mirrors.ctan.org/graphics/pgf/contrib/string-diagrams/string-diagrams.pdf).
 
 ## Contributing

Modified: trunk/Master/texmf-dist/doc/latex/string-diagrams/string-diagrams.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/source/latex/string-diagrams/string-diagrams.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/string-diagrams/string-diagrams.dtx	2023-06-13 16:08:38 UTC (rev 67353)
+++ trunk/Master/texmf-dist/source/latex/string-diagrams/string-diagrams.dtx	2023-06-13 20:17:59 UTC (rev 67354)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %% =============================================================================
 %%
-%% string-diagrams 0.1.0 (2023/05/31)
+%% string-diagrams 0.2.0 (2023/06/12)
 %%
 %% Copyright (C) 2023 by Paolo Brasolin <paolo.brasolin at gmail.com>
 %% SPDX-License-Identifier: LPPL-1.3c
@@ -27,6 +27,7 @@
 %%                                  string-diagrams.pdf.
 %%
 %% =============================================================================
+%%
 %
 % %%%=[ INSTALL ]===============================================================
 %
@@ -72,6 +73,8 @@
 %
 %<*driver>
 \documentclass[a4paper,full]{l3doc}
+\usepackage{parskip}
+
 \EnableCrossrefs
 \CodelineIndex
 \RecordChanges
@@ -84,7 +87,7 @@
 
 \lstset{
   language=[LaTeX]TeX,
-  basicstyle=\ttfamily\small,
+  basicstyle=\MacroFont,
   columns=flexible,
   ^^A keywordstyle=\color{red},
   ^^A morekeywords={},
@@ -104,7 +107,7 @@
   sidebyside,
   lefthand ratio=0.62,
   listing options={
-    xleftmargin=-0.6em, % poor man's gobble=4
+    xleftmargin=-1.6em, % poor man's gobble=4
   },
 }}
 
@@ -117,7 +120,8 @@
 %
 % \fi
 %
-% \changes{0.1.0}{2023/05/31}{Initial version}
+% \changes{0.1.0}{2023/05/31}{initial version}
+% \changes{0.2.0}{2023/06/12}{make box ports configurable}
 %
 % \GetFileInfo{\jobname.sty}
 %
@@ -150,69 +154,147 @@
 % The upside is that this is the best time to \href{https://github.com/paolobrasolin/string-diagrams#contributing}{contribute}!
 % Of course you can also just keep the \texttt{sty} along with your code and not care at all.
 % \end{tcolorbox}
-% 
 %
+%
 % \section{Documentation}
 %
-% Let's walk through the features by example.
+% \begin{function}[added=2023-05-31,updated=2023-06-12]{/pgf/box}
 %
+%   To draw boxes, you use this style on a node.
 %
-% To draw boxes, you use the \texttt{box} style on a node.
+%   \begin{tcblisting}{example}
+%     \begin{tikzpicture}
+%       \node[box] {A};
+%     \end{tikzpicture}
+%   \end{tcblisting}
 %
-% \begin{tcblisting}{example}
-%   \begin{tikzpicture}
-%     \node[box] {A};
-%   \end{tikzpicture}
-% \end{tcblisting}
+%   You can draw multiple boxes using any of your standard Ti\emph{k}Z positioning techniques.
+%   Don't forget to label the nodes so you can easily reference them.
 %
-% You can draw multiple boxes using any of your standard Ti\emph{k}Z positioning techniques.
-% Don't forget to label the nodes so you can easily reference them.
+%   \begin{tcblisting}{example}
+%     \begin{tikzpicture}
+%       \node[box] (A) at (0,0) {A};
+%       \node[box, right of=A] (B) {B};
+%       \node[box] (C) at ($(B)+(2cm,1em)$) {C};
+%     \end{tikzpicture}
+%   \end{tcblisting}
+% \end{function}
 %
-% \begin{tcblisting}{example}
-%   \begin{tikzpicture}
-%     \node[box] (A) at (0,0) {A};
-%     \node[box, right of=A] (B) {B};
-%     \node[box] (C) at ($(B)+(2cm,1em)$) {C};
-%   \end{tikzpicture}
-% \end{tcblisting}
+% \begin{function}[added=2023-06-12]{
+%   /pgf/box ports north,
+%   /pgf/box ports east,
+%   /pgf/box ports south,
+%   /pgf/box ports west,
+% }
+%   \begin{syntax}
+%     /pgf/box ports north=\meta{integer}
+%     /pgf/box ports east=\meta{integer}
+%     /pgf/box ports south=\meta{integer}
+%     /pgf/box ports west=\meta{integer}
+%   \end{syntax}
 %
-% To connect boxes, you can use the \cmd\wires\ macro.
-% The first argument is Ti\emph{k}Z styling for the wires; the second argument is a nested dicionary specifying the connectivity; the third argument is a list of the loose ends to draw.
-% \texttt{box}es have the following anchors: \texttt{west}, \texttt{west0}, \texttt{west1},  \texttt{east}, \texttt{east0}, and \texttt{east1}.
+%   You can open up any number of ports on any side of a box using the appropriate key.
+%   Then, you can refer to the opened ports by their index.
 %
-% \begin{tcblisting}{example}
-%   \begin{tikzpicture}[scale=0.6]
-%     \node[box] (A) at (-2, 0) {A};
-%     \node[box] (B) at (+2, 0) {B};
-%     \node[box] (C) at ( 0,+1) {C};
-%     \node[box] (D) at ( 0,-1) {D};
-%     \wires[]{
-%       A = { east0 = C.west, east1 = D.west },
-%       C = { east = B.west0 },
-%       D = { east = B.west1 },
-%     }{ A.west, B.east }
-%   \end{tikzpicture}
-% \end{tcblisting}
+%   \begin{tcblisting}{example,lefthand ratio=0.8}
+%     \begin{tikzpicture}[
+%       marker/.style={circle, fill, inner sep=1pt, text=white},
+%     ]
 %
-% To split and join wires, you can use \texttt{dot}s and their anchors \texttt{north}, \texttt{east}, \texttt{south}, and \texttt{west}.
-% Remember to have fun with styling wires.
+%     \node[
+%       box,
+%       box ports north=3,
+%       box ports east=3,
+%       box ports south=3,
+%       box ports west=3,
+%       minimum width=6em,
+%       minimum height=6em,
+%     ] (A) {A};
 %
-% \begin{tcblisting}{example}
-%   \begin{tikzpicture}
-%     \node[box] (A) at ( 0,+1) {A};
-%     \node[box] (B) at ( 0,-1) {B};
-%     \node[dot] (x) at (+1, 0) {};
-%     \node[dot] (y) at (-1, 0) {};
-%     \wires[looseness=1.5, dashed]{
-%       A = { east = x.north },
-%       B = { east0 = x.south },
-%       y = { north = A.west1, south = B.west },
-%     }{
-%       A.west0, B.east1, x.east, y.west
-%     }
-%   \end{tikzpicture}
-% \end{tcblisting}
+%     \foreach \side in {north,east,south,west}
+%       \foreach \index in {1,...,3}
+%         \node[marker] at (A.\side.\index) {\index};
 %
+%     \end{tikzpicture}
+%   \end{tcblisting}
+%
+% \end{function}
+%
+% \begin{function}[added=2023-06-12]{
+%   /pgf/box ports,
+% }
+%   \begin{syntax}
+%     /pgf/box ports=\meta{integer}/\meta{integer}/\meta{integer}/\meta{integer}
+%   \end{syntax}
+%
+%   The \texttt{box ports} key is a shortcut to set the number of ports on all sides at once.
+%
+%   \begin{tcblisting}{example,lefthand ratio=0.8}
+%     \begin{tikzpicture}[
+%       marker/.style={circle, fill, inner sep=1pt},
+%     ]
+%
+%     \node[box, box ports=1/2/3/4] (A) {A};
+%
+%     \foreach \side/\n in {north/1,east/2,south/3,west/4}
+%       \foreach \index in {1,...,\n}
+%         \node[marker] at (A.\side.\index) {};
+%
+%     \end{tikzpicture}
+%   \end{tcblisting}
+%
+%   The same value can also be passed to the \texttt{box} key itself.
+%
+% \end{function}
+%
+% \begin{function}[added=2023-05-31]{\wires}
+%   \begin{syntax}
+%     \cs{wires}\oarg{Ti\emph{k}Z keys}\marg{connectivity}\marg{loose ends}
+%   \end{syntax}
+%
+%   To connect boxes, you can use the \cmd\wires\ macro.
+%   The first argument is Ti\emph{k}Z styling for the wires; the second argument is a nested dicionary specifying the connectivity; the third argument is a list of the loose ends to draw.
+%   \texttt{box}es have the following anchors: \texttt{west}, \texttt{west.0}, \texttt{west.1},  \texttt{east}, \texttt{east.0}, and \texttt{east.1}.
+%
+%   \begin{tcblisting}{example}
+%     \begin{tikzpicture}[scale=0.6]
+%       \node[box=0/2/0/1] (A) at (-2, 0) {A};
+%       \node[box=0/1/0/2] (B) at (+2, 0) {B};
+%       \node[box=0/1/0/1] (C) at ( 0,+1) {C};
+%       \node[box=0/1/0/1] (D) at ( 0,-1) {D};
+%       \wires[]{
+%         A = { east.1 = C.west, east.2 = D.west },
+%         C = { east = B.west.1 },
+%         D = { east = B.west.2 },
+%       }{ A.west, B.east }
+%     \end{tikzpicture}
+%   \end{tcblisting}
+%
+% \end{function}
+%
+% \begin{function}[added=2023-05-31]{/pgf/dot}
+%
+%   To split and join wires, you can use \texttt{dot}s and their anchors \texttt{north}, \texttt{east}, \texttt{south}, and \texttt{west}.
+%   Remember to have fun with styling wires.
+%
+%   \begin{tcblisting}{example}
+%     \begin{tikzpicture}
+%       \node[box=0/1/0/2] (A) at ( 0,+1) {A};
+%       \node[box=0/2/0/1] (B) at ( 0,-1) {B};
+%       \node[dot] (x) at (+1, 0) {};
+%       \node[dot] (y) at (-1, 0) {};
+%       \wires[looseness=1.5, dashed]{
+%         A = { east = x.north },
+%         B = { east.1 = x.south },
+%         y = { north = A.west.2, south = B.west },
+%       }{
+%         A.west.1, B.east.2, x.east, y.west
+%       }
+%     \end{tikzpicture}
+%   \end{tcblisting}
+%
+% \end{function}
+%
 % That's it. This is the package, for now.
 %
 % \end{documentation}
@@ -223,13 +305,9 @@
 %
 % \section{Implementation}
 %
-% Open the \pkg{DocStrip} guards.
+% Open the \pkg{DocStrip} guards and set the internal namespace prefix (as per \LaTeX3 \pkg{DocStrip} convention).
 %    \begin{macrocode}
 %<*package>
-%    \end{macrocode}
-%
-% Identify the internal prefix (\LaTeX3 \pkg{DocStrip} convention).
-%    \begin{macrocode}
 %<@@=stridi>
 %    \end{macrocode}
 %
@@ -244,57 +322,140 @@
 %    \begin{macrocode}
 \ProvidesExplPackage
   {string-diagrams}
-  {2023/05/31}
-  {0.1.0}
+  {2023/06/12}
+  {0.2.0}
   {Draw string diagrams using TikZ}
 %    \end{macrocode}
 %
-% Define a shape with useful anchor points.
+%  \begin{macro}{
+%    /pgf/box ports north,
+%    /pgf/box ports east,
+%    /pgf/box ports south,
+%    /pgf/box ports west,
+%    /pgf/box ports,
+%  }
+%
+%    Define high level keys to configure the number of ports on each side.
 %    \begin{macrocode}
+\pgfkeys{
+  /pgf/box~ports~north/.initial=1,
+  /pgf/box~ports~east/.initial=1,
+  /pgf/box~ports~south/.initial=1,
+  /pgf/box~ports~west/.initial=1,
+  /pgf/box~ports/.style~args={#1/#2/#3/#4}{
+    /pgf/box~ports~north=#1,
+    /pgf/box~ports~east=#2,
+    /pgf/box~ports~south=#3,
+    /pgf/box~ports~west=#4,
+  },
+}
+%    \end{macrocode}
+%  \end{macro}
+%
+%  \begin{macro}{\@@_intersect_hv_lines_through:NN}
+%    Calculates the intersection of two lines parallel to axes passing through given points on the plane.
+%    \begin{arguments}
+%      \item Point through which the vertical line passes
+%      \item Point through which the horizontal line passes
+%    \end{arguments}
+%    \begin{macrocode}
+\cs_new:Nn \@@_intersect_hv_lines_through:NN {
+  \pgfextractx { \pgf at xa } { #1 }
+  \pgfextracty { \pgf at ya } { #2 }
+  \pgfpoint { \pgf at xa } { \pgf at ya }
+}
+%    \end{macrocode}
+%  \end{macro}
+%
+% \begin{macro}{\@@_subdivide_segment:nNNNNN}
+%   Defines macros numbering equally spaced points on a segment.
+%   \begin{arguments}
+%     \item Base namespace
+%     \item Points count
+%     \item Point containing the x coordinate of the starting point
+%     \item Point containing the y coordinate of the starting point
+%     \item Point containing the x coordinate of the ending point
+%     \item Point containing the y coordinate of the ending point
+%   \end{arguments}
+%    \begin{macrocode}
+\cs_new:Nn \@@_subdivide_segment:nNNNNN {
+  \int_step_inline:nnnn { #2 } { -1 } { 1 } {
+    \cs_if_exist:cTF
+      { #1.##1 }
+      { \prg_break: }
+      { \prg_do_nothing: }
+    \cs_new_nopar:cpn
+      { #1.##1 }
+      {
+        \pgfmathdivide
+          { 2 * ##1 - 1 }
+          { 2 * #2 }
+        \pgfpointlineattime
+          { \pgfmathresult }
+          { \@@_intersect_hv_lines_through:NN { #3 } { #4 } }
+          { \@@_intersect_hv_lines_through:NN { #5 } { #6 } }
+      }
+  }
+}
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{box}
+%   \changes{0.2.0}{2023/06/12}{make ports configurable through Ti\emph{k}Z keys}
+%
+%   Define a rectangular shape with configurable ports.
+%    \begin{macrocode}
 \pgfdeclareshape{box}{
-  \inheritbackgroundpath[from=rectangle]
+
+  % Inherit all the structure of rectangle
   \inheritsavedanchors[from=rectangle]
+  \clist_map_inline:nn
+    {
+      north~west,  north, north~east,
+            west, center,       east,
+        mid~west,    mid,   mid~east,
+       base~west,   base,  base~east,
+      south~west,  south, south~east,
+    }
+    { \inheritanchor[from=rectangle]{#1} }
   \inheritanchorborder[from=rectangle]
-  \inheritanchor[from=rectangle]{center}
-  \inheritanchor[from=rectangle]{north}
-  \inheritanchor[from=rectangle]{south}
-  \inheritanchor[from=rectangle]{west}
-  \inheritanchor[from=rectangle]{east}
-  \anchor{east0}{
-    \pgf at process{\southwest}
-    \pgf at ya=0.25\pgf at y
-    \pgf at process{\northeast}
-    \pgf at y=0.75\pgf at y
-    \advance\pgf at y by \pgf at ya
+  \inheritbackgroundpath[from=rectangle]
+
+  % Dump port counts into saved macros
+  \savedmacro\portsnorth
+    {\pgfmathtruncatemacro\portsnorth{\pgfkeysvalueof{/pgf/box~ports~north}}}
+  \savedmacro\portseast
+    {\pgfmathtruncatemacro\portseast{\pgfkeysvalueof{/pgf/box~ports~east}}}
+  \savedmacro\portssouth
+    {\pgfmathtruncatemacro\portssouth{\pgfkeysvalueof{/pgf/box~ports~south}}}
+  \savedmacro\portswest
+    {\pgfmathtruncatemacro\portswest{\pgfkeysvalueof{/pgf/box~ports~west}}}
+
+  % Add ports definitions to shape definition
+  \expandafter\pgfutil at g@addto at macro\csname pgf at sh@s at box\endcsname{
+    \@@_subdivide_segment:nNNNNN { pgf at anchor@box at north } { \portsnorth }
+      { \southwest } { \northeast } { \northeast } { \northeast }
+    \@@_subdivide_segment:nNNNNN { pgf at anchor@box at east } { \portseast }
+      { \northeast } { \northeast } { \northeast } { \southwest }
+    \@@_subdivide_segment:nNNNNN { pgf at anchor@box at south } { \portssouth }
+      { \southwest } { \southwest } { \northeast } { \southwest }
+    \@@_subdivide_segment:nNNNNN { pgf at anchor@box at west } { \portswest }
+      { \southwest } { \northeast } { \southwest } { \southwest }
   }
-  \anchor{east1}{
-    \pgf at process{\southwest}
-    \pgf at ya=0.75\pgf at y
-    \pgf at process{\northeast}
-    \pgf at y=0.25\pgf at y
-    \advance\pgf at y by \pgf at ya
-  }
-  \anchor{west0}{
-    \pgf at process{\northeast}
-    \pgf at ya=0.75\pgf at y
-    \pgf at process{\southwest}
-    \pgf at y=0.25\pgf at y
-    \advance\pgf at y by \pgf at ya
-  }
-  \anchor{west1}{
-    \pgf at process{\northeast}
-    \pgf at ya=0.25\pgf at y
-    \pgf at process{\southwest}
-    \pgf at y=0.75\pgf at y
-    \advance\pgf at y by \pgf at ya
-  }
+
 }
 %    \end{macrocode}
-% Define styles to draw boxes and dots.
+% \end{macro}
+%
+% \begin{macro}{/pgf/box}
+%   \changes{0.2.0}{2023/06/12}{acts as a shortcut for setting port counts}
+%
+%   Define style to draw boxes.
 %    \begin{macrocode}
 \ExplSyntaxOff
 \tikzset{
-  box/.style={
+  box/.default={0/0/0/0},
+  box/.style args={#1}{
     shape=box,
     draw,
     inner sep=.5em,
@@ -302,7 +463,19 @@
     minimum height=2em,
     execute at begin node=$,
     execute at end node=$,
+    /pgf/box ports=#1,
   },
+}
+\ExplSyntaxOn
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{/pgf/dot}
+%
+%   Define style to draw dots.
+%    \begin{macrocode}
+\ExplSyntaxOff
+\tikzset{
   dot/.style={
     shape=circle,
     fill,
@@ -312,9 +485,10 @@
 }
 \ExplSyntaxOn
 %    \end{macrocode}
+% \end{macro}
 %
-% Define our main actor.
 % \begin{macro}{\wires}
+%   Define our main actor.
 %    \begin{macrocode}
 \NewDocumentCommand{\wires}{ o m m }
 {
@@ -363,8 +537,9 @@
 %    \end{macrocode}
 % \end{macro}
 %
-% \iffalse
+% Close the \pkg{DocStrip} guards and call it a day.
+%    \begin{macrocode}
 %</package>
-% \fi
+%    \end{macrocode}
+%
 % \end{implementation}
-%% =============================================================================

Modified: trunk/Master/texmf-dist/source/latex/string-diagrams/string-diagrams.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/string-diagrams/string-diagrams.ins	2023-06-13 16:08:38 UTC (rev 67353)
+++ trunk/Master/texmf-dist/source/latex/string-diagrams/string-diagrams.ins	2023-06-13 20:17:59 UTC (rev 67354)
@@ -8,7 +8,7 @@
 %% 
 %% =============================================================================
 %%
-%% string-diagrams 0.1.0 (2023/05/31)
+%% string-diagrams 0.2.0 (2023/06/12)
 %%
 %% Copyright (C) 2023 by Paolo Brasolin <paolo.brasolin at gmail.com>
 %% SPDX-License-Identifier: LPPL-1.3c
@@ -34,6 +34,7 @@
 %%                                  string-diagrams.pdf.
 %%
 %% =============================================================================
+%%
 \input l3docstrip.tex
 \keepsilent
 \askforoverwritefalse
@@ -46,4 +47,3 @@
 \generate{\file{\jobname.sty}{\from{\jobname.dtx}{package}}}
 
 \endbatchfile
-%% =============================================================================

Modified: trunk/Master/texmf-dist/tex/latex/string-diagrams/string-diagrams.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/string-diagrams/string-diagrams.sty	2023-06-13 16:08:38 UTC (rev 67353)
+++ trunk/Master/texmf-dist/tex/latex/string-diagrams/string-diagrams.sty	2023-06-13 20:17:59 UTC (rev 67354)
@@ -8,7 +8,7 @@
 %% 
 %% =============================================================================
 %%
-%% string-diagrams 0.1.0 (2023/05/31)
+%% string-diagrams 0.2.0 (2023/06/12)
 %%
 %% Copyright (C) 2023 by Paolo Brasolin <paolo.brasolin at gmail.com>
 %% SPDX-License-Identifier: LPPL-1.3c
@@ -34,54 +34,93 @@
 %%                                  string-diagrams.pdf.
 %%
 %% =============================================================================
+%%
 \RequirePackage{expl3}[2023/05/11]
 \RequirePackage{tikz}[2023/01/15]
 \ProvidesExplPackage
   {string-diagrams}
-  {2023/05/31}
-  {0.1.0}
+  {2023/06/12}
+  {0.2.0}
   {Draw string diagrams using TikZ}
+\pgfkeys{
+  /pgf/box~ports~north/.initial=1,
+  /pgf/box~ports~east/.initial=1,
+  /pgf/box~ports~south/.initial=1,
+  /pgf/box~ports~west/.initial=1,
+  /pgf/box~ports/.style~args={#1/#2/#3/#4}{
+    /pgf/box~ports~north=#1,
+    /pgf/box~ports~east=#2,
+    /pgf/box~ports~south=#3,
+    /pgf/box~ports~west=#4,
+  },
+}
+\cs_new:Nn \__stridi_intersect_hv_lines_through:NN {
+  \pgfextractx { \pgf at xa } { #1 }
+  \pgfextracty { \pgf at ya } { #2 }
+  \pgfpoint { \pgf at xa } { \pgf at ya }
+}
+\cs_new:Nn \__stridi_subdivide_segment:nNNNNN {
+  \int_step_inline:nnnn { #2 } { -1 } { 1 } {
+    \cs_if_exist:cTF
+      { #1.##1 }
+      { \prg_break: }
+      { \prg_do_nothing: }
+    \cs_new_nopar:cpn
+      { #1.##1 }
+      {
+        \pgfmathdivide
+          { 2 * ##1 - 1 }
+          { 2 * #2 }
+        \pgfpointlineattime
+          { \pgfmathresult }
+          { \__stridi_intersect_hv_lines_through:NN { #3 } { #4 } }
+          { \__stridi_intersect_hv_lines_through:NN { #5 } { #6 } }
+      }
+  }
+}
 \pgfdeclareshape{box}{
-  \inheritbackgroundpath[from=rectangle]
+
+  % Inherit all the structure of rectangle
   \inheritsavedanchors[from=rectangle]
+  \clist_map_inline:nn
+    {
+      north~west,  north, north~east,
+            west, center,       east,
+        mid~west,    mid,   mid~east,
+       base~west,   base,  base~east,
+      south~west,  south, south~east,
+    }
+    { \inheritanchor[from=rectangle]{#1} }
   \inheritanchorborder[from=rectangle]
-  \inheritanchor[from=rectangle]{center}
-  \inheritanchor[from=rectangle]{north}
-  \inheritanchor[from=rectangle]{south}
-  \inheritanchor[from=rectangle]{west}
-  \inheritanchor[from=rectangle]{east}
-  \anchor{east0}{
-    \pgf at process{\southwest}
-    \pgf at ya=0.25\pgf at y
-    \pgf at process{\northeast}
-    \pgf at y=0.75\pgf at y
-    \advance\pgf at y by \pgf at ya
+  \inheritbackgroundpath[from=rectangle]
+
+  % Dump port counts into saved macros
+  \savedmacro\portsnorth
+    {\pgfmathtruncatemacro\portsnorth{\pgfkeysvalueof{/pgf/box~ports~north}}}
+  \savedmacro\portseast
+    {\pgfmathtruncatemacro\portseast{\pgfkeysvalueof{/pgf/box~ports~east}}}
+  \savedmacro\portssouth
+    {\pgfmathtruncatemacro\portssouth{\pgfkeysvalueof{/pgf/box~ports~south}}}
+  \savedmacro\portswest
+    {\pgfmathtruncatemacro\portswest{\pgfkeysvalueof{/pgf/box~ports~west}}}
+
+  % Add ports definitions to shape definition
+  \expandafter\pgfutil at g@addto at macro\csname pgf at sh@s at box\endcsname{
+    \__stridi_subdivide_segment:nNNNNN { pgf at anchor@box at north } { \portsnorth }
+      { \southwest } { \northeast } { \northeast } { \northeast }
+    \__stridi_subdivide_segment:nNNNNN { pgf at anchor@box at east } { \portseast }
+      { \northeast } { \northeast } { \northeast } { \southwest }
+    \__stridi_subdivide_segment:nNNNNN { pgf at anchor@box at south } { \portssouth }
+      { \southwest } { \southwest } { \northeast } { \southwest }
+    \__stridi_subdivide_segment:nNNNNN { pgf at anchor@box at west } { \portswest }
+      { \southwest } { \northeast } { \southwest } { \southwest }
   }
-  \anchor{east1}{
-    \pgf at process{\southwest}
-    \pgf at ya=0.75\pgf at y
-    \pgf at process{\northeast}
-    \pgf at y=0.25\pgf at y
-    \advance\pgf at y by \pgf at ya
-  }
-  \anchor{west0}{
-    \pgf at process{\northeast}
-    \pgf at ya=0.75\pgf at y
-    \pgf at process{\southwest}
-    \pgf at y=0.25\pgf at y
-    \advance\pgf at y by \pgf at ya
-  }
-  \anchor{west1}{
-    \pgf at process{\northeast}
-    \pgf at ya=0.25\pgf at y
-    \pgf at process{\southwest}
-    \pgf at y=0.75\pgf at y
-    \advance\pgf at y by \pgf at ya
-  }
+
 }
 \ExplSyntaxOff
 \tikzset{
-  box/.style={
+  box/.default={0/0/0/0},
+  box/.style args={#1}{
     shape=box,
     draw,
     inner sep=.5em,
@@ -89,7 +128,12 @@
     minimum height=2em,
     execute at begin node=$,
     execute at end node=$,
+    /pgf/box ports=#1,
   },
+}
+\ExplSyntaxOn
+\ExplSyntaxOff
+\tikzset{
   dot/.style={
     shape=circle,
     fill,
@@ -142,4 +186,3 @@
     } { ##1 } {} {}
   }
 }
-%% =============================================================================



More information about the tex-live-commits mailing list.