From 8f6a85906eed05ad9e0bf213a1232b24ab5f5d71 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Fri, 9 Mar 2018 22:45:46 +0000 Subject: adigraph (9mar18) git-svn-id: svn://tug.org/texlive/trunk@46901 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/tex/latex/adigraph/adigraph.sty | 679 ++++++++++++---------- 1 file changed, 375 insertions(+), 304 deletions(-) (limited to 'Master/texmf-dist/tex/latex/adigraph') diff --git a/Master/texmf-dist/tex/latex/adigraph/adigraph.sty b/Master/texmf-dist/tex/latex/adigraph/adigraph.sty index 1d12cc9892d..5d8ad435831 100644 --- a/Master/texmf-dist/tex/latex/adigraph/adigraph.sty +++ b/Master/texmf-dist/tex/latex/adigraph/adigraph.sty @@ -9,349 +9,420 @@ % \NeedsTeXFormat{LaTeX2e}[1994/06/01] \ProvidesPackage{adigraph} - [2018/02/16 v1.0 LaTeX package for creating augmenting directed graphs] +[2018/03/09 v1.2 LaTeX package for creating augmenting directed graphs] +\RequirePackage{etoolbox} \RequirePackage{fp} \RequirePackage{xparse} \RequirePackage{xstring} \RequirePackage{tikz} \usetikzlibrary{calc} -\def\zero{0} - \makeatletter -\newcommand*{\rom}[1]{\expandafter\@slowromancap\romannumeral #1@} +\newcommand*{\AdigraphRom}[1]{\expandafter\@slowromancap\romannumeral #1@} +\makeatother + +\newcounter{AdigraphNumberOfPaths} +\setcounter{AdigraphNumberOfPaths}{0} + +\newcounter{AdigraphCurrentPathNumber} +\setcounter{AdigraphCurrentPathNumber}{0} + +\NewDocumentCommand{\AdigraphDrawNode}{m}{% + % + % #1 is node normalized id + % + \letcs{\nodeX}{adigraphNode#1X} + \letcs{\nodeY}{adigraphNode#1Y} + \letcs{\nodeLabel}{adigraphNode#1Label} + \letcs{\nodeColor}{adigraphNode#1Color} + % + \node[vertex,\nodeColor] (#1) at (\nodeX,\nodeY) {\nodeLabel}; +} + +\NewDocumentCommand{\AdigraphDrawEdge}{m m}{% + % + % #1 is first node normalized id + % #2 is second node normalized id + % + \ifbool{adigraphEdge#1v#2Drawn}{% + % This edge was already drawn + }{% + \letcs{\firstX}{adigraphNode#1X} + \letcs{\firstY}{adigraphNode#1Y} + \letcs{\secondX}{adigraphNode#2X} + \letcs{\secondY}{adigraphNode#2Y} -\NewDocumentCommand{\storeCoordinate}{m m m}{ - \@namedef{adigraphNode#1#2}{#3}% + \ifnumgreater{\secondX-\firstX}{0}{% + \def\AdigraphLabelPosition{above} + }{% + \ifnumequal{\secondX-\firstX}{0}{% + \ifnumgreater{\secondY-\firstY}{0}{% + \def\AdigraphLabelPosition{left} + }{% + \def\AdigraphLabelPosition{right} + } + }{% + \def\AdigraphLabelPosition{below} + } + } + + \booltrue{adigraphEdge#1v#2Drawn} + \letcs{\edgeLabelPosition}{adigraphEdge#1v#2LabelPosition} + \letcs{\edgeWeight}{adigraphEdge#1v#2Weight} + \ifcsdef{adigraphEdge#2v#1Weight}{% + \letcs{\AdigraphTwinEdgeWeight}{adigraphEdge#2v#1Weight} + }{% + \def\AdigraphTwinEdgeWeight{0} + } + \letcs{\edgeColor}{adigraphEdge#1v#2Color} + \ifbool{adigraphEdge#1v#2HasLabel}{% + \letcs{\edgeLabel}{adigraphEdge#1v#2Label} + }{% + \letcs{\edgeLabel}{adigraphEdge#1v#2Weight} + } + \ifnumequal{\edgeWeight}{0}{% + % We don't draw edges with weight 0 + }{% + \ifnumequal{\AdigraphTwinEdgeWeight}{0}{% + % 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); + }% + }% + } } -\NewDocumentCommand{\storeParsedEdge}{m m}{ - \@namedef{parsed#1#2}{1}% + +\NewDocumentCommand{\AdigraphMemorizeNode}{m m G{black}}{} + +\NewDocumentCommand{\AdigraphBuildNode}{m > { \SplitArgument{ 2 } {,} } m G{#1}}{% + % + % #1 -> given node name, not normalized + % #2 -> list of coordinates and color + % #3 -> optional label + % + \ifblank{#1}{% + %Do nothing, this is the tail of the list + }{% + \IfInteger{#1}{% + \def\AdigraphNodeName{\AdigraphRom{#1}}% + \listgadd{\AdigraphNodeList}{\AdigraphRom{#1}} + }{% + \def\AdigraphNodeName{#1}% + \listgadd{\AdigraphNodeList}{#1} + }% + \RenewDocumentCommand{\AdigraphMemorizeNode}{m m G{black}}{% + \csdef{adigraphNode\AdigraphNodeName Label}{#3}% + \csdef{adigraphNode\AdigraphNodeName X}{##1}% + \csdef{adigraphNode\AdigraphNodeName Y}{##2}% + \csdef{adigraphNode\AdigraphNodeName Color}{##3}% + }% + \AdigraphMemorizeNode#2 + } } -\makeatother -\newcommand{\markEdgeAsParsed}[2]{% - % - % #1 -> First node of edge - % #2 -> Second node of edge - % - \IfInteger{#1}{% - \def\nodeA{\rom{#1}}% - }{% - \def\nodeA{#1}% - }% - \IfInteger{#2}{% - \def\nodeB{\rom{#2}}% - }{% - \def\nodeB{#2}% - }% - \storeParsedEdge{\nodeA}{\nodeB} + +\NewDocumentCommand{\AdigraphMemorizeEdge}{m m G{black}}{} + +\NewDocumentCommand{\AdigraphBuildEdge}{> {\SplitArgument{2}{,}} m m m m}{% + % + % #1 -> List of edge nodes and its color, validated + % #2 -> Weight + % #3 -> Label, defaults to weight + % #4 -> Label position, defaults to midway + % + \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} + }{% + \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}% + } + \AdigraphMemorizeEdge#1 +} + +\NewDocumentCommand{\AdigraphBuildEdgeWrapper}{m G{} G{} G{midway}}{% + % + % #1 -> List of edge nodes and its color + % #2 -> Weight + % #3 -> Label + % #4 -> Label position + % + \ifblank{#1}{% + %Do nothing, this is the tail of the list + }{% + \AdigraphBuildEdge{#1}{#2}{#3}{#4} + } +} + +\NewDocumentCommand{\AdigraphElaboratePath}{m m G{black}}{} + +\newcount\AdigraphCounter +\NewDocumentCommand{\AdigraphSimpleSum}{m m m}{% + % + % #1 -> First addendum + % #2 -> Second addendum + % #3 -> Variable to store sum + % + \AdigraphCounter #1\relax + \advance\AdigraphCounter +#2\relax + \FPset{#3}{\the\AdigraphCounter} +} + +\NewDocumentCommand{\AdigraphPathBuilder}{m m m}{% + % + % #1 -> first node + % #2 -> second node + % #3 -> units + % + \ifcsdef{adigraphEdge#1v#2Weight}{% + \letcs{\AdigraphWeightA}{adigraphEdge#1v#2Weight} + }{% + \def\AdigraphWeightA{0} + \newbool{adigraphEdge#1v#2HasLabel} + \ifcsdef{adigraphEdge#2v#1LabelPosition}{% + \csdef{adigraphEdge#1v#2LabelPosition}{\csuse{adigraphEdge#2v#1LabelPosition}} + }{% + \csdef{adigraphEdge#1v#2LabelPosition}{midway} + } + \csdef{adigraphEdge#1v#2LabelPosition}{midway} + \newbool{adigraphEdge#1v#2Drawn} + \csdef{adigraphEdge#1v#2Color}{black}% + \listgadd{\AdigraphEdgeList}{#1,#2} + } + \ifcsdef{adigraphEdge#2v#1Weight}{% + \letcs{\AdigraphWeightB}{adigraphEdge#2v#1Weight} + }{% + \def\AdigraphWeightB{0} + \newbool{adigraphEdge#2v#1HasLabel} + \ifcsdef{adigraphEdge#1v#2LabelPosition}{% + \csdef{adigraphEdge#2v#1LabelPosition}{\csuse{adigraphEdge#1v#2LabelPosition}} + }{% + \csdef{adigraphEdge#2v#1LabelPosition}{midway} + } + \newbool{adigraphEdge#2v#1Drawn} + \csdef{adigraphEdge#2v#1Color}{black}% + \listgadd{\AdigraphEdgeList}{#2,#1} + } + + \ifnum\value{AdigraphCurrentPathNumber}=\value{AdigraphNumberOfPaths} + \csdef{adigraphEdge#1v#2Color}{blue}% + \csdef{adigraphEdge#2v#1Color}{red}% + \else + % Leaves the default colors + \fi + \expandafter\AdigraphSimpleSum\expandafter{\AdigraphWeightA}{-#3}{\resultA} + \expandafter\AdigraphSimpleSum\expandafter{\AdigraphWeightB}{#3}{\resultB} + \cslet{adigraphEdge#1v#2Weight}{\resultA}% + \cslet{adigraphEdge#2v#1Weight}{\resultB}% } -\newcommand{\edgeWasParsed}[3]{% - % - % #1 -> Variable to store boolean result - % #2 -> First node of edge - % #3 -> Second node of edge - % - \IfInteger{#2}{% - \def\nodeA{\rom{#2}}% - }{% - \def\nodeA{#2}% - }% - \IfInteger{#3}{% - \def\nodeB{\rom{#3}}% - }{% - \def\nodeB{#3}% - }% - \ifcsname parsed\nodeA\nodeB\endcsname - \FPset{#1}{1} - \else% - \FPset{#1}{0} - \fi% +\NewDocumentCommand{\AdigraphBuildPath}{> { \SplitList{,} } m m}{% + % + % #1 -> List of nodes + % #2 -> Units to send over path + % + \RenewDocumentCommand{\AdigraphElaboratePath}{m}{% + \IfInteger{##1}{% + \def\AdigraphCurrentNode{\AdigraphRom{##1}}% + }{% + \def\AdigraphCurrentNode{##1}% + }% + \ifdef{\AdigraphLastParsedNode}{% + \expandafter\expandafter\expandafter\AdigraphPathBuilder\expandafter\expandafter\expandafter{\expandafter\AdigraphLastParsedNode\expandafter}\expandafter{\AdigraphCurrentNode}{#2} + }{% + % This is the first iteration + } + \IfInteger{##1}{% + \def\AdigraphLastParsedNode{\AdigraphRom{##1}}% + }{% + \def\AdigraphLastParsedNode{##1}% + }% + } + \ProcessList{#1}{\AdigraphElaboratePath} + \undef{\AdigraphLastParsedNode} } -\newcommand{\saveNodeCoordinate}[3]{ - % - % #1 -> Node name - % #2 -> Coordinate, either X or Y - % #3 -> Numeric value - % - \IfInteger{#1}{% - \def\nodeName{\rom{#1}}% - }{% - \def\nodeName{#1}% - }% - \storeCoordinate{#2}{\nodeName}{#3} +\NewDocumentCommand{\AdigraphNodeBuilder}{ > { \SplitArgument{ 2 } {:} } m }{% + \AdigraphBuildNode#1 } -\newcommand{\retrieveNodeCoordinate}[3]{ - % - % #1 -> Variable to store coordinate into - % #2 -> Node name - % #3 -> Coordinate, either X or Y - % - \IfInteger{#2}{% - \def\nodeName{\rom{#2}}% - }{% - \def\nodeName{#2}% - }% - - \FPset{#1}{\csname adigraphNode#3\nodeName\endcsname} +\NewDocumentCommand{\AdigraphEdgeBuilder}{ > { \SplitArgument{ 3 } {:} } m }{% + \AdigraphBuildEdgeWrapper#1 } -\newcommand{\saveNodeCoordinates}[3]{ - % - % #1 -> Node name - % #2 -> X value - % #3 -> Y value - % - \saveNodeCoordinate{#1}{X}{#2}% - \saveNodeCoordinate{#1}{Y}{#3}% +\NewDocumentCommand{\AdigraphEdgeDrawer}{ > { \SplitArgument{ 1 } {,} } m }{% + \AdigraphDrawEdge#1 } -\newcommand{\swp}[3]{ - % - % #1 -> variable to assign - % #2 -> First node name - % #3 -> Second node name - % - \retrieveNodeCoordinate{\firstX}{#2}{X} - \retrieveNodeCoordinate{\firstY}{#2}{Y} - \retrieveNodeCoordinate{\secondX}{#3}{X} - \retrieveNodeCoordinate{\secondY}{#3}{Y} - % - \FPsub{\xSub}{\secondX}{\firstX} - \FPsub{\ySub}{\secondY}{\firstY} - \FPset{#1}{1} - \FPifgt{\xSub}{0} - \FPset{#1}{3} - \else% - \FPset{#1}{4} - \fi% - % - \FPifeq{\xSub}{0} - \FPset{\xiszero}{1} - \else% - \FPset{\xiszero}{0} - \fi% - % - \FPifgt{\ySub}{0} - \FPset{\yispos}{1} - \else% - \FPset{\yispos}{4} - \fi% - % - \FPadd{\xzeroypos}{\xiszero}{\yispos} - % - \FPifeq{\xzeroypos}{2} - \FPset{#1}{1} - \fi% - \FPifeq{\xzeroypos}{5} - \FPset{#1}{2} - \fi% +\NewDocumentCommand{\AdigraphProcessNodes}{> { \SplitList{;} } m}{% + \ProcessList{#1}{\AdigraphNodeBuilder} + \forlistloop{\AdigraphDrawNode}{\AdigraphNodeList} } -\newcommand{\executeNodeBuilder}[5]{ - % - % #1 is node name - % #2 is x coordinate - % #3 is y coordinate - % #4 is label, that defaults to #1 when absent - % #5 is color, that defaults to black when absent - % - \IfValueT{#2}{ - \IfValueTF{#4}{ - \def\nodeLabel{#4} - }{ - \def\nodeLabel{#1} - } - \IfValueTF{#5}{ - \def\nodeColor{#5} - }{ - \def\nodeColor{black} - } - \saveNodeCoordinates{#1}{#2}{#3} - \node[vertex,\nodeColor] (#1) at (#2,#3) {$\nodeLabel$}; - } +\NewDocumentCommand{\AdigraphProcessEdges}{> { \SplitList{;} } m}{% + \ProcessList{#1}{\AdigraphEdgeBuilder} } -\NewDocumentCommand{\nodeBuilder}{ > { \SplitArgument { 4 } { , } } m }{ - \executeNodeBuilder #1 +\NewDocumentCommand{\AdigraphProcessPaths}{> { \SplitArgument{ 1 } {:} } m}{% + \stepcounter{AdigraphCurrentPathNumber} + \AdigraphBuildPath#1 } -\newcommand{\executeEdgeBuilder}[7]{ - % - % #1 is first node - % #2 is second node - % #3 is weight of first edge, which defaults to 0 - % #4 is weight of second edge, which defaults to 0 - % #5 Should we color edge? Or first optional color - % #6 Second optional color - % #7 Label position on axis - % - \edgeWasParsed{\isParsed}{#1}{#2} - \FPifeq{\isParsed}{0} - \markEdgeAsParsed{#1}{#2} - \markEdgeAsParsed{#2}{#1} - \fi% - \IfValueT{#2}{ - \def\firstNode{#1} - \def\secondNode{#2} - \IfValueTF{#3}{ - \def\firstEdgeWeight{#3} - }{ - \def\firstEdgeWeight{0} - } - \IfValueTF{#4}{ - \def\secondEdgeWeight{#4} - }{ - \def\secondEdgeWeight{0} - } - \IfValueTF{#7}{ - \def\labelPosition{#7} - }{ - \def\labelPosition{midway} - } - \IfValueTF{#6}{ - \IfValueTF{#5}{ - \def\firstEdgeColor{#5} - \def\secondEdgeColor{#6} - }{ - \def\firstEdgeColor{black} - \def\secondEdgeColor{black} - } - }{ - \IfValueTF{#5}{ - \def\firstEdgeColor{red} - \def\secondEdgeColor{blue} - }{ - \def\firstEdgeColor{black} - \def\secondEdgeColor{black} - } - } - - \FPadd{\weightSum}{\firstEdgeWeight}{\secondEdgeWeight} - \FPmul{\weightMul}{\firstEdgeWeight}{\secondEdgeWeight} - \FPadd{\firstZero}{\weightMul}{\firstEdgeWeight} - \FPadd{\secondZero}{\weightMul}{\secondEdgeWeight} - - \swp{\firstWeightPositionFlag}{#1}{#2} - \swp{\secondWeightPositionFlag}{#2}{#1} - - \FPifeq{\firstWeightPositionFlag}{1} - \def\firstWeightPosition{left} - \fi - \FPifeq{\firstWeightPositionFlag}{2} - \def\firstWeightPosition{right} - \fi - \FPifeq{\firstWeightPositionFlag}{3} - \def\firstWeightPosition{above} - \fi - \FPifeq{\firstWeightPositionFlag}{4} - \def\firstWeightPosition{below} - \fi - - \FPifeq{\secondWeightPositionFlag}{1} - \def\secondWeightPosition{left} - \fi - \FPifeq{\secondWeightPositionFlag}{2} - \def\secondWeightPosition{right} - \fi - \FPifeq{\secondWeightPositionFlag}{3} - \def\secondWeightPosition{above} - \fi - \FPifeq{\secondWeightPositionFlag}{4} - \def\secondWeightPosition{below} - \fi - \FPifeq{\isParsed}{1} - \else - \FPifeq{\weightSum}{0} - % No edge has weights, so we draw both with no labels. - \draw[edge,\firstEdgeColor] (\firstNode) to [bend right=20] (\secondNode); - \draw[edge,\secondEdgeColor] (\secondNode) to [bend right=20] (\firstNode); - \else - \FPifeq{\weightSum}{0} - \draw[edge,\firstEdgeColor] (\firstNode) to node[\labelPosition, \secondWeightPosition] {$\firstEdgeWeight$}(\secondNode); - \else - \FPifeq{\firstZero}{0} - \draw[edge,\secondEdgeColor] (\secondNode) to node[\labelPosition, \firstWeightPosition] {$\secondEdgeWeight$}(\firstNode); - \FPifeq{\weightMul}{0} - \else - \draw[edge,\firstEdgeColor] (\firstNode) to [bend right=20] node[\labelPosition, \firstWeightPosition] {$\firstEdgeWeight$}(\secondNode); - \draw[edge,\secondEdgeColor] (\secondNode) to [bend right=20] node[\labelPosition, \secondWeightPosition] {$\secondEdgeWeight$}(\firstNode); - \fi - } +\NewDocumentCommand{\AdigraphCountPaths}{m}{% + \stepcounter{AdigraphNumberOfPaths} } -\NewDocumentCommand{\edgeBuilder}{> { \SplitArgument { 6 } { , } } m}{ - \executeEdgeBuilder #1 +\NewDocumentCommand{\AdigraphCalculateOrientation}{m m m}{% + \letcs{\firstX}{adigraphNode#2X} + \letcs{\firstY}{adigraphNode#2Y} + \letcs{\secondX}{adigraphNode#3X} + \letcs{\secondY}{adigraphNode#3Y} + + \ifnumequal{\secondX-\firstX}{0}{% + \FPset{#1}{90} + }{% + \FPsub{\deltaY}{\secondY}{\firstY} + \FPsub{\deltaX}{\secondX}{\firstX} + \FPdiv{\deltaDiv}{\deltaY}{\deltaX} + \FParctan{\arcResult}{\deltaDiv} + \FPmul{#1}{\arcResult}{57.2958} + } } -\NewDocumentCommand{\calculateOrientation}{m m m}{ - \retrieveNodeCoordinate{\firstX}{#2}{X} - \retrieveNodeCoordinate{\firstY}{#2}{Y} - \retrieveNodeCoordinate{\secondX}{#3}{X} - \retrieveNodeCoordinate{\secondY}{#3}{Y} - \FPsub{\deltaY}{\secondY}{\firstY} - \FPsub{\deltaX}{\secondX}{\firstX} - \FPifeq{\deltaX}{0} - \Fpset{#1}{90} - \else - \FPdiv{\deltaDiv}{\deltaY}{\deltaX} - \FParctan{\arcResult}{\deltaDiv} - \FPmul{#1}{\arcResult}{57.2958} - \fi +\NewDocumentCommand{\AdigraphExecuteCutBuilder}{m m G{black}}{% +\ifblank{#1}{% +% Reached end of list +}{% +\IfInteger{#1}{% + \def\AdigraphFirstNode{\AdigraphRom{#1}}% +}{% + \def\AdigraphFirstNode{#1}% +}% +\IfInteger{#2}{% + \def\AdigraphSecondNode{\AdigraphRom{#2}}% +}{% + \def\AdigraphSecondNode{#2}% +}% +\AdigraphCalculateOrientation{\orientation}{\AdigraphFirstNode}{\AdigraphSecondNode} +\draw[dashed,#3,rotate=\orientation] ([yshift=10pt]$(\AdigraphFirstNode)!0.7!(\AdigraphSecondNode)$) -- ([yshift=-10pt]$(\AdigraphFirstNode)!0.7!(\AdigraphSecondNode)$); +} } -\NewDocumentCommand{\executeCutBuilder}{m m}{ - \IfValueT{#2}{ - \calculateOrientation{\orientation}{#1}{#2} - \draw[dashed,red,rotate=\orientation] ([yshift=10pt]$(#1)!0.7!(#2)$) -- ([yshift=-10pt]$(#1)!0.7!(#2)$); - % %\node[vertex] (d) at (-3,-3) {$ARIAN$}; - } +\NewDocumentCommand{\AdigraphCutBuilder}{> { \SplitArgument { 2 } { , } } m}{% + \AdigraphExecuteCutBuilder #1 } -\NewDocumentCommand{\cutBuilder}{> { \SplitArgument { 1 } { , } } m}{ - \executeCutBuilder #1 +\NewDocumentCommand{\AdigraphProcessCuts}{> { \SplitList{;} } m}{% + \ProcessList{#1}{\AdigraphCutBuilder} } -\NewDocumentCommand{\smartGraph}{> { \SplitList { ; } } m > { \SplitList { ; } } m > { \SplitList { ; } } m > { \SplitList { ; } } m}{ - % - % #1 -> Vertices - % #2 -> Edges - % #3 -> Modified edges - % #4 -> Cuts - % - \begin{tikzpicture} - \tikzset{ - vertex/.style={circle,draw,minimum size=2em}, - edge/.style={->,> = latex} - } - - % vertices - \ProcessList {#1} {\nodeBuilder} - - %edges - \ProcessList {#3} {\edgeBuilder} - \ProcessList {#2} {\edgeBuilder} - - %cuts - \ProcessList {#4} {\cutBuilder} - \end{tikzpicture} +\NewDocumentCommand{\Adigraph}{m m m m m}{% + % + % #1 -> Vertices + % #2 -> Edges + % #3 -> Augmenting paths + % #4 -> Cuts + % #5 -> Current augmenting paths + % + \def\AdigraphNodeList{} + \def\AdigraphEdgeList{} + \letcs{\AdigraphAugmentingPaths}{#3} + \begin{tikzpicture} + \tikzset{% + vertex/.style={circle,draw,minimum size=2em}, + edge/.style={->,> = latex} + } + + % vertices + \ifblank{#1}{% + % List is empty + }{% + \AdigraphProcessNodes{#1} + } + + \ifblank{#2}{% + % List is empty + }{% + \AdigraphProcessEdges{#2} + } + + \ifblank{\AdigraphAugmentingPaths}{% + % List is empty + }{% + \ifblank{#5}{% + \defcounter{AdigraphNumberOfPaths}{100000} + }{% + } + \forlistloop{\AdigraphCountPaths}{\AdigraphAugmentingPaths} + \forlistloop{\AdigraphProcessPaths}{\AdigraphAugmentingPaths} + } + + \ifblank{#2}{% + % List is empty + }{% + \forlistloop{\AdigraphEdgeDrawer}{\AdigraphEdgeList} + } + + %cuts + \ifblank{#4}{% + % List is empty + }{% + \AdigraphProcessCuts{#4} + } + \end{tikzpicture} } -\NewDocumentCommand{\NewAdigraph}{m m m}{ - % - % #1 -> Variable to assign to as command - % #2 -> Nodes - % #3 -> Edges - % - \expandafter\newcommand\csname #1\endcsname[2][]{ - % - % ##1 -> Modified edges - % - \smartGraph{#2}{#3}{##2}{##1} - }% +\NewDocumentCommand{\NewAdigraph}{m m G{}}{% + % + % #1 -> Variable to assign to as command + % #2 -> Nodes + % #3 -> Edges + % + \csdef{Adigraph#1AugmentingPaths}{}% + \expandafter\NewDocumentCommand{\AdigraphProcessAugmentingPaths}{m}{% + \listcsgadd{Adigraph#1AugmentingPaths}{##1} + } + \expandafter\NewDocumentCommand{\AdigraphProcessAugmentingPathsList}{> { \SplitList{;} } m}{% + \AdigraphProcessAugmentingPaths##1 + } + \expandafter\NewDocumentCommand\expandafter{\csname #1\endcsname}{m G{}}{% + % + % ##1 -> Augmenting path + % + \AdigraphProcessAugmentingPathsList{##1} + \Adigraph{#2}{#3}{Adigraph#1AugmentingPaths}{##2}{##1} + }% } \endinput -- cgit v1.2.3