% Copyright 2011 by FlorĂȘncio Neves % % This file may be distributed and/or modified % % 1. under the LaTeX Project Public License and/or % 2. under the GNU Public License. % \ProvidesPackage{tikz-cd}[2011/10/21 v0.2 Commutative diagrams with tikz.] \RequirePackage{tikz} \usetikzlibrary{matrix} \usepgflibrary{arrows} \usetikzlibrary{decorations.pathmorphing} \newtoks\tikzcd@temptoksa \newtoks\tikzcd@temptoksb \newtoks\tikzcd@temptoksc \newif\iftikzcd@mathmode \newcount\tikzcd@currcol \newcount\tikzcd@currrow \newcount\tikzcd@targetrow \newcount\tikzcd@targetcol \pgfqkeys{/tikz/commutative diagrams}{ /tikz/commutative diagrams/.search also={/tikz}, arrows/.style={ /tikz/commutative diagrams/every arrow/.append style={#1}}, labels/.style={ /tikz/commutative diagrams/every label/.append style={#1}}, diagrams/.style={ /tikz/commutative diagrams/every diagram/.append style={#1}}, description/.style={ /tikz/anchor=center, text height=, text depth=, /tikz/fill=\pgfkeysvalueof{/tikz/commutative diagrams/background color}, /tikz/inner sep=\pgfkeysvalueof{/tikz/commutative diagrams/description clearance}}, crossing over/.style={ /tikz/preaction={ /tikz/draw=\pgfkeysvalueof{/tikz/commutative diagrams/background color}, /tikz/arrows=-, /tikz/line width=\pgfkeysvalueof{/tikz/commutative diagrams/crossing over clearance}}}, row sep/.code={\tikzcd@sep{row}{#1}}, column sep/.code={\tikzcd@sep{column}{#1}}, math mode/.is if=tikzcd@mathmode, matrix of math nodes maybe/.style={% /tikz/matrix of nodes, /tikz/nodes={ execute at begin node=\iftikzcd@mathmode$\fi, %$ execute at end node=\iftikzcd@mathmode$\fi}}, %$ path operation/.store in=\tikzcd@pathoperator, start anchor/.code={% \ifx#1\pgfkeysnovalue\let\tikzcd@sourceanchor\empty% \else\def\tikzcd@sourceanchor{.#1}\fi}, end anchor/.code={% \ifx#1\pgfkeysnovalue\let\tikzcd@targetanchor\empty% \else\def\tikzcd@targetanchor{.#1}\fi}, arrow style/.is choice} % The Computer Modern arrow style \pgfkeys{/tikz/commutative diagrams/arrow style/computer modern/.style={ /tikz/commutative diagrams/.cd, default arrow/.style={ /tikz/line join=round, /tikz/arrows=cm cap-cm to, /tikz/line width=0.0929ex}, rightarrow/.style={/tikz/arrows=cm cap-cm to}, Rightarrow/.style={ /tikz/arrows=cm implies cap-cm implies, /tikz/commutative diagrams/double line}, leftarrow/.style={/tikz/arrows=cm to-cm cap}, Leftarrow/.style={ /tikz/arrows=cm implies-cm implies cap, /tikz/commutative diagrams/double line}, leftrightarrow/.style={/tikz/arrows=cm to-cm to}, Leftrightarrow/.style={ /tikz/arrows=cm implies-cm implies, /tikz/commutative diagrams/double line}, mapsto/.style={/tikz/arrows=cm |-cm to}, hookrightarrow/.style={/tikz/arrows=cm right hook-cm to}, hookleftarrow/.style={/tikz/arrows=cm to-cm left hook}, rightharpoonup/.style={/tikz/arrows=cm cap-cm left to}, rightharpoondown/.style={/tikz/arrows=cm cap-cm right to}, leftharpoonup/.style={/tikz/arrows=cm right to-cm cap}, leftharpoondown/.style={/tikz/arrows=cm left to-cm cap}, dashrightarrow/.style={/tikz/commutative diagrams/.cd,rightarrow,dashed}, dashleftarrow/.style={/tikz/commutative diagrams/.cd,leftarrow,dashed}, rightarrowtail/.style={/tikz/arrows=cm to reversed-cm to}, leftarrowtail/.style={/tikz/arrows=cm to-cm to reversed}, twoheadrightarrow/.style={/tikz/arrows=cm cap-cm double to}, twoheadleftarrow/.style={/tikz/arrows=cm double to-cm cap}, rightsquigarrow/.style={/tikz/commutative diagrams/.cd,rightarrow,squiggly}, leftsquigarrow/.style={/tikz/commutative diagrams/.cd,leftarrow,squiggly}, leftrightsquigarrow/.style={ /tikz/commutative diagrams/.cd,leftrightarrow,squiggly}, equals/.style={ /tikz/arrows=cm implies cap-cm implies cap, /tikz/commutative diagrams/double line}, maps to/.code={\pgfsetarrowsstart{cm |}}, hook/.code={\pgfsetarrowsstart{cm right hook}}, two heads/.code={\pgfsetarrowsend{cm double to}}, tail/.code={\pgfsetarrowsstart{cm to reversed}}, squiggly/.style={ %http://tex.stackexchange.com/questions/12678/ decorate, decoration={ zigzag, segment length=4, amplitude=.9, post=lineto, post length=2pt, pre=lineto, pre length=2pt}}, double line/.style={ /tikz/double=\pgfkeysvalueof{/tikz/commutative diagrams/background color}, /tikz/double distance=3.643\pgflinewidth}, dashed/.style={/tikz/densely dashed}}} % The tikz arrow style \pgfkeys{/tikz/commutative diagrams/arrow style/tikz/.style={ /tikz/commutative diagrams/.cd, default arrow/.style={/tikz/arrows=->}, rightarrow/.style={/tikz/arrows=->}, Rightarrow/.style={ /tikz/arrows=-implies, /tikz/commutative diagrams/double line}, leftarrow/.style={/tikz/arrows=<-}, Leftarrow/.style={ /tikz/arrows=implies-, /tikz/commutative diagrams/double line}, leftrightarrow/.style={/tikz/arrows=<->}, Leftrightarrow/.style={ /tikz/arrows=implies-implies, /tikz/commutative diagrams/double line}, mapsto/.style={/tikz/arrows=|->}, hookrightarrow/.style={/tikz/arrows=right hook->}, hookleftarrow/.style={/tikz/arrows=<-left hook}, rightharpoonup/.style={/tikz/arrows=-left to}, rightharpoondown/.style={/tikz/arrows=-right to}, leftharpoonup/.style={/tikz/arrows=right to-}, leftharpoondown/.style={/tikz/arrows=left to-}, dashrightarrow/.style={/tikz/commutative diagrams/.cd,rightarrow,dashed}, dashleftarrow/.style={/tikz/commutative diagrams/.cd,leftarrow,dashed}, rightarrowtail/.style={/tikz/arrows=>->}, leftarrowtail/.style={/tikz/arrows=<-<}, twoheadrightarrow/.style={/tikz/arrows=->>}, twoheadleftarrow/.style={/tikz/arrows=<<-}, rightsquigarrow/.style={ /tikz/commutative diagrams/.cd, rightarrow, squiggly}, leftsquigarrow/.style={ /tikz/commutative diagrams/.cd, leftarrow, squiggly}, leftrightsquigarrow/.style={ /tikz/commutative diagrams/.cd, leftrightarrow, squiggly}, equals/.style={ /tikz/arrows=-, /tikz/commutative diagrams/double line}, maps to/.code={\pgfsetarrowsstart{|}}, hook/.code={\pgfsetarrowsstart{right hook}}, two heads/.code={ \pgfsetarrowsend{\csname tikz@special@arrow@end>>\endcsname}}, tail/.code={ \pgfsetarrowsstart{\csname tikz@special@arrow@start>\endcsname}}, squiggly/.style={ %http://tex.stackexchange.com/questions/12678/ decorate, decoration={ zigzag, segment length=4, amplitude=.9, post=lineto, post length=2pt, pre=lineto, pre length=2pt}}, double line/.style={ /tikz/double=\pgfkeysvalueof{/tikz/commutative diagrams/background color}}}} % Default settings \pgfqkeys{/tikz/commutative diagrams}{ every arrow/.style={ /tikz/commutative diagrams/.cd, /tikz/draw, /tikz/commutative diagrams/default arrow}, every label/.style={ /tikz/commutative diagrams/.cd, /tikz/auto, /tikz/font=\scriptsize, /tikz/inner sep=0.5ex, /tikz/text height=, /tikz/text depth=}, every diagram/.style={ /tikz/commutative diagrams/.cd, row sep=normal, column sep=normal, /tikz/text height=1.5ex, /tikz/text depth=0.25ex, /tikz/baseline=0pt}, math mode=true, row sep/huge/.initial=10ex, row sep/large/.initial=7.5ex, row sep/normal/.initial=5ex, row sep/scriptsize/.initial=3.75ex, row sep/small/.initial=2.5ex, row sep/tiny/.initial=1.25ex, column sep/huge/.initial=12ex, column sep/large/.initial=9ex, column sep/normal/.initial=6ex, column sep/scriptsize/.initial=4.5ex, column sep/small/.initial=3ex, column sep/tiny/.initial=1.5ex, arrow style=computer modern, path operation=to, start anchor, end anchor, description clearance/.initial=1.5pt, crossing over clearance/.initial=6pt, background color/.initial=white} % Branch depending on whether the next character is [, { or none of those. \def\tikzcd@threefold#1#2#3{% \def\tikzcd@tempa{#1}% \def\tikzcd@tempb{#2}% \def\tikzcd@tempc{#3}% \futurelet\next\tikzcd@@threefold} \def\tikzcd@@threefold{% \ifx[\next\let\tikzcd@tempd\tikzcd@tempa% \else\ifx\bgroup\next\let\tikzcd@tempd\tikzcd@tempb% \else\let\tikzcd@tempd\tikzcd@tempc\fi\fi% \tikzcd@tempd} %The arrow commands \def\tikzcd@arrow{% \tikzcd@targetrow\tikzcd@currrow% \tikzcd@targetcol\tikzcd@currcol% \tikzcd@threefold{\tikzcd@ar@getdir}{\tikzcd@ar@getdir[]}{}} \def\tikzcd@ar@getdir[#1]#2{% \tikzcd@temptoksa{\path[/tikz/commutative diagrams/every arrow,#1]}% \tikzcd@parse#2\relax% \tikzcd@temptoksb{}% this will store the labels \tikzcd@threefold{\tikzcd@ar@getlabel}{\tikzcd@ar@getlabel[]}{\tikzcd@ar@final}} \def\tikzcd@ar@getlabel[#1]#2{% \tikzcd@temptoksb\expandafter{\the\tikzcd@temptoksb % node[/tikz/commutative diagrams/every label,#1]{\tikzcd@mathmaybe{#2}}}% \tikzcd@threefold{\tikzcd@ar@getlabel}{\tikzcd@ar@getlabel[]}{\tikzcd@ar@final}} \def\tikzcd@ar@final{% \tikzcd@temptoksc\expandafter{\tikzcd@savedpaths}% \global\edef\tikzcd@savedpaths{% \the\tikzcd@temptoksc% the previously saved stuff \the\tikzcd@temptoksa% the current arrow (\tikzmatrixname-\the\tikzcd@currrow-\the\tikzcd@currcol% \noexpand\tikzcd@sourceanchor)% \noexpand\tikzcd@pathoperator% \the\tikzcd@temptoksb% the current labels (\tikzmatrixname-\the\tikzcd@targetrow-\the\tikzcd@targetcol% \noexpand\tikzcd@targetanchor);}} \def\tikzcd@xar#1#2{% \tikzcd@targetrow\tikzcd@currrow% \advance\tikzcd@targetrow by#1% \tikzcd@targetcol\tikzcd@currcol% \advance\tikzcd@targetcol by#2% \tikzcd@threefold{\tikzcd@@xar}{\tikzcd@@xar[]}{\tikzcd@@xar[]}} \def\tikzcd@@xar[#1]{% \tikzcd@temptoksa{\path[/tikz/commutative diagrams/every arrow,#1]}% \tikzcd@temptoksb{}% this will store the labels \tikzcd@threefold{\tikzcd@ar@getlabel}{\tikzcd@ar@getlabel[]}{\tikzcd@ar@final}} % Parser for arrow direction argument \def\tikzcd@parse#1{% \def\tikzcd@tempa{\tikzcd@parse}% \ifx#1r\advance\tikzcd@targetcol by1\else% \ifx#1d\advance\tikzcd@targetrow by1\else% \ifx#1l\advance\tikzcd@targetcol by-1\else% \ifx#1u\advance\tikzcd@targetrow by-1\else% \ifx#1\relax\let\tikzcd@tempa\empty% \else\errmessage{Arrow direction argument must contain % only the characters l, r, u or d}\fi\fi\fi\fi\fi% \tikzcd@tempa} %The tikzcd environment \def\tikzcd{\tikzcd@threefold{\tikzcd@}{\tikzcd@[]}{\tikzcd@[]}} \def\tikzcd@[#1]{% \tikzpicture[/tikz/commutative diagrams/every diagram,#1]% \tikzcd@initialize% \matrix[/tikz/commutative diagrams/matrix of math nodes maybe,% /tikz/execute at begin cell=% \tikzcd@currcol\pgfmatrixcurrentcolumn% \tikzcd@currrow\pgfmatrixcurrentrow]% \bgroup} \def\endtikzcd{% \pgfmatrixendrow\egroup;% \tikzcd@finalize% \endtikzpicture} \def\tikzcd@initialize{% \def\arrow{\tikzcd@arrow}% \def\ar{\tikzcd@arrow}% \def\rar{\tikzcd@xar{0}{1}}% \def\lar{\tikzcd@xar{0}{-1}}% \def\dar{\tikzcd@xar{1}{0}}% \def\uar{\tikzcd@xar{-1}{0}}% \def\urar{\tikzcd@xar{-1}{1}}% \def\ular{\tikzcd@xar{-1}{-1}}% \def\drar{\tikzcd@xar{1}{1}}% \def\dlar{\tikzcd@xar{1}{-1}}% \global\let\tikzcd@savedpaths\empty} \def\tikzcd@finalize{\tikzcd@savedpaths} \def\tikzcd@mathmaybe#1{\iftikzcd@mathmode$#1$\else#1\fi} \def\tikzcd@sep#1#2{ \pgfkeysifdefined{/tikz/commutative diagrams/#1 sep/#2}% {\tikzset{#1 sep=\pgfkeysvalueof{/tikz/commutative diagrams/#1 sep/#2}}}% {\tikzset{#1 sep=#2}}} %Computer modern arrow tips \pgfarrowsdeclare{cm to}{cm to} { \pgfarrowsleftextend{-5.833\pgflinewidth} \pgfarrowsrightextend{0.5\pgflinewidth} } { \pgfutil@tempdima=\pgflinewidth \pgfsetdash{}{+0pt} \pgfsetroundcap \pgfsetroundjoin \pgfpathmoveto{\pgfqpoint{-5.333\pgfutil@tempdima}{6\pgfutil@tempdima}} \pgfpathcurveto {\pgfqpoint{-4.2\pgfutil@tempdima}{2.5\pgfutil@tempdima}} {\pgfqpoint{-2.133\pgfutil@tempdima}{0.6\pgfutil@tempdima}} {\pgfpointorigin} \pgfpathcurveto {\pgfqpoint{-2.133\pgfutil@tempdima}{-0.6\pgfutil@tempdima}} {\pgfqpoint{-4.2\pgfutil@tempdima}{-2.5\pgfutil@tempdima}} {\pgfqpoint{-5.333\pgfutil@tempdima}{-6\pgfutil@tempdima}} \pgfusepathqstroke } \pgfarrowsdeclare{cm implies}{cm implies} { \pgfmathsetlength{\pgfutil@tempdima}{-0.729\pgflinewidth+.25*\pgfinnerlinewidth} \pgfarrowsleftextend{\pgfutil@tempdima} \pgfmathsetlength{\pgfutil@tempdima}{1.094\pgflinewidth-.25*\pgfinnerlinewidth} \pgfarrowsrightextend{\pgfutil@tempdima} } { \pgfmathsetlength{\pgfutil@tempdimb}{.5\pgflinewidth-.5*\pgfinnerlinewidth} \pgfutil@tempdima\pgflinewidth \pgfsetlinewidth{\pgfutil@tempdimb} \pgfsetdash{}{+0pt} \pgfsetroundcap \pgfsetroundjoin \pgfpathmoveto{\pgfqpoint{-0.542\pgfutil@tempdima}{1.142\pgfutil@tempdima}} \pgfpathcurveto {\pgfqpoint{-0.247\pgfutil@tempdima}{0.476\pgfutil@tempdima}} {\pgfqpoint{0.29\pgfutil@tempdima}{0.114\pgfutil@tempdima}} {\pgfqpoint{0.844\pgfutil@tempdima}{0pt}} \pgfpathcurveto {\pgfqpoint{0.29\pgfutil@tempdima}{-0.114\pgfutil@tempdima}} {\pgfqpoint{-0.247\pgfutil@tempdima}{-0.476\pgfutil@tempdima}} {\pgfqpoint{-0.542\pgfutil@tempdima}{-1.142\pgfutil@tempdima}} \pgfusepathqstroke } \pgfarrowsdeclare{cm bold to}{cm bold to} { \pgfarrowsleftextend{-4.055\pgflinewidth} \pgfarrowsrightextend{0.5\pgflinewidth} } { \pgfutil@tempdima=0.667\pgflinewidth \pgfsetdash{}{+0pt} \pgfsetroundcap \pgfsetroundjoin \pgfpathmoveto{\pgfqpoint{-5.333\pgfutil@tempdima}{6\pgfutil@tempdima}} \pgfpathcurveto {\pgfqpoint{-4.2\pgfutil@tempdima}{2.5\pgfutil@tempdima}} {\pgfqpoint{-2.133\pgfutil@tempdima}{0.6\pgfutil@tempdima}} {\pgfpointorigin} \pgfpathcurveto {\pgfqpoint{-2.133\pgfutil@tempdima}{-0.6\pgfutil@tempdima}} {\pgfqpoint{-4.2\pgfutil@tempdima}{-2.5\pgfutil@tempdima}} {\pgfqpoint{-5.333\pgfutil@tempdima}{-6\pgfutil@tempdima}} \pgfusepathqstroke } \pgfarrowsdeclare{cm left to}{cm left to} { \pgfarrowsleftextend{-5.833\pgflinewidth} \pgfarrowsrightextend{0.5\pgflinewidth} } { \pgfutil@tempdima=\pgflinewidth \pgfsetdash{}{+0pt} \pgfsetroundcap \pgfsetroundjoin \pgfpathmoveto{\pgfqpoint{-5.333\pgfutil@tempdima}{6\pgfutil@tempdima}} \pgfpathcurveto {\pgfqpoint{-4.2\pgfutil@tempdima}{2.5\pgfutil@tempdima}} {\pgfqpoint{-2.133\pgfutil@tempdima}{0.6\pgfutil@tempdima}} {\pgfpointorigin} \pgfusepathqstroke } \pgfarrowsdeclare{cm right to}{cm right to} { \pgfarrowsleftextend{-5.833\pgflinewidth} \pgfarrowsrightextend{0.5\pgflinewidth} } { \pgfutil@tempdima=\pgflinewidth \pgfsetdash{}{+0pt} \pgfsetroundcap \pgfsetroundjoin \pgfpathmoveto{\pgfpointorigin} \pgfpathcurveto {\pgfqpoint{-2.133\pgfutil@tempdima}{-0.6\pgfutil@tempdima}} {\pgfqpoint{-4.2\pgfutil@tempdima}{-2.5\pgfutil@tempdima}} {\pgfqpoint{-5.333\pgfutil@tempdima}{-6\pgfutil@tempdima}} \pgfusepathqstroke } \pgfarrowsdeclare{cm |}{cm |} { \pgfarrowsleftextend{-0.5\pgflinewidth} \pgfarrowsrightextend{0.5\pgflinewidth} } { \pgfsetdash{}{+0pt} \pgfsetroundcap \pgfpathmoveto{\pgfqpoint{0pt}{-4\pgflinewidth}} \pgfpathlineto{\pgfqpoint{0pt}{4\pgflinewidth}} \pgfusepathqstroke } \pgfarrowsdeclare{cm left hook}{cm left hook} { \pgfarrowsleftextend{-0.5\pgflinewidth} \pgfarrowsrightextend{3.5\pgflinewidth} } { \pgfsetdash{}{+0pt} \pgfsetroundcap \pgfpathmoveto{\pgfqpoint{0pt}{4.667\pgflinewidth}} \pgfpathcurveto {\pgfqpoint{4\pgflinewidth}{4.667\pgflinewidth}} {\pgfqpoint{4\pgflinewidth}{0pt}} {\pgfpointorigin} \pgfusepathqstroke } \pgfarrowsdeclare{cm right hook}{cm right hook} { \pgfarrowsleftextend{-0.5\pgflinewidth} \pgfarrowsrightextend{3.5\pgflinewidth} } { \pgfsetdash{}{+0pt} \pgfsetroundcap \pgfpathmoveto{\pgfqpoint{0pt}{-4.667\pgflinewidth}} \pgfpathcurveto {\pgfqpoint{4\pgflinewidth}{-4.667\pgflinewidth}} {\pgfqpoint{4\pgflinewidth}{0pt}} {\pgfpointorigin} \pgfusepathqstroke } \pgfarrowsdeclare{cm o}{cm o} { \pgfarrowsleftextend{+-.5\pgflinewidth} \pgfarrowsrightextend{7.167\pgflinewidth} } { \pgfpathcircle{\pgfqpoint{3.333\pgflinewidth}{0pt}}{3.333\pgflinewidth} \pgfusepathqstroke } \pgfarrowsdeclare{cm *}{cm *} { \pgfarrowsleftextend{+-.5\pgflinewidth} \pgfarrowsrightextend{7.167\pgflinewidth} } { \pgfpathcircle{\pgfqpoint{3.333\pgflinewidth}{0pt}}{3.333\pgflinewidth} \pgfusepathqfillstroke } \pgfarrowsdeclare{cm cap}{cm cap} { \pgfarrowsleftextend{+0pt} \pgfarrowsrightextend{+\pgflinewidth} } { \pgfsetdash{}{+0pt} \pgfsetroundcap \pgfpathmoveto{\pgfpointorigin} \pgfpathlineto{\pgfqpoint{0.5\pgflinewidth}{0pt}} \pgfusepathqstroke } \pgfarrowsdeclare{cm implies cap}{cm implies cap} { \pgfmathsetlength{\pgfutil@tempdima}{.5\pgflinewidth-.5*\pgfinnerlinewidth} \pgfarrowsleftextend{+0pt} \pgfarrowsrightextend{+\pgfutil@tempdima} } { \pgfmathsetlength{\pgfutil@tempdima}{.5\pgflinewidth-.5*\pgfinnerlinewidth} \pgfmathsetlength{\pgfutil@tempdimb}{.5\pgflinewidth-.5*\pgfutil@tempdima} \pgfsetlinewidth{\pgfutil@tempdima} \pgfsetdash{}{+0pt} \pgfsetroundcap \pgfpathmoveto{\pgfqpoint{0pt}{+1\pgfutil@tempdimb}} \pgfpathlineto{\pgfqpoint{0.5\pgfutil@tempdima}{+1\pgfutil@tempdimb}} \pgfpathmoveto{\pgfqpoint{0pt}{-1\pgfutil@tempdimb}} \pgfpathlineto{\pgfqpoint{0.5\pgfutil@tempdima}{-1\pgfutil@tempdimb}} \pgfusepathqstroke } \pgfarrowsdeclarereversed{cm to reversed}{cm to reversed}{cm to}{cm to} \pgfarrowsdeclarereversed{cm left to reversed}{cm left to reversed}{cm left to}{cm left to} \pgfarrowsdeclarereversed{cm right to reversed}{cm right to reversed}{cm right to}{cm right to} \pgfarrowsdeclaredouble{cm double to}{cm double to}{cm to}{cm to} \pgfarrowsdeclaredouble{cm double to reversed}{cm double to reversed}{cm to reversed}{cm to reversed} \endinput