\NeedsTeXFormat{LaTeX2e} \ProvidesPackage{pmdraw}[2024-04-09 v1.3 pmdraw] % *------------------------------* % |2````````````````````````````3| % |`````____````____`````````````| % |````|MFMF\ /MFMF|````````````| % |````|MF|MF\/MF|MF|````````````| % |````|MF|\MFMF/|MF|_______`````| % |````|MF|``````|MFMFMFMFMF|````| % |````|MF|``````|MF|````````````| % |````|MF|``````|MF|___`````````| % |``````````````|MFMFMF|````````| % |``````````````|MF|````````````| % |``````````````|MF|````````````| % |``````````````|MF|````````````| % |1````````````````````````````1| % *------------------------------* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % Required packages % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \RequirePackage{datetime} \RequirePackage{keyval} \RequirePackage{tikz} \usetikzlibrary{math,decorations.pathreplacing,calligraphy,backgrounds} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % Internal control and option commands % % - loosely ordered alphabetically % % - includes default values where appropriate % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \newcommand{\pmdraw@braceLabel}{}% Label of brace \newcommand{\pmdraw@diagSep}{1}% Vertical separation between bottom row of top diagram and top row of bottom diagram in product diagram \newcommand{\pmdraw@drawAedgesOptions}{}% Draw options for added edges in product diagram \newcommand{\pmdraw@drawAedges}[2]{% Draws added edges in product diagram from #1 vertex to #2 vertex, assumes #1<#2 \foreach \x in {#1,...,#2} {% For each vertex in range \draw[dotted,thick,apply style/.expand once=\pmdraw@drawAedgesOptions] (\x,0) -- (\x,-\pmdraw@diagSep);% Draw concatenation edge }% \pmdraw@AedgesLoop% Restart for loop } \newcommand{\pmdraw@drawBraceDrawOptions}{}% Draw options for brace \newcommand{\pmdraw@drawBraceNodeOptions}{}% Node options for brace \newcommand{\pmdraw@drawBraceDefault}[3]{% Draws brace a brace starting from #1 vertex to #2 vertex with label #3, assumes #1<#2 - DEFAULT \ifnum\pmdraw@ifProdDiag=1% If drawing a product diagram or if placing brace above diagram \draw[ very thick, decorate, decoration={calligraphic brace,amplitude=6pt}, apply style/.expand once=\pmdraw@drawBraceDrawOptions ] (#1-0.17,\pmdraw@rowSep+0.5) -- (#2+0.17,\pmdraw@rowSep+0.5) node[ pos=0.5, above=6pt, apply style/.expand once=\pmdraw@drawBraceNodeOptions ] {\(#3\)};% Draw brace on top of diagram \else% If not drawing a product diagram or if placing brace below diagram \draw[ very thick, decorate, decoration={calligraphic brace,mirror,amplitude=6pt}, apply style/.expand once=\pmdraw@drawBraceDrawOptions ] (#1-0.17,-0.5) -- (#2+0.17,-0.5) node[ pos=0.5, below=6pt, apply style/.expand once=\pmdraw@drawBraceNodeOptions ] {\(#3\)};% Draw brace on bottom of diagram \fi% } \let\pmdraw@drawBrace\pmdraw@drawBraceDefault% Draws brace a brace starting from #1 vertex to #2 vertex with label #3, assumes #1<#2 \newcommand{\pmdraw@drawDotsDrawOptions}{}% Draw options for dots between bricks \newcommand{\pmdraw@drawDotsNodeOptions}{}% Node options for dots between bricks \newcommand{\pmdraw@drawDotsDefault}[2]{% Draws dots between bricks at (#1,#2) - DEFAULT \draw[apply style/.expand once=\pmdraw@drawDotsDrawOptions] (#1,#2) node[apply style/.expand once=\pmdraw@drawDotsNodeOptions] {\(\dots\)};% } \let\pmdraw@drawDots\pmdraw@drawDotsDefault% Draws dots between bricks at (#1,#2) \newcommand{\pmdraw@drawEdgeDrawOptions}{}% Draw options for edge \newcommand{\pmdraw@drawLabelBDrawOptions}{}% Draw options for label of a vertex in bottom row \newcommand{\pmdraw@drawLabelBNodeOptions}{}% Node options for label of a vertex in bottom row \newcommand{\pmdraw@drawLabelBottomDefault}[3]{% For bottom row, draws the label #3 for a vertex at (#1,#2) - DEFAULT \draw[apply style/.expand once=\pmdraw@drawLabelBDrawOptions] (#1,#2) node[below=6pt,apply style/.expand once=\pmdraw@drawLabelBNodeOptions] {\(#3'\)};% } \let\pmdraw@drawLabelBottom\pmdraw@drawLabelBottomDefault% For bottom row, draws the label #3 for a vertex at (#1,#2) \newcommand{\pmdraw@drawLabelTDrawOptions}{}% Draw options for label of a vertex in top row \newcommand{\pmdraw@drawLabelTNodeOptions}{}% Node options for label of a vertex in top row \newcommand{\pmdraw@drawLabelTopDefault}[3]{% For top row, draws the label #3 for a vertex at (#1,#2) - DEFAULT \draw[apply style/.expand once=\pmdraw@drawLabelTDrawOptions] (#1,#2) node[above=6pt,apply style/.expand once=\pmdraw@drawLabelTNodeOptions] {\(#3\)};% } \let\pmdraw@drawLabelTop\pmdraw@drawLabelTopDefault% For top row, draws the label #3 for a vertex at (#1,#2) \newcommand{\pmdraw@drawLedgesDrawOptions}{}% Draw options for lower non-transversal edges \newcommand{\pmdraw@drawLedgesDrawDefault}[2]{% Draws lower non-transversal edge from #1 vertex to #2 vertex, assumes #1<#2 - DEFAULT \draw[apply style/.expand once=\pmdraw@drawLedgesDrawOptions,apply style/.expand once=\pmdraw@drawEdgeDrawOptions] (#1,0) arc (180:90:\pmdraw{edgeHeight});% Draw left arch \draw[apply style/.expand once=\pmdraw@drawLedgesDrawOptions,apply style/.expand once=\pmdraw@drawEdgeDrawOptions] (#1+\pmdraw{edgeHeight},\pmdraw{edgeHeight}) -- (#2-\pmdraw{edgeHeight},\pmdraw{edgeHeight});% Draw straight line \draw[apply style/.expand once=\pmdraw@drawLedgesDrawOptions,apply style/.expand once=\pmdraw@drawEdgeDrawOptions] (#2-\pmdraw{edgeHeight},\pmdraw{edgeHeight}) arc (90:0:\pmdraw{edgeHeight});% Draw right arc \renewcommand{\pmdraw@drawEdgeDrawOptions}{}% Reset draw options for edge } \let\pmdraw@drawLedgesDraw\pmdraw@drawLedgesDrawDefault% Draws lower non-transversal edge from #1 vertex to #2 vertex, assumes #1<#2 \newcommand{\pmdraw@drawTedgesDrawOptions}{}% Draw options for transversal edges \newcommand{\pmdraw@drawTedgesDrawDefault}[2]{% Draws transversal edge from #1 vertex in top row to #2 vertex in bottom row - DEFAULT \ifnum\pmdraw@ifTedgeHorizontal=0% If drawing a straight line edge \draw[apply style/.expand once=\pmdraw@drawTedgesDrawOptions,apply style/.expand once=\pmdraw@drawEdgeDrawOptions] (#1,\pmdraw@rowSep) -- (#2,0);% Draw straight line \else% If transversal edge is drawn horizontally \ifnum#1>#2% If edge goes from top right to bottom left \draw[apply style/.expand once=\pmdraw@drawTedgesDrawOptions,apply style/.expand once=\pmdraw@drawEdgeDrawOptions] (#2,0) arc (180:90:\pmdraw{Tlevel});% Draw bottom arch \draw[apply style/.expand once=\pmdraw@drawTedgesDrawOptions,apply style/.expand once=\pmdraw@drawEdgeDrawOptions] (#2+\pmdraw{Tlevel},\pmdraw{Tlevel}) -- (#1-\pmdraw@rowSep+\pmdraw{Tlevel}, \pmdraw{Tlevel});% Draw straight line \draw[apply style/.expand once=\pmdraw@drawTedgesDrawOptions,apply style/.expand once=\pmdraw@drawEdgeDrawOptions] (#1-\pmdraw@rowSep+\pmdraw{Tlevel},\pmdraw{Tlevel}) arc (270:360:{\pmdraw@rowSep-\pmdraw{Tlevel}});% Draw top arc \else% If edge goes from top left to bottom right \draw[apply style/.expand once=\pmdraw@drawTedgesDrawOptions,apply style/.expand once=\pmdraw@drawEdgeDrawOptions] (#2,0) arc (0:90:\pmdraw{Tlevel});% Draw bottom arch \draw[apply style/.expand once=\pmdraw@drawTedgesDrawOptions,apply style/.expand once=\pmdraw@drawEdgeDrawOptions] (#2-\pmdraw{Tlevel},\pmdraw{Tlevel}) -- (#1+\pmdraw@rowSep-\pmdraw{Tlevel}, \pmdraw{Tlevel});% Draw straight line \draw[apply style/.expand once=\pmdraw@drawTedgesDrawOptions,apply style/.expand once=\pmdraw@drawEdgeDrawOptions] (#1+\pmdraw@rowSep-\pmdraw{Tlevel},\pmdraw{Tlevel}) arc (270:180:{\pmdraw@rowSep-\pmdraw{Tlevel}});% Draw top arc \fi% \renewcommand{\pmdraw@ifTedgeHorizontal}{0}% Reset flag to default \fi% \renewcommand{\pmdraw@drawEdgeDrawOptions}{}% Reset draw options for edge } \let\pmdraw@drawTedgesDraw\pmdraw@drawTedgesDrawDefault% Draws transversal edge from #1 vertex in top row to #2 vertex in bottom row \newcommand{\pmdraw@drawUedgesDrawOptions}{}% Draw options for upper non-transversal edges \newcommand{\pmdraw@drawUedgesDrawDefault}[2]{% Draws upper non-transversal edge from #1 vertex to #2 vertex, assumes #1<#2 - DEFAULT \draw[apply style/.expand once=\pmdraw@drawUedgesDrawOptions,apply style/.expand once=\pmdraw@drawEdgeDrawOptions] (#1,\pmdraw@rowSep) arc (180:270:\pmdraw{edgeHeight});% Draw left arch \draw[apply style/.expand once=\pmdraw@drawUedgesDrawOptions,apply style/.expand once=\pmdraw@drawEdgeDrawOptions] (#1+\pmdraw{edgeHeight},\pmdraw@rowSep-\pmdraw{edgeHeight}) -- (#2-\pmdraw{edgeHeight},\pmdraw@rowSep-\pmdraw{edgeHeight});% Draw straight line \draw[apply style/.expand once=\pmdraw@drawUedgesDrawOptions,apply style/.expand once=\pmdraw@drawEdgeDrawOptions] (#2-\pmdraw{edgeHeight},\pmdraw@rowSep-\pmdraw{edgeHeight}) arc (270:360:\pmdraw{edgeHeight});% Draw right arc \renewcommand{\pmdraw@drawEdgeDrawOptions}{}% Reset draw options for edge } \let\pmdraw@drawUedgesDraw\pmdraw@drawUedgesDrawDefault% Draws upper non-transversal edge from #1 vertex to #2 vertex, assumes #1<#2 \newcommand{\pmdraw@drawVertexOptions}{}% Draw options for vertices \newcommand{\pmdraw@drawVertex}[2]{% Draws a vertex at (#1,#2) \fill[apply style/.expand once=\pmdraw@drawVertexOptions] (#1,#2) circle (.17);% } \newcommand{\pmdraw@hookAfterBrick}{}% Hook after drawing a brick \newcommand{\pmdraw@hookAfterDiagram}{}% Hook after drawing a diagram \newcommand{\pmdraw@hookBeforeBrick}{}% Hook before drawing a brick \newcommand{\pmdraw@hookBeforeDiagram}{}% Hook before drawing a diagram \newcommand{\pmdraw@ifDiagWDots}{0}% Boolean if drawing a diagram with dots \newcommand{\pmdraw@ifEdgesFirst}{0}% Boolean if drawing edges before vertices \newcommand{\pmdraw@ifGrid}{0}% Boolean if displaying helper grid \newcommand{\pmdraw@ifLabelsB}{0}% Boolean if displaying labels for vertices in bottom row \newcommand{\pmdraw@ifLabelsT}{0}% Boolean if displaying labels for vertices in top row \newcommand{\pmdraw@ifProdDiag}{0}% Boolean if drawing a product diagram \newcommand{\pmdraw@ifTedgesFirst}{0}% Boolean if drawing transversal edges before non-transversal edges \newcommand{\pmdraw@ifTedgeHorizontal}{0}% Boolean if transversal edge is drawn horizontally \newcommand{\pmdraw@NTedgesHeight}{-1000}% Height of non-transversal edges if manually set, a value of -1000 sets height automatically \newcommand{\pmdraw@reset}{% Resets user keys and other flags to default values after drawing diagram \renewcommand{\pmdraw@diagSep}{1}% Resets vertical space between product diagrams \renewcommand{\pmdraw@drawAedgesOptions}{}% Resets draw options for added edges in product diagram \let\pmdraw@drawDots\pmdraw@drawDotsDefault% Resets drawing of dots between bricks \renewcommand{\pmdraw@hookAfterDiagram}{}% Clears hook after drawing a diagram \renewcommand{\pmdraw@hookBeforeDiagram}{}% Clears hook before drawing a diagram \renewcommand{\pmdraw@ifGrid}{0}% Hides grid \renewcommand{\pmdraw@ifDiagWDots}{0}% Reset if drawing a diagram with dots \renewcommand{\pmdraw@rowSep}{2}% Resets vertical separation between rows of vertices in brick \renewcommand{\pmdraw@tikz}{}% Resets tikz options \renewcommand{\pmdraw@vertexSep}{0}% Resets vertical space between product diagrams \setcounter{pmdraw@blankB}{0}% Resets number of blank vertices in bottom row to the left of brick \setcounter{pmdraw@blankT}{0}% Resets number of blank vertices in top row to the left of brick \setcounter{pmdraw@bottomShift}{0}% Resets shift on right end of bottom row of brick \setcounter{pmdraw@topShift}{0}% Resets shift on right end of top row of brick \setcounter{pmdraw@ifDiagWDotsFirst}{1}% Reset if drawing first brick of diagram } \newcommand{\pmdraw@rowSep}{2}% Vertical separation between rows of vertices in brick \newcommand{\pmdraw@tikz}{}% Tikz options \newcommand{\pmdraw@vertexSep}{0}% Vertical separation between bottom row of top diagram and top row of bottom diagram in product diagram not for added edges %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % Counters % % - loosely ordered alphabetically % % - includes default values where appropriate % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \newcounter{pmdraw@blankB}% Number of blank vertices in bottom row to the left of brick \newcounter{pmdraw@blankT}% Number of blank vertices in top row to the left of brick \newcounter{pmdraw@bottomTotal}% Size of bottom row of brick \newcounter{pmdraw@bottomShift}% Shift on right end of bottom row of brick \newcounter{pmdraw@braceL}% Left starting vertex of brace \newcounter{pmdraw@braceR}% Right terminating vertex of brace \newcounter{pmdraw@brickShift}% Shift required for bricks after dots in diagram with dots \newcounter{pmdraw@degreeB}% Degree (number of vertices) of bottom row of brick \newcounter{pmdraw@degreeT}% Degree (number of vertices) of top row of brick \newcounter{pmdraw@ifDiagWDotsFirst}% In drawing with dots, boolean if drawing first brick of diagram \setcounter{pmdraw@ifDiagWDotsFirst}{1} \newcounter{pmdraw@labelStartB}% Starting value of labels of vertices in bottom row \setcounter{pmdraw@labelStartB}{1} \newcounter{pmdraw@labelStartT}% Starting value of labels of vertices in top row \setcounter{pmdraw@labelStartT}{1} \newcounter{pmdraw@NTlevel}% Level corresponding to a height for a non-transversal edge \newcounter{pmdraw@topTotal}% Size of top row of brick \newcounter{pmdraw@topShift}% Shift on right end of top row of brick %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % Keys for bricks % % - ordered as per manual % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % To pass draw options to \draw command % Verbatim copy from: % https://tex.stackexchange.com/a/64237 \tikzset{apply style/.code={\tikzset{#1}}} \define@key{pmdraw@brick}{degree}{% Sets degree (number of vertices per row) of diagram \setcounter{pmdraw@degreeB}{#1}% Sets degree (number of vertices per row) for bottom row \setcounter{pmdraw@degreeT}{#1}% Sets degree (number of vertices per row) for top row } \define@key{pmdraw@brick}{degree bottom}{% Sets degree (number of vertices per row) for bottom row \setcounter{pmdraw@degreeB}{#1}% } \define@key{pmdraw@brick}{degree top}{% Sets degree (number of vertices per row) for top row \setcounter{pmdraw@degreeT}{#1}% } \define@key{pmdraw@brick}{blank bottom}{% Sets the number of blank vertices on left of bottom row \setcounter{pmdraw@blankB}{#1}% } \define@key{pmdraw@brick}{blank top}{% Sets the number of blank vertices on left of top row \setcounter{pmdraw@blankT}{#1}% } \define@key{pmdraw@brick}{row sep}{% Sets vertical separation between rows of vertices in brick \renewcommand{\pmdraw@rowSep}{#1}% } \define@key{pmdraw@brick}{vertices}{% Sets the draw options of vertices \renewcommand{\pmdraw@drawVertexOptions}{#1}% } \define@key{pmdraw@brick}{vertices options}{% Sets the draw command of vertices \renewcommand{\pmdraw@drawVertex}[2]{#1}% } \define@key{pmdraw@brick}{labels}[]{% Draws labels for vertices \renewcommand{\pmdraw@ifLabelsB}{1}% \renewcommand{\pmdraw@ifLabelsT}{1}% } \define@key{pmdraw@brick}{labels bottom}[]{% Draws labels for bottom vertices \renewcommand{\pmdraw@ifLabelsB}{1}% } \define@key{pmdraw@brick}{labels top}[]{% Draws labels for top vertices \renewcommand{\pmdraw@ifLabelsT}{1}% } \define@key{pmdraw@brick}{labels start}{% Sets starting number for vertex labels \setcounter{pmdraw@labelStartT}{#1}% \setcounter{pmdraw@labelStartB}{#1}% } \define@key{pmdraw@brick}{labels bottom start}{% Sets starting number for bottom vertex labels \setcounter{pmdraw@labelStartB}{#1}% } \define@key{pmdraw@brick}{labels top start}{% Sets starting number for top vertex labels \setcounter{pmdraw@labelStartT}{#1}% } \define@key{pmdraw@brick}{labels bottom draw}{% Sets the draw options for labels of bottom vertices \renewcommand{\pmdraw@drawLabelBDrawOptions}{#1}% } \define@key{pmdraw@brick}{labels bottom node}{% Sets the node options for labels of bottom vertices \renewcommand{\pmdraw@drawLabelBNodeOptions}{#1}% } \define@key{pmdraw@brick}{labels top draw}{% Sets the draw options for labels of top vertices \renewcommand{\pmdraw@drawLabelTDrawOptions}{#1}% } \define@key{pmdraw@brick}{labels top node}{% Sets the node options for labels of top vertices \renewcommand{\pmdraw@drawLabelTNodeOptions}{#1}% } \define@key{pmdraw@brick}{labels bottom options}{% Sets the draw command of labels of bottom vertices \renewcommand{\pmdraw@drawLabelBottom}[3]{#1}% } \define@key{pmdraw@brick}{labels top options}{% Sets the draw command of labels of bottom vertices \renewcommand{\pmdraw@drawLabelTop}[3]{#1}% } \define@key{pmdraw@brick}{no dots}[]{% Does not draw dots in bricks \setcounter{pmdraw@ifDiagWDotsFirst}{1}% } \define@key{pmdraw@brick}{dots draw}{% Sets the draw options for drawing of dots \renewcommand{\pmdraw@drawDotsDrawOptions}{#1}% } \define@key{pmdraw@brick}{dots node}{% Sets the node options for drawing of dots \renewcommand{\pmdraw@drawDotsNodeOptions}{#1}% } \define@key{pmdraw@brick}{levels}[1]{% Sets number of horizontal levels for non-transversal edges and evenly spaces them \tikzmath{% \pmdraw{edgeSepU} = (0.5*\pmdraw@rowSep)/(#1 + 1);% Calculates vertical separation between each edge \pmdraw{edgeSepL} = \pmdraw{edgeSepU};% Calculates vertical separation between each edge }% } \define@key{pmdraw@brick}{levels bottom}{% Sets number of horizontal levels for lower non-transversal edges and evenly spaces them \tikzmath{% \pmdraw{edgeSepL} = (0.5*\pmdraw@rowSep)/(#1 + 1);% Calculates vertical separation between each edge }% } \define@key{pmdraw@brick}{levels top}{% Sets number of horizontal levels for upper non-transversal edges and evenly spaces them \tikzmath{% \pmdraw{edgeSepU} = (0.5*\pmdraw@rowSep)/(#1 + 1);% Calculates vertical separation between each edge }% } \define@key{pmdraw@brick}{levels sep}{% Sets vertical separation of horizontal levels for non-transversal edges \tikzmath{% \pmdraw{edgeSepU} = #1;% \pmdraw{edgeSepL} = \pmdraw{edgeSepU};% }% } \define@key{pmdraw@brick}{levels sep bottom}{% Sets vertical separation of lower horizontal levels for non-transversal edges \tikzmath{% \pmdraw{edgeSepL} = #1;% }% } \define@key{pmdraw@brick}{levels sep top}{% Sets vertical separation of upper horizontal levels for non-transversal edges \tikzmath{% \pmdraw{edgeSepU} = #1;% }% } \define@key{pmdraw@brick}{edges}{% Sets the draw options of all edges \renewcommand{\pmdraw@drawUedgesDrawOptions}{#1}% \renewcommand{\pmdraw@drawLedgesDrawOptions}{#1}% \renewcommand{\pmdraw@drawTedgesDrawOptions}{#1}% } \define@key{pmdraw@brick}{edges non-transversal}{% Sets the draw options of non-transversal edges \renewcommand{\pmdraw@drawUedgesDrawOptions}{#1}% \renewcommand{\pmdraw@drawLedgesDrawOptions}{#1}% } \define@key{pmdraw@brick}{edges upper}{% Sets the draw options of upper non-transversal edges \renewcommand{\pmdraw@drawUedgesDrawOptions}{#1}% } \define@key{pmdraw@brick}{edges lower}{% Sets the draw options of lower non-transversal edges \renewcommand{\pmdraw@drawLedgesDrawOptions}{#1}% } \define@key{pmdraw@brick}{edges transversal}{% Sets the draw options of transversal edges \renewcommand{\pmdraw@drawTedgesDrawOptions}{#1}% } \define@key{pmdraw@brick}{edges first}[]{% Draws edges before vertices \renewcommand{\pmdraw@ifEdgesFirst}{1}% } \define@key{pmdraw@brick}{transversals first}[]{% Draws transversal edges before non-transversal edges \renewcommand{\pmdraw@ifTedgesFirst}{1}% } \define@key{pmdraw@brick}{brace}{% Draws a brace \setkeys{pmdraw@brace}{#1}% Processes details of brace \pmdraw@drawBrace{\value{pmdraw@braceL}}{\value{pmdraw@braceR}}{\pmdraw@braceLabel}% Draws brace \let\pmdraw@drawBrace\pmdraw@drawBraceDefault% Resets brace options if changed } \define@key{pmdraw@brick}{brace draw}{% Sets the draw options for drawing of brace \renewcommand{\pmdraw@drawBraceDrawOptions}{#1}% } \define@key{pmdraw@brick}{brace node}{% Sets the node options for drawing of brace \renewcommand{\pmdraw@drawBraceNodeOptions}{#1}% } \define@key{pmdraw@brick}{decorate before}{% Hook for decorations before brick is drawn \renewcommand{\pmdraw@hookBeforeBrick}{#1}% } \define@key{pmdraw@brick}{decorate after}{% Hook for decorations after brick is drawn \renewcommand{\pmdraw@hookAfterBrick}{#1}% } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % Keys for edges % % - ordered as per manual % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \define@key{pmdraw@NTedges}{level}{% Sets level of non-transversal edge \setcounter{pmdraw@NTlevel}{#1}% } \define@key{pmdraw@NTedges}{height}{% Sets manual height of non-transversal edge \renewcommand{\pmdraw@NTedgesHeight}{#1}% } \define@key{pmdraw@NTedges}{edge draw}{% Sets the draw options for drawing of edge \renewcommand{\pmdraw@drawEdgeDrawOptions}{#1}% } \define@key{pmdraw@NTedges}{options}{% Sets the draw command of non-transversal edge \renewcommand{\pmdraw@drawUedgesDraw}[2]{#1}% \renewcommand{\pmdraw@drawLedgesDraw}[2]{#1}% } \define@key{pmdraw@Tedges}{height}{% Sets manual height of transversal edge \tikzmath{% \pmdraw{Tlevel} = #1;% }% \renewcommand{\pmdraw@ifTedgeHorizontal}{1}% Flags manual height } \define@key{pmdraw@Tedges}{edge draw}{% Sets the draw options for drawing of edge \renewcommand{\pmdraw@drawEdgeDrawOptions}{#1}% } \define@key{pmdraw@Tedges}{options}{% Sets the draw command of transversal edge \renewcommand{\pmdraw@drawTedgesDraw}[2]{#1}% } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % Keys for brace % % - ordered as per manual % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \define@key{pmdraw@brace}{left}{% Sets starting position of brace \setcounter{pmdraw@braceL}{#1}% } \define@key{pmdraw@brace}{right}{% Sets terminating position of brace \setcounter{pmdraw@braceR}{#1}% } \define@key{pmdraw@brace}{label}{% Sets label of brace \renewcommand{\pmdraw@braceLabel}{#1}% } \define@key{pmdraw@brace}{above}[]{% Set flag to draw brace above diagram \renewcommand{\pmdraw@ifProdDiag}{1}% } \define@key{pmdraw@brace}{options}{% Sets the draw command of brace \renewcommand{\pmdraw@drawBrace}[3]{#1}% } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % Keys for diagrams and product diagrams % % - ordered as per manual % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \define@key{pmdraw@diagram}{row sep}{% Sets vertical separation between rows of vertices in diagram \renewcommand{\pmdraw@rowSep}{#1}% } \define@key{pmdraw@diagram}{tikz}{% Sets the tikz options \renewcommand{\pmdraw@tikz}{#1}% } \define@key{pmdraw@diagram}{dots options}{% Sets the draw command of dots between bricks \renewcommand{\pmdraw@drawDots}[2]{#1}% } \define@key{pmdraw@diagram}{grid}[]{% Flag for drawing coordinate grid \renewcommand{\pmdraw@ifGrid}{1}% } \define@key{pmdraw@diagram}{decorate before}{% Hook before drawing diagrams \renewcommand{\pmdraw@hookBeforeDiagram}{#1}% } \define@key{pmdraw@diagram}{decorate after}{% Hook after drawing diagrams \renewcommand{\pmdraw@hookAfterDiagram}{#1}% } \define@key{pmdraw@diagram}{diagram sep}{% Sets vertical separation between bottom row of top diagram and top row of bottom diagram in product diagram \renewcommand{\pmdraw@diagSep}{#1}% } \define@key{pmdraw@diagram}{vertex sep}{% Sets vertical separation between bottom row of top diagram and top row of bottom diagram in product diagram not for added edges \renewcommand{\pmdraw@vertexSep}{#1}% } \define@key{pmdraw@diagram}{edges added}{% Sets the draw options for drawing of added edges in product diagram \renewcommand{\pmdraw@drawAedgesOptions}{#1}% } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % User commands % % - loosely ordered alphabetically % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \newcommand{\pmdBrick}[4][]{% Draws brick % #1 Options % #2 Upper non-transversal edges, as list []{}{}, eg [level=1]{2}{3} % #3 Lower non-transversal edges, as list []{}{}, eg [level=1]{2}{3} % #4 Transversals, as list []{}{}, eg [level=1]{2}{3} \pmdDiagram{{[#1]{#2}{#3}{#4}}}% Uses complete diagram method to draw brick } \newcommand{\pmdDiagram}[2][]{% Draws diagram % #1 Options % #2 List of bricks \setkeys{pmdraw@diagram}{#1}% Processes options \renewcommand{\pmdraw@ifDiagWDots}{1}% Flags that diagram has dots \setcounter{pmdraw@brickShift}{0}% Reset shifting of individual bricks \ifmmode% If drawing diagram in a maths equation \,% Add space \ifnum\pmdraw@ifGrid=1% If displaying helper grid \begin{tikzpicture}[scale=.5,baseline=0.405cm,show grid=true,apply style/.expand once=\pmdraw@tikz]% \else% If not displaying helper grid \begin{tikzpicture}[scale=.5,baseline=0.405cm,apply style/.expand once=\pmdraw@tikz]% \fi% \pmdraw@hookBeforeDiagram% Hook before drawing diagrams \pmdraw@bricksLoop% Commences loop for each brick to be drawn #2% \pmdEmpty% Terminates loop \pmdraw@hookAfterDiagram% Hook after drawing diagrams \end{tikzpicture}% \,% Add space \else% If drawing diagram in normal text \raisebox{0.5cm}{% Raise diagram so bottom row is on text baseline \ifnum\pmdraw@ifGrid=1% If displaying helper grid \begin{tikzpicture}[scale=.5,baseline=0.405cm,show grid=true,apply style/.expand once=\pmdraw@tikz]% \else% If not displaying helper grid \begin{tikzpicture}[scale=.5,baseline=0.405cm,apply style/.expand once=\pmdraw@tikz]% \fi% \pmdraw@hookBeforeDiagram% Hook before drawing diagrams \pmdraw@bricksLoop% Commences loop for each brick to be drawn #2% \pmdEmpty% Terminates loop \pmdraw@hookAfterDiagram% Hook after drawing diagrams \end{tikzpicture}% }% \fi% \pmdraw@reset% Resets user keys and other flags to default values } \newcommand{\pmdEmpty}{}% Indicates no edges, internally halts input loops, always is = {} \newcommand{\pmdProduct}[4][]{% Draws product diagram % #1 Options % #2 List of added edges % #3 Top diagram as list of bricks % #4 Bottom diagram as list of bricks \setkeys{pmdraw@diagram}{#1}% Processes options \ifmmode% If drawing diagram in a maths equation \,% Add space \ifnum\pmdraw@ifGrid=1% If displaying helper grid \begin{tikzpicture}[scale=.5,baseline=-.3475cm,show grid=true,apply style/.expand once=\pmdraw@tikz]% \else% If not displaying helper grid \begin{tikzpicture}[scale=.5,baseline=-.3475cm,apply style/.expand once=\pmdraw@tikz]% \fi% \pmdraw@hookBeforeDiagram% Hook before drawing diagrams \pmdraw@AedgesLoop% Commences loop for added edges to be drawn #2% \pmdEmpty% Terminates loop \renewcommand{\pmdraw@ifDiagWDots}{1}% Flags that diagram has dot \renewcommand{\pmdraw@ifProdDiag}{1}% Flags that diagram is product \setcounter{pmdraw@brickShift}{0}% Reset shifting of individual bricks \pmdraw@bricksLoop% Commences loop for each brick to be drawn #3% \pmdEmpty% Terminates loop \renewcommand{\pmdraw@ifProdDiag}{0}% Resets flag that diagram is product \setcounter{pmdraw@ifDiagWDotsFirst}{1}% Reset if drawing first brick of diagram \setcounter{pmdraw@brickShift}{0}% Reset shifting of individual bricks \begin{scope}[shift={(0,-\pmdraw@diagSep-\pmdraw@rowSep-\pmdraw@vertexSep)}]% Shift coordinates to be underneath top diagram \pmdraw@bricksLoop% Commences loop for each brick to be drawn #4% \pmdEmpty% Terminates loop \renewcommand{\pmdraw@ifDiagWDots}{0}% Reset if drawing a diagram with dots \setcounter{pmdraw@ifDiagWDotsFirst}{1}% Reset if drawing first brick of diagram \end{scope}% \pmdraw@hookAfterDiagram% Hook after drawing diagrams \end{tikzpicture}% \,% Add space \else% If drawing diagram in normal text \raisebox{2cm}{% Raise diagram so bottom row is on text baseline \ifnum\pmdraw@ifGrid=1% If displaying helper grid \begin{tikzpicture}[scale=.5,baseline=0.405cm,show grid=true,apply style/.expand once=\pmdraw@tikz]% \else% If not displaying helper grid \begin{tikzpicture}[scale=.5,baseline=0.405cm,apply style/.expand once=\pmdraw@tikz]% \fi% \pmdraw@hookBeforeDiagram% Hook before drawing diagrams \pmdraw@AedgesLoop% Commences loop for added edges to be drawn #2% \pmdEmpty% Terminates loop \renewcommand{\pmdraw@ifDiagWDots}{1}% Flags that diagram has dot \renewcommand{\pmdraw@ifProdDiag}{1}% Flags that diagram is product \setcounter{pmdraw@brickShift}{0}% Reset shifting of individual bricks \pmdraw@bricksLoop% Commences loop for each brick to be drawn #3% \pmdEmpty% Terminates loop \renewcommand{\pmdraw@ifProdDiag}{0}% Resets flag that diagram is products \setcounter{pmdraw@ifDiagWDotsFirst}{1}% Reset if drawing first brick of diagram \setcounter{pmdraw@brickShift}{0}% Reset shifting of individual bricks \begin{scope}[shift={(0,-\pmdraw@diagSep-\pmdraw@rowSep-\pmdraw@vertexSep)}]% Shift coordinates to be underneath top diagram \pmdraw@bricksLoop% Commences loop for each brick to be drawn #4% \pmdEmpty% Terminates loop \renewcommand{\pmdraw@ifDiagWDots}{0}% Reset if drawing a diagram with dots \setcounter{pmdraw@ifDiagWDotsFirst}{1}% Reset if drawing first brick of diagram \end{scope}% \pmdraw@hookAfterDiagram% Hook after drawing diagrams diagram \end{tikzpicture}% }% \fi% \pmdraw@reset% Resets user keys and other flags to default values } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % For loop commands % % - loosely ordered alphabetically % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \newcommand{\pmdraw@AedgesLoop}{% Starts loop for added edges in product diagram \@ifnextchar\pmdEmpty{}{% If not at end of list \pmdraw@drawAedges% Draw each edge }% } \newcommand{\pmdraw@bricksLoop}{% Starts loop to iterate over each brick in diagram \@ifnextchar\pmdEmpty{}{% If not at end of list \pmdraw@drawBrickInit% Draw each brick }% } \newcommand{\pmdraw@LedgesLoop}{% Starts loop for lower non-transversal edges \@ifnextchar\pmdEmpty{}{% If not at end of list \pmdraw@drawLedges% Draw each edge }% } \newcommand{\pmdraw@TedgesLoop}{% Starts loop for transversal edges \@ifnextchar\pmdEmpty{}{% If not at end of list \pmdraw@drawTedges% Draw each edge }% } \newcommand{\pmdraw@UedgesLoop}{% Starts loop for upper non-transversal edges \@ifnextchar\pmdEmpty{}{% If not at end of list \pmdraw@drawUedges% Draw each edge }% } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % Draw commands % % - loosely ordered alphabetically % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \newcommand{\pmdraw@drawBottomVertices}{% Draws bottom row of vertices \setcounter{pmdraw@bottomTotal}{\value{pmdraw@blankB}}% Store size of bottom row of vertices \addtocounter{pmdraw@bottomTotal}{\value{pmdraw@degreeB}}% Store size of bottom row of vertices \ifnum\value{pmdraw@ifDiagWDotsFirst}=1% If drawing first brick of diagram \setcounter{pmdraw@ifDiagWDotsFirst}{0}% Mark that first brick has been drawn \else% If not drawing first brick of diagram \pmdraw@drawDots{0.5*\value{pmdraw@topShift}+0.5*\value{pmdraw@blankT}}{\pmdraw@rowSep}% Draw upper dots \pmdraw@drawDots{0.5*\value{pmdraw@bottomShift}+0.5*\value{pmdraw@blankB}}{0}% Draw lower dots \fi% \ifnum\value{pmdraw@topTotal}>\value{pmdraw@bottomTotal}% If top row is longer than bottom row \ifnum\pmdraw@ifDiagWDots=1% If drawing a diagram with dots \addtocounter{pmdraw@brickShift}{\value{pmdraw@topTotal}}% Keep track of size of diagram % Store shifts \setcounter{pmdraw@topShift}{-\value{pmdraw@topTotal}}% \addtocounter{pmdraw@topShift}{\value{pmdraw@topTotal}}% \setcounter{pmdraw@bottomShift}{-\value{pmdraw@topTotal}}% \addtocounter{pmdraw@bottomShift}{\value{pmdraw@bottomTotal}}% \else% If drawing a diagram without dots \setcounter{pmdraw@brickShift}{\value{pmdraw@topTotal}}% Keep track of size of diagram \fi% \else% If bottom row is longer than top row \ifnum\pmdraw@ifDiagWDots=1% If drawing a diagram with dots \addtocounter{pmdraw@brickShift}{\value{pmdraw@bottomTotal}}% Keep track of size of diagram % Store shifts \setcounter{pmdraw@topShift}{-\value{pmdraw@bottomTotal}}% \addtocounter{pmdraw@topShift}{\value{pmdraw@topTotal}}% \setcounter{pmdraw@bottomShift}{-\value{pmdraw@bottomTotal}}% \addtocounter{pmdraw@bottomShift}{\value{pmdraw@bottomTotal}}% \else% If drawing a diagram without dots \setcounter{pmdraw@brickShift}{\value{pmdraw@bottomTotal}}% Keep track of size of diagram \fi% \fi% \foreach \x in {1,...,\value{pmdraw@degreeB}} {% For each vertex in row \pmdraw@drawVertex{\x + \value{pmdraw@blankB}}{0}% Draw lower vertex \ifnum\pmdraw@ifLabelsB=1% If drawing labels \pmdraw@drawLabelBottom{\x + \value{pmdraw@blankT}}{0}{\thepmdraw@labelStartB}% Draw label \stepcounter{pmdraw@labelStartB}% Update label counter \fi% }% } \newcommand{\pmdraw@drawBrickInit}[1]{% Initialises the drawing of a brick \ifnum\value{pmdraw@ifDiagWDotsFirst}=0% If not drawing first brick in diagram \stepcounter{pmdraw@brickShift}% Makes space for dots to left of current brick \fi% \begin{scope}[shift={(\value{pmdraw@brickShift},0)}]% Shift brick to the right of already drawn bricks \pmdraw@drawBrick#1% Draw brick \end{scope}% \pmdraw@bricksLoop% Restart for loop } \newcommand{\pmdraw@drawBrick}[4][]{% Draws a brick % #1 Options % #2 Upper non-transversal edges, as list []{}{}, eg [level=1]{2}{3} % #3 Lower non-transversal edges, as list []{}{}, eg [level=1]{2}{3} % #4 Transversals, as list []{}{}, eg [level=1]{2}{3} \setkeys{pmdraw@brick}{levels,#1}% Processes options and set default levels \pmdraw@hookBeforeBrick% Hook before drawing brick \ifnum\pmdraw@ifEdgesFirst=0% If drawing vertices first \pmdraw@drawTopVertices% Draw base diagram \pmdraw@drawBottomVertices% Draw base diagram \ifnum\pmdraw@ifTedgesFirst=0% If drawing non-transversals first \pmdraw@UedgesLoop% Draws upper edges #2% \pmdEmpty% \pmdraw@LedgesLoop% Draws lower edges #3% \pmdEmpty% \pmdraw@TedgesLoop% Draws transversals #4% \pmdEmpty% \else% If drawing transversal first \pmdraw@TedgesLoop% Draws transversals #4% \pmdEmpty% \pmdraw@UedgesLoop% Draws upper edges #2% \pmdEmpty% \pmdraw@LedgesLoop% Draws lower edges #3% \pmdEmpty% \fi% \else% If drawing edges first \ifnum\pmdraw@ifTedgesFirst=0% If drawing non-transversals first \pmdraw@UedgesLoop% Draws upper edges #2% \pmdEmpty% \pmdraw@LedgesLoop% Draws lower edges #3% \pmdEmpty% \pmdraw@TedgesLoop% Draws transversals #4% \pmdEmpty% \else% If drawing transversal first \pmdraw@TedgesLoop% Draws transversals #4% \pmdEmpty% \pmdraw@UedgesLoop% Draws upper edges #2% \pmdEmpty% \pmdraw@LedgesLoop% Draws lower edges #3% \pmdEmpty% \fi% \pmdraw@drawTopVertices% Draw base diagram \pmdraw@drawBottomVertices% Draw base diagram \fi% \pmdraw@hookAfterBrick% Hook after drawing brick % Resets user keys and other flags to default values \renewcommand{\pmdraw@drawBraceDrawOptions}{}% \renewcommand{\pmdraw@drawBraceNodeOptions}{}% \renewcommand{\pmdraw@drawDotsDrawOptions}{}% \renewcommand{\pmdraw@drawDotsNodeOptions}{}% \renewcommand{\pmdraw@drawLabelBDrawOptions}{}% \renewcommand{\pmdraw@drawLabelBNodeOptions}{}% \renewcommand{\pmdraw@drawLabelTDrawOptions}{}% \renewcommand{\pmdraw@drawLabelTNodeOptions}{}% \renewcommand{\pmdraw@drawLedgesDrawOptions}{}% \renewcommand{\pmdraw@drawTedgesDrawOptions}{}% \renewcommand{\pmdraw@drawUedgesDrawOptions}{}% \renewcommand{\pmdraw@drawVertexOptions}{}% \renewcommand{\pmdraw@hookBeforeBrick}{}% \renewcommand{\pmdraw@hookAfterBrick}{}% \renewcommand{\pmdraw@ifEdgesFirst}{0}% \renewcommand{\pmdraw@ifLabelsB}{0}% \renewcommand{\pmdraw@ifLabelsT}{0}% \renewcommand{\pmdraw@ifTedgesFirst}{0}% \let\pmdraw@drawLabelBottom\pmdraw@drawLabelBottomDefault% \let\pmdraw@drawLabelTop\pmdraw@drawLabelTopDefault% \let\pmdraw@drawLabelBottom\pmdraw@drawLabelBottomDefault% \setcounter{pmdraw@blankB}{0}% \setcounter{pmdraw@blankT}{0}% \setcounter{pmdraw@labelStartB}{1}% \setcounter{pmdraw@labelStartT}{1}% } \newcommand{\pmdraw@drawLedges}[3][]{% Draws lower non-transversal edge, #1 options, #2 L vertex, #3 R vertex \setcounter{pmdraw@NTlevel}{1}% Store default level of edge \setkeys{pmdraw@NTedges}{#1}% Processes options \ifdim\pmdraw@NTedgesHeight pt=-1000pt% If using default heights \tikzmath{% \pmdraw{edgeHeight}=\value{pmdraw@NTlevel}*\pmdraw{edgeSepL};% Calculates height based on level of edge }% \else% If using manual heights \tikzmath{% \pmdraw{edgeHeight}=\pmdraw@NTedgesHeight;% Set manual height }% \fi% \pmdraw@drawLedgesDraw{#2}{#3}% Draw edge % Resets user keys and other flags to default values \renewcommand{\pmdraw@NTedgesHeight}{-1000}% \let\pmdraw@drawLedgesDraw\pmdraw@drawLedgesDrawDefault% \pmdraw@LedgesLoop% Restart for loop } \newcommand{\pmdraw@drawTedges}[3][]{% Draws transversal edge, #1 options, #2 upper vertex, #3 lower vertex \setkeys{pmdraw@Tedges}{#1}% Processes options \pmdraw@drawTedgesDraw{#2}{#3}% Draw edge \let\pmdraw@drawTedgesDraw\pmdraw@drawTedgesDrawDefault% Resets user keys and other flags to default values \pmdraw@TedgesLoop% Restart for loop } \newcommand{\pmdraw@drawTopVertices}{% Draws top row of vertices \setcounter{pmdraw@topTotal}{\value{pmdraw@blankT}}% Store size of top row of vertices \addtocounter{pmdraw@topTotal}{\value{pmdraw@degreeT}}% Store size of top row of vertices \foreach \x in {1,...,\value{pmdraw@degreeT}} {% For each vertex in row \pmdraw@drawVertex{\x + \value{pmdraw@blankT}}{\pmdraw@rowSep}% Draw upper vertex \ifnum\pmdraw@ifLabelsT=1% If drawing labels \pmdraw@drawLabelTop{\x + \value{pmdraw@blankT}}{\pmdraw@rowSep}{\thepmdraw@labelStartT}% Draw label \stepcounter{pmdraw@labelStartT}% Update label counter \fi% }% } \newcommand{\pmdraw@drawUedges}[3][]{% Draws upper non-transversal edge, #1 options, #2 L vertex, #3 R vertex \setcounter{pmdraw@NTlevel}{1}% Store default level of edge \setkeys{pmdraw@NTedges}{#1}% Processes options \ifdim\pmdraw@NTedgesHeight pt=-1000pt% If using default heights \tikzmath{% \pmdraw{edgeHeight}=\value{pmdraw@NTlevel}*\pmdraw{edgeSepU};% Calculates height based on level of edge }% \else% If using manual heights \tikzmath{% \pmdraw{edgeHeight}=\pmdraw@rowSep-\pmdraw@NTedgesHeight;% Set manual height }% \fi% \pmdraw@drawUedgesDraw{#2}{#3}% Draw edge % Resets user keys and other flags to default values \renewcommand{\pmdraw@NTedgesHeight}{-1000}% \let\pmdraw@drawLedgesDraw\pmdraw@drawLedgesDrawDefault% \let\pmdraw@drawUedgesDraw\pmdraw@drawUedgesDrawDefault% \pmdraw@UedgesLoop% Restart for loop } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % Grid creation % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % This is a verbatim copy of: % https://tex.stackexchange.com/a/467908 \newif\if@showgrid@grid \newif\if@showgrid@left \newif\if@showgrid@right \newif\if@showgrid@below \newif\if@showgrid@above \tikzset{% every show grid/.style={}, show grid/.style={execute at end picture={\@showgrid{grid=true,#1}}},% show grid/.default={true}, show grid/.cd, labels/.style={font={\sffamily\small},help lines}, xlabels/.style={}, ylabels/.style={}, keep bb/.code={\useasboundingbox (current bounding box.south west) rectangle (current bounding box.north west);}, true/.style={left,below}, false/.style={left=false,right=false,above=false,below=false,grid=false}, none/.style={left=false,right=false,above=false,below=false}, all/.style={left=true,right=true,above=true,below=true}, grid/.is if=@showgrid@grid, left/.is if=@showgrid@left, right/.is if=@showgrid@right, below/.is if=@showgrid@below, above/.is if=@showgrid@above, false, } \def\@showgrid#1{% \begin{scope}[every show grid,show grid/.cd,#1] \if@showgrid@grid \begin{pgfonlayer}{background} \draw [help lines] (current bounding box.south west) grid (current bounding box.north east); % \pgfpointxy{1}{1}% \edef\xs{\the\pgf@x}% \edef\ys{\the\pgf@y}% \pgfpointanchor{current bounding box}{south west} \edef\xa{\the\pgf@x}% \edef\ya{\the\pgf@y}% \pgfpointanchor{current bounding box}{north east} \edef\xb{\the\pgf@x}% \edef\yb{\the\pgf@y}% \pgfmathtruncatemacro\xbeg{ceil(\xa/\xs)} \pgfmathtruncatemacro\xend{floor(\xb/\xs)} \if@showgrid@below \foreach \X in {\xbeg,...,\xend} { \node [below,show grid/labels,show grid/xlabels] at (\X,\ya) {\X}; } \fi \if@showgrid@above \foreach \X in {\xbeg,...,\xend} { \node [above,show grid/labels,show grid/xlabels] at (\X,\yb) {\X}; } \fi \pgfmathtruncatemacro\ybeg{ceil(\ya/\ys)} \pgfmathtruncatemacro\yend{floor(\yb/\ys)} \if@showgrid@left \foreach \Y in {\ybeg,...,\yend} { \node [left,show grid/labels,show grid/ylabels] at (\xa,\Y) {\Y}; } \fi \if@showgrid@right \foreach \Y in {\ybeg,...,\yend} { \node [right,show grid/labels,show grid/ylabels] at (\xb,\Y) {\Y}; } \fi \end{pgfonlayer} \fi \end{scope} } \tikzset{every show grid/.style={show grid/keep bb}}% Keep the original bounding box! \endinput