% -------------------------------------------------------------------------- % the CARBOHYDRATES package % % ready drawn carbohydrates with chemfig % % -------------------------------------------------------------------------- % Clemens Niederberger % Web: https://github.com/cgnieder/carbohydrates % E-Mail: contact@mychemistry.eu % -------------------------------------------------------------------------- % Copyright 2014-2015 Clemens Niederberger % % This work may be distributed and/or modified under the % conditions of the LaTeX Project Public License, either version 1.3 % of this license or (at your option) any later version. % The latest version of this license is in % http://www.latex-project.org/lppl.txt % and version 1.3 or later is part of all distributions of LaTeX % version 2005/12/01 or later. % % This work has the LPPL maintenance status `maintained'. % % The Current Maintainer of this work is Clemens Niederberger. % -------------------------------------------------------------------------- % If you have any ideas, questions, suggestions or bugs to report, please % feel free to contact me. % -------------------------------------------------------------------------- \def\cbhdr@date{2015/12/01} \def\cbhdr@version{v0.1} \def\cbhdr@info{carbohydrate molecules with chemfig} \ProvidesPackage{carbohydrates}[% \cbhdr@date\space \cbhdr@version\space \cbhdr@info\space (CN)] \RequirePackage{etoolbox} \RequirePackage{chemfig,xcolor} % ========================================================================== % message handling % generic help message: \newrobustcmd\cbhdr@create@message[2]{% \ifstrequal{#1}{Error} {% \lowercase{\csdef{cbhdr@#1}}##1{% \csuse{Package#1}{carbohydrates}{##1}{#2}}% }{% \lowercase{\csdef{cbhdr@#1}}##1{% \csuse{Package#1}{carbohydrates}{##1}}% }} \newcommand*\cbhdr@error@message{% For details have a look at the `carbohydrates' manual.% } % create message macros: \cbhdr@create@message{Error}{\cbhdr@error@message} \cbhdr@create@message{Warning}{} \cbhdr@create@message{WarningNoLine}{} \cbhdr@create@message{Info}{} \newcommand*\cbhdr@ring@error[2]{% \cbhdr@error{#1 can't form #2 rings}% } \newcommand*\cbhdr@define@ring@error[3]{% \protected\csdef{cbhdr@aldo#2@#1@ring@#3}{\cbhdr@ring@error{#2s}{#3}}% } \newcommand*\cbhdr@define@chain@error[2]{% \protected\csdef{cbhdr@aldo#2@#1@chain}{% \cbhdr@error{The chain is not implemented for #2s in the #1 model}% }% } \newcommand*\cbhdr@chair@error[1]{% \cbhdr@error{The chair model is not implemented for #1}% } \newcommand*\cbhdr@define@chair@errors[1]{% \protected\csdef{cbhdr@aldo#1@chair@chain}{\cbhdr@chair@error{#1s}}% \protected\csdef{cbhdr@aldo#1@chair@ring@pyranose}{\cbhdr@chair@error{#1s}}% \protected\csdef{cbhdr@aldo#1@chair@ring@furanose}{\cbhdr@chair@error{#1s}}% } \newrobustcmd\cbhdr@expand@x[2]{% \begingroup\edef\cbhdr@expand@tmp{\endgroup\unexpanded{#1}{#2}}% \cbhdr@expand@tmp } \newrobustcmd\cbhdr@expand@nx[3]{% \begingroup\edef\cbhdr@expand@tmp{\endgroup\unexpanded{#1{#2}}{#3}}% \cbhdr@expand@tmp } \newcommand*\cbhdr@stripbs{\expandafter\@gobble\string} % ========================================================================== % colors \newrobustcmd*\cbhdr@defcolor[2]{\colorlet{cbhdr@#1}{#2}} \cbhdr@defcolor{C1}{black} \cbhdr@defcolor{C6}{black} \cbhdr@defcolor{O-C6}{black} \cbhdr@defcolor{H-C6}{black} \cbhdr@defcolor{anomerO}{black} \cbhdr@defcolor{anomerH}{black} \cbhdr@defcolor{ringO}{black} \newcommand*\cbhdr@atom@color[2]{\unexpanded{\textcolor{cbhdr@#1}{#2}}} % ========================================================================== % wavy bonds: \usetikzlibrary{decorations.pathmorphing} \pgfdeclaredecoration{cbhdr wave}{initial}{ \state{initial}[ width = +0pt , next state = sine, persistent precomputation = { \pgfmathsetmacro\matchinglength{ \pgfdecoratedinputsegmentlength / int(\pgfdecoratedinputsegmentlength/\pgfdecorationsegmentlength) } \setlength{\pgfdecorationsegmentlength}{\matchinglength pt} } ]{} \state{sine}[width=\pgfdecorationsegmentlength]{ \pgfpathsine{ \pgfpoint {0.25\pgfdecorationsegmentlength} {0.5\pgfdecorationsegmentamplitude} } \pgfpathcosine{ \pgfpoint {0.25\pgfdecorationsegmentlength} {-0.5\pgfdecorationsegmentamplitude} } \pgfpathsine{ \pgfpoint {0.25\pgfdecorationsegmentlength} {-0.5\pgfdecorationsegmentamplitude} } \pgfpathcosine{ \pgfpoint {0.25\pgfdecorationsegmentlength} {0.5\pgfdecorationsegmentamplitude} } } \state{final}{} } \tikzset{ cbhdr/wavy bond/.style = { decorate, decoration = { amplitude = 0.23*\CF@atom@sep/3 , post length = 0 pt, pre length = 0 pt, % Use the atom spacing: saved segment length = \CF@atom@sep/5 , cbhdr wave } } } % ========================================================================== % sub molecules for all the modular building of the molecules later \newcommand*\cbhdr@C[1]{\cbhdr@atom@color{C#1}{C}} \newcommand*\cbhdr@OH[1]{% \cbhdr@atom@color{O-C#1}{O}|% \cbhdr@atom@color{H-C#1}{H}% } \newcommand*\cbhdr@HO[1]{% \cbhdr@atom@color{H-C#1}{H}|% \cbhdr@atom@color{O-C#1}{O}% } \newcommand*\cbhdr@ring@O{\cbhdr@atom@color{ringO}{O}} \newcommand*\cbhdr@anomer@O{\cbhdr@atom@color{anomerO}{O}} \newcommand*\cbhdr@anomer@OH{% \cbhdr@atom@color{anomerO}{O}|% \cbhdr@atom@color{anomerH}{H}% } \newcommand*\cbhdr@anomer@HO{% \cbhdr@atom@color{anomerH}{H}|% \cbhdr@atom@color{anomerO}{O}% } \newrobustcmd*\cbhdr@definesubmol@expand{\cbhdr@expand@nx\definesubmol} \newrobustcmd*\cbhdr@chemfig@expand{\cbhdr@expand@x\chemfig} \newrobustcmd\cbhdr@define@Csubmols[1]{% \cbhdr@defcolor{O-C#1}{black}% \cbhdr@defcolor{H-C#1}{black}% \cbhdr@defcolor{C#1}{black}% % aldohexoses: % fischer: % skeletons \cbhdr@definesubmol@expand{cbhdr@fischer@skeleton@C#1@OHr}{(-[:0]\cbhdr@OH{#1})}% \cbhdr@definesubmol@expand{cbhdr@fischer@skeleton@C#1@OHl}{(-[:180]\cbhdr@HO{#1})}% \cbhdr@definesubmol@expand{cbhdr@fischer@skeleton@C#1@OH0}{}% % with C and H \cbhdr@definesubmol@expand{cbhdr@fischer@C#1@OHr}{(-[:0]\cbhdr@OH{#1})(-[:180]H)}% \cbhdr@definesubmol@expand{cbhdr@fischer@C#1@OHl}{(-[:180]\cbhdr@HO{#1})(-[:0]H)}% \cbhdr@definesubmol@expand{cbhdr@fischer@C#1@OH0}{(-[:180]H)(-[:0]H)}% % haworth: \ifnum#1=5\relax \cbhdr@definesubmol@expand{cbhdr@haworth@C#1@OHr}{(-[:0]\cbhdr@OH{#1})}% \cbhdr@definesubmol@expand{cbhdr@haworth@C#1@OHl}{(-[:180,.5]\cbhdr@HO{#1})}% \else \cbhdr@definesubmol@expand{cbhdr@haworth@C#1@OHr}{(-[:-90,.5,,1]\cbhdr@OH{#1})}% \cbhdr@definesubmol@expand{cbhdr@haworth@C#1@OHl}{(-[:90,.5,,1]\cbhdr@OH{#1})}% \fi \definesubmol{cbhdr@haworth@C#1@OH0}{}% % chair: \ifcase#1 \or % 1 \or % 2 \cbhdr@definesubmol@expand{cbhdr@chair@C#1@OHr}{(-[:-55,.75,,1]\cbhdr@OH{#1})}% \cbhdr@definesubmol@expand{cbhdr@chair@C#1@OHl}{(-[:90,.5,,1]\cbhdr@OH{#1})}% \or % 3 \cbhdr@definesubmol@expand{cbhdr@chair@C#1@OHr}{(-[:-90,.5,,1]\cbhdr@OH{#1})}% \cbhdr@definesubmol@expand{cbhdr@chair@C#1@OHl}{(-[:170,.75,,2]\cbhdr@HO{#1})}% \or % 4 \cbhdr@definesubmol@expand{cbhdr@chair@C#1@OHr}{(-[:190,.75,,2]\cbhdr@HO{#1})}% \cbhdr@definesubmol@expand{cbhdr@chair@C#1@OHl}{(-[:90,.5,,1]\cbhdr@OH{#1})}% \or % 5 \cbhdr@definesubmol@expand{cbhdr@chair@C#1@OHr}{(-[:10,.75,,1]\cbhdr@OH{#1})}% \cbhdr@definesubmol@expand{cbhdr@chair@C#1@OHl}{(-[:-90,.5,,1]\cbhdr@OH{#1})}% \fi \definesubmol{cbhdr@chair@C#1@OH0}{}% } \cbhdr@define@Csubmols{2} \cbhdr@define@Csubmols{3} \cbhdr@define@Csubmols{4} \cbhdr@define@Csubmols{5} \cbhdr@definesubmol@expand{cbhdr@haworth@furanose@C2@OHr}{(-[:-90,.5]\cbhdr@OH{2})} \cbhdr@definesubmol@expand{cbhdr@haworth@furanose@C2@OHl}{(-[:90,.5,,2]\cbhdr@HO{2})} \cbhdr@definesubmol@expand{cbhdr@haworth@furanose@C2@OH0}{} \cbhdr@definesubmol@expand{cbhdr@haworth@furanose@C3@OHr}{(-[:-90,.5]\cbhdr@OH{3})} \cbhdr@definesubmol@expand{cbhdr@haworth@furanose@C3@OHl}{(-[:90,.5]\cbhdr@OH{3})} \cbhdr@definesubmol@expand{cbhdr@haworth@furanose@C3@OH0}{} \cbhdr@definesubmol@expand{cbhdr@haworth@furanose@C4@OHr}{(-[:20]\cbhdr@OH{4})} \cbhdr@definesubmol@expand{cbhdr@haworth@furanose@C4@OH0}{} % 4=r, 5=r \cbhdr@definesubmol@expand{cbhdr@haworth@furanose@C4@OHr@C5@OHr}{( -[:90,.5](<[:30,.5]\cbhdr@OH{5}) -[:120,.5] -[:-180,.5,,2]HO )} % 4=l, 5=r \cbhdr@definesubmol@expand{cbhdr@haworth@furanose@C4@OHl@C5@OHr}{( -[:-90,.5](<:[:150,.5]\cbhdr@HO{5}) -[:-120,.5] -[:180,.5,,2]HO )} % 4=r, 5=l \cbhdr@definesubmol@expand{cbhdr@haworth@furanose@C4@OHr@C5@OHl}{( -[:90,.5](<:[:30,.5]\cbhdr@OH{5}) -[:120,.5] -[:-180,.5,,2]HO )} % 4=l, 5=l \cbhdr@definesubmol@expand{cbhdr@haworth@furanose@C4@OHl@C5@OHl}{( -[:-90,.5](<[:150,.5]\cbhdr@HO{5}) -[:-120,.5] -[:180,.5,,2]HO )} % 4=r, 5=0 \cbhdr@definesubmol@expand{cbhdr@haworth@furanose@C4@OHr@C5@OH0}{( -[:90,.5] -[:120,.5] -[:-180,.5]HO )} % 4=l, 5=0 \cbhdr@definesubmol@expand{cbhdr@haworth@furanose@C4@OHl@C5@OH0}{( -[:-90,.5] -[:-120,.5] -[:180,.5]HO )} % 4=0 wouldn't make sense since then the furanose ring cannot be formed % fischer \cbhdr@definesubmol@expand{cbhdr@fischer@skeleton@aldehyde}{(=_[:30]\cbhdr@anomer@O)} \cbhdr@definesubmol@expand{cbhdr@fischer@skeleton@OHalpha}{(-[:0]\cbhdr@anomer@OH)} \cbhdr@definesubmol@expand{cbhdr@fischer@skeleton@OHbeta}{(-[:180]\cbhdr@anomer@HO)} \cbhdr@definesubmol@expand{cbhdr@fischer@skeleton@OHundetermined}{(-[:0]\cbhdr@anomer@OH)} \cbhdr@definesubmol@expand{cbhdr@fischer@aldehyde}{(=[:30]\cbhdr@anomer@O)(-[:150]H)} \cbhdr@definesubmol@expand{cbhdr@fischer@OHalpha}{(-[:0]\cbhdr@anomer@OH)(-[:180]H)} \cbhdr@definesubmol@expand{cbhdr@fischer@OHbeta}{(-[:180]\cbhdr@anomer@HO)(-[:0]H)} \cbhdr@definesubmol@expand{cbhdr@fischer@OHundetermined}{(-[:0]\cbhdr@anomer@HO)(-[:180]H)} % haworth \cbhdr@definesubmol@expand{cbhdr@haworth@OHalpha}{(-[:-90,.5,,1]\cbhdr@anomer@OH)} \cbhdr@definesubmol@expand{cbhdr@haworth@OHbeta}{(-[:90,.5,,1]\cbhdr@anomer@OH)} \cbhdr@definesubmol@expand{cbhdr@haworth@OHundetermined} {(-[:0,.75,,1,cbhdr/wavy bond]\cbhdr@anomer@OH)} % chair: \cbhdr@definesubmol@expand{cbhdr@chair@OHalpha}{(-[:-90,.5,,1]\cbhdr@anomer@OH)} \cbhdr@definesubmol@expand{cbhdr@chair@OHbeta}{(-[:10,.75,,1]\cbhdr@anomer@OH)} \cbhdr@definesubmol@expand{cbhdr@chair@OHundetermined} {(-[:0,.75,,1,cbhdr/wavy bond]\cbhdr@anomer@OH)} % ========================================================================== % commands to define the chain and ring molecules avoiding code duplication: % the arguments of a chain refer to r and l for the chiral centers. A hexose % needs four arguments: \cbhdr@newchain\hexose#1#2#3#4{} % \cbhdr@newchain{} \protected\def\cbhdr@newchain#1{\cbhdr@newchain@aux@i{#1}} \protected\def\cbhdr@newchain@aux@i#1#2#{\cbhdr@newchain@aux@ii{#1}{#2}} \protected\def\cbhdr@newchain@aux@ii#1#2#3{% \protected\csdef{\cbhdr@stripbs#1@aux}#2\q@stop{\cbhdr@chemfig@expand{#3}}% \newrobustcmd*#1[1]{\csuse{\cbhdr@stripbs#1@aux}##1\q@stop}% } % the first argument of a ring always is alpha/beta, the following arguments % refer to r and l for the chiral centers. A hexose needs five arguments: % \cbhdr@newring\hexose#1#2#3#4#5{} % \cbhdr@newring{} \protected\def\cbhdr@newring#1{\cbhdr@newring@aux@i{#1}} \protected\def\cbhdr@newring@aux@i#1#2#{\cbhdr@newring@aux@ii{#1}{#2}} \protected\def\cbhdr@newring@aux@ii#1#2#3{% \protected\csdef{\cbhdr@stripbs#1@aux}#2\q@stop{\cbhdr@chemfig@expand{#3}}% \newrobustcmd*#1[1]{\csuse{\cbhdr@stripbs#1@aux}{\cbhdr@anomer}##1\q@stop}% } % ========================================================================== % now let's build the molecules using the submolecules from above. They're % all named using the following naming scheme: % % \@@/(@) % % -------------------------------------------------------------------------- % Fischer - skeleton formulas %%% % hexoses % chain \cbhdr@newchain\cbhdr@aldohexose@fischer@skeleton@chain#1#2#3#4{ !{cbhdr@fischer@skeleton@aldehyde} -[:-90]!{cbhdr@fischer@skeleton@C2@OH#1} -[:-90]!{cbhdr@fischer@skeleton@C3@OH#2} -[:-90]!{cbhdr@fischer@skeleton@C4@OH#3} -[:-90]!{cbhdr@fischer@skeleton@C5@OH#4} -[:-90](-[:0]\cbhdr@OH{6}) } % pyranoses \cbhdr@newring\cbhdr@aldohexose@fischer@skeleton@ring@pyranose#1#2#3#4#5{% !{cbhdr@fischer@skeleton@OH#1}(-[:90]-[:0]-?) -[:-90]!{cbhdr@fischer@skeleton@C2@OH#2} -[:-90]!{cbhdr@fischer@skeleton@C3@OH#3} -[:-90]!{cbhdr@fischer@skeleton@C4@OH#4} -[:-90](-[:0]\cbhdr@ring@O-?) -[:-90](-[:0]\cbhdr@OH{6}) } % furanoses \cbhdr@newring\cbhdr@aldohexose@fischer@skeleton@ring@furanose#1#2#3#4#5{% !{cbhdr@fischer@skeleton@OH#1}(-[:90]-[:0]-?) -[:-90]!{cbhdr@fischer@skeleton@C2@OH#2} -[:-90]!{cbhdr@fischer@skeleton@C3@OH#3} -[:-90](-[:0]\cbhdr@ring@O-?) -[:-90]!{cbhdr@fischer@skeleton@C5@OH#5} -[:-90](-[:0]\cbhdr@OH{6}) } %%% % pentoses % chain \cbhdr@newchain\cbhdr@aldopentose@fischer@skeleton@chain#1#2#3{% !{cbhdr@fischer@skeleton@aldehyde} -[:-90]!{cbhdr@fischer@skeleton@C2@OH#1} -[:-90]!{cbhdr@fischer@skeleton@C3@OH#2} -[:-90]!{cbhdr@fischer@skeleton@C4@OH#3} -[:-90](-[:0]\cbhdr@OH{5}) } % pyranoses \cbhdr@newring\cbhdr@aldopentose@fischer@skeleton@ring@pyranose#1#2#3#4{% !{cbhdr@fischer@skeleton@OH#1}(-[:90]-[:0]-?) -[:-90]!{cbhdr@fischer@skeleton@C2@OH#2} -[:-90]!{cbhdr@fischer@skeleton@C3@OH#3} -[:-90]!{cbhdr@fischer@skeleton@C4@OH#4} -[:-90](-[:0]\cbhdr@ring@O-?) } % furanoses \cbhdr@newring\cbhdr@aldopentose@fischer@skeleton@ring@furanose#1#2#3#4{% !{cbhdr@fischer@skeleton@OH#1}(-[:90]-[:0]-?) -[:-90]!{cbhdr@fischer@skeleton@C2@OH#2} -[:-90]!{cbhdr@fischer@skeleton@C3@OH#3} -[:-90](-[:0]\cbhdr@ring@O-?) -[:-90](-[:0]\cbhdr@OH{5}) } %%% % tetroses % chain \cbhdr@newchain\cbhdr@aldotetrose@fischer@skeleton@chain#1#2{% !{cbhdr@fischer@skeleton@aldehyde} -[:-90]!{cbhdr@fischer@skeleton@C2@OH#1} -[:-90]!{cbhdr@fischer@skeleton@C3@OH#2} -[:-90](-[:0]\cbhdr@OH{4}) } % pyranoses \cbhdr@define@ring@error{fischer@skeleton}{tetrose}{pyranose} % furanoses \cbhdr@newring\cbhdr@aldotetrose@fischer@skeleton@ring@furanose#1#2#3{% !{cbhdr@fischer@skeleton@OH#1}(-[:90]-[:0]-?) -[:-90]!{cbhdr@fischer@skeleton@C2@OH#2} -[:-90]!{cbhdr@fischer@skeleton@C3@OH#3} -[:-90](-[:0]\cbhdr@ring@O-?) } %%% % trioses % chain \cbhdr@newchain\cbhdr@aldotriose@fischer@skeleton@chain#1{% !{cbhdr@fischer@skeleton@aldehyde} -[:-90]!{cbhdr@fischer@skeleton@C2@OH#1} -[:-90](-[:0]\cbhdr@OH{3}) } % pyranoses \cbhdr@define@ring@error{fischer@skeleton}{triose}{pyranose} % furanoses \cbhdr@define@ring@error{fischer@skeleton}{triose}{furanose} % -------------------------------------------------------------------------- % Fischer - with C and H %%% % hexoses % chain \cbhdr@newchain\cbhdr@aldohexose@fischer@chain#1#2#3#4{% \cbhdr@C{1}!{cbhdr@fischer@aldehyde} -[:-90]\cbhdr@C{2}!{cbhdr@fischer@C2@OH#1} -[:-90]\cbhdr@C{3}!{cbhdr@fischer@C3@OH#2} -[:-90]\cbhdr@C{4}!{cbhdr@fischer@C4@OH#3} -[:-90]\cbhdr@C{5}!{cbhdr@fischer@C5@OH#4} -[:-90]\cbhdr@C{6}(-[:0]\cbhdr@OH{6})(-[:180]H) -[:-90]H } % pyranoses \cbhdr@newring\cbhdr@aldohexose@fischer@ring@pyranose#1#2#3#4#5{% \cbhdr@C{1}!{cbhdr@fischer@OH#1}(-[:90]-[:0]-?) -[:-90]\cbhdr@C{2}!{cbhdr@fischer@C2@OH#2} -[:-90]\cbhdr@C{3}!{cbhdr@fischer@C3@OH#3} -[:-90]\cbhdr@C{4}!{cbhdr@fischer@C4@OH#4} -[:-90]\cbhdr@C{5}(-[:0]\cbhdr@ring@O-?)(-[:180]H) -[:-90]\cbhdr@C{6}(-[:0]\cbhdr@OH{6})(-[:180]H) -[:-90]H } % furanoses \cbhdr@newring\cbhdr@aldohexose@fischer@ring@furanose#1#2#3#4#5{% \cbhdr@C{1}!{cbhdr@fischer@OH#1}(-[:90]-[:0]-?) -[:-90]\cbhdr@C{2}!{cbhdr@fischer@C2@OH#2} -[:-90]\cbhdr@C{3}!{cbhdr@fischer@C3@OH#3} -[:-90]\cbhdr@C{4}(-[:0]\cbhdr@ring@O-?)(-[:180]H) -[:-90]\cbhdr@C{5}!{cbhdr@fischer@C5@OH#5} -[:-90]\cbhdr@C{6}(-[:0]\cbhdr@OH{6})(-[:180]H) -[:-90]H } %%% % pentoses % chain \cbhdr@newchain\cbhdr@aldopentose@fischer@chain#1#2#3{% \cbhdr@C{1}!{cbhdr@fischer@aldehyde} -[:-90]\cbhdr@C{2}!{cbhdr@fischer@C2@OH#1} -[:-90]\cbhdr@C{3}!{cbhdr@fischer@C3@OH#2} -[:-90]\cbhdr@C{4}!{cbhdr@fischer@C4@OH#3} -[:-90]\cbhdr@C{5}(-[:0]\cbhdr@OH{5})(-[:180]H) -[:-90]H } % pyranoses \cbhdr@newring\cbhdr@aldopentose@fischer@ring@pyranose#1#2#3#4{% \cbhdr@C{1}!{cbhdr@fischer@OH#1}(-[:90]-[:0]-?) -[:-90]\cbhdr@C{2}!{cbhdr@fischer@C2@OH#2} -[:-90]\cbhdr@C{3}!{cbhdr@fischer@C3@OH#3} -[:-90]\cbhdr@C{4}!{cbhdr@fischer@C4@OH#4} -[:-90]\cbhdr@C{5}(-[:0]\cbhdr@ring@O-?)(-[:180]H) -[:-90]H } % furanoses \cbhdr@newring\cbhdr@aldopentose@fischer@ring@furanose#1#2#3#4{% \cbhdr@C{1}!{cbhdr@fischer@OH#1}(-[:90]-[:0]-?) -[:-90]\cbhdr@C{2}!{cbhdr@fischer@C2@OH#2} -[:-90]\cbhdr@C{3}!{cbhdr@fischer@C3@OH#3} -[:-90]\cbhdr@C{4}(-[:0]\cbhdr@ring@O-?)(-[:180]H) -[:-90]\cbhdr@C{5}(-[:0]\cbhdr@OH{5})(-[:180]H) -[:-90]H } %%% % tetroses % chain \cbhdr@newchain\cbhdr@aldotetrose@fischer@chain#1#2{% \cbhdr@C{1}!{cbhdr@fischer@aldehyde} -[:-90]\cbhdr@C{2}!{cbhdr@fischer@C2@OH#1} -[:-90]\cbhdr@C{3}!{cbhdr@fischer@C3@OH#2} -[:-90]\cbhdr@C{4}(-[:0]\cbhdr@OH{4})(-[:180]H) -[:-90]H } % pyranoses \cbhdr@define@ring@error{fischer}{tetrose}{pyranose} % furanoses \cbhdr@newring\cbhdr@aldotetrose@fischer@ring@furanose#1#2#3{% \cbhdr@C{1}!{cbhdr@fischer@OH#1}(-[:90]-[:0]-?) -[:-90]\cbhdr@C{2}!{cbhdr@fischer@C2@OH#2} -[:-90]\cbhdr@C{3}!{cbhdr@fischer@C3@OH#3} -[:-90]\cbhdr@C{4}(-[:0]\cbhdr@ring@O-?)(-[:180]H) -[:-90]H } %%% % trioses % chain \cbhdr@newchain\cbhdr@aldotriose@fischer@chain#1{% \cbhdr@C{1}!{cbhdr@fischer@aldehyde} -[:-90]\cbhdr@C{2}!{cbhdr@fischer@C2@OH#1} -[:-90]\cbhdr@C{3}(-[:0]\cbhdr@OH{3})(-[:180]H) -[:-90]H } % pyranoses \cbhdr@define@ring@error{fischer}{triose}{pyranose} % furanoses \cbhdr@define@ring@error{fischer}{triose}{furanose} % -------------------------------------------------------------------------- % Haworth \newcommand*\cbhdr@decr{-} % > \newcommand*\cbhdr@thick{} % line width=3pt \newcommand*\cbhdr@incr{-} % < %%% % hexoses % chain \cbhdr@newchain\cbhdr@aldohexose@haworth@chain#1#2#3#4{% -[:30] ?(-[:90,.5]-[:150,.5]\cbhdr@HO{6})!{cbhdr@haworth@C5@OH#4}-[,,,,draw=none] -[:-30,,1,,draw=none](=_[:0]\cbhdr@anomer@O) \cbhdr@incr[:-150]!{cbhdr@haworth@C2@OH#1} -[:-180,,,,\cbhdr@thick]!{cbhdr@haworth@C3@OH#2} \cbhdr@decr[:150]?!{cbhdr@haworth@C4@OH#3} } % pyranoses \cbhdr@newring\cbhdr@aldohexose@haworth@ring@pyranose#1#2#3#4#5{% -[:30] ?(-[:90,.5]-[:150,.5]\cbhdr@HO{6})-\cbhdr@ring@O -[:-30]!{cbhdr@haworth@OH#1} \cbhdr@incr[:-150]!{cbhdr@haworth@C2@OH#2} -[:-180,,,,\cbhdr@thick]!{cbhdr@haworth@C3@OH#3} \cbhdr@decr[:150]?!{cbhdr@haworth@C4@OH#4} } % furanoses \cbhdr@newring\cbhdr@aldohexose@haworth@ring@furanose#1#2#3#4#5{% \cbhdr@ring@O?-[:-20]!{cbhdr@haworth@OH#1} -[:-110]!{cbhdr@haworth@furanose@C2@OH#2} -[:180,1.1954]!{cbhdr@haworth@furanose@C3@OH#3} -[:110]?!{cbhdr@haworth@furanose@C4@OH#4@C5@OH#5} } %%% % pentoses % chain \cbhdr@newchain\cbhdr@aldopentose@haworth@chain#1#2#3{% ?-[:-20,,,,draw=none](=_[:0]\cbhdr@anomer@O) -[:-110]!{cbhdr@haworth@furanose@C2@OH#1} -[:180,1.1954]!{cbhdr@haworth@furanose@C3@OH#2} -[:110]?[,,{draw=none}](-[:90,.5]-[:150,.5]\cbhdr@HO{5}) !{cbhdr@haworth@furanose@C4@OH#3} } % pyranoses \cbhdr@newring\cbhdr@aldopentose@haworth@ring@pyranose#1#2#3#4{% -[:30] ?-\cbhdr@ring@O -[:-30]!{cbhdr@haworth@OH#1} \cbhdr@incr[:-150]!{cbhdr@haworth@C2@OH#2} -[:-180,,,,\cbhdr@thick]!{cbhdr@haworth@C3@OH#3} \cbhdr@decr[:150]?!{cbhdr@haworth@C4@OH#4} } % furanoses \cbhdr@newring\cbhdr@aldopentose@haworth@ring@furanose#1#2#3#4{% \cbhdr@ring@O?-[:-20]!{cbhdr@haworth@OH#1} -[:-110]!{cbhdr@haworth@furanose@C2@OH#2} -[:180,1.1954]!{cbhdr@haworth@furanose@C3@OH#3} -[:110]?(-[:90,.5]-[:150,.5]\cbhdr@HO{5}) } %%% % tetroses % chain \cbhdr@define@chain@error{haworth}{tetrose} % pyranoses \cbhdr@define@ring@error{haworth}{tetrose}{pyranose} % furanoses \cbhdr@newring\cbhdr@aldotetrose@haworth@ring@furanose#1#2#3{% \cbhdr@ring@O?-[:-20]!{cbhdr@haworth@OH#1} -[:-110]!{cbhdr@haworth@furanose@C2@OH#2} -[:180,1.1954]!{cbhdr@haworth@furanose@C3@OH#3} -[:110]? } %%% % trioses % chain \cbhdr@define@chain@error{haworth}{triose} % pyranoses \cbhdr@define@ring@error{haworth}{triose}{pyranose} % furanoses \cbhdr@define@ring@error{haworth}{triose}{furanose} % -------------------------------------------------------------------------- % Chair %%% % hexoses % chain \cbhdr@newchain\cbhdr@aldohexose@chair@chain#1#2#3#4{% -[:-10] ?(-[:150,.75]-[:90,.5,,1]\cbhdr@OH{6})!{cbhdr@chair@C5@OH#4}-[:10,,,,draw=none] -[:-50,,1,,draw=none](=_[:70]\cbhdr@anomer@O) \cbhdr@incr[:-170]!{cbhdr@chair@C2@OH#1} -[:-190,,,,\cbhdr@thick]!{cbhdr@chair@C3@OH#2} \cbhdr@decr[:130]?!{cbhdr@chair@C4@OH#3} } % pyranoses \cbhdr@newring\cbhdr@aldohexose@chair@ring@pyranose#1#2#3#4#5{% -[:-10] ?(-[:150,.75]-[:90,.5,,1]\cbhdr@OH{6})-[:10]\cbhdr@ring@O -[:-50]!{cbhdr@chair@OH#1} \cbhdr@incr[:170]!{cbhdr@chair@C2@OH#2} -[:190,,,,\cbhdr@thick]!{cbhdr@chair@C3@OH#3} \cbhdr@decr[:130]?!{cbhdr@chair@C4@OH#4} } % furanoses \newrobustcmd*\cbhdr@aldohexose@chair@ring@furanose{% \cbhdr@chair@error{furanose rings}% } %%% % pentoses \cbhdr@define@chair@errors{pentose} %%% % tetroses \cbhdr@define@chair@errors{tetrose} %%% % trioses \cbhdr@define@chair@errors{triose} % ========================================================================== % the user commands - built from the commands above using the already % mentioned naming scheme % % @@/(@) \newcommand*\cbhdr@model{} % fischer/haworth/chair \newcommand*\cbhdr@fischer{} % @skeleton \newcommand*\cbhdr@form{} % chain/ring \newcommand*\cbhdr@chain{chain} \newcommand*\cbhdr@ring{ring@\cbhdr@ringtype} \newcommand*\cbhdr@ringtype{} % pyranose/furanose \newcommand*\cbhdr@ringtype@default{} % -------------------------------------------------------------------------- % options for the user command: \pgfkeys{ cbhdr/.cd, model/.is choice , model/fischer/.is choice , model/fischer/skeleton/.code = \def\cbhdr@model{fischer@skeleton} , model/fischer/full/.code = \def\cbhdr@model{fischer} , model/fischer/.default = full , model/haworth/.code = \def\cbhdr@model{haworth} , model/chair/.code = \def\cbhdr@model{chair} , chain/.code = \def\cbhdr@constitution{chain} , ring/.is choice , ring/true/.code = \def\cbhdr@constitution{ring@\cbhdr@ringtype@default} , ring/pyranose/.code = \def\cbhdr@constitution{ring@pyranose} , ring/furanose/.code = \def\cbhdr@constitution{ring@furanose} , ring/.default = true , anomer/.is choice , anomer/alpha/.code = \def\cbhdr@anomer{alpha} , anomer/beta/.code = \def\cbhdr@anomer{beta} , anomer/undetermined/.code = \def\cbhdr@anomer{undetermined} , length/.is choice , length/6/.code = \def\cbhdr@ringtype@default{pyranose} \def\cbhdr@length{aldohexose} , length/5/.code = \def\cbhdr@ringtype@default{furanose} \def\cbhdr@length{aldopentose} , length/4/.code = \def\cbhdr@ringtype@default{furanose} \def\cbhdr@length{aldotetrose} , length/3/.code = % doesn't matter: will cause an error anyway \def\cbhdr@ringtype@default{pyranose} \def\cbhdr@length{aldotriose} , hexose/.style = { length=6 } , pentose/.style = { length=5 } , tetrose/.style = { length=4 } , triose/.style = { length=3 } , 3d/.is choice , 3d/true/.code = \def\cbhdr@decr{>} \def\cbhdr@thick{line width=3pt} \def\cbhdr@incr{<} , 3d/false/.code = \def\cbhdr@decr{-} \def\cbhdr@thick{} \def\cbhdr@incr{-} , 3d/.default = true , defaults/.style = { model = fischer , chain , anomer = alpha , length = 6 } , color/.code 2 args = \cbhdr@defcolor{#1}{#2} } \pgfqkeys{/cbhdr}{defaults} % -------------------------------------------------------------------------- % the user command: \newrobustcmd*\cbhdr@carbohydrate[2]{% \begingroup \pgfqkeys{/cbhdr}{defaults,#1}% \csuse{cbhdr@\cbhdr@length @\cbhdr@model @\cbhdr@constitution}{#2}% \endgroup } \newrobustcmd*\carbohydrate[2][]{\cbhdr@carbohydrate{#1}{#2}} % ========================================================================== % a command to define ready made carbohydrates \newrobustcmd*\newaldose[1]{% \@ifnextchar[ % ] {\cbhdr@newaldose{#1}} {\cbhdr@newaldose{#1}[]}% } \protected\def\cbhdr@newaldose#1[#2]#3{% \cbhdr@expand@x \pgfkeys{ cbhdr/.cd, \cbhdr@stripbs#1-defaults/.style={\unexpanded{#2}} }% \newrobustcmd*#1[1][]{% \expandafter\cbhdr@carbohydrate\expandafter{\cbhdr@stripbs#1-defaults,##1}{#3}% }% } \newrobustcmd*\renewaldose[1]{% \@ifnextchar[ % ] {\cbhdr@renewaldose{#1}} {\cbhdr@renewaldose{#1}[]}% } \protected\def\cbhdr@renewaldose#1[#2]#3{% \cbhdr@expand@x \pgfkeys{ cbhdr/.cd, \cbhdr@stripbs#1-defaults/.style={\unexpanded{#2}} }% \renewrobustcmd*#1[1][]{% \expandafter\cbhdr@carbohydrate\expandafter{\cbhdr@stripbs#1-defaults,##1}{#3}% }% } % ========================================================================== % predefined carbohydrates: % aldohexoses: \newaldose \allose [hexose]{rrrr} \newaldose \altrose [hexose]{lrrr} \newaldose \glucose [hexose]{rlrr} \newaldose \gulose [hexose]{rrlr} \newaldose \mannose [hexose]{llrr} \newaldose \idose [hexose]{lrlr} \newaldose \galactose[hexose]{rllr} \newaldose \talose [hexose]{lllr} % aldopentoses: \newaldose \ribose [pentose]{rrr} \newaldose \arabinose[pentose]{lrr} \newaldose \xylose [pentose]{rlr} \newaldose \lyxose [pentose]{llr} \newaldose \desoxyribose[pentose]{0rr} % aldotetroses: \newaldose \erythrose[tetrose]{rr} \newaldose \threose [tetrose]{lr} % aldotrioses: \newaldose \glycerinaldehyde[triose]{r} % ========================================================================== % setup commands % general defaults: \newrobustcmd*\setcarbohydrates[1]{% \pgfkeys{ cbhdr/.cd , defaults/.style = {#1} , defaults }% } % defaults for particular carbohydrate defined with \newaldose: \newrobustcmd*\setcarbohydratedefaults[2]{% \edef\cbhdr@tmpa{\cbhdr@stripbs#1}% \pgfkeys{ cbhdr/.cd , \cbhdr@tmpa-defaults/.style = { #2 } , \cbhdr@tmpa-defaults }% } \endinput % ========================================================================== % HISTORY: % ========================================================================== % TODO: - Ringe fuer L-Saccharide - Ketten für Tri- Tetr- und Pentosen - Optionen für Farben - Ketosen - viell. nur Fructose - Optionen für oxidierte u reduzierte Formen?