summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2015-12-02 22:26:36 +0000
committerKarl Berry <karl@freefriends.org>2015-12-02 22:26:36 +0000
commit8612f7f48afa4bd985eb1ba2824afc9bc0d9737f (patch)
tree1b8ef82b18c55dbced22eecdea9e4c5800728e93
parent716c0e5e86ce4d876fdceb4d9898018ab1216d9d (diff)
carbohydrates (2dec15)
git-svn-id: svn://tug.org/texlive/trunk@39000 c570f23f-e606-0410-a88d-b1316a301751
-rw-r--r--Master/texmf-dist/doc/latex/carbohydrates/README33
-rw-r--r--Master/texmf-dist/doc/latex/carbohydrates/carbohydrates_en.pdfbin0 -> 478777 bytes
-rw-r--r--Master/texmf-dist/doc/latex/carbohydrates/carbohydrates_en.tex375
-rw-r--r--Master/texmf-dist/doc/latex/carbohydrates/test.tex143
-rw-r--r--Master/texmf-dist/tex/latex/carbohydrates/carbohydrates.sty874
-rwxr-xr-xMaster/tlpkg/bin/tlpkg-ctan-check2
-rw-r--r--Master/tlpkg/tlpsrc/carbohydrates.tlpsrc0
-rw-r--r--Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc1
8 files changed, 1427 insertions, 1 deletions
diff --git a/Master/texmf-dist/doc/latex/carbohydrates/README b/Master/texmf-dist/doc/latex/carbohydrates/README
new file mode 100644
index 00000000000..9d9c162a3af
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/carbohydrates/README
@@ -0,0 +1,33 @@
+--------------------------------------------------------------------------
+the CARBOHYDRATES package v0.1 2015/12/01
+
+ 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.
+--------------------------------------------------------------------------
+The carbohydrates package consists of the files
+ - carbohydrates.sty
+ - carbohydrates_en.tex, carbohydrates_en.pdf
+ - README
+--------------------------------------------------------------------------
+If you have any ideas, questions, suggestions or bugs to report, please
+feel free to contact me.
+--------------------------------------------------------------------------
+
diff --git a/Master/texmf-dist/doc/latex/carbohydrates/carbohydrates_en.pdf b/Master/texmf-dist/doc/latex/carbohydrates/carbohydrates_en.pdf
new file mode 100644
index 00000000000..317bd283ed6
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/carbohydrates/carbohydrates_en.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/latex/carbohydrates/carbohydrates_en.tex b/Master/texmf-dist/doc/latex/carbohydrates/carbohydrates_en.tex
new file mode 100644
index 00000000000..4da1156d2a9
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/carbohydrates/carbohydrates_en.tex
@@ -0,0 +1,375 @@
+% arara: pdflatex
+% arara: biber
+% arara: pdflatex
+% arara: pdflatex
+\documentclass[load-preamble+]{cnltx-doc}
+\usepackage[utf8]{inputenc}
+\usepackage{carbohydrates}
+
+\setcnltx{
+ package = {carbohydrates} ,
+ authors = Clemens Niederberger ,
+ email = contact@mychemistry.eu ,
+ info = {carbohydrate molecules with \pkg*{chemfig}} ,
+ url = https://github.com/cgnieder/carbohydrates/ ,
+ abstract = {%
+ \carbohydrates\ offers macros for making exercise sheets when teaching
+ carbohydrate chemistry a lot less tedious. It uses \pkg{chemfig} for
+ drawing the formulas.
+ } ,
+ add-cmds = {
+ allose , altrose , arabinose ,
+ carbohydrate ,
+ desoxyribose ,
+ erythrose ,
+ galactose , glucose , glycerinaldehyde , gulose ,
+ idose ,
+ lyxose ,
+ mannose ,
+ newaldose ,
+ ribose ,
+ setcarbohydrates , setcarbohydratedefaults ,
+ talose , threose ,
+ xylose
+ } ,
+ add-silent-cmds = {
+ arrow ,
+ bondboldwidth , bondhashlength , bondwidth ,
+ D ,
+ chemfig , chemname , chemnameinit ,
+ definesubmol ,
+ iupac ,
+ printatom ,
+ schemestart , schemestop , setatomsep , setbondoffset , setbondstyle ,
+ setcrambond , setdoublesep
+ } ,
+ index-setup = { othercode = \footnotesize , level = \addsec } ,
+ makeindex-setup = { columns = 3 , columnsep = 1em }
+}
+
+\defbibheading{bibliography}[References]{\addsec{#1}}
+\addbibresource{\jobname.bib}
+
+\usepackage{filecontents}
+\begin{filecontents*}{\jobname.bib}
+@online{texdev,
+ url = {http://www.texdev.net/} ,
+ urldate = {2014-04-25} ,
+ author = {Joseph Wright}
+}
+\end{filecontents*}
+
+\usepackage{varioref}
+
+\usepackage{chemmacros}
+\chemsetup{greek=newtx}
+\newcommand*{\bondwidth}{0.06642 em}
+\newcommand*{\bondboldwidth}{0.22832 em}
+\newcommand*{\bondhashlength}{0.25737 em}
+\setdoublesep{0.35700 em}
+\setatomsep{1.78500 em}
+\setbondoffset{0.18265 em}
+\setbondstyle{line width = \bondwidth}
+\setcrambond
+ {\dimexpr\bondwidth*2 + \bondboldwidth\relax}
+ {\bondwidth}
+ {\bondhashlength}
+\renewcommand*\printatom[1]{{\small\ensuremath{\mathsf{#1}}}}
+
+\usepackage{rotating,array,tabu,booktabs}
+
+\defabbr\vs{\cnltxlatin{vs}}
+
+\begin{document}
+
+\section{Licence and Requirements}
+\license
+
+\carbohydrates\ loads the packages \pkg{chemfig}~\cite{pkg:chemfig},
+\pkg{etoolbox}~\cite{pkg:etoolbox} and \pkg{xcolor}~\cite{pkg:xcolor}.
+
+\section{The Idea}
+When teaching chemistry -- and in the case of this package: carbohydrate
+chemistry -- you have to show many examples of the basic aldoses and you have
+to explain the Fischer and the Haworth representation as well. This means you
+may have nearly the same \pkg{chemfig}~\cite{pkg:chemfig} formulas over and
+over in your documents. \carbohydrates\ aims to ease this task.
+
+The following example will give a short impression of what the package does:
+\begin{example}
+ \glucose
+ \glucose[model={fischer=skeleton}]
+ \setatomsep{2.5em}
+ \glucose[model=haworth,ring]
+ \glucose[model=haworth,ring=furanose]
+\end{example}
+
+\section{Usage}
+\subsection{The Base Macro}
+\begin{commands}
+ \command{carbohydrate}[\oarg{options}\marg{spec}]
+ A generic macro for typesetting carbohydrates.
+\end{commands}
+We will talk about the options in a bit. First lets see what \meta{spec}
+means. This argument is a series of the tokens \code{r}, \code{l} and
+\code{0} denoting an hydroxy group placed to the right or the left in the
+Fischer projection of the carbohydrate. A \code{0} means that the hydroxy
+group is to be left out. The series of tokens is meant to describe the
+hydroxy groups at the chiral centers. The aldehyde group\footnote{Also the
+ keto group once ketoses will be implemented.} and the hydroxy group at the
+end of the chain will be set automatically. Unless specified otherwise the
+command expects a hexose which means a series of \emph{four} tokens.
+
+\begin{example}
+ \chemname{\carbohydrate{llrr}}{\iupac{\D-Mannose}}
+ \chemname{\carbohydrate[model={fischer=skeleton}]{llrr}}{\iupac{\D-Mannose}}
+ \setatomsep{2.5em}\chemnameinit{}
+ \chemname{\carbohydrate[model=chair]{llrr}}{\iupac{\D-Mannose}}
+ \chemname{\carbohydrate[model=haworth]{llrr}}{\iupac{\D-Mannose}}
+\end{example}
+
+Adding the option \option{pentose} means that now only \emph{three} tokens
+need to be specified.
+
+\begin{example}
+ \chemname{\carbohydrate[pentose]{rlr}}{\iupac{\D-Xylose}}
+ \chemname{\carbohydrate[pentose,model={fischer=skeleton}]{rlr}}{\iupac{\D-Xylose}}
+ \setatomsep{2.5em}\chemnameinit{}
+ \chemname{\carbohydrate[pentose,model=haworth,ring]{rlr}}{\iupac{\D-Xylose}}
+ \chemname{\carbohydrate[pentose,model=haworth,ring=pyranose]{rlr}}{\iupac{\D-Xylose}}
+\end{example}
+
+\subsection{Available Options}
+As you have already seen in the pevious examples \cs{carbohydrate} has an
+optional argument that takes different options. Here is a complete list:
+\begin{options}
+ % model/fischer/skeleton/.code = \def\cbhdr@model{fischer@skeleton} ,
+ % model/fischer/full/.code = \def\cbhdr@model{fischer} ,
+ \keychoice{model}{fischer,haworth,chair}\Default{fischer}
+ The model to be used to draw the molecule. The choice \option{fischer}
+ is itself an option with two choices: \keyis{fischer}{skeleton} and
+ \keyis{fischer}{full}. Leaving the choice out will use \code{full} as
+ default choice.
+ \opt{chain}
+ Draw the open chain isomer.
+ \keychoice{ring}{\default{true},pyranose,furanose}
+ Draw a ring isomer. If you don't specify what ring type should be drawn
+ (\ie, if you choose \code{true}) the default depends on the length of the
+ carbohydrate. For example for hexoses the default ring type is
+ \code{pyranose}.
+ \keychoice{anomer}{alpha,beta,undetermined}\Default{alpha}
+ The ring anomer.
+ \keychoice{length}{6,5,4,3}\Default{6}
+ The length of the carbohydrate. \keyis{length}{6} draws a hexose,
+ \keyis{length}{3} draws a triose.
+ \opt{hexose}
+ An alias for \keyis{length}{6}.
+ \opt{pentose}
+ An alias for \keyis{length}{5}.
+ \opt{tetrose}
+ An alias for \keyis{length}{4}.
+ \opt{triose}
+ An alias for \keyis{length}{3}.
+ \keybool{3d}\Default{false}
+ Draw some of the bonds of the rings in the \code{haworth} and \code{chair}
+ models in a way that indicates the three dimensional structure of the
+ molecules.
+ \keylit-{color}{\marg{name}\marg{color}}
+ This option takes two arguments: \meta{name} specifies which part of the
+ molecule is to be colored, \meta{color} specifies the color to be used,
+ also see table~\vref{tab:color} and section~\ref{sec:colors}.
+\end{options}
+
+\begin{table}[htb]
+ \centering
+ \caption{Available names for the \option*{color} option.}\label{tab:color}
+ \begin{tabular}{>{\ttfamily}ll}
+ \toprule
+ \rmfamily\bfseries Name & \bfseries Function \\
+ \midrule
+ C1 & carbon 1 \\
+ C2 & carbon 2 \\
+ O-C2 & oxygen of the hydroxy group at carbon 2 \\
+ H-C2 & hydrogen of the hydroxy group at carbon 2 \\
+ C3 & carbon 3 \\
+ O-C3 & oxygen of the hydroxy group at carbon 3 \\
+ H-C3 & hydrogen of the hydroxy group at carbon 3 \\
+ C4 & carbon 4 \\
+ O-C4 & oxygen of the hydroxy group at carbon 4 \\
+ H-C4 & hydrogen of the hydroxy group at carbon 4 \\
+ C5 & carbon 5 \\
+ O-C5 & oxygen of the hydroxy group at carbon 5 \\
+ H-C5 & hydrogen of the hydroxy group at carbon 5 \\
+ C6 & carbon 6 \\
+ O-C6 & oxygen of the hydroxy group at carbon 6 \\
+ H-C6 & hydrogen of the hydroxy group at carbon 6 \\
+ anomerO & oxygen of the anomeric hydroxy group\slash aldehyde oxygen \\
+ anomerH & hydrogen of the anomeric hydroxy group \\
+ ringO & oxygen in the ring \\
+ \bottomrule
+ \end{tabular}
+\end{table}
+
+\subsection{Defining Shortcuts}\label{sec:defining-shortcuts}
+
+\carbohydrates\ allows to define shortcuts for aldoses:
+
+\begin{commands}
+ \command{newaldose}[\marg{cs}\oarg{options}\marg{spec}]
+ This defines the macro \meta{cs} with preset options \meta{options}.
+ \meta{spec} has the same meaning as for \cs{carbohydrate}.
+ \command{renewaldose}[\marg{cs}\oarg{options}\marg{spec}]
+ The same command but redefines an existing macro.
+\end{commands}
+
+In fact, \carbohydrates\ already defines macros for the common aldoses. They
+are listed in table~\ref{tab:predefined-aldoses} on
+page~\pageref{tab:predefined-aldoses}. They don't have any predefined options
+(except for \option{hexose}, \option{pentose} \etc).
+
+\begin{sidewaystable}
+ \setcarbohydrates{model={fischer=skeleton}}
+ \caption{Overview over the predefined aldoses.}
+ \label{tab:predefined-aldoses}
+ \begin{tabu}{*{8}{X[c]<{\strut}}}
+ \toprule
+ \allose & \altrose & \glucose & \mannose &
+ \gulose & \idose & \galactose & \talose \\
+ \cs{allose} & \cs{altrose} & \cs{glucose} & \cs{mannose} &
+ \cs{gulose} & \cs{idose} & \cs{galactose} & \cs{talose} \\
+ \iupac{\D-Allose} & \iupac{\D-Altrose} &
+ \iupac{\D-Glucose} & \iupac{\D-Mannose} &
+ \iupac{\D-Gulose} & \iupac{\D-Idose} &
+ \iupac{\D-Galactose} & \iupac{\D-Talose} \\
+ \midrule
+ \ribose & \arabinose & \xylose & \lyxose & \desoxyribose \\
+ \cs{ribose} & \cs{arabinose} & \cs{xylose} & \cs{lyxose} &
+ \multicolumn{2}{l}{\cs{desoxyribose}} \\
+ \iupac{\D-Ribose} & \iupac{\D-Arabinose} &
+ \iupac{\D-Xylose} & \iupac{\D-Lyxose} &
+ \iupac{\D-Desoxy|ribose} \\
+ \midrule
+ \erythrose & \threose & \glycerinaldehyde \\
+ \cs{erythrose} & \cs{threose} & \multicolumn{2}{l}{\cs{glycerinaldehyde}} \\
+ \iupac{\D-Erythrose} & \iupac{\D-Threose} &
+ \iupac{\D-Glycerin|aldehyde} \\
+ \bottomrule
+ \end{tabu}
+\end{sidewaystable}
+
+\subsection{Available Models}\label{sec:available-models}
+
+\carbohydrates\ implements different models for drawing carbohydrates:
+\begin{itemize}
+ \item Fischer -- skeleton: the Fischer representation with only a skeleton
+ formula.
+ \item Fischer -- full: the Fischer representation including all C and H
+ atoms.
+ \item Haworth: the Haworth representation.
+ \item Chair: the chair conformation.
+\end{itemize}
+
+While the Fischer model is implemented for all carbohydrates both Haworth and
+chair are not. The chair model is only implemented for aldohexoses, Haworth
+is implemented for aldotetroses, -pentoses and -hexoses.
+
+\begin{example}
+ \glucose[model={fischer=skeleton}]
+ \glucose[model={fischer=full}]
+ \setatomsep{2.5em}
+ \glucose[model=haworth]
+ \glucose[model=chair]
+\end{example}
+
+\subsection{Chain \vs\ Ring Forms}
+
+While the chain forms are available in all models the ring forms obviously
+aren't. There are two ring forms for hexoses and pentoses: pyranoses and
+furanoses. For tetroses only the furanose rings are available as there don't
+exist pyranose ring forms (for obvious reasons). It is also clear that
+neither pyranose nor furanose forms of trioses exist.
+
+\begin{example}
+ \setatomsep{2.5em}
+ \glucose[model=haworth,ring]
+ \ribose[model=haworth,ring]
+ \threose[model=haworth,ring]
+\end{example}
+
+\textbf{Actually the above is not true: the chain forms are not available in all
+models for all aldoses. As said in section~\ref{sec:available-models} the
+chair model is only implemented for aldohexoses. Also chains are not
+implemented for tetroses and trioses in the Haworth model.}
+
+\subsection{Default Settings}
+\begin{commands}
+ \command{setcarbohydrate}[\marg{options}]
+ Set package options for all carbohydrates within the current scope.
+ \command{setcarbohydratedefaults}[\marg{csname}\marg{options}]
+ Set options for a predefined carbohydrate within the current scope. The
+ first argument \meta{csname} is the macro name of the shortcut (see
+ section~\ref{sec:defining-shortcuts}).
+\end{commands}
+
+\begin{example}
+ \setatomsep{2.5em}
+ \setcarbohydratedefaults\glucose{ring,model=haworth,anomer=undetermined}
+ \glucose\
+ \mannose
+\end{example}
+
+\subsection{Colors}\label{sec:colors}
+For educating purposes it may be useful to be able to color certain atoms. The
+\option{color} option allows this.
+\begin{example}
+ \setcarbohydrates{model=chair}
+ \setatomsep{2.5em}
+ \schemestart
+ \glucose[color={anomerO}{red},color={O-C5}{green},color={H-C5}{blue}]
+ \arrow{<=>}
+ \glucose[ring,color={anomerO}{red},color={ringO}{green},color={anomerH}{blue}]
+ \schemestop
+\end{example}
+
+\section{\texorpdfstring{\textsc{todo}}{TODO}s}
+There are still quite a number of missing features that I'd like to implement
+some day such as
+\begin{itemize}
+ \item ring forms for \laevus-carbohydrates,
+ \item support for both chair conformations and the boat conformation,
+ \item support for ketoses,
+ \item support for oxidized and reduzed forms, and
+ \item disaccharides.
+\end{itemize}
+There is \emph{no} time table, though -- wether these features will be implemented
+any time soon or at all is undecided.
+
+\section{About the Examples in this Manual}
+All macros used in the examples either belong to \carbohydrates\ and are
+described in this manual or they belong to either
+\pkg{chemfig}~\cite{pkg:chemfig}, \pkg{chemmacros}~\cite{pkg:chemmacros},
+\pkg{chemformula}~\cite{pkg:chemformula}, or are standard \LaTeX\ macros. I
+encourage you to take a look at the packages for typesetting chemistry
+documents.
+
+The \pkg{chemfig} settings have been adjusted for the examples in this
+manual. Specifically the preamble of this document makes these settings:
+
+\begin{sourcecode}
+ \newcommand*{\bondwidth}{0.06642 em}
+ \newcommand*{\bondboldwidth}{0.22832 em}
+ \newcommand*{\bondhashlength}{0.25737 em}
+ \setdoublesep{0.35700 em}
+ \setatomsep{1.78500 em}
+ \setbondoffset{0.18265 em}
+ \setbondstyle{line width = \bondwidth}
+ \setcrambond
+ {\dimexpr\bondwidth*2 + \bondboldwidth\relax}
+ {\bondwidth}
+ {\bondhashlength}
+ \renewcommand*\printatom[1]{{\small\ensuremath{\mathsf{#1}}}}
+\end{sourcecode}
+These settings are taken from~\cite{texdev}. Search the page for
+\code{chemfig} and you should be able to find them there.
+
+\end{document}
diff --git a/Master/texmf-dist/doc/latex/carbohydrates/test.tex b/Master/texmf-dist/doc/latex/carbohydrates/test.tex
new file mode 100644
index 00000000000..a5bd6041f57
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/carbohydrates/test.tex
@@ -0,0 +1,143 @@
+\documentclass{scrartcl}
+\usepackage{carbohydrates}
+% \setcarbohydrates{
+% color={anomerO}{red} ,
+% color={anomerH}{blue} ,
+% color={ringO}{green} ,
+% color={C2}{yellow} ,
+% color={O-C2}{yellow} ,
+% color={H-C2}{yellow} ,
+% color={C5}{purple} ,
+% color={O-C5}{purple} ,
+% color={H-C5}{purple} ,
+% color={C6}{orange} ,
+% color={O-C6}{orange} ,
+% color={H-C6}{orange}
+% }
+
+\begin{document}
+
+\setcarbohydrates{model=chair}
+\schemestart
+ \glucose[color={anomerO}{red},color={O-C5}{green},color={H-C5}{blue}]
+ \arrow{<=>}
+ \glucose[ring,color={anomerO}{red},color={ringO}{green},color={anomerH}{blue}]
+\schemestop
+
+\end{document}
+
+\documentclass{scrartcl}
+
+\usepackage{carbohydrates}
+\colorlet{cbhdr@anomerO}{green}
+\colorlet{anomerH}{blue}
+\colorlet{cbhdr@ringO}{red}
+\colorlet{cbhdr@O-C5}{orange}
+\colorlet{cbhdr@H-C5}{yellow}
+
+\begin{document}
+
+\glucose[model=haworth,chain]
+
+\ribose[model=haworth,chain]
+
+\ribose[model=haworth,ring]
+
+\end{document}
+
+\glucose[model={fischer=skeleton}]
+\quad
+\glucose[model={fischer=skeleton},ring]
+
+\bigskip
+
+\threose[model={fischer=skeleton}]
+\quad
+\threose[ring,model=haworth]
+
+% \glycerinaldehyde[ring]
+
+\bigskip
+
+\ribose[ring=pyranose]
+\quad
+\ribose[model=haworth,ring]
+\quad
+\ribose[model=haworth,ring=pyranose]
+
+\bigskip
+
+\carbohydrate[model=haworth,ring=furanose,]{l0ll}
+
+\end{document}
+% \makeatletter
+
+\glucose
+\quad
+\glucose[ring]
+\quad
+\glucose[ring,anomer=beta]
+
+\bigskip
+
+\glucose[ring=furanose]
+\quad
+\glucose[ring=furanose,model=haworth]
+\quad
+\galactose[ring=furanose,model=haworth]
+
+\end{document}
+
+\bigskip
+
+\glucose[model={fischer=skeleton}]
+\quad
+\glucose[model={fischer=skeleton},ring]
+\quad
+\glucose[model={fischer=skeleton},ring,anomer=beta]
+
+\bigskip
+
+\glucose[model=haworth]
+\quad
+\glucose[model=haworth,ring]
+\quad
+\glucose[model=haworth,ring,anomer=beta]
+
+\bigskip
+
+\glucose[model=chair]
+\quad
+\glucose[model=chair,ring]
+\quad
+\glucose[model=chair,ring,anomer=beta]
+
+\glucose[model=haworth,ring,anomer=undetermined]
+
+\bigskip
+
+\idose[model=haworth]
+\quad
+\idose[model=haworth,ring]
+\quad
+\idose[model=haworth,ring,anomer=beta]
+
+\bigskip
+
+\idose[model=chair]
+\quad
+\idose[model=chair,ring]
+\quad
+\idose[model=chair,ring,anomer=beta]
+
+\bigskip
+
+\ribose
+\quad
+\desoxyribose
+\quad
+\desoxyribose[model={fischer=skeleton},ring]
+
+
+\end{document}
+
diff --git a/Master/texmf-dist/tex/latex/carbohydrates/carbohydrates.sty b/Master/texmf-dist/tex/latex/carbohydrates/carbohydrates.sty
new file mode 100644
index 00000000000..2e1814bab76
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/carbohydrates/carbohydrates.sty
@@ -0,0 +1,874 @@
+% --------------------------------------------------------------------------
+% 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{<code>}
+
+% \cbhdr@newchain<macro><arguments>{<chemfig code>}
+
+\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{<code>}
+
+% \cbhdr@newring<macro><arguments>{<chemfig code>}
+
+\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:
+%
+% \<module>@<model>@<chain>/<ring>(@<ringtype>)
+%
+% --------------------------------------------------------------------------
+% 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
+%
+% <module>@<model>@<chain>/<ring>(@<ringtype>)
+
+\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?
+
diff --git a/Master/tlpkg/bin/tlpkg-ctan-check b/Master/tlpkg/bin/tlpkg-ctan-check
index f2e8ccb4589..003201ea81a 100755
--- a/Master/tlpkg/bin/tlpkg-ctan-check
+++ b/Master/tlpkg/bin/tlpkg-ctan-check
@@ -113,7 +113,7 @@ my @TLP_working = qw(
c90 c-pascal cabin cachepic caladea calcage calctab calculation calculator
calligra calligra-type1 calrsfs cals calxxxx-yyyy cancel
canoniclayout cantarell
- capt-of captcont captdef caption carlisle carlito carolmin-ps
+ capt-of captcont captdef caption carbohydrates carlisle carlito carolmin-ps
cascadilla cases casyl
catchfilebetweentags catcodes catechis catoptions
cbcoptic cbfonts cbfonts-fd
diff --git a/Master/tlpkg/tlpsrc/carbohydrates.tlpsrc b/Master/tlpkg/tlpsrc/carbohydrates.tlpsrc
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/Master/tlpkg/tlpsrc/carbohydrates.tlpsrc
diff --git a/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc b/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc
index 959873bc324..71f77b22023 100644
--- a/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc
+++ b/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc
@@ -107,6 +107,7 @@ depend canoniclayout
depend capt-of
depend captcont
depend captdef
+depend carbohydrates
depend cases
depend casyl
depend catchfilebetweentags