summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/latex/adigraph
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2018-03-13 21:51:13 +0000
committerKarl Berry <karl@freefriends.org>2018-03-13 21:51:13 +0000
commiteb8ef25be547b60759a018127fc2676c21b02e6d (patch)
treefb51d59d5157abc414e1d90302e336d2427d630e /Master/texmf-dist/tex/latex/adigraph
parentf6fe5fa1202a5ac086787d0b2f99644e074f626e (diff)
adigraph (13mar18)
git-svn-id: svn://tug.org/texlive/trunk@46948 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/latex/adigraph')
-rw-r--r--Master/texmf-dist/tex/latex/adigraph/adigraph.sty280
1 files changed, 223 insertions, 57 deletions
diff --git a/Master/texmf-dist/tex/latex/adigraph/adigraph.sty b/Master/texmf-dist/tex/latex/adigraph/adigraph.sty
index 9e0f6c43215..c8e36669957 100644
--- a/Master/texmf-dist/tex/latex/adigraph/adigraph.sty
+++ b/Master/texmf-dist/tex/latex/adigraph/adigraph.sty
@@ -7,9 +7,11 @@
%
% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
%
+\def\AdigraphVersionNumber{v1.4.1}
+
\NeedsTeXFormat{LaTeX2e}[1994/06/01]
\ProvidesPackage{adigraph}
-[2018/03/10 v1.3 LaTeX package for creating augmenting directed graphs]
+[2018/03/11 \AdigraphVersionNumber LaTeX package for creating augmenting directed graphs]
\RequirePackage{etoolbox}
\RequirePackage{fp}
@@ -26,6 +28,9 @@
\newcounter{AdigraphCurrentNodeCounter}
\newcounter{AdigraphNumberOfPaths}
\newcounter{AdigraphCurrentPathNumber}
+\newcounter{AdigraphAdjacentNodes}
+
+\def\AdigraphZero{0}
\NewDocumentCommand{\AdigraphDrawNode}{m}{%
%
@@ -39,6 +44,8 @@
\node[vertex,\nodeColor] (#1) at (\nodeX,\nodeY) {\nodeLabel};
}
+\NewDocumentCommand{\sumOfOrientations}{m}{}
+
\NewDocumentCommand{\AdigraphDrawEdge}{m m}{%
%
% #1 is first node normalized id
@@ -93,24 +100,86 @@
\ifcsdef{adigraphEdge#2v#1Weight}{%
\letcs{\AdigraphTwinEdgeWeight}{adigraphEdge#2v#1Weight}
}{%
- \def\AdigraphTwinEdgeWeight{0}
+ \let\AdigraphTwinEdgeWeight\AdigraphZero
}
+ \providebool{firstWeight}
+ \FPifeq{\edgeWeight}{0}
+ \booltrue{firstWeight}
+ \else
+ \boolfalse{firstWeight}
+ \fi
+
+ \providebool{secondWeight}
+ \FPifeq{\AdigraphTwinEdgeWeight}{0}
+ \booltrue{secondWeight}
+ \else
+ \boolfalse{secondWeight}
+ \fi
+
\letcs{\edgeColor}{adigraphEdge#1v#2Color}
\ifbool{adigraphEdge#1v#2HasLabel}{%
\letcs{\edgeLabel}{adigraphEdge#1v#2Label}
}{%
\letcs{\edgeLabel}{adigraphEdge#1v#2Weight}
}
- \ifnumequal{\edgeWeight}{0}{%
+ \ifbool{firstWeight}{%
% We don't draw edges with weight 0
}{%
- \ifnumequal{\AdigraphTwinEdgeWeight}{0}{%
+ \ifbool{secondWeight}{%
% The twin edge won't be drawn
% This edge will be a straight line
\draw[edge,\edgeColor] (#1) to node[\edgeLabelPosition, \AdigraphLabelPosition] {\edgeLabel}(#2);
}{%
- % Both edges have to be drawn, they will be curly
- \draw[edge,\edgeColor] (#1) to [bend right=20] node[\edgeLabelPosition, \AdigraphLabelPosition] {\edgeLabel}(#2);
+ \IfEq{#1}{#2}{
+ % This is a self loop
+ \def\mySinSum{0}
+ \def\myCosSum{0}
+ \setcounter{AdigraphAdjacentNodes}{0}
+ \RenewDocumentCommand{\sumOfOrientations}{m}{
+ %
+ % #1 is name of node
+ %
+ \IfEq{#1}{##1}{
+ % This is the autoloop
+ }{
+ \newcount\myedgecounter
+ \myedgecounter 0\relax
+ \ifcsdef{adigraphEdge#1v##1Weight}{
+ \advance\myedgecounter 1\relax
+ }{}
+ \ifcsdef{adigraphEdge##1v#1Weight}{
+ \advance\myedgecounter 1\relax
+ }{}
+ \ifnumgreater{\the\myedgecounter}{0}{
+ \stepcounter{AdigraphAdjacentNodes}
+ \letcs{\firstX}{adigraphNode#1X}
+ \letcs{\firstY}{adigraphNode#1Y}
+ \letcs{\secondX}{adigraphNode##1X}
+ \letcs{\secondY}{adigraphNode##1Y}
+ \pgfmathsetmacro{\mySinSum}{\mySinSum+sin(atan2(\secondY-\firstY,\secondX-\firstX))}
+ \pgfmathsetmacro{\myCosSum}{\myCosSum+cos(atan2(\secondY-\firstY,\secondX-\firstX))}
+ }{}
+ }
+ }
+ \forlistloop{\sumOfOrientations}{\AdigraphNodeList}
+ \newcount\nodesNumber
+ \nodesNumber \value{AdigraphAdjacentNodes}\relax
+ \IfEq{\the\nodesNumber}{0}{
+ %No elements
+ \pgfmathsetmacro{\centralAngle}{0}
+ }{
+ \newcount\nodesNumber
+ \nodesNumber \value{AdigraphAdjacentNodes}\relax
+ \pgfmathsetmacro{\meanAngle}{atan2(\mySinSum/\the\nodesNumber,\myCosSum/\the\nodesNumber)}
+ \pgfmathsetmacro{\centralAngle}{180+360-max(\meanAngle,360-(\meanAngle))}
+ }
+ \pgfmathsetmacro{\leftAngle}{\centralAngle-35}
+ \pgfmathsetmacro{\rightAngle}{\centralAngle+35}
+ \draw[edge,\edgeColor] (#1) to [out=\leftAngle,in=\rightAngle,looseness=8] node[\edgeLabelPosition, \AdigraphLabelPosition] {\edgeLabel}(#1);
+ }{
+ % Both edges have to be drawn, they will be curly
+ \draw[edge,\edgeColor] (#1) to [bend right=20] node[\edgeLabelPosition, \AdigraphLabelPosition] {\edgeLabel}(#2);
+ }
}%
}%
}
@@ -128,10 +197,10 @@
\RenewDocumentCommand{\AdigraphGenerateNodeName}{m G{black}}{%
\IfInteger{##1}{%
\def\AdigraphNodeName{\AdigraphRom{##1}}%
- \listgadd{\AdigraphNodeList}{\AdigraphRom{##1}}
+ \listxadd{\AdigraphNodeList}{\AdigraphRom{##1}}
}{%
\def\AdigraphNodeName{##1}%
- \listgadd{\AdigraphNodeList}{##1}
+ \listxadd{\AdigraphNodeList}{##1}
}%
\csdef{adigraphNode\AdigraphNodeName Color}{##2}%
\ifblank{#3}{
@@ -179,38 +248,56 @@
%
\RenewDocumentCommand{\AdigraphMemorizeEdge}{m m G{black}}{%
\IfInteger{##1}{%
- \IfInteger{##2}{%
- \def\AdigraphEdgeName{\AdigraphRom{##1}v\AdigraphRom{##2}}%
- \listgadd{\AdigraphEdgeList}{\AdigraphRom{##1},\AdigraphRom{##2}}
- }{%
- \def\AdigraphEdgeName{\AdigraphRom{##1}v##2}%
- \listgadd{\AdigraphEdgeList}{\AdigraphRom{##1},##2}
- }%
- }{%
- \IfInteger{##2}{%
- \def\AdigraphEdgeName{##1v\AdigraphRom{##2}}%
- \listgadd{\AdigraphEdgeList}{##1,\AdigraphRom{##2}}
- }{%
- \def\AdigraphEdgeName{##1v##2}%
- \listgadd{\AdigraphEdgeList}{##1,##2}
- }%
- }%
- \newbool{adigraphEdge\AdigraphEdgeName HasLabel}
- \newbool{adigraphEdge\AdigraphEdgeName Drawn}
- \ifblank{#3}{%
- \boolfalse{adigraphEdge\AdigraphEdgeName HasLabel}
+ \csedef{AdigraphFirstNode}{\AdigraphRom{##1}}%
}{%
- \booltrue{adigraphEdge\AdigraphEdgeName HasLabel}
+ \csedef{AdigraphFirstNode}{##1}%
}%
- \ifblank{#2}{%
- \booltrue{adigraphEdge\AdigraphEdgeName HasLabel}
- \csdef{adigraphEdge\AdigraphEdgeName Weight}{1}%
+ \IfInteger{##2}{%
+ \csedef{AdigraphSecondNode}{\AdigraphRom{##2}}%
}{%
- \csdef{adigraphEdge\AdigraphEdgeName Weight}{#2}%
+ \csedef{AdigraphSecondNode}{##2}%
}%
- \csdef{adigraphEdge\AdigraphEdgeName Label}{#3}%
- \csdef{adigraphEdge\AdigraphEdgeName Color}{##3}%
- \csdef{adigraphEdge\AdigraphEdgeName LabelPosition}{#4}%
+
+ \xifinlist{\AdigraphFirstNode,\AdigraphSecondNode}{\AdigraphEdgeList}{
+ %This edge was previously added
+ }{
+ \xifinlist{\AdigraphFirstNode}{\AdigraphNodeList}{
+ \xifinlist{\AdigraphSecondNode}{\AdigraphNodeList}{
+ %This edge is new
+ \csedef{AdigraphEdgeName}{\AdigraphFirstNode v\AdigraphSecondNode}
+ \listxadd{\AdigraphEdgeList}{\AdigraphFirstNode,\AdigraphSecondNode}
+
+ \newbool{adigraphEdge\AdigraphEdgeName HasLabel}
+ \newbool{adigraphEdge\AdigraphEdgeName Drawn}
+ \ifblank{#3}{%
+ \boolfalse{adigraphEdge\AdigraphEdgeName HasLabel}
+ }{%
+ \booltrue{adigraphEdge\AdigraphEdgeName HasLabel}
+ }%
+ \ifblank{#2}{%
+ \booltrue{adigraphEdge\AdigraphEdgeName HasLabel}
+ \csdef{adigraphEdge\AdigraphEdgeName Weight}{1}%
+ }{%
+ \csdef{adigraphEdge\AdigraphEdgeName Weight}{#2}%
+ }%
+ \csdef{adigraphEdge\AdigraphEdgeName Label}{#3}%
+ \csdef{adigraphEdge\AdigraphEdgeName Color}{##3}%
+ \csdef{adigraphEdge\AdigraphEdgeName LabelPosition}{#4}%
+ }{
+ \PackageError{adigraph}{%
+ The given edge ends in the node ##2, that does not exist.
+ }{%
+ You have to create the node ##2.
+ }
+ }
+ }{
+ \PackageError{adigraph}{%
+ The given edge starts from the node ##1, that does not exist.
+ }{%
+ You have to create the node ##1.
+ }
+ }
+ }
}
\AdigraphMemorizeEdge#1
}
@@ -237,10 +324,14 @@
% #2 -> Second addendum
% #3 -> Variable to store sum
%
- \newcount\AdigraphCounter
- \AdigraphCounter #1\relax
- \advance\AdigraphCounter #2\relax
- \FPset{#3}{\the\AdigraphCounter}
+ \pgfmathsetmacro{\sat}{#1+#2}
+ \pgfmathfrac{\sat}
+ \IfEq{\pgfmathresult}{0.0}{
+ \pgfmathint{\sat}
+ \FPset{#3}{\pgfmathresult}
+ }{
+ \FPset{#3}{\sat}
+ }
}
\NewDocumentCommand{\AdigraphPathBuilder}{m m m}{%
@@ -333,6 +424,81 @@
\AdigraphBuildEdgeWrapper#1
}
+
+
+\NewDocumentCommand{\AdigraphApplyKleenePlusEdgeBuilder}{m}{%
+ %
+ % #1 -> element
+ %
+ \ifblank{#1}{
+ %end of list
+ }{
+ \IfSubStr{\AdigraphCurrentElaboratingEdge}{,#1,}{
+ %The node is already contained
+ }{
+ \IfSubStr{\AdigraphCurrentElaboratingEdge}{,#1}{
+ %The node is already contained
+ }{
+ \IfSubStr{\AdigraphCurrentElaboratingEdge}{#1,}{
+ \StrPosition{\AdigraphCurrentElaboratingEdge}{#1,}[\stringPosition]
+ \ifnumequal{\stringPosition}{1}{
+ %This is at the beginning of the list
+ }{
+ \StrSubstitute[1]{\AdigraphCurrentElaboratingEdge}{+}{#1}[\temp]%
+ \expandafter\AdigraphFirstEdgeRenormalizer\expandafter{\temp}
+ }
+ }{
+ \StrSubstitute[1]{\AdigraphCurrentElaboratingEdge}{+}{#1}[\temp]%
+ \expandafter\AdigraphFirstEdgeRenormalizer\expandafter{\temp}
+ }
+ }
+ }
+ }
+}
+
+\NewDocumentCommand{\AdigraphKleenePlusEdgeBuilder}{m}{%
+ \ifrmnum{#1}{
+ \def\AdigraphTempList{}
+ \listeadd{\AdigraphTempList}{\rmntonum{#1}}
+ \forlistloop{\AdigraphApplyKleenePlusEdgeBuilder}{\AdigraphTempList}
+ }{
+ \AdigraphApplyKleenePlusEdgeBuilder{#1}
+ }
+}
+
+\NewDocumentCommand{\AdigraphSecondEdgeRenormalizer}{m}{%
+ \xifinlist{+}{\AdigraphNodeList}{
+ %The plus is not a kleene sign, but a symbol for a node
+ \AdigraphEdgeBuilder{#1}
+ }{
+ \IfSubStr{#1}{+}{
+ \def\AdigraphCurrentElaboratingEdge{#1}
+ \forlistloop{\AdigraphKleenePlusEdgeBuilder}{\AdigraphNodeList}
+ }{
+ \AdigraphEdgeBuilder{#1}
+ }
+ }
+}
+
+\NewDocumentCommand{\AdigraphKleeneStarEdgeBuilder}{m}{%
+ \StrSubstitute[1]{\AdigraphCurrentElaboratingEdge}{*}{#1}[\temp]%
+ \expandafter\AdigraphFirstEdgeRenormalizer\expandafter{\temp}
+}
+
+\NewDocumentCommand{\AdigraphFirstEdgeRenormalizer}{m}{%
+ \xifinlist{*}{\AdigraphNodeList}{
+ %The asterisk is not a kleene sign, but a symbol for a node
+ \AdigraphSecondEdgeRenormalizer{#1}
+ }{
+ \IfSubStr{#1}{*}{
+ \def\AdigraphCurrentElaboratingEdge{#1}
+ \forlistloop{\AdigraphKleeneStarEdgeBuilder}{\AdigraphNodeList}
+ }{
+ \AdigraphSecondEdgeRenormalizer{#1}
+ }
+ }
+}
+
\NewDocumentCommand{\AdigraphEdgeDrawer}{ > { \SplitArgument{ 1 } {,} } m }{%
\AdigraphDrawEdge#1
}
@@ -363,7 +529,7 @@
}
\NewDocumentCommand{\AdigraphProcessEdges}{> { \SplitList{;} } m}{%
- \ProcessList{#1}{\AdigraphEdgeBuilder}
+ \ProcessList{#1}{\AdigraphFirstEdgeRenormalizer}
}
\NewDocumentCommand{\AdigraphProcessPaths}{> { \SplitArgument{ 1 } {:} } m}{%
@@ -375,6 +541,8 @@
\stepcounter{AdigraphNumberOfPaths}
}
+\NewDocumentCommand{\AdigraphCalculateInclination}{m m m}{}
+
\NewDocumentCommand{\AdigraphCalculateOrientation}{m m m}{%
\letcs{\firstX}{adigraphNode#2X}
\letcs{\firstY}{adigraphNode#2Y}
@@ -382,20 +550,18 @@
\letcs{\secondY}{adigraphNode#3Y}
\providebool{equalX}
- \FPifeq{\firstX}{\secondX}
+ \pgfmathsetmacro{\deltaX}{\secondX-\firstX}
+ \FPifeq{\deltaX}{0}
\booltrue{equalX}
\else
\boolfalse{equalX}
\fi
- \ifnumequal{\secondX-\firstX}{0}{%
+
+ \ifbool{equalX}{%
\FPset{#1}{90}
}{%
- \FPsub{\deltaY}{\secondY}{\firstY}
- \FPsub{\deltaX}{\secondX}{\firstX}
- \FPdiv{\deltaDiv}{\deltaY}{\deltaX}
- \FParctan{\arcResult}{\deltaDiv}
- \FPmul{#1}{\arcResult}{57.2958}
+ \pgfmathsetmacro{#1}{57.2958*atan((\secondY-\firstY)/(\deltaX))}
}
}
@@ -475,11 +641,11 @@
}
% %cuts
- % \ifblank{#4}{%
- % % List is empty
- % }{%
- % \AdigraphProcessCuts{#4}
- % }
+ \ifblank{#4}{%
+ % List is empty
+ }{%
+ \AdigraphProcessCuts{#4}
+ }
\end{tikzpicture}
}
@@ -500,10 +666,10 @@
}
}{
\csdef{Adigraph#1AugmentingPaths}{}%
- \expandafter\RenewDocumentCommand{\AdigraphProcessAugmentingPaths}{m}{%
+ \RenewDocumentCommand{\AdigraphProcessAugmentingPaths}{m}{%
\listcsgadd{Adigraph#1AugmentingPaths}{##1}
}
- \expandafter\RenewDocumentCommand{\AdigraphProcessAugmentingPathsList}{> { \SplitList{;} } m}{%
+ \RenewDocumentCommand{\AdigraphProcessAugmentingPathsList}{> { \SplitList{;} } m}{%
\AdigraphProcessAugmentingPaths##1
}
\expandafter\NewDocumentCommand\expandafter{\csname #1\endcsname}{m G{}}{%
@@ -528,10 +694,10 @@
%
\ifcsdef{#1}{
\csdef{Adigraph#1AugmentingPaths}{}%
- \expandafter\RenewDocumentCommand{\AdigraphProcessAugmentingPaths}{m}{%
+ \RenewDocumentCommand{\AdigraphProcessAugmentingPaths}{m}{%
\listcsgadd{Adigraph#1AugmentingPaths}{##1}
}
- \expandafter\RenewDocumentCommand{\AdigraphProcessAugmentingPathsList}{> { \SplitList{;} } m}{%
+ \RenewDocumentCommand{\AdigraphProcessAugmentingPathsList}{> { \SplitList{;} } m}{%
\AdigraphProcessAugmentingPaths##1
}
\expandafter\RenewDocumentCommand\expandafter{\csname #1\endcsname}{m G{}}{%