diff options
Diffstat (limited to 'Master/texmf-dist/tex/latex/pmdraw/pmdraw.sty')
-rw-r--r-- | Master/texmf-dist/tex/latex/pmdraw/pmdraw.sty | 903 |
1 files changed, 903 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/latex/pmdraw/pmdraw.sty b/Master/texmf-dist/tex/latex/pmdraw/pmdraw.sty new file mode 100644 index 00000000000..9799aa628ba --- /dev/null +++ b/Master/texmf-dist/tex/latex/pmdraw/pmdraw.sty @@ -0,0 +1,903 @@ +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{pmdraw}[2023-11-08 v1.0 pmdraw] + +% *------------------------------* +% |4````````````````````````````9| +% |`````____````____`````````````| +% |````|MFMF\ /MFMF|````````````| +% |````|MF|MF\/MF|MF|````````````| +% |````|MF|\MFMF/|MF|_______`````| +% |````|MF|``````|MFMFMFMFMF|````| +% |````|MF|``````|MF|````````````| +% |````|MF|``````|MF|___`````````| +% |``````````````|MFMFMF|````````| +% |``````````````|MF|````````````| +% |``````````````|MF|````````````| +% |``````````````|MF|````````````| +% |9````````````````````````````6| +% *------------------------------* + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% 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@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] (#1,0) arc (180:90:\pmdraw{edgeHeight}); % Draw left arch + \draw[apply style/.expand once=\pmdraw@drawLedgesDrawOptions] (#1+\pmdraw{edgeHeight},\pmdraw{edgeHeight}) -- (#2-\pmdraw{edgeHeight},\pmdraw{edgeHeight}); % Draw straight line + \draw[apply style/.expand once=\pmdraw@drawLedgesDrawOptions] (#2-\pmdraw{edgeHeight},\pmdraw{edgeHeight}) arc (90:0:\pmdraw{edgeHeight}); % Draw right arc +} +\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] (#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] (#2,0) arc (180:90:\pmdraw{Tlevel}); % Draw bottom arch + \draw[apply style/.expand once=\pmdraw@drawTedgesDrawOptions] (#2+\pmdraw{Tlevel},\pmdraw{Tlevel}) -- (#1-\pmdraw@rowSep+\pmdraw{Tlevel}, \pmdraw{Tlevel}); % Draw straight line + \draw[apply style/.expand once=\pmdraw@drawTedgesDrawOptions] (#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] (#2,0) arc (0:90:\pmdraw{Tlevel}); % Draw bottom arch + \draw[apply style/.expand once=\pmdraw@drawTedgesDrawOptions] (#2-\pmdraw{Tlevel},\pmdraw{Tlevel}) -- (#1+\pmdraw@rowSep-\pmdraw{Tlevel}, \pmdraw{Tlevel}); % Draw straight line + \draw[apply style/.expand once=\pmdraw@drawTedgesDrawOptions] (#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% +} +\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] (#1,\pmdraw@rowSep) arc (180:270:\pmdraw{edgeHeight}); % Draw left arch + \draw[apply style/.expand once=\pmdraw@drawUedgesDrawOptions] (#1+\pmdraw{edgeHeight},\pmdraw@rowSep-\pmdraw{edgeHeight}) -- (#2-\pmdraw{edgeHeight},\pmdraw@rowSep-\pmdraw{edgeHeight}); % Draw straight line + \draw[apply style/.expand once=\pmdraw@drawUedgesDrawOptions] (#2-\pmdraw{edgeHeight},\pmdraw@rowSep-\pmdraw{edgeHeight}) arc (270:360:\pmdraw{edgeHeight}); % Draw right arc +} +\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 + \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 + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% 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}{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}{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}{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}{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 [<options>]{<left vertex>}{<right vertex>}, eg [level=1]{2}{3} + % #3 Lower non-transversal edges, as list [<options>]{<left vertex>}{<right vertex>}, eg [level=1]{2}{3} + % #4 Transversals, as list [<options>]{<upper vertex>}{<lower vertex>}, 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]% + \else% If not displaying helper grid + \begin{tikzpicture}[scale=.5,baseline=0.405cm]% + \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]% + \else% If not displaying helper grid + \begin{tikzpicture}[scale=.5,baseline=0.405cm]% + \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]% + \else% If not displaying helper grid + \begin{tikzpicture}[scale=.5,baseline=-.3475cm]% + \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)}]% 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]% + \else% If not displaying helper grid + \begin{tikzpicture}[scale=.5,baseline=0.405cm]% + \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)}]% 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 [<options>]{<left vertex>}{<right vertex>}, eg [level=1]{2}{3} + % #3 Lower non-transversal edges, as list [<options>]{<left vertex>}{<right vertex>}, eg [level=1]{2}{3} + % #4 Transversals, as list [<options>]{<upper vertex>}{<lower vertex>}, 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
\ No newline at end of file |