summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/cooking-units
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /macros/latex/contrib/cooking-units
Initial commit
Diffstat (limited to 'macros/latex/contrib/cooking-units')
-rw-r--r--macros/latex/contrib/cooking-units/README.md61
-rw-r--r--macros/latex/contrib/cooking-units/cooking-units.dtx8246
-rw-r--r--macros/latex/contrib/cooking-units/cooking-units.ins54
-rw-r--r--macros/latex/contrib/cooking-units/cooking-units.pdfbin0 -> 658095 bytes
4 files changed, 8361 insertions, 0 deletions
diff --git a/macros/latex/contrib/cooking-units/README.md b/macros/latex/contrib/cooking-units/README.md
new file mode 100644
index 0000000000..9ae432ec6b
--- /dev/null
+++ b/macros/latex/contrib/cooking-units/README.md
@@ -0,0 +1,61 @@
+
+cooking-units
+=============
+
+Overview
+--------
+
+While writing a cookery book, units and their format can be quite
+troublesome. This contains not only the question of how to print those
+units, but also the question of the conversion of units. A cookery
+book doesn't contain only SI units, it contains a much more colorful
+range of units (kg, dag, g, oz, ... for example) and it may cause
+some confusion if too many different units are used, but if you just
+write a cookery book for fun you don't think about this ... until
+someone (my mother in my case) tells you that it's too confusing.
+
+This package solves both problems: It formats your input and you have
+the option to convert the units globally or locally using an easy to
+use key-value system.
+
+Please note that this package is not intended to be used to print
+units (and numbers) physically correct. It should be used for more
+light-hearted stuff (like a cookery book for example).
+
+Requirements
+------------
+
+ * expl3 & xparse
+ * translations
+ * xfrac
+ * l3keys2e
+ * fmtcount (optional)
+
+This file contains
+------------------
+
+ * README
+ * cooking-units.pdf
+ * cooking-units.dtx
+ * cooking-units.ins
+
+Changes
+-------
+
+See section 'Change History' in the documentation.
+
+Supported Languages
+-------------------
+
+* German
+* English
+* French (suboptimal)
+
+License
+-------
+This material is subject to the LaTeX Project Public License 1.3c or later. See
+
+ https://ctan.org/license/lppl1.3c
+
+for the details of that license.
+
diff --git a/macros/latex/contrib/cooking-units/cooking-units.dtx b/macros/latex/contrib/cooking-units/cooking-units.dtx
new file mode 100644
index 0000000000..74cd835484
--- /dev/null
+++ b/macros/latex/contrib/cooking-units/cooking-units.dtx
@@ -0,0 +1,8246 @@
+% \iffalse meta-comment
+% !TEX encoding = UTF-8 Unicode
+% !TEX program = pdfLaTeX
+%
+%
+%<*internal>
+\iffalse
+%</internal>
+%<*readme>
+
+cooking-units
+=============
+
+Overview
+--------
+
+While writing a cookery book, units and their format can be quite
+troublesome. This contains not only the question of how to print those
+units, but also the question of the conversion of units. A cookery
+book doesn't contain only SI units, it contains a much more colorful
+range of units (kg, dag, g, oz, ... for example) and it may cause
+some confusion if too many different units are used, but if you just
+write a cookery book for fun you don't think about this ... until
+someone (my mother in my case) tells you that it's too confusing.
+
+This package solves both problems: It formats your input and you have
+the option to convert the units globally or locally using an easy to
+use key-value system.
+
+Please note that this package is not intended to be used to print
+units (and numbers) physically correct. It should be used for more
+light-hearted stuff (like a cookery book for example).
+
+Requirements
+------------
+
+ * expl3 & xparse
+ * translations
+ * xfrac
+ * l3keys2e
+ * fmtcount (optional)
+
+
+This file contains
+------------------
+
+ * README
+ * cooking-units.pdf
+ * cooking-units.dtx
+ * cooking-units.ins
+
+Changes
+-------
+
+See section 'Change History' in the documentation.
+
+Supported Languages
+-------------------
+
+* German
+* English
+* French (suboptimal)
+
+License
+-------
+This material is subject to the LaTeX Project Public License 1.3c or later. See
+
+ https://ctan.org/license/lppl1.3c
+
+for the details of that license.
+
+%</readme>
+%<*internal>
+\fi
+\def\nameofplainTeX{plain}
+\ifx\fmtname\nameofplainTeX\else
+ \expandafter\begingroup
+\fi
+%</internal>
+%<*install>
+\input l3docstrip.tex
+%\keepsilent
+\askforoverwritefalse
+\preamble
+Copyright (C) 2016--2018 by Ben Vitecek (current Maintainer)
+
+This file may be distributed and/or modified under the
+conditions of the LaTeX Project Public License, either
+version 1.3c of this license or (at your option) any later
+version. The latest version of this license is in:
+
+ https://ctan.org/license/lppl1.3c
+
+and version 1.3c or later is part of all distributions of
+LaTeX version 2008-05-04 or later.
+
+This work has the LPPL maintenance status `maintained'.
+
+This work consists of the files README.md, cooking-units.dtx and cooking-units.ins
+and the derived file cooking-units.sty.
+
+\endpreamble
+%\postamble
+
+
+%\endpostamble
+\usedir{tex/latex/cooking-units}
+\generate{
+ \file{\jobname.sty}{\from{\jobname.dtx}{package}}
+}
+%</install>
+%<install>\endbatchfile
+%<*internal>
+\usedir{source/latex/cooking-units}
+\generate{
+ \file{\jobname.ins}{\from{\jobname.dtx}{install}}
+}
+\nopreamble\nopostamble
+\usedir{doc/latex/cooking-units}
+\generate{
+ \file{README.md}{\from{\jobname.dtx}{readme}}
+}
+\ifx\fmtname\nameofplainTeX
+ \expandafter\endbatchfile
+\else
+ \expandafter\endgroup
+\fi
+%</internal>
+%<*driver>
+\documentclass[
+ ngerman,
+ french,
+ english, %french, naustrian
+ onlydoc,
+% check-declarations,
+]{l3doc}
+\usepackage[utf8]{inputenc}
+\usepackage[main=english]{babel}
+\usepackage[use-numerals=true]{cooking-units}
+\usepackage{tikzsymbols}
+\usepackage{listings}
+\usepackage{environ}
+\usepackage{nicefrac}
+\usepackage{cleveref}
+\usepackage{mathtools}
+\usepackage{siunitx}
+\usepackage{totalcount}
+\usepackage{microtype}
+
+
+\newcounter{CookingUnitsCounter}
+\newcounter{cunumCounter}
+\newcounter{cuamCounter}
+\newcounter{cutextCounter}
+\newcounter{CutextCounter}
+\DeclareTotalCounter{CookingUnitsCounter}
+\DeclareTotalCounter{cunumCounter}
+\DeclareTotalCounter{cuamCounter}
+\DeclareTotalCounter{cutextCounter}
+\DeclareTotalCounter{CutextCounter}
+
+\babeltags{myde = ngerman}
+
+\DeclareSIUnit{\ounce}{oz}
+\DeclareSIUnit{\oz}{\ounce}
+\DeclareSIUnit{\pound}{lb}
+\DeclareSIUnit{\lb}{\pound}
+\DeclareSIUnit{\stone}{st}
+\DeclareSIUnit{\st}{\stone}
+\DeclareSIUnit{\stick}{st}
+\cusetup{print-numerals=false}
+
+%\EnableCrossrefs
+
+
+%\newcommand\TODO[1]{\footnote{\textcolor{red}{#1}}}
+
+\ExplSyntaxOn
+
+
+
+\clist_new:N \l_cookingunits_list_of_defined_befehlen_clist
+\clist_set:Nn \l_cookingunits_list_of_defined_befehlen_clist
+ {
+ cunum,
+ cutext,
+ Cutext,
+ cuam,
+ newcookingunit,
+ declarecookingunit,
+ providecookingunit,
+ cudefinename,
+ cudefinesymbol,
+ cusetup,
+ cudefinekeys,
+ cudefinesinglekey,
+ cuaddkeys,
+ cuaddsinglekeys,
+ cuaddtokeys,
+ culabel,
+ curef,
+ cudefinephrase,
+ }
+
+\NewDocumentCommand \mycs { m }
+ {
+ \clist_if_in:NnTF \l_cookingunits_list_of_defined_befehlen_clist {#1}
+ { \cs{\textcolor{blue}{#1}} }
+ { \ERROR }
+ }
+\newcommand\opt{\texttt}
+\newcommand\myunit{\texttt}
+\newcommand\mygroup{\texttt}
+\newcommand\myaarg[1]{\texttt{<}\meta{#1}\texttt{>}}
+\newcommand\true{\opt{true}}
+\newcommand\false{\opt{false}}
+
+%: \PrintUnit
+\NewDocumentCommand \PrintUnit { o m }
+ {
+ \SaveTranslation \l_tmpa_tl { #2 (cu-unitname) }
+ \tl_if_eq:NNF \l_tmpa_tl \q__cookingunits_no_translation
+ { \l_tmpa_tl }
+ \IfNoValueF {#1} {#1}
+ &
+ \texttt {#2}
+ &
+ \tl_use:c { l__cookingunits_default_unit_ #2 _tl }
+ }
+\NewDocumentCommand \PrintUnitSymbol { m }
+ {
+ \texttt {#1} &
+ \tl_use:c { l__cookingunits_default_unit_ #1 _tl }
+ }
+\NewDocumentCommand \PrintGroup { m }
+ {
+ \mygroup {#1} &
+ \seq_use:cn { l__cookingunits_group_ #1 _seq } { ,~ }
+ }
+
+\NewDocumentCommand \DeactivateForbiddenUnitError { }
+ {
+ \msg_redirect_name:nnn { cooking-units } { curef-forbidden-unit } { warning }
+ }
+
+
+%% Allyourwhitespacearebelongtous (too long)
+%% 42
+%% Miep!
+\NewDocumentCommand \dothewhitespace { O{ Ducks } }
+ {
+ \textcolor{white} {#1} \\
+ }
+\newcommand\eatthewhitespace{}
+\NewEnviron { cuexamplecode }[1][]
+ {
+ \begin{center}
+ \begin{minipage}{0.4\linewidth}
+ \tl_replace_all:Nnn \BODY { @ } { \dothewhitespace }
+ \tl_replace_all:Nnn \BODY { \% } { \color{red} \% \ignorespaces }
+ \tl_replace_all:Nnn \BODY { \\ } { \\ \color{black} }
+ \tl_replace_all:Nnn \BODY { & } { \ignorespaces }
+ \BODY
+ \end{minipage}
+
+ #1
+ \int_zero:N \l_tmpa_int
+ \begin{minipage}{0.5\linewidth}
+ \ttfamily
+ \tl_set_rescan:Nno \l_tmpa_tl
+ {
+ \char_set_catcode_other:N \{ %
+ \char_set_catcode_other:N \} %
+ \char_set_catcode_other:N \_ %
+ \char_set_catcode_other:N \~ %
+ }
+ { \BODY }
+ \tl_map_inline:Nn \l_tmpa_tl
+ {
+ \token_if_cs:NTF ##1
+ {
+ \cs_if_eq:NNTF ##1 \\
+ { \textbackslash\textbackslash \\ }
+ {
+ \tl_set_rescan:Nnn \l_tmpb_tl
+ {
+ \char_set_catcode_ignore:N \\ %
+ \char_set_catcode_ignore:N \ %
+ }
+ {##1}
+ \textbackslash \textcolor{blue}{\l_tmpb_tl}
+ }
+ }
+ {
+ \bool_lazy_any:nTF
+ {
+ { \str_if_eq_p:nn {##1} { @ } }
+ { \str_if_eq_p:nn {##1} { ! } }
+ { \str_if_eq_p:nn {##1} { & } }
+ }
+ {
+ \str_if_eq:nnTF {##1} { & }
+ { \space }
+ {
+ \str_if_eq:nnTF {##1} { ! }
+ { \ERROR }
+ { \\ }
+ }
+ }
+ {
+ \token_if_active:NTF ##1
+ {##1}
+ {
+ \token_if_parameter:NTF ##1
+ {
+ \int_compare:nNnTF { \l_tmpa_int } = { 0 }
+ {
+ \c_hash_str
+ \int_incr:N \l_tmpa_int
+ }
+ { \int_zero:N \l_tmpa_int }
+ }
+ { ##1 {} }
+ }
+ }
+ }
+ }
+ \end{minipage}
+ \end{center}
+ }
+\ProvideDocumentEnvironment{cuexamplecode}{}{}{}{}
+
+
+\NewDocumentEnvironment { cuexample } { }
+ {
+ \paragraph{Example:}
+% \par \bigskip \noindent
+% \mbox{}
+% \marginpar{\raggedleft\textbf{Example}}\
+% \ignorespaces
+ }
+ { }
+
+\NewDocumentEnvironment { cunote } { }
+ {
+ \paragraph{Note:}
+ }{ }
+
+
+\NewDocumentEnvironment { cuinterest } { m }
+ {
+ \par \bigskip
+ \clist_set:Nn \l_tmpa_clist {#1}
+ \mbox{}\marginpar{\raggedleft\opt{ \clist_use:Nn \l_tmpa_clist { \\ } }}
+ \ignorespaces
+ }
+ { }
+
+
+%: table
+\tl_new:N \l_translation_does_not_exist_tl
+\tl_set:Nn \l_translation_does_not_exist_tl { --- }
+\tl_new:N \translationdoesnotexisttl
+\tl_set_eq:NN \translationdoesnotexisttl \l_translation_does_not_exist_tl
+\tl_new:N \mytablecolumns
+\tl_set:Nn \mytablecolumns { l l l l l }
+\clist_new:N \l_list_of_units_clist
+\clist_new:N \l_list_of_textunits_clist
+\clist_set:Nn \l_list_of_textunits_clist
+ {
+ decimal-mark ,
+ one (m) ,
+ one (f) ,
+ one (n) ,
+ }
+\clist_set:Nx \l_list_of_units_clist
+ {
+ kg , dag , g , oz , lb , space ,
+ C , F , Re , K , space ,
+ d , h , min , s , space ,
+ m , dm , cm , mm , in , space ,
+ l , dl , cl , ml , space ,
+ cal , kcal , J , kJ , eV , space ,
+ pn , EL , TL , csp , dsp , ssp , Msp , space ,
+ \clist_use:Nn \l_list_of_textunits_clist { , } ,
+ THEEND
+ }
+
+\cs_new:Npn \__table_midrule:
+ {
+ \\ \midrule
+ \cs_gset:Npn \__table_midrule: { \\ }
+ }
+\cs_new_eq:NN \__table_default_midrule: \__table_midrule:
+
+\cs_new:Npn \_cook_use:n #1
+ { \cs_if_exist_use:cF { __cookingunits_#1 } {\ERRORcommandNOTexist} }
+
+\NewDocumentCommand \CreateTableForLanguages { s >{\TrimSpaces} m }
+ {
+ \IfBooleanTF {#1}
+ { \clist_gset_eq:NN \l_tmpa_clist \l_list_of_textunits_clist }
+ { \clist_gset_eq:NN \l_tmpa_clist \l_list_of_units_clist }
+ \cs_gset_eq:NN \__table_midrule: \__table_default_midrule:
+ \CreateTableHeader {#2}
+ \CreateTableRow {#2}
+ }
+
+\NewDocumentCommand \CreateTableHeader { m }
+ {
+ \meta{unit-key} &
+ printed \ unit & unit name & (plural) & gender
+ }
+\NewDocumentCommand \CreateTableRow { m }
+ {
+ \clist_map_inline:Nn \l_tmpa_clist
+ {
+ \str_case:nnF {##1}
+ {
+ { space } { \\ \addlinespace \cs_set:Npn \__table_midrule: {} }
+ { THEEND } { \\ \bottomrule }
+ }{
+ \__table_midrule:
+ \texttt{##1}
+ &
+ \clist_if_in:NnTF \l_list_of_textunits_clist {##1}
+ { \l_translation_does_not_exist_tl }
+ {
+ \_cook_use:n { translate_let:nNnV } {#1} \l_tmpa_tl {##1} \c__cookingunits_postfix_unit_tl
+ \tl_if_in:NnTF \l_tmpa_tl \q__cookingunits_no_translation
+ { \l_translation_does_not_exist_tl }
+ { \l_tmpa_tl }
+ }
+ &
+ \_cook_use:n { translate_let:nNnV } {#1} \l_tmpa_tl {##1} \c__cookingunits_postfix_unitname_tl
+ \tl_if_in:NnTF \l_tmpa_tl \q__cookingunits_no_translation
+ { \l_translation_does_not_exist_tl }
+ { \l_tmpa_tl }
+ &
+ \_cook_use:n { translate_let:nNnV } {#1} \l_tmpa_tl {##1} \c__cookingunits_postfix_unitname_tl
+ \_cook_use:n { translate_let:nNnV } {#1} \l_tmpb_tl {##1} \c__cookingunits_postfix_unitname_pl_tl
+ \tl_if_eq:NNF \l_tmpa_tl \l_tmpb_tl
+ {
+ \tl_if_in:NnTF \l_tmpb_tl \q__cookingunits_no_translation
+ { \l_translation_does_not_exist_tl }
+ { (\l_tmpb_tl) }
+ }
+ &
+ \_cook_use:n { translate_let:nNnV } {#1} \l_tmpa_tl {##1} \c__cookingunits_postfix_gender_tl
+ \tl_if_in:NnTF \l_tmpa_tl \q__cookingunits_no_translation
+ { \l_translation_does_not_exist_tl }
+ { \l_tmpa_tl }
+ }
+ }
+ }
+
+\NewDocumentCommand \CreateTableForPhrases { >{\TrimSpaces} m }
+ {
+ \tl_set:Nn \l_tmpa_tl {#1}
+ \__cookingunits_phrase_list_get_for:NNTF \l_tmpa_prop \l_tmpa_tl
+ {
+ \__cookingunits_translate_let:VNnV \l_tmpa_tl \l_tmpa_seq
+ { phrase-clist } \c__cookingunits_postfix_phrase_tl
+ }
+ { \ERRORCreateTable }
+ \seq_gput_right:Nn \l_tmpa_seq { THEEND }
+ \cs_gset_eq:NN \__table_midrule: \__table_default_midrule:
+ \begin{tabular}{ l l l l l }
+ \toprule
+ \meta{Phrase-key} & phrase & (plural) & gender
+ \CreatePhraseTableRow {#1}
+ \end{tabular}
+ }
+
+\NewDocumentCommand \CreatePhraseTableRow { m }
+ {
+ \seq_map_inline:Nn \l_tmpa_seq
+ {
+ \str_case:nnF {##1}
+ {
+ { space } { \addlinespace \cs_set:Npn \__table_midrule: {} }
+ { THEEND } { \\ \bottomrule }
+ }{
+ \__table_midrule:
+ ##1
+ &
+ \prop_get:NnN \l__cookingunits_phrase_prop {##1} \l_tmpa_tl
+ \tl_gset:NV \l_tmpa_tl \l_tmpa_tl %% Damit global
+ \l_tmpa_tl
+ &
+ \prop_get:NnN \l__cookingunits_phrase_prop {##1-pl} \l_tmpb_tl
+ \tl_if_eq:NNF \l_tmpa_tl \l_tmpb_tl { \l_tmpb_tl }
+ &
+ \__cookingunits_translate_let:nNnV {#1}
+ \l_tmpa_tl { ##1 -phrase-gender } \c__cookingunits_postfix_gender_tl
+ \l_tmpa_tl
+ }
+ }
+ }
+
+
+
+
+
+\newcommand\txtupde{\textsuperscript{de}}
+\newcommand\txtupsic{\textsuperscript{sicilian}}
+\newcommand\txtupen{\textsuperscript{en}}
+\NewDocumentCommand\unititem { m d** O{} O{} }
+ {
+ \item
+ [{
+ #1
+ \IfNoValueF {#2} { \use:c { txtup #2 } }
+ \tl_if_empty:nF {#3} {\ (#3) }
+ \tl_if_empty:nF {#4} {\ [#4] }
+ }]
+ }
+
+\NewDocumentEnvironment { myquote } { o o }
+ {
+ \list{}{%
+ \topsep 0pt
+ \leftmargin 0pt
+ }
+ \item\relax
+ \itshape
+ }{
+ \normalfont
+ \IfNoValueF{#1}{(see\ \cite{#1} \IfNoValueF{#2}{\ page \ #2} )}
+ \endlist
+ }
+\makeatletter
+\newenvironment{mydescription}
+ {\list{}{\labelwidth\z@ \itemindent-\leftmargin
+ \let\makelabel\descriptionlabel}}
+ {\endlist}
+\renewcommand*\descriptionlabel[1]{\hspace\labelsep
+ \normalfont\bfseries #1}
+\makeatother
+\ExplSyntaxOff
+
+\newcommand\cCutext{\mycs{cutext} and \mycs{Cutext}}
+
+\lstset
+ {
+ basicstyle = \ttfamily,
+ basewidth = 0.51em,
+ gobble = 3,
+ keywordstyle = \color{blue},
+ language = [LaTeX]{TeX},
+ commentstyle=\color{red!80!black},
+ moretexcs =
+ {
+ cunum,
+ cutext,
+ Cutext,
+ cuam,
+ newcookingunit,
+ declarecookingunit,
+ providecookingunit,
+ cudefinename,
+ cudefinesymbol,
+ cusetup,
+ cudefinekeys,
+ cudefinesinglekey,
+ cuaddkeys,
+ cuaddsinglekeys,
+ cuaddtokeys,
+ culabel,
+ curef,
+ cudefinephrase,
+ }
+ }
+
+\newcookingunit {st}
+\newcookingunit [\ensuremath{ {} ^ { \circ } }\kern-\scriptspace R{\text{\o}}] {Ro}
+\newcookingunit {ft}
+
+\cuaddkeys {lb}
+ {
+ {st} { 1/14 } %% 1 lb are 1/14 st
+ }
+\cuaddtokeys {m} {ft} {0.3048}
+\cuaddsinglekeys {C}
+ {
+ {Ro} { #1*21/40 + 7.5 }
+ }
+\cusetup
+ {
+ commands-add-hook = {\stepcounter{CookingUnitsCounter}} ,
+ cunum-add-hook = {\stepcounter{cunumCounter}} ,
+ cutext-add-hook = {\stepcounter{cutextCounter}} ,
+ Cutext-add-hook = {\stepcounter{CutextCounter}} ,
+ cuam-add-hook = {\stepcounter{cuamCounter}} ,
+ set-option-for-Ro = { round-to-int = true } ,
+% add-unit-to-group = { weight = {st} , temperature = {Ro} }
+ }
+
+%: \cusetup
+\cusetup
+ {
+% weight=stick,
+% 42 = true ,
+% convert-to-eV=true ,
+% cutext-range-sign = {as},
+% erase-all-options,
+% set-option-for-K= {},
+% set-unknown-message = error ,
+% check-temperature = true,
+% round-precision = 30 ,
+ }
+
+
+\EnableCrossrefs
+\CodelineIndex
+\RecordChanges
+\AtEndDocument { \PrintChanges \PrintIndex }
+
+
+\begin{document}
+\DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+%
+%
+%
+% \CharacterTable
+% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
+% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
+% Digits \0\1\2\3\4\5\6\7\8\9
+% Exclamation \! Double quote \" Hash (number) \#
+% Dollar \$ Percent \% Ampersand \&
+% Acute accent \' Left paren \( Right paren \)
+% Asterisk \* Plus \+ Comma \,
+% Minus \- Point \. Solidus \/
+% Colon \: Semicolon \; Less than \<
+% Equals \= Greater than \> Question mark \?
+% Commercial at \@ Left bracket \[ Backslash \\
+% Right bracket \] Circumflex \^ Underscore \_
+% Grave accent \` Left brace \{ Vertical bar \|
+% Right brace \} Tilde \~}
+%
+%
+% \iffalse
+%: changes
+% \fi
+%
+% \changes {2016/06/11} {0.99} {Added the package option to load 'fmtcount'.}
+% \changes {2016/08/31} {1.00} {Initial version}
+% \changes {2016/08/31} {1.00a} {Fixed calculation: degree Reamur to eV}
+% \changes {2016/09/03} {1.01} {Added units 'ssp', 'csp', 'dsp'}
+% \changes {2016/09/03} {1.01} {English unit: litre (and only litre) uses the curly l \protect\ensuremath{\protect\ell} now }
+% \changes {2016/09/03} {1.01} {British English: 'pinch' is written in full}
+% \changes {2016/09/03} {1.01} {Separated Messerspitze and pinch}
+% \changes {2016/09/05} {1.02} {Replaced \cs{cufrac} by \cs{cuam}}
+% \changes {2016/09/05} {1.02} {New message: 'obsolete-command'}
+% \changes {2016/09/09} {1.02a} {Changed name from \cs{@@_parse_fraction_in_input:www} to \cs{@@_parse_mixed_fraction_in_input:www}}
+% \changes {2016/09/09} {1.02b} {Changed name from \cs{@@_cunum_parse_range} (and derivatives) to \cs{@@_cutext_parse_range}.}
+% \changes {2016/09/09} {1.02c} {In \cs{@@_cutext_default:nnn} it is only
+% checked once if a range is inside.}
+% \changes {2016/09/09} {1.02d} {\cs{@@_calculate_input_and_store_in:nN} optimiert durch neue property-key: single.}
+% \changes {2016/09/09} {1.02d} {Add 'single' to property list of singlekeys.}
+% \changes {2016/09/16} {1.02e} {Only use \cs{phantom} if the argument (for \cs{phantom}) is not empty.}
+% \changes {2016/09/09} {1.02i} {Delete 'single' from property lists of singlekeys cause it is not as safe as I thought.}
+% \changes {2016/09/09} {1.02f} {Corrected mistake: 'ELektronenvolt' (note uppercase L) to 'Elektronenvolt' in german.}
+% \changes {2016/09/26} {1.03} {New option (and needed macros): add-temperature-to-check.}
+% \changes {2016/09/26} {1.03a} {\cs{cuaddsinglekeys} now tests if the unit exists (it didn't before).}
+% \changes {2016/09/26} {1.03b} {Replaced \cs{prop_clear_new:c} by \cs{prop_clear:c}.}
+% \changes {2016/09/26} {1.03b} {Recalculated all electron volt values for conversion (as 'kg' was wrong before). Let's hope they are correct this time.}
+% \changes {2016/09/26} {1.04} {New option: 'round-half'.}
+% \changes {2016/10/19} {1.04} {Use \cs{keys_set:nn} only if second argument is not empty.}
+% \changes {2016/10/19} {1.04} {'convert-to-eV' now also as optional argument available.}
+% \changes {2016/10/19} {1.04} {Option 'load-time-option' now spells 'available' correct.}
+% \changes {2016/10/19} {1.04} {Update of documentation.}
+% \changes {2016/10/28} {1.10alpha} {Start implementation of \enquote{Change recipe from $n$ to $m$ persons.}.}
+% \changes {2016/10/28} {1.10alpha} {\cs{cutext} (and \cs{Cutext}) and \cs{cuam} now parse their input like \cs{cunum}. This is needed as they also need to be changed.}
+% \changes {2016/10/29} {1.10alpha} {Tiding code: Now every command is separated into a \enquote{calc} function, a \enquote{print numeric value} and a \enquote{print unit} (if there) function. At least, that's the plan.}
+% \changes {2016/10/30} {1.10} {Fractions should now deal correctly with minus signs.}
+% \changes {2016/11/07} {1.10} {Finished writing v1.10.}
+% \changes {2016/11/13} {1.10} {Change amounts for specific number of persons.}
+% \changes {2016/11/13} {1.10} {\cs{cutext}, \cs{Cutext} and \cs{cuam} check their input, allows conversion of units.}
+% \changes {2016/11/13} {1.10} {New commands: \cs{culabel} and \cs{curef}.}
+% \changes {2016/11/13} {1.10} {New commands: \cs{declarecookingunit} and \cs{providecookingunit}.}
+% \changes {2016/11/13} {1.10} {New options: \opt{cutext-to-cunum}, \opt{cutext-change-unit} and \opt{cutext-space}.}
+% \changes {2016/11/13} {1.10} {New options: \opt{cuam-version} and \opt{cutext-version}}
+% \changes {2016/11/13} {1.10} {New options: \opt{recalculate-amount} and \opt{set-number-of-persons}, \opt{label}, \opt{get-label}, \opt{ref}.}
+% \changes {2017/03/10} {1.10a} {\cs{curef} is now defined by \cs{NewExpandableDocumentCommand} instead of the Declare variant.}
+% \changes {2017/03/10} {1.11} {Removed \cs{translate} and others from code
+% and replaced them with wrapper-macros.}
+% \changes {2017/03/10} {1.11} {Removed things like 'cu-unit' from translate input
+% and placed them into separate tl's.}
+%
+% \changes {2017/10/23} {1.20} {Replaced \pkg{translator} by \pkg{translations}.}
+% \changes {2017/10/23} {1.20} {Added \enquote{phrases}.}
+% \changes {2017/10/23} {1.20} {Added unit \enquote{stick} (of butter).}
+% \changes {2017/10/23} {1.20} {|<| is not allowed as a special sign anymore.}
+% \changes {2017/10/23} {1.20} {New option: \opt{set-cutext-translation-message}.}
+% \changes {2017/10/23} {1.20} {New option: \opt{print-numerals}.}
+% \changes {2017/10/23} {1.20} {New option: \opt{use-phrases}.}
+% \changes {2017/10/23} {1.20} {New option: \opt{phrase-space}.}
+% \changes {2017/10/23} {1.20} {New option: \opt{amount-unit-space}.}
+% \changes {2017/10/23} {1.20} {Now checks for ranges if both values can be printed as numerals (if activated) (bug fix).}
+% \changes {2017/10/23} {1.20} {Reworked quite a lot of code.}
+%
+% \changes {2018/04/20} {1.30} {Allow round precision to be negative.}
+% \changes {2018/04/20} {1.30} {Fix argument specifiers.}
+% \changes {2018/04/20} {1.30} {Change large portions of code.}
+% \changes {2018/04/20} {1.30} {Introduce key-groups (weight, volume, etc.).}
+% \changes {2018/04/20} {1.30} {Option: \opt{add-natural-unit}.}
+% \changes {2018/04/20} {1.30} {New Option: \opt{42}.}
+% \changes {2018/04/20} {1.30} {New options: \opt{expand-both}, \opt{expand-amount}, \opt{expand-unit}.}
+% \changes {2018/04/20} {1.30} {New options: \opt{set-option-for} \& \opt{add-option-for}.}
+% \changes {2018/04/20} {1.30} {New option: \opt{erase-all-options-for}}
+% \changes {2018/04/20} {1.30} {New option: \opt{add-unit-to-group}}
+% \changes {2018/04/20} {1.30} {New feature: Hooks}
+% \changes {2018/04/20} {1.30} {New parsing algorithm. Hopefully better
+% error recovery (if signs for fractions are in wrong order e.g.)}
+% \changes {2018/04/20} {1.30} {Add \enquote{Division-by-zero} error.}
+% \changes {2018/04/20} {1.30} {Cooking Units-keys are not allowed to contain
+% either \enquote{,} or \enquote{/}.}
+%
+% \changes {2018/06/05} {1.40} {This version introduces mayor internal changes.
+% For users not many things change.}
+% \changes {2018/06/05} {1.40} {Rework parsing code (again). As this is
+% basically an improved version of the old parsing algorithm, there is
+% no huge version change.}
+% \changes {2018/06/05} {1.40} {Improve error-recovery by a lot!}
+% \changes {2018/06/05} {1.40} {Bugfix: A range in \mycs{Cutext} (and numerals=true)
+% will print the second word small.}
+% \changes {2018/06/05} {1.40} {Add \enquote{range-sign} for translations (not usable yet).}
+% \changes {2018/06/05} {1.40} {Convert \texttt{clist} to \texttt{seq} if possible.}
+% \changes {2018/06/05} {1.40} {Remove unnecessary variants.}
+% \changes {2018/06/05} {1.40} {Fix some more argument specifiers.}
+% \changes {2018/06/05} {1.40} {Renaming of some internal commands.}
+% \changes {2018/06/05} {1.40} {\opt{set-unknown-message}: Fix default value.}
+% \changes {2018/06/05} {1.40} {Change (\texttt{amount-not-known}): Change message a bit.}
+% \changes {2018/06/05} {1.40} {Bugfix (\texttt{label-not-defined}): Add |'#1'|.}
+% \changes {2018/06/05} {1.40} {Bugfix (\texttt{unit-change}): \opt{convert-to-eV}
+% can be again used as a local argument.}
+% \changes {2018/06/05} {1.40} {Change order of boolean testing for |\@@_calc_references:NN|.}
+% \changes {2018/06/05} {1.40} {Bugfix (\texttt{phrases}): Use the phrase from the first amount to check
+% the second (and don't parse through the second amount).}
+%
+% \changes {2018/09/24} {1.45} {Changes prefix from \texttt{cooking\_units} to \texttt{cookingunits}.}
+% \changes {2018/09/24} {1.45} {New language symbols: \opt{cutext-range-sign}}
+% \changes {2018/09/24} {1.45} {Improved french (not in general, only for this package)}
+% \changes {2018/09/24} {1.45} {New section in documentation.}
+% \changes {2018/09/24} {1.45} {Remove exhaustive expansion from internals (shouldn't change anything for users).}
+%
+%
+%
+%
+%
+%
+%
+% \GetFileInfo{\jobname.sty}
+%
+%\title{The \pkg{\jobname} package^^A
+%\thanks{This document corresponds to \textsf{Benedikt Vitecek}~\fileversion, dated~\filedate.}}
+%\author{Ben Vitecek \\ b.vitecek@gmx.at}%
+%\date{\filedate}%
+%
+%
+% \maketitle
+%
+% \begin{documentation}
+% \begin{abstract}
+% This package enables user to globally format units, to switch
+% between them and since v1.10 you can also change your recipes for a given
+% number of persons.
+% It should be used for light-hearted things like
+% cookery books (and not e.g. scientific texts).\footnote{I did hide some
+% grammatical and spelling errors for easter egg hunters \Winkey.}
+%
+% Please read through the section \enquote{Important Changes}
+% \end{abstract}
+%
+% \tableofcontents
+%
+% \begin{comment}
+% \begin{myde}
+% \cusetup{print-numerals=true,use-phrases=true}
+% \cunum[convert-to-eV=true]{1}{m} \\
+% \cunum[convert-to-eV=true]{1}{m} \\
+% \cuam{6} Eier \\
+% \cuam{12} Eier \\
+% \cuam{18} Eier \\
+% \cuam{132--168} Eier \\
+% \cuam{12--60} Eier \\
+% \cuam{12--24} Eier \\
+% \cuam{12--24.2} Eier \\
+% \cuam{24--12} Eier \\
+% \cuam{18--6} Eier \\
+% \cuam[recalculate-amount=true, set-number-of-persons=10, label=Hallo*4, ref=Hallo]{24} Eier \\
+% \cuam[recalculate-amount=true, set-number-of-persons=10, ref=Hallo, use-phrases=false]{24} Eier (phrase-false)\\
+% \cuam[recalculate-amount=true, set-number-of-persons=10, ref=Hallo, parse-number=false]{12--24} Eier (no parse)\\
+% \cuam{23} Eier \\
+% \cuam{60} Eier \\
+% \cuam{62} Eier \\
+% \cuam{12--60} Eier \\
+% \cuam{288} Eier \\
+% \end{myde}
+%
+% \begingroup
+% \cusetup{print-numerals=true}
+% \cutext[convert-to-eV=true]{1}{m} \\
+% \cunum[convert-to-eV=true]{1}{m} \\
+% \cuam{6} Eier \\
+% \cuam{12} Eier \\
+% \cuam{18} Eier \\
+% \cuam[recalculate-amount=true, set-number-of-persons=10, ref=Hallo]{24} Eier \\
+% \cuam[recalculate-amount=true, set-number-of-persons=10, ref=Hallo, use-phrases=false]{24} Eier \\
+% \cuam{23} Eier \\
+% \cuam{60} Eier \\
+% \cuam{62} Eier \\
+% \endgroup
+% \end{comment}
+%
+% \section{Introduction}
+%
+%
+% While writing on a cookery book I used -- for reasons whatsoever --
+% three different units for weight: kilogram (kg), gram (g) and
+% decagram (dag, or older: dkg). Later my mother told me that she
+% doesn't like it if a cookery book uses more than two different units
+% (for weight in this case). Happily I hardly used Decagram and
+% therefore didn't have many problems changing the units. But, well
+% \dots\ I am using \LaTeX\ and changing those units by hand seemed
+% not very \LaTeX\-like, so I started writing some code to convert
+% units. I expanded the code, rewrote it in \LaTeX3 (which is much
+% more pleasant than \LaTeXe) and here it is.
+%
+%
+% \subsection{Important Changes}
+%
+% \begin{description}
+% \item[Language] I am now using the \pkg{translations} package
+% and I hope it makes things easier. As such, declaring the used language
+% through class options shouldn't be necessary anymore.
+% \item[Phrases] This package now supports the usage of \enquote{phrases}
+% (words used instead of certain integers) (which I think are called \enquote{counting
+% measures} in english, but I am not sure).
+% \item[\cCutext] If no translation is found for a specific language,
+% \cCutext\ are replaced by \mycs{cunum} with a warning is given.
+% \item[Commands] Currently, it seems that allowing \meta{label}
+% to be set by arrow-brackets was not the best idea as it leads to problems
+% if they are made active (e.g. \pkg{babel} and option \opt{spanish}). As such,
+% |<| is not allowed as a \enquote{special-sign} anymore as this package
+% tries to \enquote{fix} this idea (at least make it work). If any problems occur
+% (for this specific case or in general) please feel free to contact me.
+% \end{description}
+%
+%
+% \subsection{Supported languages}
+%
+% \begin{itemize}
+% \item German
+% \item English
+% \item French (currently suboptimal\footnote{You can only get limited information from the internet.})
+% \end{itemize}
+% Have another language to add or a correction of an existing one?
+% See \cref{sec:bug-feed} for more details. Wanna just check the
+% existing translations? See \cref{sec:Translations}.
+%
+% \section {The Commands}
+% \label{sec:commands}
+%
+%
+% This package offers the following commands for unit printing (and
+% converting):
+%
+% \begin{itemize}
+% \item \mycs{cunum}\myaarg{label}\oarg{options}\marg{amount}\oarg{space}\marg{unit-key}
+% \item \mycs{cutext}\myaarg{label}\oarg{options}\marg{amount}\marg{unit-key}
+% \item \mycs{Cutext}\myaarg{label}\oarg{options}\marg{amount}\marg{unit-key}
+% \item \mycs{cuam}\myaarg{label}\oarg{options} \marg{amount}
+% \item \mycs{cusetup}\marg{options}
+% \end{itemize}
+%
+% Numbers and units are printed using \mycs{cunum}. The numerical part
+% can interpret \verb|_| and \texttt{/} as (mixed) fractions and
+% \verb|--| as a separator for ranges; to convert units use the option
+% \texttt{\meta{old-unit}=\meta{new-unit}}\footnote{New keys can be
+% added and defined, see \cref{sec:pred-units} and
+% \cref{sec:def-units} for further information.}. It furthermore
+% allows the sign \texttt{?} to be used as a placeholder for not known
+% amounts and raises a warning to remind that this amount needs a
+% check-up\footnote{You can customize this behavior, see
+% \cref{sec:options}}. \oarg{space} adds a space between the number
+% and the unit using \lstinline|\phantom|.
+%
+% For a list of predefined units have a look at \cref{tab:def-units}.
+%
+% \meta{label} is explained in \cref{sec:labeletref}.
+%
+%
+% \begin{cuexamplecode}
+% \cunum{1}{kg} \\
+% \cunum{2.3}{kg} \\
+% \cunum{2,3}{kg} \\
+% \cunum{2--3}{kg} \\
+% \cunum{2.5--3.5}{kg} \\
+% \cunum[kg=g]{2.5--3,5}{kg} \\
+% \cunum[C=F]{200}{C} \\
+% \cunum[C=F]{180--200}{C} \\
+% \cunum{1/2}{m} \\
+% \cunum{1_1/2}{m} \\
+% \cunum[m=cm]{1_1/2}{m} \\
+% \cunum{?}{l} \\
+% \cunum{50}{dag} \\
+% \cunum{5}[0]{dag} \\
+% \cunum{1.1234}{m}
+% \end{cuexamplecode}
+%
+% Decimal numbers are automatically rounded to 2 digits after the
+% colon, temperatures (\myunit{C}, \myunit{F}, \myunit{K} and
+% \myunit{Re}) are automatically rounded to integers.\footnote{You can
+% -- of course -- change this behavior, see \cref{sec:options}.}
+%
+%
+% \cCutext\ print the number and the written name of the unit. Since
+% v1.10 it works similar\footnote{One could also say \enquote{exactly
+% like}.} to \mycs{cunum}: it allows the conversion between units and
+% interprets the numerical part (again |_| and |/| are used for
+% (mixed) fractions and |--| for ranges). Furthermore, if the package
+% option \opt{use-numerals} is used, integers below a specific integer
+% (by default 13; see \opt{use-numerals-below}) are written out with
+% \lstinline|\Cutext| capitalizing the first letter (using package
+% \pkg{fmtcount}).
+%
+%
+% \begin{cuexamplecode}
+% \cutext{1}{l} \\
+% \Cutext{1}{l} \\
+% \Cutext{1--2}{l} \\
+% \cutext{12}{l} \\
+% \Cutext{13}{l}
+% \end{cuexamplecode}
+% and using package option \opt{use-numerals=true}
+% \cusetup{print-numerals=true}
+% \begin{cuexamplecode}
+% \cutext{1}{l} \\
+% \Cutext{1}{l} \\
+% \cutext{1--2}{l} \\
+% \Cutext{1--2}{l} \\
+% \cutext{12}{l} \\
+% \Cutext{13}{l}
+% \end{cuexamplecode}
+% \cusetup{print-numerals=false}
+% Furthermore,
+% since v1.10 \cCutext\ also allow their units to be changed (this behavior
+% can be altered using \opt{cutext-change-unit}):
+% \begin{cuexamplecode}
+% \cusetup{ l=ml } @
+% \cutext{1}{l} \\
+% \Cutext{1}{l} \\
+% \cutext{1--2}{l} \\
+% \cutext{12}{l} \\
+% \Cutext{13}{l} \\
+% \Cutext{?}{l} \\
+% \Cutext{1/2}{l} \\
+% \end{cuexamplecode}
+%
+%
+% \lstinline|\cuam| works like \mycs{cunum}, but without a unit, so
+% changing units doesn't affect it. Like \mycs{cunum} \texttt{\_} and
+% \texttt{/} are used to imply a (mixed) fraction and |--| is used for ranges.
+%
+% \begin{cuexamplecode}
+% \cuam{3} \\
+% \cuam{2--3} \\
+% \cuam{2/3} \\
+% \cuam{1_2/3}
+% \end{cuexamplecode}
+%
+% Furthermore it allows the concept of \enquote{phrases} (replacing a positive integer
+% by a word, such as \enquote{12} becoming \enquote{dozen}\footnote{At least I think})
+% which can be activated by the option \opt{use-phrases}
+% (as I don't know any english phrases, I switched the language to german for the following examples)
+% \begin{myde}
+% \begin{cuexamplecode}
+% \cusetup{use-phrases=true} @
+% \cuam{11} \\
+% \cuam{12} \\
+% \cuam{13} \\
+% \cuam{24} \\
+% \cuam{12--24} \\
+% \cuam{12--13}\\
+% \cuam{18} \\
+% \cuam{60}
+% \end{cuexamplecode}
+% \end{myde}
+%
+%
+% \section{Label \& refs: Changing the amount of the recipe}
+% \label{sec:labeletref}
+%
+%
+% What if you don't want to change units, but the amounts of the recipe because
+% you cook not for 4 persons, but for 2 and don't like to do the math?
+% Simple, use the following commands:
+%
+% \begin{itemize}
+% \item \mycs{culabel}\marg{label}\marg{number of persons}
+% \item \mycs{curef}\marg{label}
+% \end{itemize}
+%
+%
+% The first one is the important one: It defines a \meta{label} for a recipe
+% which is initially for \meta{number of persons}. Afterwards \meta{label}
+% can be used to tell the commands from \cref{sec:commands} that the given
+% amounts are for \meta{number of persons}.
+% Each \meta{label} must be unique and an error is raised if a \meta{label}
+% is already defined.
+%
+% If you would like to print the number of persons this recipe is for, use
+% \mycs{curef}, which is fully expandable.
+%
+% The following example uses \mycs{culabel} to specify that the recipe is
+% initially intended for 2 persons:
+% \begin{cuexamplecode}
+% \culabel{recipe}{2} @
+% recipe & for & \curef{recipe} & persons: \\
+% \cunum<recipe>{10--20}{dag} & flour, \\
+% \cunum<recipe>{1/2}{l} & water, \\
+% \cutext[ref=recipe]{10}{g} & nuts, \\
+% \cuam<recipe>{2--3} & eggs, \\
+% \cunum{180}{C} & (\cunum[C=F]{180}{C}) & open & fire
+% \end{cuexamplecode}
+%
+% In combination with the option \opt{set-number-of-persons}
+% and \opt{recalculate-amount} you can have this recipe
+% changed to four persons:
+% \begin{lstlisting}
+% \culabel{recipe}{2}
+% %% adding options:
+% \cusetup{set-number-of-persons=4,recalculate-amount=true}
+% \end{lstlisting}
+% \cusetup{set-number-of-persons=4,recalculate-amount=true}
+%
+% \begin{cuexamplecode}
+% recipe & for & \curef{recipe} & persons: \\
+% \cunum<recipe>{10--20}{dag} & flour, \\
+% \cunum<recipe>{1/2}{l} & water, \\
+% \cutext[ref=recipe]{10}{g} & nuts, \\
+% \cuam<recipe>{2--3} & eggs, \\
+% \cunum{180}{C} & & (\cunum[C=F]{180}{C}) & open & fire
+% \end{cuexamplecode}
+% \cusetup{recalculate-amount=false}
+%
+% Note that fractions are automatically evaluated and that only values
+% with a \meta{label} are changed (\lstinline|\cunum{180}{C}| for example
+% stays the same which also makes sense as the heat should be the same).
+%
+%
+%
+%
+% \section{Some Interesting options}
+%
+% This package has some options which might be of interest and to highlight them, this section exists. All options can be
+% found in \cref{sec:options}.
+%
+%
+%\subsection{Numerals}
+% \begin{cuinterest}{use-numerals, use-numerals-below, print-numerals}
+% As seen above, you can use the \emph{package}-option
+% \opt{use-numerals} to print integers used by \cCutext{} below
+% \opt{use-numerals-below} (13 by default) by \pkg{fmtcount}.
+% You can still decide if numerals should be printed or not with \opt{print-numerals}.
+%
+% \begin{cunote}
+% \opt{use-numerals} is a package option as it needs to load
+% \pkg{fmtcount} which is not loaded by default.
+% \end{cunote}
+%
+% \end{cuinterest}
+%
+% \subsection{Phrases}
+% \begin{cuinterest}{use-phrases}
+% In (I presume) all languages there exist phrases for a given
+% amount or a number of things (think it is called \enquote{counting measurement}).
+% In German you may say instead of
+% \enquote{12}: \enquote{ein Dutzend}. Using this option you can tell this
+% package to replace predefined integers used in \mycs{cuam}
+% by phrases for the currently used language
+% (to define new ones, see \cref{sec:phrases})
+%
+% Using (for example) language \opt{ngerman} (or \opt{naustrian}, etc.) with
+% package option \opt{use-phrases=true} gives:
+% \begin{myde}
+% \begin{cuexamplecode}
+% \cusetup{use-phrases=true} @
+% \cuam{12} \\
+% \cuam{24} \\
+% \cuam{12--24} \\
+% \cuam{12--13} \\
+% \cuam{18} \\
+% \cuam{60}
+% \end{cuexamplecode}
+% \end{myde}
+% This of course also works with the \emph{package}-option \opt{use-numerals}:
+% \begin{myde}
+% \cusetup{print-numerals=true}
+% \begin{cuexamplecode}
+% \cusetup{use-phrases=true} @
+% \cuam{12} \\
+% \cuam{24} \\
+% \cuam{12--24} \\
+% \cuam{12--13} \\
+% \cuam{18} \\
+% \cuam{60}
+% \end{cuexamplecode}
+% \end{myde}
+%
+%
+% \begin{cunote}
+% Currently only the lower-case variant for \opt{use-numerals} is
+% supported. Furthermore this feature is only available for \mycs{cuam}.
+% \end{cunote}
+%
+% \end{cuinterest}
+%
+%
+%\subsection{Rounding temperatures}
+%
+% By default temperatures are rounded to integers (using \opt{round-to-int = true}).
+% Since 1.30 it is possible to round amounts to a negative precision.
+% If you want to round temperatures to the tens see the following
+% example (\opt{set-option-for-\meta{unit}} is described in \cref{sec:opt:unit-spec}).
+%
+% \begin{cuexamplecode}
+% \cunum{180}{C} \\
+% \cunum[C=F]{180}{C} \\
+% \cunum[C=Re]{180}{C} \\
+% \cunum[C=K]{180}{C} \\
+% \cusetup{set-option-for-C = { round-precision = -1 } } @
+% \cusetup{set-option-for-F = { round-precision = -1 } } @
+% \cusetup{set-option-for-Re = { round-precision = -1 } } @
+% \cusetup{set-option-for-K = { round-precision = -1 } } @
+% \cunum{180}{C} \\
+% \cunum[C=F]{180}{C} \\
+% \cunum[C=Re]{180}{C} \\
+% \cunum[C=K]{180}{C} \\
+% \end{cuexamplecode}
+%
+% \section{Predefined units \& some notes}
+% \label{sec:pred-units}
+%
+% \begin{comment}
+% In \cref{tab:def-units} and \cref{tab:some-more-units} (and \cref{tab:strange-units})
+% you can find
+% all predefined units. In \cref{sec:Translations} all translations available
+% are listed.
+% \end{comment}
+%
+% In \cref{tab:def-units} and you can find all predefined units which can be
+% transformed into each other (sorted by group). Other predefined units
+% (which cannot be used for transformation) are shown in \cref{tab:some-more-units}.
+% \Cref{tab:strange-units} pretty much exists just for fun.
+%
+%
+% \begin{table}[htbp]
+% \centering
+% \caption{^^A
+%^^A The first column shows a list of predefined unit-keys.
+%^^A The column \enquote{default} shows the abbreviation used if
+%^^A for given language no translation is defined. The translations used for \cCutext\
+%^^A are shown in \cref{sec:Translations}.
+%^^A Note that \enquote{electron volt} exists just for fun.
+%^^A
+% This table shows all units which can be transformed into each other, sorted
+% by group. The columns \enquote{default} show the abbreviations used if
+% for given language no translation is defined. The translations used for \cCutext\
+% are shown in \cref{sec:Translations}.
+% Note that \enquote{electron volt} exists just for fun.
+% }
+% \smallskip
+% \begin{tabular}{ lll @{\hspace{1cm}} lll }
+% \toprule
+% description & key & default & description & key & default \\ \midrule
+% \PrintUnit {kg} & \PrintUnit{m} \\
+% \PrintUnit {dag} & \PrintUnit{dm} \\
+% \PrintUnit {g} & \PrintUnit{cm} \\
+% \PrintUnit {oz} & \PrintUnit{mm} \\
+% \PrintUnit {lb} & \PrintUnit{in} \\
+% \PrintUnit [ (of butter)] {stick} \\ \addlinespace
+%
+% \PrintUnit {d} & \PrintUnit {l} \\
+% \PrintUnit {h} & \PrintUnit {dl} \\
+% \PrintUnit {min} & \PrintUnit {cl} \\
+% \PrintUnit {s} & \PrintUnit{ml} \\ \addlinespace
+%
+% \PrintUnit{cal} & \PrintUnit{C} \\
+% \PrintUnit{kcal} & \PrintUnit{F} \\
+% \PrintUnit{J} & \PrintUnit{Re} \\
+% \PrintUnit{kJ} & \PrintUnit{K} \\
+% \PrintUnit{eV}
+%
+% \\ \bottomrule
+% \end{tabular}
+% \label{tab:def-units}
+% \end{table}
+%
+% \begin{table}[htbp]
+% \centering
+% \caption{A (not only) spoonful of (more or less) country and
+% language dependent units. Please note that sometimes a
+% translation is nearly impossible as a unit
+% (e.g. \enquote{saltspoonful}) may not exist in another language
+% (like german; at least I never heard of it). So please only use
+% units known to you.}
+% \smallskip
+% \begin{tabular}{ lll }
+% \toprule
+% description & key & symbol \\ \midrule
+% \PrintUnit {pn} \\ \addlinespace
+% \PrintUnit {EL} \\
+% \PrintUnit {TL} \\
+% \PrintUnit {dsp} \\
+% \PrintUnit {csp} \\
+% \PrintUnit {ssp} \\ \addlinespace
+% \PrintUnit [Messerspitze (point of a knife)] {Msp} \\
+% \bottomrule
+% \end{tabular}
+% \label{tab:some-more-units}
+% \end{table}
+%
+% \begin{table}[htbp]
+% \centering
+% \caption{List of (not really) nonsense units (exist just for fun, there will be
+% no support for those units; unless -- of course -- you really want it).}
+% \smallskip
+% \begin{tabular}{ ll }
+% \toprule
+% unit-key & symbol \\ \midrule
+% \PrintUnitSymbol {eVc-2} \\
+% \PrintUnitSymbol {hbareV-1} \\
+% \PrintUnitSymbol {chbareV-1} \\
+% \PrintUnitSymbol {(chbareV-1)3} \\
+% \bottomrule
+% \end{tabular}
+% \label{tab:strange-units}
+% \end{table}
+%
+%
+%
+% \section{Defining units}
+% \label{sec:def-units}
+%
+% New units can be defined using
+% \begin{itemize}
+% \item \mycs{declarecookingunit}
+% \item \mycs{newcookingunit}
+% \item \mycs{providecookingunit}
+% \end{itemize}
+%
+% \begin{function}{\declarecookingunit,\newcookingunit,\providecookingunit}
+% \begin{syntax}
+% \mycs{declarecookingunit}\oarg{symbol}\marg{unit-key}
+% \mycs{newcookingunit}\oarg{symbol}\marg{new-unit-key}
+% \mycs{providecookingunit}\oarg{symbol}\marg{new-unit-key}
+% \end{syntax}
+% These commands define the unit \meta{unit-key}. If the
+% key is not the same as the printed symbol use \oarg{symbol}.
+% Note that \meta{unit-key} should neither contain |/| nor |,|.
+%
+% \mycs{newcookingunit} raises an error if the unit is already defined,
+% \mycs{declarecookingunit} creates or (if given) overwrites \meta{symbol}
+% and \mycs{providecookingunit} does nothing if the unit is already
+% defined.
+%
+% All units have male gender |m| by default.
+%
+% Some examples:
+%
+% \begin{lstlisting}
+% \declarecookingunit{kg}
+% \declarecookingunit{g}
+% \declarecookingunit[Msp.] {Msp}
+% \declarecookingunit[\ensuremath{{}^{\circ}}\kern-\scriptspace C] {C}
+% \end{lstlisting}
+%
+% \begin{cunote}
+% The definition of the printed degree Celsius is
+% directly copied and pasted from (a maybe older version of) \pkg{siunitx}
+% \end{cunote}
+%
+%
+% \end{function}
+%
+%
+% \section{Defining options to change units}
+% \label{sec:defining-opt}
+%
+% Options (to change units) can be newly defined or added to already existing keys (units)
+% using
+% \begin{itemize}
+% \item \mycs{cudefinekeys}
+% \item \mycs{cudefinesinglekey}
+% \item \mycs{cuaddkeys}
+% \item \mycs{cuaddsinglekeys}
+% \item \mycs{cuaddtokeys}
+% \end{itemize}
+% I apologize for the (name) inconsistency between \mycs{cudefinekeys} and
+% \mycs{cudefinesinglekey} (although they are named similarly, they work different).
+%
+% \begin{function}{\cudefinekeys,\cudefinesinglekey}
+% \begin{syntax}
+% \mycs{cudefinekeys}\marg{unit-key-1}
+% \ \ \{
+% \ \ \ \ \marg{unit-key-2} \marg{1 unit-key-1 are \dots\ unit-key-2}
+% \ \ \ \ \marg{unit-key-3} \marg{1 unit-key-1 are \dots\ unit-key-3}
+% \ \ \ \ \marg{unit-key-4} \marg{1 unit-key-1 are \dots\ unit-key-4}
+% \ \ \ \ \dots
+% \ \ \}
+%
+% \mycs{cudefinesinglekey}\marg{unit-key-1}
+% \ \ \{
+% \ \ \ \ \marg{unit-key-2} \marg{1 unit-key-2 are \dots\ unit-key-1}
+% \ \ \ \ \marg{unit-key-3} \marg{1 unit-key-3 are \dots\ unit-key-1}
+% \ \ \ \ \dots
+% \ \ \}
+% \end{syntax}
+%
+% If you define new units (see \cref{sec:def-units}) and cannot add
+% them to already existing keys you can use
+% \lstinline|\cudefinekeys| bzw. \lstinline|\cudefinesinglekey| to
+% define new keys.
+%
+% \lstinline|\cudefinekeys| takes \marg{unit-key-1} as a
+% \enquote{basis}, defines a key with the name \meta{unit-key-1} and
+% adds the values \meta{unit-key-1}, \meta{unit-key-2},
+% \meta{unit-key-3}, etc. Furthermore this command also defines the
+% keys \meta{unit-key-2}, \meta{unit-key-3}, etc. with the same
+% values as \meta{unit-key-1}. Please note that \meta{\dots} has to
+% be a number.
+%
+% Sometimes it is not that easy and the conversion of one unit into
+% another needs are more complicated formula (see for example
+% temperatures). If that is the case use
+% \lstinline|\cudefinesinglekey|. As the name says it defines
+% \emph{only} the key \meta{unit-key-1} with the values
+% \meta{unit-key-1}, \meta{unit-key-2}, etc. The advantage of this
+% command is that now \meta{\dots} can be a formula and the
+% numerical input can be placed explicitly using \texttt{\#1}.
+%
+%
+% \end{function}
+%
+% \begin{cuexample}
+%
+% This example defines following keys with their respective value:
+% \begin{itemize}
+% \item the key \myunit{kg} with the values \myunit{kg}, \myunit{dag},
+% \myunit{g} and \myunit{oz}
+% \item the key \myunit{dag} with the values \myunit{kg},
+% \myunit{dag}, \myunit{g} and \myunit{oz}
+% \item the key \myunit{g} with the values \myunit{kg}, \myunit{dag},
+% \myunit{g} and \myunit{oz}
+% \item the key \myunit{oz} with the values \myunit{kg}, \myunit{dag},
+% \myunit{g} and \myunit{oz}
+% \item the key \myunit{d} with the values \myunit{d}, \myunit{h},
+% \myunit{min} and \myunit{s}
+% \item \dots
+% \end{itemize}
+%
+%
+% \begin{align*}
+% \SI{1}{\kg}&= \SI{1}{\kg} &
+% \SI{1}{\kg}&= \SI{100}{\deka\g} &
+% \SI{1}{\kg}&= \SI{1000}{\g} \\
+% \SI{1}{\kg}&= \SI{35.27399}{\ounce} &
+% \SI{1}{\kg}&= \SI{2.204 622 6}{\pound}
+% \end{align*}
+%
+% \begin{lstlisting}
+% \cudefinekeys {kg}
+% {
+% {dag}{ 100 } %% 1 kg are 100 dag
+% {g} { 1000 } %% 1 kg are 1000 g
+% {oz} { 35.27399 } %% 1 kg are 35.27399 oz
+% {lb} { 2.204 622 6 } %% 1 kg are 2.204 622 6 lb
+% }
+%
+% \cudefinekeys {d}
+% {
+% {h} { 24 } %% 1 day are 24 hours
+% {min}{ 1440 } %% 1 day are 1440 minutes
+% {s} { 86400 } %% 1 day are 86400 seconds
+% }
+% \end{lstlisting}
+%
+% To convert degree Fahrenheit to degree Celsius, kelvin and degree R\'eamur one
+% needs the formulas\footnote{See Wikipedia.}
+% \begin{align*}
+% T_C &= ( T_F - 32 ) \cdot \frac{5}{9} \\
+% T_K &= ( T_F - 459.67 ) \cdot \frac{5}{9} \\
+% T_{Re} &= ( T_F - 32 ) \cdot \frac{4}{9}
+% \end{align*}
+% with $T_F$ being the input temperature in degree Fahrenheit and
+% $T_C$ being the same temperature in degree Celsius, etc. Using
+% \lstinline|\cudefinesinglekey| the key \myunit{F} with values
+% \myunit{C}, \myunit{K} and \myunit{Re} is defined:
+%
+% \begin{lstlisting}
+% \cudefinesinglekey {F}
+% {
+% {C} { ( #1 - 32 ) * 5/9 } %% see formulas above
+% {K} { ( #1 + 459.67 ) * 5/9 }
+% {Re} { ( #1 - 32 ) * 4/9 }
+% }
+% \end{lstlisting}
+%
+% This defines the key \myunit{F} with the values \myunit{F}, \myunit{C},
+% \myunit{K} and \myunit{Re}.
+%
+% \end{cuexample}
+%
+%
+%
+% \begin{function}{\cuaddkeys,\cuaddsinglekeys}
+%
+% \begin{syntax}
+% \mycs{cuaddkeys}\marg{unit-key-1}
+% \ \ \{
+% \ \ \ \ \marg{unit-key-2} \marg{1 unit-key-1 are \dots\ unit-key-2}
+% \ \ \ \ \marg{unit-key-3} \marg{1 unit-key-1 are \dots\ unit-key-3}
+% \ \ \ \ \marg{unit-key-4} \marg{1 unit-key-1 are \dots\ unit-key-4}
+% \ \ \ \ \dots
+% \ \ \}
+%
+% \mycs{cuaddsinglekeys}\marg{unit-key-1}
+% \ \ \{
+% \ \ \ \ \marg{unit-key-2} \marg{1 unit-key-2 are \dots\ unit-key-1}
+% \ \ \ \ \marg{unit-key-3} \marg{1 unit-key-3 are \dots\ unit-key-1}
+% \ \ \ \ \dots
+% \ \ \}
+% \end{syntax}
+%
+% These commands add \meta{unit-key-2}, etc. to the already defined
+% key \meta{unit-key-1}.
+%
+% \lstinline|\cuaddkeys| takes the already defined key
+% \marg{unit-key-1} as a \enquote{basis}, and adds
+% \meta{unit-key-2}, \meta{unit-key-3}, etc. to its
+% values. Furthermore it adds those new values to other keys linked
+% to \meta{unit-key-1} and defines the new keys \meta{unit-key-2},
+% etc. with the same values as \meta{unit-key-1}.
+%
+%
+% If the conversion is more complicated use
+% \lstinline|\cuaddsinglekeys|. It adds \meta{unit-key-2}, etc. as
+% values to \meta{unit-key-1}. The numerical input can be placed
+% using \myunit{\#1} (see \lstinline|\cudefinesinglekey|). This
+% command neither defines new keys nor does it add values to other
+% keys than \meta{unit-key-1}.
+%
+%
+% \end{function}
+%
+%
+% \begin{cuexample}
+% Suppose you are British (I am sorry, I can't think of another
+% reason to use those units) and you want to implement 'stone' (yes,
+% I was surprised myself that such a unit exists, but it even
+% appears in a Sherlock Holmes story). You exactly know that
+% \SI{1}{\st} equals \SI{14}{\lb}, well \dots\ now you have two
+% choices. \lstinline|\cuaddkeys| or \lstinline|\cuaddtokeys| (use
+% the one best fitting). This example uses the first, the next the
+% latter one.
+% \begin{lstlisting}
+% \newcookingunit{st} %% defining new unit 'stone'
+% \cuaddkeys{lb} %% adding st to lb (could also add to kg, dag and oz)
+% {
+% {st} { 1/14 } %% 1 lb are 1/14 st as 14 lb are 1 st
+% }
+% \end{lstlisting}
+% \begin{cuexamplecode}
+% \cunum[lb=st]{1}{lb} \\
+% \cunum[st=lb]{1}{st} \\
+% \cunum[st=g]{1}{st} \\
+% \cunum[st=kg]{1}{st} \\
+% \cunum[kg=st]{1}{kg} \\
+% \cunum[st=kg]{16}{st}
+% \end{cuexamplecode}
+% \end{cuexample}
+%
+%
+% \begin{cuexample}
+% Now you want to add degree R{\o}mer and convert Celsius to degree
+% R{\o}mer:
+% \begin{equation*}
+% T_{R\text\o} = T_C * \frac{21}{40} + 7.5
+% \end{equation*}
+%
+% \begin{lstlisting}
+% %% defining new unit 'degree R{\o}mer'
+% \newcookingunit [\ensuremath{ {} ^ { \circ } }\kern-\scriptspace R{\o}] {Ro}
+% \cuaddsinglekeys {C} %% adds value 'Ro' to 'C'.
+% {
+% {Ro} { #1 * 21/40 + 7.5 }
+% }
+% \cusetup %% round to integer automatically
+% {
+% set-option-for-Ro = { round-to-int = true }
+% }
+% \end{lstlisting}
+% \begin{cuexamplecode}
+% \cunum{10}{C} \\
+% \cunum[C=Ro]{10}{C}
+% \end{cuexamplecode}
+% \end{cuexample}
+%
+%
+%
+%
+%
+%
+%
+%
+%
+%
+%
+% \begin{function}{\cuaddtokeys}
+% \begin{syntax}
+% \mycs{cuaddtokeys} \marg{unit-key-1} \marg{unit-key-2} \marg{1 unit-key-2 are \dots\ unit-key-1}
+% \end{syntax}
+% Works similar to \mycs{cuaddkeys} regarding the definition of keys.
+% \end{function}
+%
+% \begin{cuexample}
+% Continuing the example from before, this time with \lstinline|\cuaddtokeys|:
+% \begin{lstlisting}
+% \newcookingunit{st} %% defining (again) new unit 'stone'
+% \cuaddtokeys {lb} {st} { 14 } %% 1 st are 14 lb
+% \end{lstlisting}
+% \begin{cuexamplecode}
+% \cunum[lb=st]{1}{lb} \\
+% \cunum[st=lb]{1}{st} \\
+% \cunum[st=g]{1}{st} \\
+% \cunum[st=kg]{1}{st} \\
+% \cunum[kg=st]{1}{kg} \\
+% \cunum[st=kg]{16}{st}
+% \end{cuexamplecode}
+% \end{cuexample}
+%
+% \begin{comment}
+% \begin{cuexample}
+% Implementation of \myunit{stick}. From https://cooking.stackexchange.com/questions/784/translating-cooking-terms-between-us-uk-au-ca-nz
+% we know that
+% \[ \SI{1}{\stick} = \SI{0.25}{\lb} \]
+%
+% There are two ways to implement \myunit{stick}:
+% either use \mycs{cuaddkeys} or \mycs{cuaddtokeys}.
+%
+% The easier way (in this case) is \mycs{cuaddtokeys} which is pretty straight forward:
+% \begin{lstlisting}
+% \cuaddtokeys { lb } { st } { 0.25 }
+% \end{lstlisting}
+% \dots\ and finished
+%
+% \end{cuexample}
+% \end{comment}
+%
+%
+%
+%
+%
+%
+%
+%
+%
+%
+%
+%
+%
+%
+% \section{Language support}
+% \label{sec:language}
+%
+% Unit names and symbols depend on the language. To change the
+% name depending on the language you can use \lstinline|\cudefinename|
+% and to only change symbols use \lstinline|\cudefinesymbol|.
+%
+% \begin{function}{decimal-mark,cutext-range-sign, one(m),one(f),one(n)}
+% Those are special keys (as they cannot be used as units). Not only
+% are printed units language depending, but as is the decimal mark
+% (\enquote{.} or \enquote{,}) and the text which substitutes the range-sign.
+% To set the decimal mark use
+% \opt{decimal-mark} (see examples below), to set the range-sign for \cCutext\
+% use \opt{cutext-range-sign}.
+%
+% Note that \opt{cutext-range-sign} is \enquote{overwritten} by the \emph{option}
+% \opt{cutext-range-sign}. If the \emph{option} is set, then the language symbol
+% will be ignored.
+%
+% Furthermore if you are using the package-option \opt{use-numerals}
+% you may also use the keys \opt{one(m)}, \opt{one(f)} and
+% \opt{one(n)}. If you use this option, integers below a certain
+% value (see option \opt{use-numerals-below}) are written-out. The
+% only problem is the written-out \enquote{1} mostly depends on the
+% gender of the following word (e.g. \enquote{ein Baum} (m),
+% \enquote{eine Pflanze} (f) and \enquote{ein Auto} (n)). To set the
+% written-out 1 to be correct with the gender of the used unit, use
+% these keys (see also examples below)
+% \end{function}
+%
+% \begin{function}{\cudefinename}
+% \begin{syntax}
+% \mycs{cudefinename}\marg{Language}
+% \ \ \{
+% \ \ \ \ \marg{unit-key-1} \oarg{symbol-1} \marg{singular-1} \oarg{plural-1} \myaarg{gender}
+% \ \ \ \ \marg{unit-key-2} \oarg{symbol-2} \marg{singular-2} \oarg{plural-2} \myaarg{gender}
+% \ \ \ \ \dots
+% \ \ \}
+% \end{syntax}
+%
+% This command defines the names (and optionally the symbol) of the
+% units printed in \lstinline|\cutext| and \lstinline|\Cutext|
+% (and \lstinline|\cunum| regarding the symbol) for the specific
+% \meta{Language}. For details regarding \meta{language} see the
+% \pkg{translations} documentation.
+%
+% If the plural form of the name differs from the singular form use
+% \oarg{plural} to specify the plural form, if no \oarg{plural} is
+% given the plural will be set equal to its singular. The singular form
+% is only used if the number in \lstinline|\cutext| and
+% \lstinline|\Cutext| is equal to 1.
+%
+% \meta{gender} can be \texttt{m} (maskulin), \texttt{f} (feminin) or
+% \texttt{n} (neutrum). If not given \texttt{m} is used as default.
+% \end{function}
+%
+% \begin{lstlisting}
+% \cudefinename {English}
+% {
+% {kg} {kilogramme}
+% {oz} {ounce}
+% {h} {hour} [hours]
+% {C} {degree\space Celsius} [degrees\space Celsius]
+% {decimal-marker} {.}
+% {cutext-range-sign} {~to~}
+% {one(m)} {one}
+% {one(f)} {one}
+% {one(n)} {one}
+% }
+% \end{lstlisting}
+% \begin{lstlisting}
+% \cudefinename {German}
+% {
+% {kg} {Kilogramm} <n>
+% {oz} {Unze} <f>
+% {d} {Tag} [Tage]
+% {h} {Stunde} [Stunden] <f>
+% {C} {Grad\space Celsius}
+% {decimal-marker} {,}
+% {cutext-range-sign} {~bis~}
+% {one(m)} {ein}
+% {one(f)} {eine}
+% {one(n)} {ein}
+% }
+% \end{lstlisting}
+%
+%
+% \begin{function}{\cudefinesymbol}
+%
+% \begin{syntax}
+% \mycs{cudefinesymbol}\marg{Language}
+% \ \ \{
+% \ \ \ \ \marg{unit-key-1} \marg{symbol-1}
+% \ \ \ \ \marg{unit-key-2} \marg{symbol-2}
+% \ \ \ \ \dots
+% \ \ \}
+% \end{syntax}
+%
+% This command defines the symbols of the units printed in
+% \lstinline|\cunum| for the specific \meta{language}. It works
+% similar as \lstinline|\cudefinename|, but only the symbols (and no
+% names) can be set. For details regarding \meta{language} see
+% the \pkg{translations} documentation.
+%
+% \end{function}
+%
+%
+% \begin{lstlisting}
+% \cudefinesymbol {English}
+% {
+% {decimal-mark} {.}
+% {cutext-range-sign} {~to~}
+% {one(m)} {one}
+% {one(f)} {one}
+% {one(n)} {one}
+% }
+% \cudefinesymbol {German}
+% {
+% {decimal-mark} {,}
+% {cutext-range-sign} {~bis~}
+% {one(m)} {ein}
+% {one(f)} {eine}
+% {one(n)} {ein}
+% }
+% \cudefinesymbol {French}
+% {
+% {l} {L}
+% {dl} {dL}
+% {cl} {cL}
+% {ml} {mL}
+% {decimal-mark} {.}
+% {one(m)} {un}
+% {one(f)} {une}
+% {one(n)} {un}
+% }
+% \end{lstlisting}
+%
+% \begin{cuexample}
+% Imagine that instead of the abbreviation \enquote{dag} for \enquote{decagramme}
+% you want to use \enquote{ducks} (because \dots\ I don't know). You can easily
+% do this via
+% \begin{lstlisting}
+% \cudefinesymbol {English}
+% {
+% {dag} {ducks}
+% }
+% \end{lstlisting}
+% \cudefinesymbol {English}
+% {
+% {dag} {ducks}
+% }
+% As you can see it may be a bit suboptimal as there is no plural version allowed.
+% You do it anyway and end up with:
+% \begin{cuexamplecode}
+% \cunum{12}{dag} & weed\\
+% \cunum{3}[0]{dag} & nuts\\
+% \cunum{10}{dag} & duckmeat
+% \end{cuexamplecode}
+%
+%
+% \end{cuexample}
+%
+%
+%
+%
+%
+%
+% \subsection{Phrases}
+% \label{sec:phrases}
+%
+% Each language has synonyms for certain (integer) numbers. This package
+% supports those phrases and they can be implemented with the following
+% command and used by \mycs{cuam}:
+%
+% \begin{function}{\cudefinephrase}
+% \begin{syntax}
+% \mycs{cudefinephrase}\marg{Language}
+% \ \ \{
+% \ \marg{integer-1} \marg{phrase-1} \oarg{phrase-1-plural} \myaarg{gender-1}
+% \ \marg{integer-2} * \marg{phrase-2} \oarg{phrase-2-plural} \myaarg{gender-2}
+% \ \dots
+% \ \ \}
+% \end{syntax}
+%
+% This command pairs for a given \marg{Language} (see package \pkg{translations})
+% the number \marg{integer-1}
+% with \marg{phrase-1} (\& plural and gender). The package then checks if the amount
+% given in \mycs{cuam} is either this number or a \emph{multiple} of it.
+%
+% If the behavior of checking for a multiple is not wanted, you can use the optional
+% star \texttt{*} for a given \marg{integer}
+%
+% \meta{gender} can be \opt{m}, \opt{f} or \opt{n}. It is \opt{m} by default.
+%
+% Afterwards the numbers are ordered from highest to lowest so that
+% the phrase with the highest number is used (if used at all).
+%
+% Furthermore, it chooses star (|*|) phrases over non-star phrases.
+%
+% \begin{cunote}
+% Numbers with the optional star |*| are stored as negative numbers.
+% \end{cunote}
+% \end{function}
+%
+% \begin{cuexample}
+% The following example creates some phrases for the language
+% \enquote{German}:
+%
+% \cudefinephrase {German}
+% {
+% { 60 } {Schock} <n>
+% { 6 }* {halbes\ Dutzend} <n>
+% }
+%
+%
+% \begin{lstlisting}
+% \cudefinephrase {German}
+% {
+% { 12 } {Dutzend} <n> %% implemented by default
+% { 60 } {Schock} <n>
+% { 6 }* {halbes\ Dutzend} <n>
+% }
+% \end{lstlisting}
+% Let's just use them (german language activated!):
+% \begin{myde}
+% \begin{cuexamplecode}
+% \cusetup{use-phrases=true} @
+% \cuam{12} \\
+% \cuam{24} \\
+% \cuam{60} \\
+% \cuam{120} \\
+% \cuam{6} \\
+% \cuam{18}
+% \end{cuexamplecode}
+% \end{myde}
+%
+% As you can see, \enquote{Schock} ($60$) is preferred over \enquote{Dutzend} ($12$)
+% as it linked to the higher number. Furthermore, for $6$ the phrase \enquote{halbes
+% Dutzend} (half a dozen) is used, but because it is a star version it is \emph{not}
+% used for $18$.
+%
+% \end{cuexample}
+%
+%
+% \section{Options}
+% \label{sec:options}
+%
+% Options in \pkg{cooking-units} can mostly be set globally using
+% \lstinline|\cusetup| or locally using the optional argument of the
+% respective command (but \emph{not} as a package option). The only
+% exception is the option given in \cref{sec:load-time-options} which
+% needs to be used as a package option.
+%
+% \subsection{Load time options}
+% \label{sec:load-time-options}
+%
+% \begin{function}{use-numerals}
+% \begin{syntax}
+% \cs{usepackage}[use-numerals=\meta{true/false}]\{cooking-units\}
+% \end{syntax}
+% If set to \true\ loads package \pkg{fmtcount} and uses
+% \cs{numberstringnum} for \mycs{cutext}
+% and \cs{Numberstringnum} for \mycs{Cutext} to write-out numbers below
+% \opt{use-numerals-below} (13 by default), integers above are
+% printed as numbers.
+% You can decide to not print any numerals by setting \opt{print-numerals}
+% to \false.
+%
+% \begin{cunote}
+% \opt{use-numerals} is a package option as it needs to load
+% \pkg{fmtcount} which is not loaded by default.
+% \end{cunote}
+%
+% \begin{cunote}
+% Please note the keys \opt{one(m)}, \opt{one(f)}
+% and \opt{one(n)} to change the printed \enquote{one} (as
+% \enquote{one} is in many languages dependent on the gender of the
+% following word. E.g in German: Masculine: ein Baum,
+% Feminin: eine Pflanze, Neutrum: ein Auto).
+% \end{cunote}
+%
+% \end{function}
+%
+% \cusetup{print-numerals=true}
+% \begin{cuexamplecode}
+% \cutext{1}{kg} \\
+% \Cutext{1}{kg} \\
+% \cutext{2}{kg} \\
+% \Cutext{2}{kg} \\
+% \cutext{12}{kg} \\
+% \cutext{13}{kg} \\
+% \cutext{13}{kg} \\
+% \Cutext{14}{kg}
+% \end{cuexamplecode}
+% \cusetup{print-numerals=false}
+%
+% \subsection{Normal options}
+%
+% Options in this subsection can only be set as local options or using
+% \lstinline|\cusetup|, but \emph{not} as load time options.
+%
+% \begin{function}{\cusetup}
+% Options can be set using \mycs{cusetup}\Arg{options}.
+% \end{function}
+%
+% \subsubsection{Unit Specific options}
+% \label{sec:opt:unit-spec}
+%
+% \begin{function}{<unit>}
+% \begin{syntax}
+% \meta{unit-key-1} = \meta{unit-key-2}
+% \end{syntax}
+% Change \meta{unit-key-1} to \meta{unit-key-2} (see
+% \cref{sec:defining-opt} to define new options).
+% \end{function}
+%
+% \begin{function}{<group>}
+% \begin{syntax}
+% \meta{group} = \meta{unit-key}
+% \end{syntax}
+% Changes each unit contained in \meta{group} to \meta{unit-key} (\meta{unit-key}
+% must be part of \meta{group}).
+%
+% \begin{center}
+% \begin{tabular}{ll}
+% \toprule
+% \meta{group} & default \meta{unit-key}s \\ \midrule
+% \PrintGroup{weight} \\
+% \PrintGroup{length} \\
+% \PrintGroup{volume} \\
+% \PrintGroup{temperature} \\
+% \PrintGroup{energy} \\
+% \PrintGroup{time} \\ \bottomrule
+% \end{tabular}
+% \end{center}
+% \end{function}
+%
+% \begin{cuexamplecode}
+% \cusetup{weight=g} @
+% \cunum{1}{kg} \\
+% \cunum{1}{dag} \\
+% \cunum{1}{g} \\
+% \cunum{1}{oz} \\
+% \cunum{1}{lb} \\
+% \cunum{1}{stick} \\
+% \end{cuexamplecode}
+%
+%
+%
+%
+% \begin{function}{add-unit-to-group}
+% \begin{syntax}
+% add-unit-to-group =
+% \ \{
+% \ \meta{group1} = \marg{unit-key-list},
+% \ \meta{group2} = \marg{unit-key-list},
+% \ \dots
+% \ \}
+% \end{syntax}
+% Adds each \meta{unit-key} in \meta{unit-keys-list} to \meta{group}.
+% \end{function}
+% \begin{cuexample}
+% This example adds the unit \myunit{st} to the group \mygroup{weight}
+% and \myunit{Ro} to \mygroup{temperature}.
+% \begin{lstlisting}
+% \cusetup
+% {
+% add-unit-to-group = { weight = {st} , temperature = {Ro} }
+% }
+% \end{lstlisting}
+%
+% \cusetup{ add-unit-to-group = { weight = {st} } }
+%
+% \begin{cuexamplecode}
+% \cusetup{weight=g} @
+% \cunum{1}{kg} \\
+% \cunum{1}{dag} \\
+% \cunum{1}{g} \\
+% \cunum{1}{oz} \\
+% \cunum{1}{lb} \\
+% \cunum{1}{stick} \\
+% \cunum{1}{st}
+% \end{cuexamplecode}
+% \end{cuexample}
+%
+%
+% \begin{function}{set-option-for-<unit-key>,add-option-for-<unit-key>}
+% \begin{syntax}
+% set-option-for-\meta{unit-key} = \marg{ key1 = value1, \dots\ }
+% add-option-for-\meta{unit-key} = \marg{ key1 = value1, \dots\ }
+% \end{syntax}
+% Sets and adds \meta{key1=value1,\dots} to a specific
+% \meta{unit-key},
+% \opt{erase-all-options} (see below) is used to erase all options for all
+% \meta{unit-key}s.
+%
+% You may want to attach some options to a special
+% \meta{unit-key}. Those options are automatically activated if (and
+% only if) the specific \meta{unit-key} is used (or changed into this
+% unit). Setting options overwrites old options. Adding options, well
+% \dots\ adds the options to the old ones.
+%
+% You can \enquote{delete} the options by setting
+% an empty value for a specific \meta{unit-key} (or use
+% \opt{erase-all-options} (or \opt{erase-all-options-for} )
+% (see below) to erase all options for all \meta{unit-key}s)
+%
+% \end{function}
+%
+% \begin{cuexample}
+% The following rounds the values to integers for \myunit{F}, \myunit{C},
+% \myunit{K} and \myunit{Re}:
+% \begin{lstlisting}
+% \cusetup
+% {
+% set-option-for-F = { round-to-int = true } ,
+% set-option-for-C = { round-to-int = true } ,
+% set-option-for-K = { round-to-int = true } ,
+% set-option-for-Re = { round-to-int = true }
+% }
+% \end{lstlisting}
+%
+%^^A The following code rounds the units to the tens:
+%^^A \begin{lstlisting}
+%^^A \cusetup
+%^^A {
+%^^A set-option-for-F = { round-precision = -1 } ,
+%^^A set-option-for-C = { round-precision = -1 } ,
+%^^A set-option-for-K = { round-precision = -1 } ,
+%^^A set-option-for-Re = { round-precision = -1 }
+%^^A }
+%^^A \end{lstlisting}
+% \end{cuexample}
+%
+%
+% \begin{function}{set-option-for, add-option-for}
+% \begin{syntax}
+% set-option-for =
+% \ \{
+% \ \meta{unit-key1} = \marg{keys=vals},
+% \ \meta{unit-key2} = \marg{keys=vals},
+% \ \dots
+% \ \}
+% add-option-for =
+% \ \{
+% \ \meta{unit-key1} = \marg{keys=vals},
+% \ \meta{unit-key2} = \marg{keys=vals},
+% \ \dots
+% \ \}
+% \end{syntax}
+% Sets/adds each \meta{keys=vals} to the specific \meta{unit-key}. Works pretty much
+% the same way their \opt{set-option-for-\meta{unit-key}} and
+% \opt{add-option-for-\meta{unit-key}} counterparts.
+%
+% \end{function}
+%
+% \begin{cuexample}
+% The following example does the same as the example above:
+% \begin{lstlisting}
+% \cusetup
+% {
+% set-option-for =
+% {
+% F = { round-to-int = true } ,
+% C = { round-to-int = true } ,
+% K = { round-to-int = true } ,
+% Re = { round-to-int = true }
+% }
+% }
+% \end{lstlisting}
+% \end{cuexample}
+%
+% \begin{function}{erase-all-options, erase-all-options-for}
+% \begin{syntax}
+% erase-all-options
+% erase-all-options-for = \marg{unit-key1, unit-key2, \dots}
+% \end{syntax}
+% Erase options added to units. \opt{erase-all-options} erases all options
+% for \emph{all} \meta{unit-key}s.
+%
+%^^A If you only want to erase options for specific \meta{unit-key}s, you may
+%^^A use \opt{erase-all-options-for}.
+%
+% \opt{erase-all-options-for} is used to remove added options from
+% the specified \meta{unit-key}s.
+%
+% \end{function}
+%
+% \begin{cuexample}
+% The following code erases all attached options from \myunit{C}, \myunit{F},
+% \myunit{K} and \myunit{Re}:
+%
+% \begin{lstlisting}
+% \cusetup{ erase-all-options-for = {C, F, K, Re} }
+% \end{lstlisting}
+% \end{cuexample}
+%
+%
+%
+% \subsubsection{Command behavior}
+%
+% \begin{function}{cutext-to-cunum}
+% \begin{syntax}
+% cutext-to-cunum = \meta{true/false}
+% \end{syntax}
+% Want to get rid of all \cCutext? Set this option to \opt{true} and all
+% \cCutext\ are changed into \mycs{cunum}.
+% \end{function}
+% \begin{cuexamplecode}
+% \cutext{1}{kg} \\
+% \Cutext{2}{kg} \\
+% \cutext{1/2}{kg} \\
+% \cutext{?}{kg} \\
+% \cutext[kg=g]{1--2}{kg} \\
+% \cusetup{cutext-to-cunum = true } @
+% \cutext{1}{kg} \\
+% \Cutext{2}{kg} \\
+% \cutext{1/2}{kg} \\
+% \cutext{?}{kg} \\
+% \cutext[kg=g]{1--2}{kg}
+% \end{cuexamplecode}
+%
+%
+% \begin{function}{cutext-change-unit}
+% \begin{syntax}
+% cutext-change-unit = \meta{true/false}
+% \end{syntax}
+% Set this option to \opt{true} if you do \emph{not} want the units of \cCutext\
+% to be changed. Set to \true\ by default
+% \end{function}
+% \begin{cuexamplecode}
+% \cutext[kg=g]{1}{kg} \\
+% \cutext[kg=g]{1/2}{kg} \\
+% \cutext[kg=g]{1--2}{kg} \\
+% \cusetup{cutext-change-unit = false } @
+% \cutext[kg=g]{1}{kg} \\
+% \cutext[kg=g]{1/2}{kg} \\
+% \cutext[kg=g]{1--2}{kg}
+% \end{cuexamplecode}
+%
+% \begin{function}{cuam-version,cutext-version}
+% \begin{syntax}
+% cuam-version = \meta{old/new}
+% cutext-version = \meta{old/new}
+% \end{syntax}
+% Since v1.10 this package also parses and checks the input of
+% \cCutext\ and \mycs{cuam}. If you want to restore the old
+% behavior, set this option to \opt{old}, but note that then you can
+% neither change the amounts for a given number of persons nor
+% change the unit of \cCutext. Both of them are set to \opt{new} by
+% default.
+% \end{function}
+%
+%
+%
+%
+% \subsubsection{Hooks}
+%
+% \begin{function}{commands-add-hook,cunum-add-hook,cutext-add-hook,Cutext-add-hook,cuam-add-hook}
+% \begin{syntax}
+% commands-add-hook = \marg{code}
+% cunum-add-hook = \marg{code}
+% cutext-add-hook = \marg{code}
+% Cutext-add-hook = \marg{code}
+% cuam-add-hook = \marg{code}
+% \end{syntax}
+% Adds \meta{code} to the respective command (or in case of the first key:
+% to \emph{all} commands). The hook is executed
+% \emph{after} setting the keys, but \emph{before} parsing and processing the input.
+%
+% Please be carful with spaces, they will be printed.
+% \end{function}
+%
+% \begin{cuexample}
+% You would like to count how often all commands of this package are used.
+% Simply add:
+% \begin{lstlisting}
+% \newcounter{CookingUnitsCounter} %% or however you like it
+% \cusetup{commands-add-hook={\stepcounter{CookingUnitsCounter}}}
+% %% beware of spaces inside the add-hook keys.
+% \end{lstlisting}
+% to your preamble. The following table lists how often each command
+% is used in this documentation (with help of \pkg{totalcount}):
+%
+% \begin{center}
+% \begin{tabular}{lr}
+% \toprule
+% command & times \\ \midrule
+% \mycs{cunum} & \totalcunumCounters \\
+% \mycs{cutext} & \totalcutextCounters \\
+% \mycs{Cutext} & \totalCutextCounters \\
+% \mycs{cuam} & \totalcuamCounters \\
+% \cmidrule{2-2}
+% total & \totalCookingUnitsCounters \\
+% \bottomrule
+% \end{tabular}
+% \end{center}
+% \end{cuexample}
+%
+% \subsubsection{Input and Outputs}
+%
+%
+% \begin{function}{expand-both , expand-amount, expand-unit}
+% \begin{syntax}
+% expand-both = \meta{n/o/f/x}
+% expand-amount = \meta{n/o/f/x}
+% expand-unit = \meta{n/o/f/x}
+% \end{syntax}
+% By default the commands \mycs{cunum}, \cCutext{} and \mycs{cunum}
+% do \emph{not} expand their input. You can change the expansion behavior of
+% the \meta{amount} and/or \meta{unit-key} using the options specified
+% above. The meaning of the available values are the same as specified
+% in the \LaTeX3\ document \enquote{interface3}.
+%
+% It is set to \texttt{n} by default.
+%
+% \end{function}
+%
+%
+%
+%
+% \begin{function}{set-special-sign,add-special-sign}
+% \begin{syntax}
+% set-special-sign = \marg{character(s)}
+% add-special-sign = \marg{character(s)}
+% \end{syntax}
+% Allows \meta{character(s)} to be used in the first mandatory argument of
+% \mycs{cunum}, \mycs{cuam}, \cCutext{} without raising an error (you can customize this
+% behavior, see \opt{set-unknown-message}). By default it is set to |?|.
+% Please note that the sign |<| is not allowed as a special sign.
+% \end{function}
+%
+% \begin{cuexamplecode}
+% \cunum{?}{kg} \\
+% \cunum[g=kg]{10?--20?}{kg} \\
+% \cusetup{add-special-sign={xX} } @
+% \cunum{x}{kg} \\
+% \cunum{X--?}{kg} \\
+% \cusetup{set-special-sign={} } @
+% \cunum{1}{kg} \\
+% \cunum{1--2}{kg}
+% \end{cuexamplecode}
+%
+% \begin{function}{set-unknown-message}
+% \begin{syntax}
+% set-unknown-message = \meta{error/warning/none}
+% \end{syntax}
+% Using a special sign (\texttt{?} by default) causes a warning to
+% be raised. Set this option to \opt{error} if you want an error (as
+% an extra emphasis), \opt{warning} if you want a warning (default)
+% and \opt{none} if you don't want to know anything about it.
+% \end{function}
+%
+% \begin{function}{set-cutext-translation-message}
+% \begin{syntax}
+% set-cutext-translation-message = \meta{error/warning/none}
+% \end{syntax}
+% If a translation for \cCutext\ is not available the commands are replaced
+% by \mycs{cunum}. Currently -- if this is happening -- a warning is shown,
+% you may change the behavior of the message (error, warning or not showing at all)
+% using this option.
+% \end{function}
+%
+% \begin{function}{print-numerals}
+% \begin{syntax}
+% print-numerals = \meta{true/false}
+% \end{syntax}
+% If the package option \opt{use-numerals} is set to \true\ you can
+% deactivate the printing of numerals by setting \opt{print-numerals} to
+% \false\ and activate them by setting it to \true.
+%
+% Note that this option is automatically set to \opt{true} if \opt{use-numerals} is used.
+% \end{function}
+% \cusetup{ print-numerals=true }
+% \begin{cuexamplecode}
+% \cutext{1}{kg} \\
+% \cutext{2}{kg} \\
+% \cutext{12}{kg} \\
+% \cutext{13}{kg} \\
+% \cusetup{ print-numerals=false } @
+% \cutext{1}{kg} \\
+% \cutext{2}{kg} \\
+% \cutext{12}{kg} \\
+% \cutext{13}{kg} \\
+% \end{cuexamplecode}
+% \cusetup{ print-numerals=false }
+%
+% \begin{function}{use-numerals-below}
+% \begin{syntax}
+% use-numerals-below = \meta{integer}
+% \end{syntax}
+% Only usable if the package option \opt{use-numerals} is
+% active. Prints the name of the numbers for integers used in
+% \mycs{cutext} and \mycs{Cutext} smaller than
+% \meta{integer}. \meta{integer} is by default 13. Package
+% \pkg{fmtcount} is used for this purpose.
+% You can deactivate the printing of numerals by \opt{print-numerals=false}.
+% \end{function}
+% \cusetup{ print-numerals=true }
+% \begin{cuexamplecode}
+% \cutext{1}{kg} \\
+% \cutext{2}{kg} \\
+% \cutext{12}{kg} \\
+% \cutext{13}{kg} \\
+% \cusetup{ use-numerals-below=10 } @
+% \cutext{1}{kg} \\
+% \cutext{2}{kg} \\
+% \cutext{12}{kg} \\
+% \cutext{13}{kg} \\
+% \cusetup{ use-numerals-below=0 } @
+% \cutext{1}{kg} \\
+% \cutext{2}{kg} \\
+% \cutext{12}{kg} \\
+% \cutext{13}{kg} \\
+% \cusetup{ use-numerals-below=12001 } @
+% \cutext[kg=g]{1}{kg} \\
+% \cutext[kg=g]{2}{kg} \\
+% \cutext[kg=g]{12}{kg} \\
+% \cutext[kg=g]{13}{kg} \\
+% \end{cuexamplecode}
+% \cusetup{ print-numerals=false }
+%
+%
+% \begin{function}{parse-number}
+% \begin{syntax}
+% parse-number = \meta{true/false}
+% \end{syntax}
+% If set to \false\ prints the number of \lstinline!\cunum!,
+% \lstinline!\cutext!, \lstinline!\Cutext! and \mycs{cuam} as they
+% are (after some \dots\ well \dots\ parsing due to
+% \enquote{\lstinline|_|}). Is set to \true\ by default.
+% \end{function}
+%
+% \begin{cuexamplecode}
+% \cusetup{ parse-number=false } @
+% \cunum[kg=g]{1}{kg} \\
+% \cunum{1--2}{kg} \\
+% \cunum{1----------2}{kg} \\
+% \cunum{1.2}{kg} \\
+% \cunum[kg=g]{1,2}{kg} \\
+% \cunum{1/2}{kg} \\
+% \cunum{1_2/3}{kg} \\
+% \cunum{1/2_3}{kg} \\
+% \cunum{some weird stuff}{kg} \\
+% \cutext{1}{kg} \\
+% \cutext{100}{kg} \\
+% \cutext{gjfak}{kg} \\
+% \cutext[kg=g]{12}{kg} \\
+% \cuam{1----------2} \\
+% \cuam{1,2} \\
+% \cuam{1_1/2} \\
+% \cuam{kwflk} \\
+% \end{cuexamplecode}
+%
+%
+%
+% \begin{function}{range-sign}
+% \begin{syntax}
+% range-sign = \marg{string}
+% cunum-range-sign = \marg{string}
+% cutext-range-sign = \marg{string}
+% \end{syntax}
+% The second sets the \emph{printed} range sign used in \mycs{cunum}
+% (and \mycs{cuam}) to \meta{string}, the third sets the printed
+% range sign used in \cCutext{} to \meta{string}.
+% Using the first option sets the
+% range signs for both \mycs{cunum} (and \mycs{cuam}) and
+% \mycs{cutext}/\mycs{Cutext} to \meta{string}.
+%
+% The default for \meta{string} is \texttt{-{}-} (for both).
+% \end{function}
+%
+% Since version 1.45 there also exits the language symbol \opt{cutext-range-sign}
+% (see \cref{sec:language}). If the \emph{option} \opt{cutext-range-sign} is set
+% the language symbol will be ignored.
+%
+% \begin{cuexamplecode}
+% \cunum{1--2}{kg} \\
+% \cuam{1--2} \\
+% \cutext{1--2}{kg} \\
+% \Cutext{1--2}{kg}
+% \end{cuexamplecode}
+% \begin{cuexamplecode}
+% \cusetup{cunum-range-sign={~to~}} @
+% \cunum{1--2}{kg} \\
+% \cuam{1--2} \\
+% \cutext{1--2}{kg} \\
+% \Cutext{1--2}{kg}
+% \end{cuexamplecode}
+% \begin{cuexamplecode}
+% \cusetup{cutext-range-sign={--}} @
+% \cunum{1--2}{kg} \\
+% \cuam{1--2} \\
+% \cutext{1--2}{kg} \\
+% \Cutext{1--2}{kg}
+% \end{cuexamplecode}
+% \begin{cuexamplecode}
+% \cusetup{range-sign={-to-}} @
+% \cunum{1--2}{kg} \\
+% \cuam{1--2} \\
+% \cutext{1--2}{kg} \\
+% \Cutext{1--2}{kg}
+% \end{cuexamplecode}
+%
+% \begin{function} {use-phrases}
+% \begin{syntax}
+% use-phrases = \meta{true/false}
+% \end{syntax}
+% Setting this option to \true\ replaces certain integers (see \cref{sec:phrases} for
+% more information) with their phrase counterpart. This option is set to \false\ by default.
+% \end{function}
+%
+% \begin{cuexample}
+% \begin{myde}
+% For the German language:
+% \begin{cuexamplecode}
+% \cuam{12} \\
+% \cuam{12--24} \\
+% \cuam{36} \\
+% \cusetup{use-phrases=true} @
+% \cuam{12} \\
+% \cuam{12--24} \\
+% \cuam{36} \\
+% \cusetup{use-phrases=true, print-numerals=true} @
+% \cuam{12} \\
+% \cuam{12--24} \\
+% \cuam{36} \\
+% \end{cuexamplecode}
+% \end{myde}
+% \end{cuexample}
+%
+%
+% \subsubsection{Rounding options}
+%
+% \begin{function}{round-precision}
+% \begin{syntax}
+% round-precision = \meta{integer}
+% \end{syntax}
+% Rounds the amount automatically to \meta{integer} digits after the
+% colon. Note that units like \myunit{C}, \myunit{F}, \myunit{K} and
+% \myunit{Re} are still rounded to integers due to
+% \texttt{set-option-for-<unit-key>}.
+% \end{function}
+%
+%
+% \begin{cuexamplecode}
+% \cusetup{round-precision= 5} @
+% \cunum{1.23456789}{kg} \\
+% \cunum[g=kg]{12.587}{g} \\
+% \cunum{194}{kg} \\
+% \cunum[C=F]{200--210}{C} \\
+% \cunum[K=C]{0.0012}{K} \\
+% \cusetup{round-precision= 1} @
+% \cunum{1.23456789}{kg} \\
+% \cunum{12.58}{kg} \\
+% \cunum[g=kg]{194}{g} \\
+% \cunum[C=F]{200--210}{C} \\
+% \cunum[K=C]{0.0012}{K}
+% \end{cuexamplecode}
+%
+% \begin{cunote}
+% Also negative numbers are allowed.
+% \begin{cuexamplecode}
+% \cusetup{erase-all-options} @
+% \cusetup{set-option-for-C={round-precision=-1}} @
+% \cusetup{set-option-for-F={round-precision=-1}} @
+% \cunum{-271,2}{C} \\
+% \cunum[K=C]{0.0012}{K} \\
+% \cunum{185}{C} \\
+% \cunum[C=F]{180--200}{C} \\
+% \end{cuexamplecode}
+% \end{cunote}
+%
+% \begin{function}{round-to-int}
+% \begin{syntax}
+% round-to-int = \meta{true/false}
+% \end{syntax}
+% Rounds the amount to an integer if set \true.
+% \end{function}
+%
+%
+% \begin{cuexamplecode}
+% \cusetup{round-to-int=true} @
+% \cunum{1.23456789}{kg} \\
+% \cunum{12.58}{kg} \\
+% \cunum[g=kg]{194--294}{g} \\
+% \cunum[kg=g]{1.23456789}{kg}
+% \end{cuexamplecode}
+%
+% \begin{function}{round-half}
+% \begin{syntax}
+% round-half = \meta{default/commercial}
+% \end{syntax}
+% This option is only important for half-way numbers
+% (e.g. $0.005$). By setting it to \opt{default} the value will be
+% rounded to the nearest even number. Setting it to
+% \opt{commercial} rounds the value away from zero.
+%
+% It is set to \opt{default} by \dots\ default.
+%
+% \begin{cunote}
+% \opt{default} actually refers to the fact that it is the default
+% rounding algorithm used by \cs{fp\_eval:n \{ round( ) \}}
+% without a third argument.
+% \end{cunote}
+%
+% \end{function}
+%
+%
+% \begin{cuexamplecode}
+% \cusetup{round-half=default} @
+% \cunum{0.005}{kg} \\
+% \cunum{-0.005}{kg} \\
+% \cunum{1.245}{kg} \\
+% \cusetup{round-half=commercial} @
+% \cunum{0.005}{kg} \\
+% \cunum{-0.005}{kg} \\
+% \cunum{1.245}{kg} @
+% \end{cuexamplecode}
+%
+%
+%
+% \subsubsection{Fractions}
+%
+% \begin{function}{eval-fraction}
+% \begin{syntax}
+% eval-fraction = \meta{true/false}
+% \end{syntax}
+% This option takes \true\ or \false\ as values.
+% If set to \true\ fractions are evaluated. Please note that divisions
+% through zero are not allowed.
+% \end{function}
+%
+% \begin{cuexamplecode}
+% \cusetup{eval-fraction=true} @
+% \cunum{1/3}{kg} \\
+% \cunum{1/2}{kg} \\
+% \cunum[kg=g]{1/2}{kg} \\
+% \cunum{1_1/2}{kg} \\
+% \cunum[kg=g]{1_1/2}{kg} \\
+% \cunum[kg=g]{-1_1/2}{kg} \\
+% \cunum[kg=g]{1_?/2}{kg} \\
+% \end{cuexamplecode}
+%
+% \begin{function}{fraction-command}
+% \begin{syntax}
+% fraction-command = \meta{\cs{command}}
+% \end{syntax}
+% Sets the command used for printing fractions equal to \meta{\cs{command}}.
+% \meta{\cs{command}} has to take two arguments. By default
+% it is equal to |\sfrac| from \pkg{xfrac}.
+%
+% Please note that the amount is \emph{not} printed inside a math
+% environment by default.
+% \end{function}
+%
+% \begin{cuexamplecode}
+% \newcommand\myfrac[2]{#1/#2} @
+% \cusetup{fraction-command=\myfrac} @
+% \cuam{1/8} \\
+% \cunum{1/2}{kg} \\
+% \cunum{4/5}{C} \\
+% \cunum{1_2/3}{kg} \\
+% \cusetup{fraction-command=\nicefrac} @
+% \cuam{1/8} \\
+% \cunum{1/2}{kg} \\
+% \cunum{4/5}{C} \\
+% \cunum{1_2/3}{kg}
+% \end{cuexamplecode}
+%
+% \begin{function}{fraction-inline}
+% \begin{syntax}
+% fraction-inline = \marg{input containing \#1 and \#2}
+% \end{syntax}
+% Similar to \opt{fraction-command} only that you don't have to
+% define a command to alter the output of the fraction.
+% \end{function}
+%
+% \begin{cuexamplecode}
+% \cusetup{fraction-inline={#1/#2} } @
+% \cuam{1/8} \\
+% \cunum{1/2}{kg} \\
+% \cunum{4/5}{C} \\
+% \cunum{1_2/3}{kg} \\
+% \cusetup{fraction-inline={\nicefrac{#2}{#1}} } @
+% \cuam{1/8} \\
+% \cunum{1/2}{kg} \\
+% \cunum{4/5}{C} \\
+% \cunum{1_2/3}{kg}
+% \end{cuexamplecode}
+%
+% \subsubsection{Spaces}
+%
+% \begin{function}{mixed-fraction-space}
+% \begin{syntax}
+% mixed-fraction-space = \meta{length}
+% \end{syntax}
+% Sets the length between the fraction and the number in a mixed-fraction,
+% default is \texttt{0.1em} (because I said so; if someone has some literature
+% or sources to look up the space, please let me know).
+% \end{function}
+% \begin{cuexamplecode}
+% \cuam{1_2/3} \\
+% \cunum{1_2/3}{kg} \\
+% \cunum{10_2/3}{kg} \\
+% \cusetup{mixed-fraction-space=1em } @
+% \cuam{1_2/3} \\
+% \cunum{1_2/3}{kg} \\
+% \cunum{10_2/3}{kg} \\
+% \cusetup{mixed-fraction-space=0em } @
+% \cuam{1_2/3} \\
+% \cunum{1_2/3}{kg} \\
+% \cunum{10_2/3}{kg}
+% \end{cuexamplecode}
+%
+% \begin{function}{cutext-space}
+% \begin{syntax}
+% cutext-space = \marg{string}
+% \end{syntax}
+% \meta{string} is inserted between the numeral part and the unit part
+% when using \cCutext. By default it is set to \cs{space}. Use this option
+% if you want to e.g.\ insert an unbreakable space.
+% \end{function}
+% \begin{cuexamplecode}
+% \cutext{1}{kg}\\
+% \Cutext{10}{kg}\\
+% \cusetup { cutext-space = ~ } @
+% \cutext{1}{kg}\\
+% \Cutext{10}{kg}\\
+% \cusetup { cutext-space = {} } @
+% \cutext{1}{kg}\\
+% \Cutext{10}{kg}\\
+% \cusetup { cutext-space = {qwe} } @
+% \cutext{1}{kg}\\
+% \Cutext{10}{kg}\\
+% \end{cuexamplecode}
+%
+%
+% \begin{function}{phrase-space}
+% \begin{syntax}
+% phrase-space = \marg{string}
+% \end{syntax}
+% \meta{string} is inserted between the numeral part and the phrase part
+% while using \mycs{cuam}. By default it is set to \cs{space}. Use this option
+% if you want to e.g.\ insert an unbreakable space.
+% \end{function}
+% \begin{myde}
+% \cusetup{use-phrases=true}
+% (Switching to german)
+% \begin{cuexamplecode}
+% \cuam{12}\\
+% \cuam{144}\\
+% \cusetup { phrase-space = ~ } @
+% \cuam{12}\\
+% \cuam{144}\\
+% \cusetup { phrase-space = {} } @
+% \cuam{12}\\
+% \cuam{144}\\
+% \cusetup { phrase-space = {qwe} } @
+% \cuam{12}\\
+% \cuam{144}\\
+% \end{cuexamplecode}
+% \cusetup{use-phrases=false}
+% \end{myde}
+%
+% \begin{function}{amount-unit-space}
+% \begin{syntax}
+% amount-unit-space = \marg{string}
+% \end{syntax}
+% Change the spacing for \mycs{cunum} between the printed amount(s) and
+% the unit. The default value is |\thinspace|.
+% \end{function}
+%
+% \begin{cuexamplecode}
+% \selectlanguage{ngerman} @
+% \cunum{1}{kg}\\
+% \cunum{1/2}{kg}\\
+% \cunum{1--2}{kg}\\
+% \cusetup { amount-unit-space = {\hspace{1em}} } @
+% \cunum{1}{kg}\\
+% \cunum{1/2}{kg}\\
+% \cunum{1--2}{kg}\\
+% \cusetup { amount-unit-space = {} } @
+% \cunum{1}{kg}\\
+% \cunum{1/2}{kg}\\
+% \cunum{1--2}{kg}\\
+% \cusetup { amount-unit-space = {qwe} } @
+% \cunum{1}{kg}\\
+% \cunum{1/2}{kg}\\
+% \cunum{1--2}{kg}\\
+% \end{cuexamplecode}
+%
+% \subsubsection{label \& refs}
+%
+% \begin{function}{recalculate-amount}
+% \begin{syntax}
+% recalculate-amount = \meta{true/false}
+% \end{syntax}
+% Set this option to \opt{true} if you want to change your recipes to the given
+% number of people set by \opt{set-number-of-persons}. Note that only those
+% values who have a label are changed.
+% \end{function}
+%
+% \begin{function}{set-number-of-persons}
+% \begin{syntax}
+% set-number-of-persons = \meta{integer}
+% \end{syntax}
+% With this option you can determine the number of people your recipes
+% are for. Note that this option only has an effect on those who have a \meta{label}
+% given. It is set to \opt{4} by default. Please also note the use of
+% \opt{recalculate-amount}.
+% \end{function}
+% \begin{cuexamplecode}
+% \culabel{anotherrecipe}{2} @
+% \curef{anotherrecipe}~persons \\
+% \cunum<anotherrecipe>{1}{kg}\\
+% \cuam<anotherrecipe>{1}\\
+% \cutext<anotherrecipe>{1}{kg}\\
+% \curef{anotherrecipe}~persons \\ @
+% \cusetup{ recalculate-amount = true } @
+% \curef{anotherrecipe}~persons \\
+% \cunum<anotherrecipe>{1}{kg}\\
+% \cuam<anotherrecipe>{1}\\
+% \cutext<anotherrecipe>{1}{kg}\\
+% \Cutext[ref=anotherrecipe]{10}{kg}\\ @
+% \cusetup { set-number-of-persons = 3 } @
+% \curef{anotherrecipe}~persons \\
+% \cunum<anotherrecipe>{1}{kg}\\
+% \cuam<anotherrecipe>{1}\\
+% \cutext<anotherrecipe>{1}{kg}\\
+% \Cutext[ref=anotherrecipe]{10}{kg}\\ @
+% \cusetup { set-number-of-persons = 2 } @
+% \curef{anotherrecipe}~persons \\
+% \cunum<anotherrecipe>{1}{kg}\\
+% \cuam<anotherrecipe>{1}\\
+% \cutext<anotherrecipe>{1}{kg}\\
+% \Cutext[ref=anotherrecipe]{10}{kg}\\ @
+% \cusetup { set-number-of-persons = 1 } @
+% \curef{anotherrecipe}~person \\
+% \cunum<anotherrecipe>{1}{kg}\\
+% \cuam<anotherrecipe>{1}\\
+% \cutext<anotherrecipe>{1}{kg}\\
+% \Cutext[ref=anotherrecipe]{10}{kg}\\
+% \end{cuexamplecode}
+%
+%
+% \begin{function}{label}
+% \begin{syntax}
+% label = \{\meta{string}*\meta{integer}\}
+% \end{syntax}
+% The key-value version of \mycs{culabel}. It defines the label \meta{string}
+% which is originally for \meta{integer} people. Please note that the \texttt{*}
+% is mandatory as it separates the string from the integer. Each
+% label is defined globally and must be unique.
+% \end{function}
+% \begin{cuexamplecode}
+% \cusetup{label=Toast*1} @
+% \curef{Toast}~person \\
+% \cuam<Toast>{2} \\
+% \cunum<Toast>{2}{dag} \\
+% \cusetup { recalculate-amount = true } @
+% \curef{Toast}~persons \\
+% \cuam<Toast>{2} \\
+% \cunum<Toast>{2}{dag}
+% \end{cuexamplecode}
+%
+%
+% \begin{function}{get-label}
+% \begin{syntax}
+% get-label = \marg{label}
+% \end{syntax}
+% The key-value version of \mycs{curef}. Note that this key doesn't save the value
+% inside a macro but rather prints it directly into the document.
+% \end{function}
+% \begin{cuexamplecode}
+% \culabel{Schinken}{3} @
+% \cusetup{get-label=Schinken} \\
+% \curef{Schinken} \\
+% \cusetup { recalculate-amount = true } @
+% \cusetup{get-label=Schinken} \\
+% \curef{Schinken} \\
+% \end{cuexamplecode}
+%
+% \begin{cunote}
+% \mycs{curef} \emph{is} expendable.
+% \end{cunote}
+%
+%
+% \begin{function}{ref}
+% \begin{syntax}
+% ref = \marg{label}
+% \end{syntax}
+% Instead of using the first optional arguments of the commands in \cref{sec:commands}
+% you may use this option. It requires a valid value and throws an error if \meta{label}
+% is not defined.
+% \end{function}
+% \begin{cuexamplecode}
+% \culabel{Kaese}{3} @
+% \cunum<Kaese> [m=dm]{1}{m} \\
+% \cunum[ref=Kaese,m=dm]{1}{m} \\
+% \cusetup { recalculate-amount = true } @
+% \cunum<Kaese>[m=dm]{1}{m} \\
+% \cunum[ref=Kaese,m=dm]{1}{m}
+% \end{cuexamplecode}
+%
+%
+%
+% \begin{function}{curef-add-forbidden-unit, curef-remove-forbidden-unit,curef-clear-forbidden-units}
+% \begin{syntax}
+% curef-add-forbidden-unit = \marg{unit list}
+% curef-remove-forbidden-unit = \marg{unit list}
+% curef-clear-forbidden-units = \meta{true/false}
+% \end{syntax}
+%^^A How much of a specify ingredient is used generally depends on the number of folks the meal
+%^^A is for. Change the number of folks and the needed weight of an ingredient will most probably
+%^^A change, \emph{but} there are units which do not change automatically if you have $2$ instead
+%^^A of $4$ guests. Units which measure the temperature are for example one of them. So changing
+%^^A them using the label \& ref system would be accidental and should in the best case create an error.
+%^^A Use the given options to define units which will throw an error if they are about to be changed
+%^^A by the label \& ref system. Of course, you can also remove units or clear the whole list.
+%
+% There are units which do not depend on the number of folks you are cooking for, units measuring
+% the temperature are for example some of them. Changing those units with the label \& ref
+% system would be accidental and in the best case throw an error. With the following options
+% you can add units to the \enquote{forbidden unit list}, remove them and clear the whole list
+% entirely.
+%
+% By default the list contains \texttt{C}, \texttt{F}, \texttt{K} and \texttt{Re}.
+% \end{function}
+% \begingroup
+% \DeactivateForbiddenUnitError
+% \begin{cuexamplecode}
+% \culabel{check}{2} @
+% \cusetup{ recalculate-amount=true } @
+% \cunum<check>{1}{m} \\
+% \cunum<check>{1}{kg} \\
+% \cunum[ref=check]{1}{C} \\
+% \cusetup { curef-add-forbidden-unit = { m, kg } } @
+% \cunum<check>[m]{1}{m} \\
+% \cunum<check>[m]{1}{kg} \\
+% \cunum[ref=check]{1}{C} \\
+% \cusetup { curef-remove-forbidden-unit = { C } } @
+% \cunum<check>[m]{1}{m} \\
+% \cunum<check>[m]{1}{kg} \\
+% \cunum[ref=check]{1}{C} \\
+% \cusetup { curef-clear-forbidden-units = true } @
+% \cunum<check>[m]{1}{m} \\
+% \cunum<check>[m]{1}{kg} \\
+% \cunum[ref=check]{1}{C}
+% \end{cuexamplecode}
+% \endgroup
+%
+%
+%
+%
+%
+%
+%
+%
+%
+%
+%
+%
+%
+%
+%
+% \subsection{Weird options}
+%
+% \begin{function}{check-temperature}
+% \begin{syntax}
+% check-temperature = \meta{true/false}
+% \end{syntax}
+% Checks if the used temperature is below absolute zero.
+% Currently \myunit{C}, \myunit{F}, \myunit{K} and \myunit{Re} are supported.
+% While \lstinline|\cunum{0}{K}| is ok, \lstinline!\cunum{-1}{K}! raises an error,
+% same for the others. Is set to \false\ by default. To add new units
+% see \opt{add-temperature-to-check}.
+% \end{function}
+%
+% \begin{function}{add-temperature-to-check}
+% \begin{syntax}
+% add-temperature-to-check =
+% \ \ \{
+% \ \ \ \ \meta{unit-key-1} = \meta{minimum-value-1} ,
+% \ \ \ \ \meta{unit-key-2} = \meta{minimum-value-2} ,
+% \ \ \ \ \dots
+% \ \ \}
+% \end{syntax}
+% This option adds \meta{unit-key-1} and so on to the list of units to be checked
+% if \opt{check-temperature} is active. The argument can be a comma-separated
+% list of \meta{unit-key} = \meta{minimum-value}. This sets the allowed minimum
+% value of \meta{unit-key} to \meta{minimum-value}.
+%
+% \end{function}
+%
+% \begin{cuexample}
+% This package implements the allowed minimum values for the
+% temperatures \myunit{C}, \myunit{F}, \myunit{K} and \myunit{Re} to be checked if
+% \opt{check-temperature} is active using:
+% \begin{lstlisting}
+% \cusetup
+% {
+% add-temperature-to-check =
+% {
+% K = 0,
+% C = -273.15 ,
+% F = -459.67 ,
+% Re = -218.52
+% }
+% }
+% \end{lstlisting}
+%
+% If you want to add a new value, for example degree R{\o}mer
+% (which has be defined in another example) you can write:
+% \begin{lstlisting}
+% \cusetup
+% {
+% add-temperature-to-check = { Ro = -135.90375 }
+% }
+% \end{lstlisting}
+% \end{cuexample}
+%
+%
+%
+%
+% \begin{function}{convert-to-eV}
+% \begin{syntax}
+% convert-to-eV = \meta{true/false}
+% \end{syntax}
+% Converts (nearly) every unit in \cref{tab:def-units}
+% to electron volt or the respective derivative (if possible). Note that this
+% option is:
+% a) experimental and probably will forever be and b) just a joke, you are not
+% supposed to use this units in a cookery book (and as you see this package
+% doesn't support the arrangement of such huge numbers). Also you may
+% want to check the values if you really want to use them, just to be sure
+% (I've checked them several times and hope they are finally correct, but mistakes
+% happen).
+%
+% \end{function}
+%
+% \begin{cuexamplecode}[\hfill]
+% \cusetup{ convert-to-eV=true } @
+% \cunum{1}{kg} \\
+% \cunum{1}{l} \\
+% \cunum{1}{J} \\
+% \cunum{1}{m} \\
+% \cunum{1}{C} \\
+% \cunum{1}{s}
+% \end{cuexamplecode}
+%
+% \begin{function}{add-natural-unit}
+% \begin{syntax}
+% add-natural-unit = \meta{unit-key}
+% \end{syntax}
+% This option adds \meta{unit-key} to the list of units \opt{convert-to-eV}
+% uses to determine how a unit is transformed if set to \true.
+% \end{function}
+%
+%
+%
+%
+% \begin{function}{42}
+% \begin{syntax}
+% 42 = \meta{true/false}
+% \end{syntax}
+% Take a good guess.
+% \end{function}
+%
+% \begin{cuexamplecode}[\hfill]
+% \cusetup{ 42=true } @
+% \cunum{1}{kg} \\
+% \cunum[kg=g]{1}{kg} \\
+% \cunum{1.5}{J} \\
+% \cunum{180}{C} \\
+% \cunum{15}{s}
+% \end{cuexamplecode}
+%
+%
+%
+%
+%
+%
+%
+%^^A \section{Notes}
+%
+%^^A There is a unit called \enquote{Batman}.
+%
+%
+%
+%
+%
+%
+%
+%
+%
+%
+%
+%
+%
+% \section{Bugs \& Feedback}
+% \label{sec:bug-feed}
+%
+% Bug reports are always welcome. If you are sending a bug report
+% please include a minimal working example showing the bug and a short
+% description. If you use mail please add \pkg{cooking-units}
+% to the e-mail header. GMX has the habit of putting e-mails into the
+% spam account and adding \pkg{cooking-units} to the header makes
+% it easier to recognize those e-mails. It can also take longer of GitHub,
+% but I hope I figured out how to get a mail if a new issue is created (by not me).
+%
+% Feedback and requests (commands, units, etc.) are also welcome. Please
+% also add (if possible) an example of the desired output into the
+% minimal example (and -- if by mail -- add \pkg{cooking-units} to the
+% header).
+%
+% Furthermore, as you can see I am not able to speak too many
+% languages (german and english to be precise; I managed to add french
+% with the help of the internet, which is not optimal) so if you are
+% able to speak a language not yet implemented and would like to help
+% you can send me the translations known to you. A list of all units
+% (and their current translations) is given in \cref{sec:Translations}.
+%
+%
+%
+%
+%
+% \clearpage
+%
+% \section{Bens Einheitensammelsurium (Bens unit Almanac)}
+%
+% Units are a fascinating mess. There are so many different ones which are different and
+% the few ones which are the same (in name at least) are \emph{also} different, depending on
+% geographical position, time period and probably pure spite. We can be glad that SI-units exist.
+%
+%
+%^^A Units are a fascinating mess. There are so many different ones that one can be glad
+%^^A that SI-units exist in this world. This section offers some units which didn't manage
+%^^A to appear in \cref{tab:def-units} and \cref{tab:some-more-units}.^^A\footnote{This somehow
+%^^A ^^A reminds me of the story of \enquote{Tower of Babel} in the bible. This tower is -- according to the
+%^^A ^^A story -- the reason (or the symptom) of why people speak different languages.
+%^^A ^^A I suppose what didn't make it into the story was that as even more severe punishment,
+%^^A ^^A different units were created. Just my take at lest.}.
+%
+% So for those units which didn't make it into \cref{tab:def-units} and \cref{tab:some-more-units},
+% this section exists. Please note that this list is intended to be a just-for-fun list and not a
+% compilation of every unit in existence with its exact value ordered by geographical and chronological
+% position. I am sadly neither a historian nor very good in regards to languages. It would sound like
+% fun, but ultimately, I wouldn't have the time.
+% Therefore I am only taking units into account which I either found in literature (stone, canna, etc.),
+% are well known (foot) or have some other experience with them (ell) (exception: Batman). The reason I
+% am not including units which I found in the internet is that I would like to
+% see those units in their \enquote{natural environment}.
+%
+% \begin{comment}
+% \begin{tabular}{lllllll}
+% \toprule
+% unit & original & abréviation & type & source \\ \midrule
+%
+% Batman & & & weight\\
+%^^A Rottel\txtupde & Sicilian: \emph{rotolo} && length & \cite{Gattopardo}\\
+%^^A Rute\txtupde & Sicilian: \emph{canna} & & weight & \cite{Gattopardo}\\
+% rotolo\txtupsic & Rottel\txtupde && length & \cite{Gattopardo}\\
+% canna\txtupsic & rod\txtupen, Rute\txtupde & & weight & \cite{Gattopardo}\\
+% \bottomrule
+% \end{tabular}
+%
+% {\footnotesize \txtupde German }
+% \end{comment}
+%
+% \begin{description}
+%
+% \unititem{unit}*in given language*[translation][abbreviation] Description, containing a
+% quote or not. \emph{Please note that most of the units are country dependent!
+% So the translation may not have the same amount as the word it is translated to.}
+%
+% \unititem{Batman}
+% So \dots\ You wanna be Batman? Be like Bruce Wayne? Having a secret identity?
+% Then congratulations! You \emph{are} Batman! How much Batman depends on the location,
+% but Wikipedia is your friend in this matter.
+%
+%
+% \unititem{Rotolo}*sic*[Rottel\txtupde] Around \SI{0.850}{\kg}
+% \begin{myquote}[Gattopardo][51]
+% Auf den Fußboden lagen vier ungereifte Käse zu je \emph{zwölf Rottel},
+% jeder ungefähr zehn Kilo schwer.
+% \end{myquote}
+%
+% \unititem{Canna}*sic*[Rute\txtupde, rod\txtupen] About \SI{2}{\m} bzw.\ about $6$ foot.
+% \begin{myquote}[Gattopardo][25]
+% \enquote{Unsinn, Stella, Unsinn; was soll mir zustoßen? Sie kennen mich alle:
+% Männer, die \emph{eine Rute} lange sind, gibt es wenige in Palermo.}
+% \end{myquote}
+%
+% \unititem{Stone}[][st] \cunum[st=kg]{1}{st}. According to a fellow student
+% this unit is still used in
+% Great Britain. I've also recently found it in a video game; in the german translation
+% of said video game to be precise. Why is the german translation using stone
+% and not kilogram (at least in braces)?
+%
+% \begin{myquote}[Sh:3][988]
+% As we had expected, the telegramm was soon followed by its sender, and the card of Mr.\ Cyril Overton, Trinity College, Cambridge, announced the arrival of an enormous young man, \emph{sixteen stone} \emph{[\cunum[st=kg]{16}{st}]} of solid bone and muscle, who spanned the doorway with his broad shoulders \emph{[\dots\!]}
+% \end{myquote} (Story \enquote{The missing Three Quarters})
+%
+% \unititem{Foot}[][ft] Equals exactly \cunum[ft=m,round-precision=10]{1}{ft}
+% or \cunum[ft=in]{1}{ft}.
+%
+% A bit of a strange unit (for me at least). Where I am from, people
+% tend to have different feet sizes. Also present in the german translation of the
+% video game that uses \enquote{Stone}.
+%
+% \unititem{degree Rèamur}[][\ensuremath{{}^{\circ}}\kern-\scriptspace R\'{e}] Like degree Celsius, but instead of having the
+% water boiling at \SI{100}{\degree} (Celsius), water boils at \SI{80}{\degree}.
+% Water thankfully still freezes at \SI{0}{\degree}. Don't think that this unit
+% is used anymore. I think I learned about in physics.
+%
+% \unititem{Ell} Just read the Wikipedia article.
+%
+% Fun Fact: At the Stephansdom
+% in Vienna left of the main entrance are two metal bars. One is the
+% \enquote{Tuchelle} (drapery ell, circa \SI{78}{\cm}), the other the
+% \enquote{Leinenelle} (linen ell, around \SI{89.6}{\cm}).
+%
+% \unititem{cup} I think the idea of having a \enquote{cup} and it not being
+% equal to \cunum{250}{ml} is a bit strange, for me at least. What other sizes can a
+% cup have? I can imagine \cunum{500}{ml}, but are there other sizes?
+% ^^A Any person who writes \enquote{cup} and
+% ^^A \emph{doesn't} mean
+% ^^A a cup equal to \SI{250}{\ml} should be
+%^^A^^A -- in my humble opinion\footnote{Which, now that I admitted
+%^^A^^A my humbleness, is automatically
+%^^A^^A more important than yours.} --
+%^^A excommunicated by default (or incommunicated,
+%^^A if you are an atheist).
+%
+% \unititem{stick} A unit I've made fun of because it is quite regional and doesn't make
+% any sense for foreigners. Then I realized that I am using the unit \enquote{Packerl}
+% in my cookery book which is also quite locally\footnote{And maybe doesn't even exist
+% outside my family} and -- even worse -- the weight changes depending
+% the content (See \emph{Packerl}).
+%
+% \unititem{Packerl}*de*[small bag] I'm a bit split on this unit as I don't actually
+% know if it exists. The reason I have the unit \emph{Packerl} for my cookery
+% book is that in Austria you can buy baking powder, (dry) Germ, Natrium, etc.
+% in small bags (similar to \emph{stick}). The problem: Depending on the content,
+% the weight of \emph{Packerl} differs. Not only that, but it can also differ
+% between different producers (but not more than \SI{2}{\g} bzw.\ \cunum[g=oz]{2}{g}).
+% Here is a table:
+%
+% \begin{tabular}{l @{\space} l @{\space} l r l}
+%
+% 1 Packerl & Backpulver & (baking powder) & \cunum{16}{g} & (\cunum[g=oz]{16}{g}) \\
+% & Natrium & & \cunum{14}{g} & (\cunum[g=oz]{14}{g}) \\
+% & Vanillin(-zucker) & (vanillin(-sugar)) & \cunum{8}{g} & (\cunum[g=oz]{8}{g}) \\
+% & Germ* & & \cunum{7}{g} & (\cunum[g=oz]{7}{g}) \\
+% \end{tabular}
+%
+% {\footnotesize *Tockengerm (dry Germ) to be precise}
+%
+% For what kind of thing do I need \emph{Natrium} for?
+% \end{description}
+%
+%
+% \begin{comment}
+% Fun Wikipedia articles:
+% \begin{itemize}
+% \item Old Austrian units: https://en.wikipedia.org/wiki/Obsolete_Austrian_units_of_measurement
+% \end{itemize}
+% \end{comment}
+%
+%
+%
+%
+%
+%
+% \clearpage
+% \appendix
+%
+% \section{Translations}
+% \label{sec:Translations}
+% This section contains the list of available translations. Each table
+% shows the available translations regarding the unit symbol, the unit name
+% (printed if \mycs{cutext} or \mycs{Cutext} is used) and
+% the plural form (if different from the singular form). A second table
+% shows the translations used for phrases (if given).
+%
+% If a translation is not available a \enquote{\translationdoesnotexisttl} is
+% shown.
+%
+% \small
+%
+% \newpage
+% \subsection{English}
+% \begin{tabular}{ l l l l l }
+% \toprule
+% \CreateTableForLanguages{ English }
+% \end{tabular}
+%
+%
+% \newpage
+% \subsection{american}
+%
+% \begin{tabular}{ l l l l l }
+% \toprule
+% \CreateTableForLanguages{ american }
+% \end{tabular}
+%
+% \newpage
+% \subsection{German}
+% \begin{tabular}{ l l l l l }
+% \toprule
+% \CreateTableForLanguages{ German }
+% \end{tabular}
+%
+% \bigskip
+%
+% \CreateTableForPhrases { German }
+%
+% \bigskip
+% \begin{minipage}{\textwidth}
+% Some further phrases, just to write them down (they are not implemented,
+% as they are barely used).
+%
+% \begin{tabular} { l l @{\space} l l l l }
+% \toprule
+% \meta{number} & name & \multicolumn{2}{c}{Note} & (plural) & gender \\ \midrule
+% 60 & Schock & (5 Dutzend, & $12*5$) & & n \\
+% 144 & Gros & (12 Dutzend, & $12*12$) && n \\
+% 1728 & Gro{\ss}gros &(12 Gro{\ss}, & $12*144$) && n \\
+% \bottomrule
+% \end{tabular}
+% \end{minipage}
+%
+% Note that Gro{\ss}gros has other (probably more common) synonyms.
+%
+% \newpage
+% \subsection{French}
+% \begin{tabular}{ l l l l l }
+% \toprule
+% \CreateTableForLanguages{ French }
+% \end{tabular}
+%
+% If the spoons should be extra full:
+% \begin{itemize}
+% \item cuill\`{e}re \`{a} soupe rase
+% \item cuill\`{e}re \`{a} caf\'{e} rase
+% \end{itemize}
+%
+% \clearpage
+%
+% \begin{comment}
+%^^A \section{Notes and other stuff}
+%^^A This section contains stuff which might or might not be interesting.
+%^^A
+%^^A \subsection{More or less FAQ}
+%^^A
+%^^A \num{624150912.6 +- 3.9 e+10}
+%^^A \num{6.241509126 +- 0.000000039 e+18}
+%^^A
+%^^A \num{8.6173303 +- 00000.0000050 e-5}
+%^^A
+%^^A \subsection{Calculation}
+%^^A This subsection deals with some regarding the conversion to certain units.
+%^^A Mostly to (I like to call them) \enquote{electron volt units} (or natural units).
+%^^A Let's begin.
+%^^A
+%^^A We start with the easiest one: conversion of joule into electron volt.
+%^^A Easy because Wikipedia and nearly every physics book knows the answer.
+%^^A And according to Wikipedia
+%^^A \begin{align}
+%^^A \SI{1}{\eV} &= \SI{1.6021766208(98)e-19}{\joule} \\
+%^^A \SI{1}{\joule} &= \SI{6.241509126 +- 0.000000039 e+18}{\eV}
+%^^A \end{align}
+%^^A Adding this is no problem:
+%^^A \begin{lstlisting}
+%^^A \cuaddtokeys {J} {eV} { 1.6021766208e-19 }
+%^^A \end{lstlisting}
+%^^A
+%^^A
+%^^A Great, next Temperature (kelvin) to electron volt. Also no problem at all
+%^^A because joule and kelvin are related by the boltzmann constant $k_B$ with
+%^^A \begin{equation}
+%^^A energy (\si{\joule}) = k_B \cdot temperature (\si{\kelvin})
+%^^A \end{equation}
+%^^A as $[k_B]= \sfrac{\si{\joule}}{\si{\kelvin}}$ and
+%^^A $k_B= \SI{1.38064852(79)e-23}{\joule\per\kelvin}$. Now using the power
+%^^A of (more or less basic, but somehow annoying) mathematics we get:
+%^^A \begin{align}
+%^^A [k_B] &= \SI{1.38064852(79)e-23}{\joule\per\kelvin} = \\
+%^^A &= \num{1.38064852(79)e-23} \cdot \SI{6.241509126 +- 0.000000039 e+18 }{\eV\per\K} = \\
+%^^A &= \SI{8.6173303 +- 0.0000050 e-5 }{\eV\per\K}
+%^^A \end{align}
+%
+%
+%^^A \section{Notes and other stuff}
+%^^A \subsection{Some details to electron volts}
+%^^A This section explains how I calculated the values for conversion into electron volt
+%^^A or the respective derivative. Let's begin with some constants (from Wikipedia), note that
+%^^A \begin{equation*}
+%^^A \num{1.23456(78)e-9} = \num[separate-uncertainty = true]{1.23456(78)e-9}
+%^^A \end{equation*}
+%^^A just for info.
+%^^A
+%^^A \begin{align}
+%^^A \SI{1}{\eV} &= \SI{1.6021766208(98)e-19}{\J} \\
+%^^A \hbar &= \SI{1.054571800(13)e-34}{\J\s} \\
+%^^A k_B &= \SI{1.38064852(79)e-23}{\J\per\K} = \SI{8.6173303(50)e-5}{\eV\per\K}\\
+%^^A c &= \SI{299792458}{\m\per\s}
+%^^A \end{align}
+%^^A
+%^^A Note that all those and following values are rounded to the second relevant figure of the
+%^^A uncertainty of the value.
+%^^A
+%^^A Well then, next are temperatures.
+%^^A
+%^^A Temperatures are fairly easy. Just convert the temperature of your choice to kelvin
+%^^A and multiplicate it with $k_B$:
+%^^A \begin{align}
+%^^A \SI{1}{\K} * k_B &= \SI{8.6173303(50)e-5}{\eV}
+%^^A \end{align}
+%^^A
+%^^A Next is more complicated. To compute the resulting unceartanity I using
+%^^A \enquote{Gauß'sches Fehlerfortpflanzungsgesetz} (I don't know if this has
+%^^A a translation). Anyway. We know that
+%^^A \begin{align*}
+%^^A \frac{\SI{1}{\eV}}{c^2} &= \frac{\SI{1.6021766208e-19}{\J}}{(\SI{299792458}{\m\per\s})^2}
+%^^A = \frac{\SI{1.6021766208e-19}{\kg\m\squared\per\s\squared}}{\SI{8,98755178736818E16}{\m\squared\per\s\squared}} = \\
+%^^A &\frac{\SI{1.6021766208e-3}{\kg}}{\num{8,98755178736818}} =
+%^^A \SI{1782661906,94091624922088}{\kg}
+%^^A \end{align*}
+%^^A
+%^^A Great, now we have to calucalte the unceartinity:
+%^^A \begin{align}
+%^^A f(\si{\eV},c) &= \frac{\si{\eV}}{c^2} \\
+%^^A df(\si\eV,c) &= \sqrt{ (\frac{\partial f}{\partial \si\eV})^2 * (\Delta \si\eV)^2 + (\frac{\partial f}{\partial c})^2 * (\Delta c)^2 } = \\
+%^^A &= \sqrt{ (\frac{1}{c^2})^2 * (\Delta \si\eV)^2 + (-2\frac{eV}{c^{-3}})^2 * (\Delta c)^2 }
+%^^A \end{align}
+%^^A
+%^^A Now we know that $\Delta c = 0$:
+%^^A \begin{align}
+%^^A df(\si\eV,c) &= \sqrt{ (\frac{1}{c^2})^2 * (\Delta \si\eV)^2 } =
+%^^A \sqrt{ \frac{1}{(\SI{299792458}{\m\per\s} )^2} * (\SI{0.0000000098e-19}{\J})^2 } \\
+%^^A &=
+%^^A \end{align}
+% \end{comment}
+%
+%
+%
+%
+%
+%
+% \end{documentation}
+%
+%
+%
+%
+%
+%
+%
+%
+%
+%
+% \begin{implementation}
+%
+% \section{Implementation}
+%
+% \subsection{Beginning}
+%
+% \begin{macrocode}
+%<@@=cookingunits>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+%
+%
+% Na dann, auf gehts!
+%
+% \begin{macrocode}
+\@ifpackageloaded {xparse}
+ { }
+ { \RequirePackage {xparse} }
+\@ifpackageloaded {expl3}
+ { }
+ { \RequirePackage {expl3} }
+% \end{macrocode}
+%
+%: Package
+% \begin{macrocode}
+\ProvidesExplPackage
+ {cooking-units}
+ {2018/09/24}
+ {1.45}
+ {Ein Paket fuer Kocheinheiten}
+% \end{macrocode}
+%
+% Checking if \pkg{expl3} is up-to-date, otherwise abort the loading of the package.
+% \begin{macrocode}
+\@ifpackagelater { expl3 } { 2018/08/23 }
+ { }
+ {
+ \PackageError { cooking-units } { Support~package~expl3~too~old }
+ {
+ You~need~to~update~your~installation~of~the~bundles~'l3kernel'~and~
+ 'l3packages'.\MessageBreak
+ Loading~cooking-units~will~abort!
+ }
+ \tex_endinput:D
+ }
+% \end{macrocode}
+% Loading some needed packages.
+% \begin{macrocode}
+\@ifpackageloaded { translations } { } { \RequirePackage { translations } }
+\@ifpackageloaded { xfrac } { } { \RequirePackage { xfrac } }
+\@ifpackageloaded { l3keys2e } { } { \RequirePackage { l3keys2e } }
+% \end{macrocode}
+%
+% Checking if \pkg{translations} is up-to-date, otherwise abort the loading of the package.
+% \begin{macrocode}
+\@ifpackagelater { translations } { 2017/08/31 }
+ { }
+ {
+ \PackageError { cooking-units } { Support~package~translations~too~old }
+ {
+ You~need~to~update~your~installation~of~the~package~'translations'.\MessageBreak
+ Loading~cooking-units~will~abort!
+ }
+ \tex_endinput:D
+ }
+% \end{macrocode}
+%
+% Define the only load-time option for this package. If it is set,
+% load package \pkg{fmtcount}.
+% \begin{macrocode}
+\bool_new:N \g_@@_opt_numeral_bool
+\keys_define:nn { cooking-units }
+ {
+ use-numerals .bool_gset:N = \g_@@_opt_numeral_bool ,
+ use-numerals .default:n = { false },
+ }
+% \end{macrocode}
+% Now process the package options \dots
+% \begin{macrocode}
+\ProcessKeysOptions { cooking-units }
+\bool_if:NT \g_@@_opt_numeral_bool
+ {
+ \@ifpackageloaded { fmtcount } { } { \RequirePackage { fmtcount } }
+ }
+% \end{macrocode}
+% \dots\ and redefine the package option such that it cannot be used elsewhere.
+% \begin{macrocode}
+\keys_define:nn { cooking-units }
+ {
+ use-numerals .code:n = { \msg_error:nnn { cooking-units } { load-time-option } { fmtcount } } ,
+ }
+% \end{macrocode}
+%
+%
+%
+% \subsection {Defining Variables}
+%
+% \begin{macro}
+% {
+% \tl_replace_all:NVn,
+% \tl_replace_once:NnV , \tl_replace_once:NVn ,
+% \tl_if_in:nVTF ,
+% \tl_if_in:NVTF ,
+% \tl_if_in:NVT ,
+% \fp_compare:vNnT ,
+% \fp_eval:c ,
+% \prop_get:cVc ,
+% \int_abs:c ,
+% }
+% Some variations of commands we will need later.
+% \begin{macrocode}
+\cs_generate_variant:Nn \tl_replace_all:Nnn { NVn }
+\cs_generate_variant:Nn \tl_replace_once:Nnn { NVn }
+\cs_generate_variant:Nn \tl_if_in:nnTF { nV }
+\cs_generate_variant:Nn \tl_if_in:NnTF { NVTF }
+\cs_generate_variant:Nn \tl_if_in:NnT { NVT }
+\cs_generate_variant:Nn \fp_compare:nNnT { vNnT }
+\cs_generate_variant:Nn \prop_get:NnN { cVc }
+\cs_generate_variant:Nn \tl_set_rescan:Nnn { NnV }
+\cs_generate_variant:Nn \msg_error:nnnn { nnnV }
+\cs_generate_variant:Nn \msg_error:nnn { nnV }
+\cs_generate_variant:Nn \msg_warning:nnn { nnV }
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{ \@@_dim_horizontal:N }
+% Using this command (which is essential |\tex_kern:D| until an official
+% command exists.
+% \begin{macrocode}
+\cs_new:Npn \@@_dim_horizontal:N #1 { \tex_kern:D #1 }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_frac:nn}
+% This command is used to print the fractions and can be changed
+% accordingly.
+% \begin{macrocode}
+\cs_new_eq:NN \@@_frac:nn \sfrac
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_set_amount:Nn,\@@_set_unit:Nn}
+% \begin{macrocode}
+\cs_new_eq:NN \@@_set_amount:Nn \tl_set:Nn
+\cs_new_eq:NN \@@_set_unit:Nn \tl_set:Nn
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\@@_print_numeral:n , \@@_print_Numeral:n}
+% This command is used to print the fractions and can be changed
+% accordingly.
+% \begin{macrocode}
+\cs_new:Npn \@@_print_numeral:n #1 { }
+\cs_new:Npn \@@_print_Numeral:n #1 { }
+\bool_if:NT \g_@@_opt_numeral_bool
+ {
+ \cs_set_eq:NN \@@_print_numeral:n \numberstringnum
+ \cs_set_eq:NN \@@_print_Numeral:n \Numberstringnum
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{ \l_@@_change_unit_prop }
+% Conversions of units are stored within this property list.
+% If someone requests that \myunit{kg} should be changed into \myunit{g},
+% \myunit{kg} is stored as a key with the value \myunit{g}. If someone
+% then uses the unit \myunit{kg} the value \myunit{g} is restored and the unit
+% is changed accordingly.
+% \begin{macrocode}
+\prop_new:N \l_@@_change_unit_prop
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}
+% {
+% \l_@@_number_tmpa_tl,
+% \l_@@_number_tmpb_tl,
+% \l_@@_tmpa_tl,
+% \l_@@_tmpb_tl,
+% \l_@@_mixed_fraction_tl,
+% \l_@@_given_unit_tl,
+% \l_@@_option_unit_tl,
+% \l_@@_language_tl,
+% \l_@@_cunum_range_sign_tl,
+% \l_@@_cutext_range_sign_tl,
+% \l_@@_value_unit_space_tl,
+% \l_@@_input_digits_tl ,
+% \l_@@_input_decimal_mark_tl,
+% \l_@@_input_value_signs_tl,
+% \l_@@_input_allowed_special_signs_tl ,
+% \c_@@_input_str_hash_one_tl ,
+% \l_@@_input_range_sign_tl,
+% \l_@@_cutext_space_tl,
+% \l_@@_cuphrase_space_tl,
+% \l_@@_translation_tmpa_tl,
+% \l_@@_cutext_last_value_tl,
+% \l_@@_phrase_phrase_tl ,
+% }
+% Quite a lot of tl's.
+% \begin{macrocode}
+\tl_new:N \l_@@_number_tmpa_tl
+\tl_new:N \l_@@_number_tmpb_tl
+\tl_new:N \l_@@_tmpa_tl
+\tl_new:N \l_@@_tmpb_tl
+\tl_new:N \l_@@_mixed_fraction_tl
+\tl_new:N \l_@@_given_amount_tl
+\tl_new:N \l_@@_given_unit_tl
+\tl_new:N \l_@@_option_unit_tl
+\tl_new:N \l_@@_language_tl
+\tl_new:N \l_@@_cunum_range_sign_tl
+\tl_new:N \l_@@_cutext_range_sign_tl
+\tl_new:N \l_@@_value_unit_space_tl
+\tl_new:N \l_@@_input_digits_tl
+\tl_new:N \l_@@_input_decimal_mark_tl
+\tl_new:N \l_@@_input_value_signs_tl
+\tl_new:N \l_@@_input_allowed_special_signs_tl
+\tl_new:N \c_@@_input_str_hash_one_tl
+\tl_new:N \l_@@_input_range_sign_tl
+\tl_new:N \l_@@_cutext_space_tl
+\tl_new:N \l_@@_cuphrase_space_tl
+\tl_new:N \l_@@_translation_tmpa_tl
+\tl_new:N \l_@@_cutext_last_value_tl
+\tl_new:N \l_@@_phantom_tl
+\tl_new:N \l_@@_phrase_phrase_tl
+\tl_new:N \l_@@_unit_letter_not_allowed_tl
+\tl_new:N \l_@@_input_fraction_sign_tl
+\tl_new:N \l_@@_input_mixed_fraction_sign_tl
+% \end{macrocode}
+% \begin{macrocode}
+\tl_new:N \l_@@_cunum_hook_tl
+\tl_new:N \l_@@_cutext_hook_tl
+\tl_new:N \l_@@_Cutext_hook_tl
+\tl_new:N \l_@@_cuam_hook_tl
+% \end{macrocode}
+% \end{macro}
+%
+%
+% Setting some token lists to their default value.
+% \lstinline|str_hash_one_tl| is used for defining single keys.
+% (You will see, I didn't have a better idea)
+% \begin{macrocode}
+\tl_set:Nn \l_@@_input_digits_tl { 0123456789 }
+\tl_set:Nn \l_@@_input_range_sign_tl { -- }
+\tl_set:Nn \l_@@_input_fraction_sign_tl { / }
+\tl_set:Nn \l_@@_input_mixed_fraction_sign_tl { _ }
+\tl_set:Nn \l_@@_input_decimal_mark_tl { . , }
+\tl_set:Nn \l_@@_input_value_signs_tl { + - }
+\tl_set:Nn \l_@@_input_allowed_special_signs_tl { ? }
+\tl_set_rescan:Nnn \c_@@_input_str_hash_one_tl
+ { \char_set_catcode_letter:N \# } {#1}
+% \end{macrocode}
+% \begin{macrocode}
+\tl_set:Nn \l_@@_cunum_range_sign_tl { -- }
+\tl_set:Nn \l_@@_cutext_range_sign_tl {}
+\tl_set:Nn \l_@@_value_unit_space_tl { \thinspace }
+\tl_set:Nn \l_@@_cutext_space_tl { \space }
+\tl_set:Nn \l_@@_cuphrase_space_tl { \space }
+\tl_set:Nn \l_@@_unit_letter_not_allowed_tl { , / }
+% \end{macrocode}
+%
+% Flat out stolen from \pkg{siunitx}
+% \begin{macrocode}
+\AtBeginDocument {
+ \cs_if_free:cT { T@TS1 }
+ {
+ \DeclareFontEncoding { TS1 } { } { }
+ \DeclareFontSubstitution { TS1 } { cmr } { m } { n }
+ }
+}
+% \end{macrocode}
+% \begin{macrocode}
+\DeclareTextSymbolDefault \c_@@_minus_tl { TS1 }
+\DeclareTextSymbol \c_@@_minus_tl { TS1 } { 61 }
+\AtBeginDocument {
+ \@ifpackageloaded { fontspec }
+ {
+ \@ifpackageloaded { eulervm }
+ { }
+ {
+ \int_const:Nn \c_@@_minus_int { 8722 }
+ \tl_set:Nn \c_@@_minus_tl
+ { \tex_char:D \c_@@_minus_int }
+ }
+ }
+ { }
+}
+% \end{macrocode}
+%
+% \begin{macro}{ \l_@@_mixed_frac_dim }
+% The dimension between the fraction and the mixed fraction part is
+% stored within this macro. There is no real reason why I have
+% chosen this distance to be 0.1em, I just thought that it looks
+% best. But if someone has some ideas of how large this distance
+% should be I am happy to listen.
+% \begin{macrocode}
+\dim_new:N \l_@@_mixed_frac_dim
+\dim_set:Nn \l_@@_mixed_frac_dim { 0.1 em }
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{ \l_@@_round_precision_int }
+% Stores the round-precision inside.
+% \begin{macrocode}
+\int_new:N \l_@@_round_precision_int
+\int_set:Nn \l_@@_round_precision_int { 2 }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{ \l_@@_print_numerals_below_int }
+% Used if option 'use-numerals' is active. Uses numerals for
+% integers smaller than this number. I learned this number
+% at school.
+% \begin{macrocode}
+\int_new:N \l_@@_print_numerals_below_int
+\int_set:Nn \l_@@_print_numerals_below_int { 13 }
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{ \l_@@_local_number_of_persons_int }
+% Each recipe defined by \cs{culabel} defines a counter to
+% store the number of persons the recipe is for. For calculation
+% the value is retrived and stored inside this temporal counter.
+% \begin{macrocode}
+\int_new:N \l_@@_local_number_of_persons_int
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{ \l_@@_wanted_number_of_persons_int }
+% Not only the number of persons are recipe is for is needed
+% for calculation, but also the number of persons you want
+% the recipe to be. This information is stored here.
+% \begin{macrocode}
+\int_new:N \l_@@_wanted_number_of_persons_int
+\int_set:Nn \l_@@_wanted_number_of_persons_int { 4 }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+\int_new:N \l_@@_phrase_number_tl
+% \end{macrocode}
+%
+%
+% \begin{macro}{ \l_@@_list_of_defined_keys_clist , \g_@@_list_of_defined_units_clist }
+% Sequence of defined units and keys. Units are defined
+% globally as they create new commands, keys do not do that
+% (I think). Could be my mistake.
+% \begin{macrocode}
+\seq_new:N \l_@@_list_of_defined_keys_seq
+\seq_new:N \g_@@_list_of_defined_units_seq
+% \end{macrocode}
+%\end{macro}
+%
+%
+% \begin{macro} { \g_@@_allowed_special_keys_seq }
+% \changes {2016/06/12} {New: \cs{g_@@_allowed_unit_phrases_tl}}
+% Used for the keys 'one(m)', 'one(f)', etc. Those are special keys
+% which cannot be used as units, but are processed by the commands in
+% the language section as such.
+% \begin{macrocode}
+\seq_new:N \g_@@_allowed_special_keys_seq
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro} { \l_@@_phrase_numbers_seq }
+% Inside this list the numbers for which a phrase is defined
+% is stored in. As this is language specific, the list is stored
+% inside a language-sensitive command and retrived when needed.
+% \begin{macrocode}
+\seq_new:N \l_@@_phrase_numbers_seq
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro} { \l_@@_temperatures_to_check_seq }
+% \changes {1.02h} {New.}
+% Stores units which should be tested if \opt{check-temperature} equals true.
+% \begin{macrocode}
+\seq_new:N \l_@@_temperatures_to_check_seq
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro} { \l_@@_curef_do_not_change_seq }
+% This contains the units which shouldn't be changed.
+% \begin{macrocode}
+\seq_new:N \l_@@_curef_do_not_change_seq
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro} { \l_@@_phrase_prop }
+% Stores the number and he respective phrase. For example
+% if \enquote{12} has the phrase \enquote{Dutzend}, this
+% key-value pair is stored inside.
+% \begin{macrocode}
+\prop_new:N \l_@@_phrase_prop
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}
+% {
+% \l_@@_minus_bool,
+% \l_@@_round_number_bool,
+% \l_@@_error_bool,
+% \l_@@_eval_fractions_bool,
+% \l_@@_draft_bool,
+% \l_@@_round_to_int_bool,
+% \l_@@_special_sign_bool,
+% \l_@@_single_key_bool,
+% \l_@@_check_temperature_bool,
+% \l_@@_convert_to_eV_bool,
+% \l_@@_cutext_uppercase_word_bool,
+% \l_@@_error_for_unknown_value_bool,
+% \l_@@_using_cutext_bool,
+% \l_@@_cuam_old_bool,
+% \l_@@_change_number_of_persons_bool,
+% \l_@@_calc_because_ref_was_given_bool,
+% \l_@@_lokal_persons_bool,
+% \l_@@_cutext_to_cunum_bool,
+% \l_@@_cutext_old_bool,
+% \l_@@_cutext_keep_unit_bool,
+% \l_@@_round_commercial_bool,
+% \l_@@_use_phrases_bool,
+% \l_@@_lokal_phrase_bool
+% }
+% Some booleans we need later.
+% \begin{macrocode}
+\bool_new:N \l_@@_minus_bool
+\bool_new:N \l_@@_round_number_bool
+\bool_new:N \l_@@_error_bool
+\bool_new:N \l_@@_eval_fractions_bool
+\bool_new:N \l_@@_draft_bool
+\bool_new:N \l_@@_round_to_int_bool
+\bool_new:N \l_@@_special_sign_bool
+\bool_new:N \l_@@_single_key_bool
+\bool_new:N \l_@@_check_temperature_bool
+\bool_new:N \l_@@_convert_to_eV_bool
+\bool_new:N \l_@@_cutext_uppercase_word_bool
+\bool_new:N \l_@@_error_for_unknown_value_bool
+\bool_new:N \l_@@_using_cutext_bool
+\bool_new:N \l_@@_cuam_old_bool
+\bool_new:N \l_@@_change_number_of_persons_bool
+\bool_new:N \l_@@_calc_because_ref_was_given_bool
+\bool_new:N \l_@@_lokal_persons_bool
+\bool_new:N \l_@@_cutext_to_cunum_bool
+\bool_new:N \l_@@_cutext_old_bool
+\bool_new:N \l_@@_cutext_keep_unit_bool
+\bool_new:N \l_@@_round_commercial_bool
+\bool_new:N \l_@@_use_phrases_bool
+\bool_new:N \l_@@_lokal_phrase_bool
+\bool_new:N \l_@@_print_numeral_bool
+\bool_new:N \l_@@_lokal_numeral_bool
+\bool_new:N \l_@@_round_precision_positive_bool
+\bool_new:N \l_@@_fourty_two_bool
+\bool_new:N \l_@@_phrase_negative_bool
+% \end{macrocode}
+%
+% While rewriting the code I searched for those
+% booleans a lot.
+% \begin{macrocode}
+\bool_new:N \l_@@_range_in_input_bool
+\bool_new:N \l_@@_lokal_fraction_bool
+\bool_new:N \l_@@_print_fraction_bool
+\bool_new:N \l_@@_lokal_mixed_fraction_bool
+\bool_new:N \l_@@_check_decimal_bool
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% Setting some of them to \true\ or another boolean respectively.
+% \begin{macrocode}
+\bool_set_false:N \l_@@_cutext_keep_unit_bool
+\bool_set_eq:NN \l_@@_print_numeral_bool \g_@@_opt_numeral_bool
+% \end{macrocode}
+%
+%
+% \begin{macro}{ \q_@@_range }
+% Replacing the sign \enquote{-{}-} with \lstinline|\q_@@_range| for testing.
+% \begin{macrocode}
+\quark_new:N \q_@@_range
+% \end{macrocode}
+%\end{macro}
+%
+% \begin{macro}{ \q_@@_no_translation }
+% \begin{macrocode}
+\quark_new:N \q_@@_no_translation
+% \end{macrocode}
+%\end{macro}
+%
+% \begin{macro}{ \q_@@_decimal , \q_@@_fraction , \q_@@_mixed_fraction }
+% \begin{macrocode}
+\quark_new:N \q_@@_decimal
+\quark_new:N \q_@@_fraction
+\quark_new:N \q_@@_mixed_fraction
+% \end{macrocode}
+%\end{macro}
+%
+% \begin{macro}{
+% \l_@@_tmpa_fp ,
+% \l_@@_tmpa_clist ,
+% \l_@@_tmpa_prop ,
+% \l_@@_tmpb_prop ,
+% \l_@@_tmpa_seq ,
+% }
+% Some temporal stores which are used throughout the code.
+% \begin{macrocode}
+\fp_new:N \l_@@_tmpa_fp
+\clist_new:N \l_@@_tmpa_clist
+\prop_new:N \l_@@_tmpa_prop
+\prop_new:N \l_@@_tmpb_prop
+\seq_new:N \l_@@_tmpa_seq
+\int_new:N \l_@@_tmpa_int
+\int_new:N \l_@@_tmpb_int
+% \end{macrocode}
+%\end{macro}
+%
+%
+%
+% \subsection {Keys}
+%
+%
+% Let's define some keys.
+% \begin{macrocode}
+\keys_define:nn { cooking-units }
+ {
+% \end{macrocode}
+%
+%
+% \begin{macro}{ add-unit-to-group }
+% \begin{macrocode}
+ add-unit-to-group .code:n =
+ {
+ \keyval_parse:NNn
+ \@@_unit_group_add_unit_error:n
+ \@@_unit_group_add_unit:nn
+ {#1}
+ } ,
+ add-unit-to-group .default:n = {} ,
+% \end{macrocode}
+% \end{macro}
+%
+%\begin{macro}{ set-option-for }
+% Setting options.
+% \begin{macrocode}
+ set-option-for .code:n =
+ {
+ \keyval_parse:NNn
+ \@@_set_options_for_error:n
+ \@@_set_options_for:nn
+ {#1}
+ },
+% \end{macrocode}
+% \end{macro}
+%
+%\begin{macro}{ add-option-for }
+% Setting options.
+% \begin{macrocode}
+ add-option-for .code:n =
+ {
+ \keyval_parse:NNn
+ \@@_add_options_for_error:n
+ \@@_add_options_for:nn
+ {#1}
+ },
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{ erase-all-options }
+% Erasing all preset options.
+% \begin{macrocode}
+ erase-all-options .code:n =
+ {
+ \seq_map_inline:Nn \g_@@_list_of_defined_units_seq
+ {
+ \clist_clear:c { l_@@_predefined_option_ ##1 _clist }
+ }
+ },
+ erase-all-options .value_forbidden:n = { true } ,
+% \end{macrocode}
+% \end{macro}
+%
+%\begin{macro}{ erase-all-options-for }
+% Erasing options.
+% \begin{macrocode}
+ erase-all-options-for .code:n =
+ {
+ \keyval_parse:NNn
+ \@@_erase_options_for:n
+ \@@_erase_options_for_error:nn
+ {#1}
+ },
+ erase-all-options-for .value_required:n = { true } ,
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%
+%
+% \begin{macro}{ cutext-to-cunum }
+% Don't want any \mycs{cutext} (or \mycs{Cutext}) in your
+% document? Use this option!
+% \begin{macrocode}
+ cutext-to-cunum .bool_set:N = \l_@@_cutext_to_cunum_bool ,
+ cutext-to-cunum .default:n = { false } ,
+ cutext-to-cunum .groups:n = { change-command } ,
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{ cutext-change-unit }
+% Do not wanna change units in \mycs{cutext}? Use this option.
+% \begin{macrocode}
+ cutext-change-unit .bool_set_inverse:N = \l_@@_cutext_keep_unit_bool ,
+ cutext-change-unit .default:n = { true } ,
+ cutext-change-unit .groups:n = { change-unit } ,
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{ cuam-version , cutext-version}
+% Some keys with horrible option names. Reverts
+% the respective command back to its older state (pre v1.10).
+% \begin{macrocode}
+ cuam-version .choices:nn =
+ { new , old }
+ {
+ \int_case:nn { \l_keys_choice_int }
+ {
+ { 1 } { \bool_set_false:N \l_@@_cuam_old_bool }
+ { 2 } { \bool_set_true:N \l_@@_cuam_old_bool }
+ }
+ } ,
+ cuam-version .default:n = { new } ,
+ cutext-version .choices:nn =
+ { new , old }
+ {
+ \int_case:nn { \l_keys_choice_int }
+ {
+ { 1 } { \bool_set_false:N \l_@@_cutext_old_bool }
+ { 2 } { \bool_set_true:N \l_@@_cutext_old_bool }
+ }
+ } ,
+ cutext-version .default:n = { new } ,
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{ expand-both , expand-amount, expand-unit }
+% \begin{macrocode}
+ expand-both .choices:nn =
+ { n , o , f , x }
+ {
+ \cs_set_eq:Nc \@@_set_unit:Nn { tl_set:N \l_keys_choice_tl }
+ \cs_set_eq:Nc \@@_set_amount:Nn { tl_set:N \l_keys_choice_tl }
+ } ,
+ expand-both .default:n = { n } ,
+% \end{macrocode}
+% \begin{macrocode}
+ expand-amount .choices:nn =
+ { n , o , f , x }
+ {
+ \cs_set_eq:Nc \@@_set_amount:Nn { tl_set:N \l_keys_choice_tl }
+ } ,
+ expand-amount .default:n = { n } ,
+% \end{macrocode}
+% \begin{macrocode}
+ expand-unit .choices:nn =
+ { n , o , f , x }
+ {
+ \cs_set_eq:Nc \@@_set_unit:Nn { tl_set:N \l_keys_choice_tl }
+ } ,
+ expand-unit .default:n = { n } ,
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%
+%\begin{macro}{ set-special-sign }
+% Doing the same as above but also overrides the old signs.
+% \begin{macrocode}
+ set-special-sign .code:n =
+ {
+ \tl_map_inline:nn {#1}
+ {
+ \str_if_eq:nnT {##1} { < }
+ {
+ \msg_error:nn { cooking-units } { <-not-allowed-as-special-sign }
+ \tl_map_break:n { \use_none:nn }
+ }
+ }
+ \use:n { \tl_set:Nn \l_@@_input_allowed_special_signs_tl {#1} }
+ } ,
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{ add-special-sign }
+% Adding a (some) special sign(s) which is (are) allowed in the input.
+% \begin{macrocode}
+ add-special-sign .code:n =
+ {
+ \tl_map_inline:nn {#1}
+ {
+ \str_if_eq:nnTF {##1} { < }
+ {
+ \msg_error:nn { cooking-units } { <-not-allowed-as-special-sign }
+ }{
+ \tl_put_right:Nn \l_@@_input_allowed_special_signs_tl {##1}
+ }
+ }
+ } ,
+ add-special-sign .default:n = { } ,
+% \end{macrocode}
+%\end{macro}
+%
+%
+% \begin{macro}{ set-unknown-message }
+% Sets the message for a special-sign to error, warning or none.
+% \begin{macrocode}
+ set-unknown-message .choices:nn =
+ { error , warning , none }
+ {
+ \msg_redirect_name:nnn { cooking-units } { amount-not-known }
+ { \l_keys_choice_tl }
+ } ,
+ set-unknown-message .default:n = { warning } ,
+% \end{macrocode}
+%\end{macro}
+%
+% \begin{macro}{ set-unknown-message }
+% Sets the message for a special-sign to error, warning or none.
+% \begin{macrocode}
+ set-cutext-translation-message .choices:nn =
+ { error , warning , none }
+ {
+ \msg_redirect_name:nnn { cooking-units } { cutext-no-translation-available }
+ { \l_keys_choice_tl }
+ } ,
+ set-cutext-translation-message .default:n = { warning } ,
+% \end{macrocode}
+%\end{macro}
+%
+%
+% \begin{macro}{ print-numerals }
+% A not very good name, but I couldn't think of a better name.
+% \begin{macrocode}
+ print-numerals .bool_set:N = \l_@@_print_numeral_bool ,
+ print-numerals .default:n = { true } ,
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{ use-numerals-below }
+% Use numerals if the integer is below the integer set by this option.
+% \begin{macrocode}
+ use-numerals-below .int_set:N = \l_@@_print_numerals_below_int ,
+ use-numerals-below .default:n = { 13 } ,
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{ parse-number }
+% Parse the input? If no the input is printed as is (after some safety parsing).
+% \begin{macrocode}
+ parse-number .bool_set_inverse:N = \l_@@_draft_bool ,
+ parse-number .default:n= { true } ,
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{ range-sign }
+% Setting the printed range sign and make a difference between cunum
+% and c(C)utext.
+% \begin{macrocode}
+ range-sign .meta:n =
+ {
+ cunum-range-sign = {#1} ,
+ cutext-range-sign = {#1}
+ } ,
+ range-sign .default:n = { -- } ,
+ cunum-range-sign .tl_set:N = \l_@@_cunum_range_sign_tl ,
+ cunum-range-sign .default:n = { -- } ,
+ cutext-range-sign .tl_set:N = \l_@@_cutext_range_sign_tl ,
+ cutext-range-sign .default:n = { -- } ,
+% \end{macrocode}
+%\end{macro}
+%
+% \begin{macro}{ use-phrases }
+% Do not wanna use phrases in \mycs{cuam}? Use this option!
+% \begin{macrocode}
+ use-phrases .bool_set:N = \l_@@_use_phrases_bool ,
+ use-phrases .default:n = { true } ,
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%
+%
+%\begin{macro}{ round-precision }
+% Setting the round-precision. Setting those two at once to
+% not calculate it every time.
+% \begin{macrocode}
+ round-precision .code:n =
+ {
+ \int_set:Nn \l_@@_round_precision_int {#1}
+ \int_compare:nNnTF {#1} < { 0 }
+ { \bool_set_false:N \l_@@_round_precision_positive_bool }
+ { \bool_set_true:N \l_@@_round_precision_positive_bool }
+ } ,
+ round-precision .default:n = { 2 } ,
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{ round-to-int }
+% Rounding the results to an integer.
+% \begin{macrocode}
+ round-to-int .bool_set:N = \l_@@_round_to_int_bool ,
+ round-to-int .default:n = { false } ,
+% \end{macrocode}
+%\end{macro}
+%
+% \begin{macro}{ round-half }
+% Choosing between \enquote{normal} rounding to even
+% and commercial rounding and sets the boolean accordingly.
+% \begin{macrocode}
+ round-half .choices:nn =
+ { default , commercial }
+ {
+ \int_case:nn { \l_keys_choice_int }
+ {
+ { 1 } { \bool_set_false:N \l_@@_round_commercial_bool }
+ { 2 } { \bool_set_true:N \l_@@_round_commercial_bool }
+ }
+ },
+ round-half .default:n = { default },
+% \end{macrocode}
+% \end{macro}
+%
+%\begin{macro}{ eval-fraction }
+% If set to true the fractions are evaluated.
+% \begin{macrocode}
+ eval-fraction .bool_set:N = \l_@@_eval_fractions_bool ,
+ eval-fraction .default:n = { false } ,
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{ fraction-command }
+% Setting the fraction command
+% \begin{macrocode}
+ fraction-command .code:n = { \cs_set_eq:NN \@@_frac:nn #1 } ,
+ fraction-command .default:n = { \sfrac } ,
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{ fraction-inline }
+% Setting the code inline.
+% \begin{macrocode}
+ fraction-inline .code:n = { \cs_set:Npn \@@_frac:nn ##1##2 {#1} } ,
+ fraction-inline .default:n = { \sfrac {#1} {#2} } ,
+% \end{macrocode}
+%\end{macro}
+%
+%
+%
+%
+%
+%
+%\begin{macro}{ mixed-fraction-space }
+% Setting the space between the mixed fraction part and the fraction.
+% \begin{macrocode}
+ mixed-fraction-space .dim_set:N = \l_@@_mixed_frac_dim ,
+ mixed-fraction-space .default:n = { 0.1 em } ,
+% \end{macrocode}
+%\end{macro}
+%
+% \begin{macro}{ cutext-space }
+% The space used in \mycs{cutext} between the number (or numeral)
+% and unit.
+% \begin{macrocode}
+ cutext-space .tl_set:N = \l_@@_cutext_space_tl ,
+ cutext-space .default:n = { \space } ,
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{ phrase-space }
+% Same as before, but for phrases
+% \begin{macrocode}
+ phrase-space .tl_set:N = \l_@@_cuphrase_space_tl ,
+ phrase-space .default:n = { \space } ,
+% \end{macrocode}
+% \end{macro}
+%
+%\begin{macro}{ amount-unit-space }
+% Setting the space between the value and the printed unit.
+% \begin{macrocode}
+ amount-unit-space .tl_set:N = \l_@@_value_unit_space_tl ,
+ amount-unit-space .default:n = { \thinspace } ,
+% \end{macrocode}
+%\end{macro}
+%
+%
+%
+%
+%
+%
+% \begin{macro}{ recalculate-amount }
+% Setting the number of persons your recipes should be for
+% is not enough; it is also needed to tell the package to
+% recalculate the amounts.
+% \begin{macrocode}
+ recalculate-amount .bool_set:N = \l_@@_change_number_of_persons_bool ,
+ recalculate-amount .default:n = { false } ,
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{ set-number-of-persons }
+% Setting the number of persons the recipe should be for.
+% \begin{macrocode}
+ set-number-of-persons .int_set:N = \l_@@_wanted_number_of_persons_int ,
+ set-number-of-persons .default:n = { 4 } ,
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{ label }
+% Defines a label \dots\ is \mycs{culabel} as a key.
+% \begin{macrocode}
+ label .code:n = \@@_label_and_persons:n {#1} ,
+ label .value_required:n = { true } ,
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{ get-label }
+% \mycs{curef} as a key.
+% \begin{macrocode}
+ get-label .code:n = \@@_curef:n {#1} ,
+ label .value_required:n = { true } ,
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{ ref }
+% The |<>| option for keys.
+% \begin{macrocode}
+ ref .code:n = \@@_reference_label_and_persons:n {#1} ,
+ ref .value_required:n = { true } ,
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%
+%
+%\begin{macro}{ check-temperature }
+% Weird option. Checking the temperature, if the temperature is below the absolute zero temperature
+% it raises an error.
+% \begin{macrocode}
+ check-temperature .bool_set:N = \l_@@_check_temperature_bool ,
+ check-temperature .default:n = { true } ,
+% \end{macrocode}
+%
+%\begin{macro}{ add-temperature-to-check }
+% Adds a temperature to check for \texttt{check-temperature}.
+% It uses the \cs{keyval\_parse:NNn} command as this
+% macro is used to parse keys (which is what I need).
+% \begin{macrocode}
+ add-temperature-to-check .code:n =
+ {
+ \keyval_parse:NNn
+ \@@_temperature_to_check_print_error:n
+ \@@_temperatures_to_check_define:nn
+ {#1}
+ } ,
+ temperature-to-check .value_required:n = { true } ,
+% \end{macrocode}
+% \end{macro}
+%
+%\begin{macro}{ convert-to-eV }
+% Another weird option, converts pretty much any unit defined by this
+% package to electron volt or the respective derivative.
+% As this is a unit transformation, it needs to be inside the
+% group.
+% \begin{macrocode}
+ convert-to-eV .bool_set:N = \l_@@_convert_to_eV_bool ,
+ convert-to-eV .default:n = { true } ,
+ convert-to-eV .groups:n = { change-unit } ,
+% \end{macrocode}
+%\end{macro}
+%
+% \begin{macro}{ add-natural-unit }
+% \begin{macrocode}
+ add-natural-unit .code:n =
+ {
+ \@@_error_if_unit_not_defined:n {#1}
+ \seq_set_from_clist:Nn \l_@@_tmpa_seq {#1}
+ \seq_concat:NNN \g_@@_natural_units_seq \g_@@_natural_units_seq \l_@@_tmpa_seq
+ \seq_remove_duplicates:N \g_@@_natural_units_seq
+ } ,
+ add-natural-unit .value_required:n = { true } ,
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{ 42 }
+% \begin{macrocode}
+ 42 .choice: ,
+ 42 / true .code:n = { \bool_set_true:N \l_@@_fourty_two_bool } ,
+ 42 / false .code:n = { \msg_fatal:nnn { cooking-units } { 42-is-...-wrong? } } ,
+ 42 .default:n = { true } ,
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%
+%
+%
+%
+%
+%
+%
+%
+%
+%
+%
+%
+%
+%
+%
+% \begin{macro}{ input-range-sign }
+% Don't wanna use \verb|--| as a range sperator in \mycs{cunum}?
+% Use this option.
+% \begin{macrocode}
+ input-range-sign .tl_set:N = \l_@@_input_range_sign_tl ,
+ input-range-sign .default:n = { -- } ,
+% \end{macrocode}
+%\end{macro}
+%
+% \begin{macro}{ numeral-function , Numeral-function }
+% \begin{macrocode}
+ numeral-function .code:n = { \cs_set_eq:NN \@@_print_numeral:n #1 } ,
+ Numeral-function .code:n = { \cs_set_eq:NN \@@_print_Numeral:n #1 } ,
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+% \begin{macro}{hooks}
+% \begin{macrocode}
+ commands-add-hook .meta:n =
+ {
+ cunum-add-hook = {#1} ,
+ cutext-add-hook = {#1} ,
+ Cutext-add-hook = {#1} ,
+ cuam-add-hook = {#1} ,
+ } ,
+ cunum-add-hook .code:n = { \tl_put_right:Nn \l_@@_cunum_hook_tl {#1} } ,
+ cutext-add-hook .code:n = { \tl_put_right:Nn \l_@@_cutext_hook_tl {#1} } ,
+ Cutext-add-hook .code:n = { \tl_put_right:Nn \l_@@_Cutext_hook_tl {#1} } ,
+ cuam-add-hook .code:n = { \tl_put_right:Nn \l_@@_cuam_hook_tl {#1} } ,
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%
+%
+%
+%
+%
+%
+%
+%
+%
+%
+%
+%
+%
+% \begin{macro}{curef-add-forbidden-unit, curef-remove-forbidden-unit, curef-clear-forbidden-units}
+% \begin{macrocode}
+ curef-add-forbidden-unit .code:n =
+ {
+ \seq_set_from_clist:Nn \l_@@_tmpa_seq {#1}
+ \seq_map_inline:Nn \l_@@_tmpa_seq
+ {
+ \seq_if_in:NnF \l_@@_curef_do_not_change_seq {##1}
+ { \seq_put_right:Nn \l_@@_curef_do_not_change_seq {##1} }
+ }
+ } ,
+ curef-add-forbidden-unit .default:n = { } ,
+ curef-remove-forbidden-unit .code:n =
+ {
+ \seq_set_from_clist:Nn \l_@@_tmpa_seq {#1}
+ \seq_map_inline:Nn \l_@@_tmpa_seq
+ {
+ \seq_if_in:NnTF \l_@@_curef_do_not_change_seq {##1}
+ { \seq_remove_all:Nn \l_@@_curef_do_not_change_seq {##1} }
+ {
+ \msg_warning:nnn { cooking-units } { curef-not-inside-list } {##1}
+ { \seq_use:Nnnn \l_@@_curef_do_not_change_seq { ',~ ' } { ',~ ' } { ' ~ and ~ ' } }
+ }
+ }
+ } ,
+ curef-remove-forbidden-unit .default:n = { } ,
+ curef-clear-forbidden-units .choice: ,
+ curef-clear-forbidden-units/true .code:n = { \seq_clear:N \l_@@_curef_do_not_change_seq } ,
+ curef-clear-forbidden-units/false .code:n = { } ,
+ curef-clear-forbidden-units .value_required:n = true,
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%
+%
+%
+%
+%
+%
+% Ending the definition of keys.
+% \begin{macrocode}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%
+%
+% \subsection {Messages}
+%
+% Defining messages.
+%
+% \begin{macro} {Messages}
+% I do not allow fractions and ranges in the same input. Maybe I will
+% change this.
+% \begin{macrocode}
+\msg_new:nnnn { cooking-units } { fraction-not-allowed-with-range }
+ {
+ You \ cannot \ use \ '/' \ ( and \ '_' )\ in \ combination \
+ with \ '\l_@@_input_range_sign_tl' \ in \ '#1'.
+ }{
+ You \ cannot \ use \ fractions \ with \ a \ range.
+ \msg_see_documentation_text:n { cooking-units }
+ }
+% \end{macrocode}
+%
+% Do not allow a \_ without a /.
+% \begin{macrocode}
+\msg_new:nnnn { cooking-units } { missing-slash }
+ {
+ You \ cannot \ use \ '_' \ without \
+ '/' \ in \ '#1'.
+ }{
+ You \ cannot \ have \ a \ mixed \ fraction \ ('_') \ without \
+ a \ normal \ fraction \ ('/').
+ \msg_see_documentation_text:n { cooking-units }
+ }
+\msg_new:nnnn { cooking-units } { fraction-wrong-order }
+ {
+ You \ cannot \ use \ '/' \ before \ '_' \ in \ '#1'.
+ }{
+ You \ can \ only \ use \ '_' \ before \ '/'.
+ \msg_see_documentation_text:n { cooking-units }
+ }
+% \end{macrocode}
+% Error message if unit is not known to this package.
+% \begin{macrocode}
+\msg_new:nnnn { cooking-units } { unknown-unit }
+ {
+ The \ unit \ '#1' \ is \ not \ defined. \ Use \
+ \newcookingunit ~ (or \ one \ of \ the \ others) \ to \
+ define \ new \ units.
+ }{
+ Define \ units \ before \ using \ or \ check \ if \ the \
+ unit-key \ is \ written \ correctly.
+ \msg_see_documentation_text:n { cooking-units }
+ }
+% \end{macrocode}
+% Error if unit is already defined.
+% \begin{macrocode}
+\msg_new:nnnn { cooking-units } { unit-already-defined }
+ { The\ unit \ '#1' \ is \ already \ defined. }
+ {
+ The \ unit-key \ is \ already \ defined. \ Please \ use \ a \ different \
+ key \ for \ a \ new \ unit.
+ \msg_see_documentation_text:n {cooking-units}
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\msg_new:nnnn { cooking-units } { character-not-allowed }
+ {
+ Unit-keys \ are \ not \ allowed \ to \ either \ contain \ ',' \ or \ '/' \
+ in \ '#1'.
+ }{
+ The \ unit-key \ is \ not \ allowed \ to \ contain \ ',' \ or \ '/'. \
+ Due \ to \ internal \ reasons.
+ \msg_see_documentation_text:n {cooking-units}
+ }
+% \end{macrocode}
+%
+% Missing argument in \lstinline|\cudefinesymbols| (et all).
+% \begin{macrocode}
+\msg_new:nnnn { cooking-units } { missing-argument }
+ { There \ is \ a \ missing \ argument. }
+ {
+ You \ probably \ have \ forgotten \ a \ curly-brace \ pair.
+ \msg_see_documentation_text:n {cooking-units}
+ }
+% \end{macrocode}
+% If fractions are evaluated division by zero is not allowed.
+% \begin{macrocode}
+\msg_new:nnnn { cooking-units } { Division-by-zero }
+ { Division\ by \ zero \ is \ not \ allowed \ in \ '#1'. }
+ { See \ a \ math \ book \ of \ your \ choice \ or \ for \ example \ Wikipedia. }
+% \end{macrocode}
+% Showing the not allowed token in the input. Hope this helps.
+% \begin{macrocode}
+\msg_new:nnnn { cooking-units } { Token-not-allowed }
+ { The \ token \ '#1' \ is \ not \ allowed \ in \ '#2'. }
+ {
+ The \ command \ accepts \ only \ a \ fixed \ number \ of \ tokens.
+ \msg_see_documentation_text:n {cooking-units}
+ }
+% \end{macrocode}
+% A second decimal sign is not allowed (No na net).
+% \begin{macrocode}
+\msg_new:nnnn { cooking-units } { Second-decimal-sign-not-allowed }
+ { A \ second \ decimal \ sign \ is \ not \ allowed \ in \ '#1'. }
+ {
+ Perhaps \ you \ didn't \ type \ it \ correctly.
+ \msg_see_documentation_text:n {cooking-units}
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\msg_new:nnnn { cooking-units } { Second-fraction-sign-not-allowed }
+ { A \ second \ fraction \ sign \ is \ not \ allowed \ in \ '#1'. }
+ {
+ Perhaps \ you \ didn't \ type \ it \ correctly.
+ \msg_see_documentation_text:n {cooking-units}
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\msg_new:nnnn { cooking-units } { Second-mixed-fraction-sign-not-allowed }
+ { A \ second \ mixed \ fraction \ sign \ is \ not \ allowed \ in \ '#1'. }
+ {
+ Perhaps \ you \ didn't \ type \ it \ correctly.
+ \msg_see_documentation_text:n {cooking-units}
+ }
+% \end{macrocode}
+% Error message for an undefined key.
+% \begin{macrocode}
+\msg_new:nnnn { cooking-units } { Key-not-defined }
+ {
+ The \ key \ '#1' \ is \ not \ defined. \ Use \ \cudefinekeys ~ or \
+ \cudefinesinglekey ~ to \ define \ keys.
+ }
+ {
+ This \ key \ is \ not \ defined, \ perhaps \ you \ misspelled \ it.
+ \msg_see_documentation_text:n {cooking-units}
+ }
+% \end{macrocode}
+%
+% If the temperature is too low print this error message.
+% Now prints all units for which a zero-point is defined.
+% \begin{macrocode}
+\msg_new:nnnn { cooking-units } { Temperature-too-low }
+ {
+ The \ temperature \ '#1' \ is \ too \ low.\ It \ cannot \ be \
+ below \ the \ absolute \ zero - point \ of \ '#2'. \ Note \ that \
+ the \ temperatures \
+ '\seq_use:Nnnn \l_@@_temperatures_to_check_seq
+ { ', ~ ' } { ', ~ ' } { ' ~ and ~ ' }' \
+ are \ rounded \ to \ integers \ by \ default.
+ \\\\
+ You \ can \ disable \ the \ option \ 'check-temperature' \ to \
+ disable \ this \ error.
+ }
+ { See \ for \ example \ Wikipedia. }
+% \end{macrocode}
+% If for an unit-key the value is wrong the following error message is shown.
+% \begin{macrocode}
+\msg_new:nnnn { cooking-units } { key-choice-unknown }
+ {
+ The \ key \ '#1' \ only \ accepts \ only \
+ '#3' \ as \ a \ set \ of \ choices \ and \ '#2' \ is \ non \ of \ these.
+ }{
+ The \ key \ accepts \ only \ a \ fixed \ set \ of \ choices. \
+ You \ can \ add \ new \ choices \ via \ \cuaddkeys, ~ \cuaddsinglekeys ~
+ and \ \cuaddtokeys.
+ \msg_see_documentation_text:n {cooking-units}
+ }
+% \end{macrocode}
+% Adding a message for unit-groups.
+% \begin{macrocode}
+\msg_new:nnnn { cooking-units } { group-choice-not-allowed }
+ {
+ The \ group \ key \ '#1' \ accepts \ only \
+ '#3' \ as \ a \ set \ of \ choices \ and \ '#2' \ is \ non \ of \ these.
+ }{
+ The \ key \ accepts\ only \ a \ fixed \ set \ of \ choices. \
+ You \ can \ add \ new \ choices \ via \ option \ 'add-unit-to-group'.
+ \msg_see_documentation_text:n {cooking-units}
+ }
+% \end{macrocode}
+%
+%\changes {v0.98a} {2016/06/11} {New option: 'value-not-known'.}
+%\changes {v0.99} {2016/06/12} {Renamed option: 'amount-not-known'.}
+% An info message for unknown messages.
+% \begin{macrocode}
+\msg_new:nnnn { cooking-units } { amount-not-known }
+ {
+ The \ amount \ '#1' \ is \ not \ known \ at \ line \
+ \msg_line_number: .
+ }
+ {
+ You \ used\ a\ special\ sign\ indicating\ that\ the\ true\ amount\ of\ the\
+ specific\ ingredient\ is\ (was) \ not\ known\ to\ you. This\ message\
+ reminds\ you\ about\ that\ fact.
+ \msg_see_documentation_text:n {cooking-units}
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\msg_new:nnnn { cooking-units } { group-key-unknown }
+ {
+ The \ group \ key \ '#1' \ is \ not \ defined. \ Perhaps
+ \ you \ misspelled \ it?
+ }{
+ The \ group \ key \ is \ not \ defined.
+ \msg_see_documentation_text:n { cooking-units }
+ }
+% \end{macrocode}
+%
+% If a load time option is not used as a package option, this
+% message is shown.
+% \begin{macrocode}
+\msg_new:nnnn { cooking-units } { load-time-option }
+ {
+ The \ option \ '#1' \ is \ only \ available \ as \ a \ load-time-option. \
+ Please \ set \ it \ as \ a \ package \ option.
+ }
+ {
+ You \ cannot \ set \ this \ option \ using \ \cusetup ~
+ but \ only \ as \ a \ package \ option.
+ \msg_see_documentation_text:n { cooking-units }
+ }
+% \end{macrocode}
+%
+% Messages for obsolete commands.
+% \begin{macrocode}
+\msg_new:nnnn { cooking-units } { obsolete-command }
+ {
+ Command \ #1 is \ obsolete. \ Please \ use \ #2 instead.
+ }{
+ Don't \ use \ this \ old \ command \ ...
+ \msg_see_documentation_text:n { cooking-units }
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\msg_new:nnnn { cooking-units } { No-Value-given }
+ {
+ Please \ input \ a \ value \ for \ the \ key-value \ list \ in \ '#1'
+ }
+ {
+ Each \ element \ of \ the \ list \ needs \ a \ value.
+ \msg_see_documentation_text:n { cooking-units }
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\msg_new:nnnn { cooking-units } { Value-not-allowed }
+ {
+ The \ key-list \ in \ '#1' \ does \ not \ take \ a \ value.
+ }
+ {
+ This \ key-list \ does \ not \ take \ a \ value. \ The \
+ given \ value \ will \ be \ ignored.
+ \msg_see_documentation_text:n { cooking-units }
+ }
+% \end{macrocode}
+%
+% Error message if a zero-point temperature is already defined.
+% \begin{macrocode}
+\msg_new:nnnn { cooking-units } { Minimum-already-defined }
+ {
+ A \ minimum \ for \ '#1' \ has \ already \ been \ defined.
+ }{
+ You \ cannot \ redefine \ it.
+ \msg_see_documentation_text:n { cooking-units }
+ }
+% \end{macrocode}
+%
+% Using the key version of \mycs{culabel} one needs to give the number of
+% people the recipe is for after a \enquote{*}.
+% \begin{macrocode}
+\msg_new:nnnn { cooking-units } { Number-of-persons-missing }
+ {
+ Please \ add \ the \ number \ of \ persons \ this \ recipe \ is \ for \ in \ '#1'. \
+ Note \ that\ the \ number \ must \ be \ given \ after \ a \ '*'.
+ }
+ {
+ Write \ 'Schweinsbraten*4' \ to \ create \ the \ label \ 'Schweinsbraten' \
+ which \ is \ initially \ for \ 4 \ persons.
+ \msg_see_documentation_text:n { cooking-units }
+ }
+% \end{macrocode}
+%
+% The number of persons, must be an integer \dots\
+% \begin{macrocode}
+\msg_new:nnnn { cooking-units } { Number-of-persons-is-not-an-integer }
+ {
+ The \ number \ of \ persons \ the \ recipe \ is \ for \ must \ be \ an \
+ integer. \ '#1' \ is \ not \ allowed.
+ }
+ {
+ The \ number \ '#1' \ is \ not \ allowed.
+ \msg_see_documentation_text:n { cooking-units }
+ }
+% \end{macrocode}
+%
+% Each label defined by \mycs{culabel} needs to be new.
+% \begin{macrocode}
+\msg_new:nnnn { cooking-units } { label-already-defined }
+ {
+ The \ label \ '#1' \ has \ already \ been \ defined.
+ }{
+ Each \ label \ must \ be \ unique.
+ \msg_see_documentation_text:n { cooking-units }
+ }
+% \end{macrocode}
+%
+% Message if a label is not defined.
+% \begin{macrocode}
+\msg_new:nnnn { cooking-units } { label-not-defined }
+ {
+ The \ label \ '#1' \ is \ not \ defined. \ Please \ note \ that \ a \ label
+ \ has \ to \ defined \ before \ it \ is \ referenced.
+ }{
+ Define \ the \ label \ before \ using \ it.
+ \msg_see_documentation_text:n { cooking-units }
+ }
+% \end{macrocode}
+%
+% If an unit is already defined and redefined by an \mycs{declarecookingunit}.
+% \begin{macrocode}
+\msg_new:nnnn { cooking-units } { redefine-unit }
+ {
+ The \ unit \ '#1' \ is \ redefined \ by \ \declarecookingunit ~ at \
+ \msg_line_context: .
+ }{
+ \msg_see_documentation_text:n { cooking-units }
+ }
+% \end{macrocode}
+%
+% A \enquote{phrase} must be an integer.
+% \begin{macrocode}
+\msg_new:nnnn { cooking-units } { phrase-unit-not-an-integer }
+ {
+ A \ phrase \ must \ be \ an \ integer, \ '#1' \ is \ not \ allowed.
+ }{
+ You \ can \ only \ use \ integers.
+ \msg_see_documentation_text:n { cooking-units }
+ }
+% \end{macrocode}
+%
+% A translation for \cs{cutext} or \cs{Cutext} is not available. For this case
+% -- instead of printing the key-name (see \pkg{translations}) -- we fall back
+% to \cs{cunum}.
+% \begin{macrocode}
+\msg_new:nnnn { cooking-units } { cutext-no-translation-available }
+ {
+ For \ the \ unit \ '#1' \ there \ exists \ no \ translation \ to \ be \ used \
+ for \ \cutext ~ and \ \Cutext. \
+ You \ can \ define \ new \ translations \ for \ a \ given \ language \ using \
+ \cudefinename.
+ }
+ {
+ \cunum ~ is \ used \ instead.
+ \msg_see_documentation_text:n { cooking-units }
+ }
+% \end{macrocode}
+%
+%
+% \begin{macrocode}
+\msg_new:nnnn { cooking-units } { Translation-not-available }
+ {
+ The \ translation \ for \ #1 \ does \ not \ exist.
+ Please \ define \ it \ using \ \cudefinename.
+ }
+ {
+ And \ you \ may \ send \ me \ the \ translation \ as \ it \ is \
+ not \ available \ yet.
+ \msg_see_documentation_text:n { cooking-units }
+ }
+% \end{macrocode}
+%
+%
+% \begin{macrocode}
+\msg_new:nnnn { cooking-units } { <-not-allowed-as-special-sign }
+ {
+ Currently \ (and \ probably \ forever) \ the \ sign \ '<' \
+ is \ not \ allowed \ to \ be \ used \ as \ a \ special \ sign.
+ }
+ {
+ I \ apologize \ for \ the \ inconvenience.
+ \msg_see_documentation_text:n { cooking-units }
+ }
+% \end{macrocode}
+%
+%
+% \begin{macrocode}
+\msg_new:nnnn { cooking-units } { unknown-gender }
+ {
+ '#1' \ is \ not \ allowed \ to \ be \ used \ as \ a \ gender-specification.
+ Only \ 'm', \ 'f' \ or \ 'n' \ are \ allowed.
+ }{
+ Please \ remove \ spaces \ if \ there \ are \ some.
+ \msg_see_documentation_text:n { cooking-units }
+ }
+% \end{macrocode}
+%
+%
+% \begin{macrocode}
+\msg_new:nnnn { cooking-units } { curef-not-inside-list }
+ {
+ '#1' \ cannot \ be \ removed \ from \ the \ 'forbidden \ unit' \ list \ because
+ \ it \ is \ not \ inside \ the \ list.
+ }{
+ Currently \ the \ list\ contains \ '#2'.
+ \msg_see_documentation_text:n { cooking-units }
+ }
+% \end{macrocode}
+%
+%
+% \begin{macrocode}
+\msg_new:nnnn { cooking-units } { curef-forbidden-unit }
+ {
+ The \ amount \ of \ '#1' \ cannot \ be \ changed \ using \ cooking-units` \ label \ \& \ ref \ feature.
+ }{
+ You \ can \ remove \ the \ unit \ using \ 'curef-remove-forbidden-unit'.
+ \msg_see_documentation_text:n { cooking-units }
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\msg_new:nnnn { cooking-units } { 42-is-...-wrong? }
+ {
+ You \ requested \ to \ set \ 42 \ to \ 'false'. \ This \ doesn't \ make
+ \ any \ sense! \ It \ cannot \ be \ 'false', \ it \ is \ the \ answer \ to \ the
+ \ question \ of \ life, \ universe \ and \ everything. \ For \ the \ sake \ of \
+ the \ world \ I \ cannot \ allow \ you \ to \ set \ it \ to \ 'false', \ the \ universe
+ \ might \ explode \ otherwise. \\
+ The \ run \ will \ be \ aborted.
+ }{
+ Phew ... \ this \ might \ have \ ended \ disastrous.
+ \msg_see_documentation_text:n { cooking-units }
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\msg_new:nnnn { cooking-units } { internal-error }
+ {
+ This \ error \ shouldn't \ show. \ This \ means \ I
+ \ (the \ package \ author) \ screwed
+ \ up.
+ }{
+ Please \ send \ me \ a \ bug \ report.
+ \msg_see_documentation_text:n { cooking-units }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \section {Helper Macros}
+%
+% The name says it all.
+%
+%\begin{macro}
+% {
+% \@@_error_if_unit_not_defined:n,
+% \@@_error_if_unit_not_defined:V,
+% }
+% A little helper macro. Checks if the unit is defined, if not raise an error.
+% \begin{macrocode}
+\cs_new:Npn \@@_error_if_unit_not_defined:n #1
+ {
+ \seq_if_in:NnF \g_@@_list_of_defined_units_seq {#1}
+ { \msg_error:nnn { cooking-units } { unknown-unit } {#1} }
+ }
+\cs_generate_variant:Nn \@@_error_if_unit_not_defined:n { V }
+% \end{macrocode}
+%\end{macro}
+%
+%
+%
+%
+%
+%
+% \begin{macro}{ \@@_if_integer:n }
+% Checking if the input consists only of numbers.
+% \begin{macrocode}
+\prg_new_protected_conditional:Npnn \@@_if_integer:n #1 { TF , F }
+ {
+ \tl_map_inline:nn {#1}
+ {
+ \tl_if_in:NnF \l_@@_input_digits_tl {##1}
+ {
+ \tl_map_break:n { \use_iii:nnn }
+ }
+ }
+ \use_i:nn \prg_return_true: \prg_return_false:
+ }
+\cs_generate_variant:Nn \@@_if_integer:nTF { V }
+\cs_generate_variant:Nn \@@_if_integer:nF { V }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{ \@@_if_integer:n }
+% Checking if the input consists only of numbers.
+% \begin{macrocode}
+\cs_new:Npn \@@_bool_set_if_integers:NNN #1#2#3
+ {
+ \@@_if_integer:VTF #2
+ { \bool_set_true:N #1 }
+ { \bool_set_false:N #1 }
+ \bool_lazy_and:nnT
+ { \l_@@_range_in_input_bool } {#1}
+ {
+ \@@_if_integer:VF #3
+ { \bool_set_false:N #1 }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \begin{macro}[TF]{ \@@_fp_if_equal_one:n}
+% \begin{macro}[TF]{ \@@_int_if_equal_one:n}f
+% \begin{macrocode}
+\prg_new_conditional:Npnn \@@_fp_if_equal_one:n #1 { TF }
+ {
+ \fp_compare:nNnTF {#1} = { 1.0 }
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+\prg_new_conditional:Npnn \@@_int_if_equal_one:n #1 { TF }
+ {
+ \int_compare:nNnTF {#1} = { 1 }
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+% \end{macrocode}
+% \end{macro} \end{macro}
+%
+%
+%
+% \begin{macro}{}
+% \begin{macrocode}
+\prg_new_conditional:Npnn \@@_change_cutext_to_cunum:n #1 { TF }
+ {
+ \keys_set_groups:nnn { cooking-units } { change-command } {#1}
+ \bool_if:NTF \l_@@_cutext_to_cunum_bool
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{ \@@_check_if_correct_gender_input:n }
+% \begin{macrocode}
+\cs_new:Npn \@@_check_if_correct_gender_input:n #1
+ {
+ \str_case:nnF {#1}
+ {
+ { m } { }
+ { f } { }
+ { n } { }
+ } { \msg_error:nnn { cooking-units } { unknown-gender } {#1} }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_define_unit_group:nn}
+% \begin{macrocode}
+\cs_new:Npn \@@_define_unit_group:nn #1#2
+ {
+ \seq_new:c { l_@@_group_ #1 _seq }
+ \seq_set_from_clist:cn { l_@@_group_ #1 _seq } {#2}
+ \keys_define:nn { cooking-units }
+ {
+ #1 .code:n = { \@@_unit_group_convert_units:nn {#1} {##1} } ,
+ #1 .groups:n = { change-unit } ,
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_error_if_group_not_defined:n}
+% \begin{macrocode}
+\cs_new:Npn \@@_error_if_group_not_defined:n #1
+ {
+ \seq_if_exist:cF { l_@@_group_ #1 _seq }
+ { \msg_error:nn { cooking-units} { group-key-unknown } }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_unit_group_convert_units:nn}
+% \begin{macrocode}
+\cs_new:Npn \@@_unit_group_convert_units:nn #1#2
+ {
+ \@@_error_if_group_not_defined:n {#1}
+ \@@_error_if_unit_not_defined:n {#2}
+ \seq_if_in:cnTF { l_@@_group_ #1 _seq } {#2}
+ {
+ \seq_map_inline:cn { l_@@_group_ #1 _seq }
+ { \@@_keys_set:nnn { cooking-units } {##1} {#2} }
+ }{
+ \msg_error:nnxxx
+ { cooking-units }
+ { group-choice-not-allowed }
+ {#1}
+ {#2}
+ { \seq_use:cnnn { l_@@_group_ #1 _seq } { ',~ ' } { ',~ ' } { ' ~ and ~ ' } }
+ }
+ }
+\@@_define_unit_group:nn { weight } { kg , dag, g, oz, lb, stick }
+\@@_define_unit_group:nn { length } { m , dm , cm , mm , in }
+\@@_define_unit_group:nn { volume } { l , dl , cl , ml }
+\@@_define_unit_group:nn { temperature } { C , F , K , Re }
+\@@_define_unit_group:nn { energy } { cal, kcal , J , kJ , eV }
+\@@_define_unit_group:nn { time } { d , h , min , s }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_unit_group_add_unit_error:n , \@@_unit_group_add_unit:nn }
+% \begin{macrocode}
+\cs_new:Npn \@@_unit_group_add_unit_error:n #1
+ {
+ \msg_error:nnn { cooking-units } { No-Value-given } { add-unit-to-group }
+ }
+\cs_new:Npn \@@_unit_group_add_unit:nn #1#2
+ {
+ \@@_error_if_group_not_defined:n {#1}
+ \clist_map_inline:nn {#2}
+ {
+ \@@_error_if_unit_not_defined:n {##1}
+ \seq_if_in:cnF { l_@@_group_ #1 _seq } {##1}
+ { \seq_put_right:cn { l_@@_group_ #1 _seq } {##1} }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_convert_to_eV:}
+% Still work in progress. Will probably forever be. Changes all
+% predefined units into natural units (except for those who cannot
+% be changed, like |Msp.| for example).
+%
+% \begin{macrocode}
+\seq_new:N \g_@@_natural_units_seq
+\prop_new:N \g_@@_convert_to_eV_remember_prop
+\seq_set_from_clist:Nn \g_@@_natural_units_seq
+ {
+ eV ,
+ eVc-2 ,
+ hbareV-1 ,
+ chbareV-1 ,
+ (chbareV-1)3 ,
+ }
+\cs_new:Npn \@@_keys_set:nnn #1#2#3
+ {
+ \keys_set:nn {#1} { #2 = #3 }
+ }
+\cs_generate_variant:Nn \@@_keys_set:nnn { nVV , nVn }
+\cs_new:Npn \@@_convert_to_eV:
+ {
+ \prop_if_exist:cT { l_@@_cukeys_ \l_@@_given_unit_tl _prop }
+ {
+ \prop_get:NVNTF \g_@@_convert_to_eV_remember_prop
+ \l_@@_given_unit_tl \l_@@_tmpa_tl
+ {
+ \@@_keys_set:nVV { cooking-units } \l_@@_given_unit_tl \l_@@_tmpa_tl
+ }{
+ \prop_get:cnNT { l_@@_cukeys_ \l_@@_given_unit_tl _prop } { Liste } \l_@@_tmpa_seq
+ {
+ \seq_map_inline:Nn \g_@@_natural_units_seq
+ {
+ \seq_if_in:NnT \l_@@_tmpa_seq {##1}
+ {
+ \prop_gput:NVn \g_@@_convert_to_eV_remember_prop
+ \l_@@_given_unit_tl {##1}
+ \@@_keys_set:nVn { cooking-units } \l_@@_given_unit_tl {##1}
+ \seq_map_break:
+ }
+ }
+ }
+ }
+ }
+ }
+% \end{macrocode}
+%\end{macro}
+%
+%
+%
+%
+% \begin{macro}{\@@_tl_eval:Nn}
+% I am using this construction often enough, so \dots\ yeah.
+% \begin{macrocode}
+\cs_new:Npn \@@_tl_eval:Nn #1#2 { \tl_set:Nf #1 { \fp_eval:n {#2} } }
+\cs_generate_variant:Nn \@@_tl_eval:Nn { Nv }
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \begin{macro}{ }
+% I am using this construction often enough, so \dots\ yeah.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \@@_change_unit: { TF }
+ {
+ \bool_lazy_any:nTF
+ {
+ { \l_@@_lokal_fraction_bool }
+ { \l_@@_special_sign_bool }
+ { \l_@@_draft_bool }
+ }
+ { \prg_return_false: }
+ { \prg_return_true: }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\@@_temperature_to_check_print_error:n,\@@_temperatures_to_check_define:nn}
+% Commands used in the option \texttt{temperature-to-check}.
+% If no value is given (first command) it raises an error. If a value
+% is given the unit is added to a check-list and a new
+% constant is defined.
+% \begin{macrocode}
+\cs_new:Npn \@@_temperature_to_check_print_error:n #1
+ {
+ \@@_error_if_unit_not_defined:n {#1}
+ \msg_error:nnn { cooking-units } { No-Value-given } { add-temperature-to-check }
+ }
+\cs_new:Npn \@@_temperatures_to_check_define:nn #1#2
+ {
+ \@@_error_if_unit_not_defined:n {#1}
+ \fp_if_exist:cTF { c_@@_ #1 _min_fp }
+ { \msg_warning:nnn { cooking-units } { Minimum-already-defined } {#1} }
+ {
+ \seq_put_right:Nn \l_@@_temperatures_to_check_seq {#1}
+ \fp_const:cn { c_@@_ #1 _min_fp } {#2}
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{ \@@_erase_options_for:n , \@@_erase_options_for_error:nn }
+% \begin{macrocode}
+\cs_new:Npn \@@_erase_options_for:n #1
+ {
+ \@@_error_if_unit_not_defined:n {#1}
+ \clist_clear:c { l_@@_predefined_option_ ##1 _clist }
+ }
+\cs_new:Npn \@@_erase_options_for_error:nn #1#2
+ {
+ \@@_error_if_unit_not_defined:n {#1}
+ \msg_error:nnn { cooking-units } { Value-not-allowed } { erase-all-options-for }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{ \@@_set_options_for_error:n , \@@_set_options_for:nn }
+% \begin{macrocode}
+\cs_new:Npn \@@_set_options_for_error:n #1
+ {
+ \@@_error_if_unit_not_defined:n {#1}
+ \msg_error:nnn { cooking-units } { No-Value-given } { set-option-for }
+ }
+\cs_new:Npn \@@_set_options_for:nn #1#2
+ {
+ \@@_error_if_unit_not_defined:n {#1}
+ \clist_set:cn { l_@@_predefined_option_#1_clist } {#2}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{ \@@_add_options_for_error:n , \@@_add_options_for:nn }
+% \begin{macrocode}
+\cs_new:Npn \@@_add_options_for_error:n #1
+ {
+ \@@_error_if_unit_not_defined:n {#1}
+ \msg_error:nnn { cooking-units } { No-Value-given } { add-option-for }
+ }
+\cs_new:Npn \@@_add_options_for:nn #1#2
+ {
+ \@@_error_if_unit_not_defined:n {#1}
+ \clist_put_right:cn { l_@@_predefined_option_ #1 _clist } {#2}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_rounding_function:n}
+% I think this definition is somewhat stupid, but I don't have a better idea.
+% \begin{macrocode}
+\cs_new:Npn \@@_rounding_function:n #1
+ {
+ #1
+ \bool_if:NTF \l_@@_round_to_int_bool
+ { , 0 }
+ { , \l_@@_round_precision_int }
+ \bool_if:NT \l_@@_round_commercial_bool
+ { , #1 }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_label_and_persons:n}
+% \begin{macrocode}
+\cs_new:Npn \@@_label_and_persons:n #1
+ {
+ \tl_if_in:nnTF {#1} { * }
+ {
+ \@@_label_and_persons_times_persons:ww #1 \q_stop
+ }{
+ \msg_error:nnn { cooking-units} { Number-of-persons-missing } {#1}
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+\cs_new:Npn \@@_label_and_persons_times_persons:ww #1 * #2 \q_stop
+ {
+ \@@_culabel:nn {#1} {#2}
+ }
+% \end{macrocode}
+%
+% \begin{macro}{ \@@_culabel:nn }
+% \begin{macrocode}
+\cs_new:Npn \@@_culabel:nn #1#2
+ {
+ \int_if_exist:cTF { g_@@_number_of_persons_ #1 _int }
+ {
+ \msg_error:nnn { cooking-units } { label-already-defined } {#1}
+ }{
+ \@@_if_integer:nTF {#2}
+ {
+ \int_new:c { g_@@_number_of_persons_ #1 _int }
+ \int_gset:cn { g_@@_number_of_persons_ #1 _int } {#2}
+ }
+ { \msg_error:nnn { cooking-units } { Number-of-persons-is-not-an-integer } {#2} }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{ \@@_reference_label_and_persons:n }
+% \begin{macrocode}
+\cs_new:Npn \@@_reference_label_and_persons:n #1
+ {
+ \int_if_exist:cTF { g_@@_number_of_persons_ #1 _int }
+ {
+ \bool_set_true:N \l_@@_calc_because_ref_was_given_bool
+ \int_set_eq:Nc \l_@@_local_number_of_persons_int
+ { g_@@_number_of_persons_ #1 _int }
+ }
+ { \msg_error:nnn { cooking-units } { label-not-defined } {#1} }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{ \@@_curef:n }
+% \begin{macrocode}
+\cs_new:Npn \@@_curef:n #1
+ {
+ \int_if_exist:cTF { g_@@_number_of_persons_ #1 _int }
+ {
+ \bool_if:NTF \l_@@_change_number_of_persons_bool
+ { \int_use:N \l_@@_wanted_number_of_persons_int }
+ { \int_use:c { g_@@_number_of_persons_ #1 _int } }
+ }{ \msg_error:nnn { cooking-units } { label-not-defined } {#1} }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{ \culabel , \curef }
+% \begin{macrocode}
+\NewDocumentCommand \culabel { m m } { \@@_culabel:nn {#1} {#2} }
+\NewExpandableDocumentCommand \curef { m } { \@@_curef:n {#1} }
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+% \begin{macro}{ \@@_tl_if_in_remove_and_set_bool:NnN }
+% Can probably optimize this as the sign is always at the first place
+% (this is done after cheking the input, so the asumption is safe), but yeah \dots
+% \begin{macrocode}
+\cs_new:Npn \@@_tl_if_in_remove_and_set_bool:NnN #1#2#3
+ {
+ \tl_if_in:NnTF #1 {#2}
+ {
+ \bool_set_true:N #3
+ \tl_remove_once:Nn #1 {#2}
+ }
+ { \bool_set_false:N #3 }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{ \@@_tl_if_in_remove_and_reverse_bool:NnN }
+% \begin{macrocode}
+\cs_new:Npn \@@_tl_if_in_remove_and_reverse_bool:NnN #1#2#3
+ {
+ \tl_if_in:NnT #1 {#2}
+ {
+ \bool_if:NTF #3
+ { \bool_set_false:N #3 }
+ { \bool_set_true:N #3 }
+ \tl_remove_once:Nn #1 {#2}
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \subsection{Language Macros}
+%
+% \begin{macrocode}
+\tl_const:Nn \c_@@_postfix_unit_tl { ( cu-unit ) }
+\tl_const:Nn \c_@@_postfix_unit_pl_tl { ( cu-unit-pl ) }
+\tl_const:Nn \c_@@_postfix_unitname_tl { ( cu-unitname ) }
+\tl_const:Nn \c_@@_postfix_unitname_pl_tl { ( cu-unitname-pl ) }
+\tl_const:Nn \c_@@_postfix_gender_tl { ( cu-unitgender ) }
+\tl_const:Nn \c_@@_postfix_phrase_tl { ( cu-unitphrase ) }
+% \end{macrocode}
+%
+% \begin{macro}{ \@@_deftranslation:nn }
+% \begin{macro}{ \@@_deftranslation:xxn , \@@_deftranslation:Vnv}
+% \begin{macrocode}
+\cs_new:Npn \@@_deftranslation_base:nnn #1#2#3
+ {
+ \declaretranslationfallback { #1 #2 } {#3}
+ }
+\cs_new:Npn \@@_deftranslation_to:nnnn #1#2#3#4
+ {
+ \declaretranslation {#1} { #2 #3 } {#4}
+ }
+\cs_generate_variant:Nn \@@_deftranslation_base:nnn { xx , xxV }
+\cs_generate_variant:Nn \@@_deftranslation_to:nnnn { Vxxv, VxxV , Vxxn, Vxxx,Vxxo,Vxxf }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+%
+%
+% \begin{macro}{\@@_newtranslation:xxn }
+% \begin{macro}{\@@_newtranslation:nxxn }
+% \begin{macrocode}
+\cs_new:Npn \@@_newtranslation_base:nnn #1#2#3
+ {
+ \definetranslationfallback { #1 #2 } {#3}
+ }
+\cs_new:Npn \@@_newtranslation_to:nnnn #1#2#3#4
+ {
+ \definetranslation {#1} { #2 #3 } {#4}
+ }
+\cs_generate_variant:Nn \@@_newtranslation_base:nnn { nVn }
+\cs_generate_variant:Nn \@@_newtranslation_to:nnnn { nnVn }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+%
+% \begin{macro}{\@@_translate:nn , \@@_translate:xV }
+% \begin{macro}{\@@_translate_let:Nnn , \@@_translate_let:NnV }
+% \begin{macro}{\@@_translate_let:nNnn , \@@_translate_let:VNnV }
+% \begin{macrocode}
+\cs_new:Npn \@@_translate:nn #1#2
+ {
+ \GetTranslation { #1 #2 }
+ }
+\cs_new:Npn \@@_translate_let:Nnn #1#2#3
+ {
+ \SaveTranslation {#1} { #2 #3 }
+ }
+\cs_new:Npn \@@_translate_let:nNnn #1#2#3#4
+ {
+ \SaveTranslationFor {#2} {#1} { #3 #4 }
+ }
+\cs_generate_variant:Nn \@@_translate:nn { VV, nV }
+\cs_generate_variant:Nn \@@_translate_let:Nnn { NnV }
+\cs_generate_variant:Nn \@@_translate_let:nNnn { VNnV, nNnV }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[TF]{\@@_unitname_get:Nn,\@@_unitname_get:Nx }
+% \begin{macrocode}
+\prg_new_conditional:Npnn \@@_unitname_get:Nn #1#2 { F }
+ {
+ \@@_translate_let:NnV #1 {#2} \c_@@_postfix_unitname_tl
+ \tl_if_eq:NNTF #1 \q_@@_no_translation
+ { \prg_return_false: }
+ { \prg_return_true: }
+ }
+\cs_generate_variant:Nn \@@_unitname_get:NnF { Nx }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_translate_one_and_check_existance:Nx }
+% As |#2| is already going to be expanded, using |\@@_translate_let:NnV| is safe.
+% \begin{macrocode}
+\cs_new:Npn \@@_translate_one_and_check_existance:Nn #1#2
+ {
+ \@@_translate_let:NnV #1 {#2} \c_@@_postfix_gender_tl
+ \@@_unitname_get:NxF #1 { one (#1) }
+ {
+ \@@_translate_let:NnV #1 {#2} \c_@@_postfix_gender_tl
+ \msg_error:nnn { cooking-units } { Translation-not-available } { one (#1) }
+ }
+ }
+\cs_generate_variant:Nn \@@_translate_one_and_check_existance:Nn { Nx }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{ decimal-mark, one(m), one(f), one(n) }
+% Defining the translation for the decimal-mark. Note that those
+% 'phrases' are stored inside
+% \verb|\g_@@_allowed_special_keys_seq|.
+% Furthermore some translations are defined.
+% \begin{macrocode}
+\seq_gset_from_clist:Nn \g_@@_allowed_special_keys_seq
+ {
+ decimal-mark ,
+ one (m) ,
+ one (f) ,
+ one (n)
+ }
+% \end{macrocode}
+% \end{macro}
+% \begin{macrocode}
+\@@_newtranslation_base:nVn { decimal-mark } \c_@@_postfix_unitname_tl { . }
+\@@_newtranslation_base:nVn { decimal-mark } \c_@@_postfix_unitname_pl_tl { \q_@@_no_translation }
+\@@_newtranslation_to:nnVn { German } { decimal-mark } \c_@@_postfix_unitname_tl { , }
+% \end{macrocode}
+% Note that the plural versions just exist for completing the set.
+% \begin{macrocode}
+\@@_newtranslation_base:nVn { one (m) } \c_@@_postfix_unitname_tl { \q_@@_no_translation }
+\@@_newtranslation_base:nVn { one (f) } \c_@@_postfix_unitname_tl { \q_@@_no_translation }
+\@@_newtranslation_base:nVn { one (n) } \c_@@_postfix_unitname_tl { \q_@@_no_translation }
+\@@_newtranslation_base:nVn { one (m) } \c_@@_postfix_unitname_pl_tl { \q_@@_no_translation }
+\@@_newtranslation_base:nVn { one (f) } \c_@@_postfix_unitname_pl_tl { \q_@@_no_translation }
+\@@_newtranslation_base:nVn { one (n) } \c_@@_postfix_unitname_pl_tl { \q_@@_no_translation }
+% \end{macrocode}
+% \begin{macrocode}
+\@@_newtranslation_to:nnVn { English } { one (m) } \c_@@_postfix_unitname_tl { one }
+\@@_newtranslation_to:nnVn { English } { one (f) } \c_@@_postfix_unitname_tl { one }
+\@@_newtranslation_to:nnVn { English } { one (n) } \c_@@_postfix_unitname_tl { one }
+% \end{macrocode}
+% \begin{macrocode}
+\@@_newtranslation_to:nnVn { German } { one (m) } \c_@@_postfix_unitname_tl { ein }
+\@@_newtranslation_to:nnVn { German } { one (f) } \c_@@_postfix_unitname_tl { eine }
+\@@_newtranslation_to:nnVn { German } { one (n) } \c_@@_postfix_unitname_tl { ein }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\@@_newtranslation_base:nVn { cutext-range-sign } \c_@@_postfix_unitname_tl { -- }
+\@@_newtranslation_base:nVn { cutext-range-sign } \c_@@_postfix_unitname_pl_tl { \q_@@_no_translation }
+\@@_newtranslation_to:nnVn { German } { cutext-range-sign } \c_@@_postfix_unitname_tl { ~bis~ }
+\@@_newtranslation_to:nnVn { English } { cutext-range-sign } \c_@@_postfix_unitname_tl { ~to~ }
+% \end{macrocode}
+%
+%
+% \section{General}
+%
+% This section collects commands which are used by all four main commands
+% (\mycs{cunum}, \cCutext, \mycs{cuam}), hence the name.
+%
+%
+% \begin{macro}{\@@_initialise_default:n ,
+% \@@_initialise_unit_change:n ,
+% \@@_initialise_after_unit_change:nn
+% }
+% Functions shared by all initialization functions:
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_initialise_default:n #1
+ {
+ \@@_set_unit:Nn \l_@@_given_unit_tl {#1}
+ \@@_error_if_unit_not_defined:V \l_@@_given_unit_tl
+ \bool_set_false:N \l_@@_special_sign_bool
+ \bool_set_false:N \l_@@_error_bool
+ \bool_set_false:N \l_@@_range_in_input_bool
+ \bool_set_false:N \l_@@_lokal_fraction_bool
+ \bool_set_false:N \l_@@_lokal_mixed_fraction_bool
+ }
+% \end{macrocode}
+% Some units have options added to them. To get those options it is first
+% needed to know which unit will be used at all. Therefore units will
+% be changed first and afterwards the other options are processed.
+%
+% |\l_@@_convert_to_eV_bool| must be checked after processing the keys
+% as the option \opt{convert-to-eV} is set during this process.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_initialise_unit_change:n #1
+ {
+ \tl_if_empty:nF {#1}
+ { \keys_set_groups:nnn { cooking-units } { change-unit } {#1} }
+ \bool_if:NT \l_@@_convert_to_eV_bool
+ { \@@_convert_to_eV: }
+ \prop_get:NVNF \l_@@_change_unit_prop \l_@@_given_unit_tl \l_@@_option_unit_tl
+ { \tl_set_eq:NN \l_@@_option_unit_tl \l_@@_given_unit_tl }
+ }
+% \end{macrocode}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_initialise_after_unit_change:nn #1#2
+ {
+ \IfNoValueF {#1}
+ { \@@_reference_label_and_persons:n {#1} }
+ \clist_if_empty:cF { l_@@_predefined_option_ \l_@@_option_unit_tl _clist }
+ {
+ \keys_set_filter:nnv
+ { cooking-units }
+ { change-unit }
+ { l_@@_predefined_option_ \l_@@_option_unit_tl _clist }
+ }
+ \tl_if_empty:nF {#2}
+ { \keys_set_filter:nnn { cooking-units } { change-unit } {#2} }
+ \bool_lazy_and:nnTF
+ { \l_@@_calc_because_ref_was_given_bool } { \l_@@_change_number_of_persons_bool }
+ { \bool_set_true:N \l_@@_lokal_persons_bool }
+ { \bool_set_false:N \l_@@_lokal_persons_bool }
+ \bool_lazy_and:nnTF
+ { \g_@@_opt_numeral_bool } { \l_@@_print_numeral_bool }
+ { \bool_set_true:N \l_@@_lokal_numeral_bool }
+ { \bool_set_false:N \l_@@_lokal_numeral_bool }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{ \@@_print_input:N , \@@_print_correct_unit: ,
+% \@@_post_process_input:NN , \@@_pre_process_input:NN}
+% Wrapper macro for printing the (not)calculated output. Note that if no
+% calculation happens in \mycs{cutext} (and \mycs{Cutext}) \cs{l_@@_option_unit_tl}
+% is set to \cs{l_@@_given_unit_tl} (the unit given in the second argument of
+% \mycs{cutext} or \mycs{Cutext}) by default.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_print_input:N #1 { }
+\cs_new_protected:Npn \@@_print_correct_unit: { }
+\cs_new_protected:Npn \@@_do_not_process_input:NN #1#2 { }
+\cs_new_eq:NN \@@_pre_process_input:NN \@@_do_not_process_input:NN
+\cs_new_eq:NN \@@_post_process_input:NN \@@_do_not_process_input:NN
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro} { \@@_set_process_and_print_for_cunum: ,
+% \@@_set_process_and_print_for_cutext: ,
+% \@@_set_process_and_print_for_cuam:
+% }
+% It is handy to set the \enquote{print} and \enquote{process}
+% command all in one go. It's also less messy to use.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_set_process_and_print_for_cunum:
+ {
+ \cs_set_eq:NN \@@_print_input:N \@@_print_numerical_input:N
+ \cs_set_eq:NN \@@_print_correct_unit: \@@_cunum_print_correct_unit:
+ \cs_set_eq:NN \@@_pre_process_input:NN \@@_do_not_process_input:NN
+ \cs_set_eq:NN \@@_post_process_input:NN \@@_do_not_process_input:NN
+ }
+\cs_new_protected:Npn \@@_set_process_and_print_for_cutext:
+ {
+ \cs_set_eq:NN \@@_print_input:N \@@_cutext_print_input:N
+ \cs_set_eq:NN \@@_print_correct_unit: \@@_cutext_print_correct_unitname:
+ \cs_set_eq:NN \@@_pre_process_input:NN \@@_cutext_pre_process_input:NN
+ \cs_set_eq:NN \@@_post_process_input:NN \@@_cutext_post_process_input:NN
+ }
+\cs_new_protected:Npn \@@_set_process_and_print_for_cuam:
+ {
+ \cs_set_eq:NN \@@_print_input:N \@@_cuam_print_numerical_input:N
+ \cs_set_eq:NN \@@_print_correct_unit: \@@_cuam_print_correct_unitphrase:
+ \cs_set_eq:NN \@@_pre_process_input:NN \@@_do_not_process_input:NN
+ \cs_set_eq:NN \@@_post_process_input:NN \@@_cuam_post_process_input:NN
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%
+% \begin{macro}{ \@@_print_numerical_input:N }
+% Prints the numerical output (if it is not a fraction).
+%
+% Changed \lstinline|\l_@@_tmpa_tl| by |\l_@@_translation_tmpa_tl|, it's better that way.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_print_numerical_input:N #1
+ {
+ \tl_if_in:NnT #1 { . }
+ {
+ \@@_translate_let:NnV \l_@@_translation_tmpa_tl
+ { decimal-mark } \c_@@_postfix_unitname_tl
+ \tl_replace_once:Nnn #1 { . } { \l_@@_translation_tmpa_tl }
+ }
+ \tl_replace_once:Nnn #1 { - } \c_@@_minus_tl
+ #1
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{ \@@_print_fractions:nnn }
+% The name of this function is the name of the game: It prints fractions.
+% Furthermore it sets the boolean \lstinline|fraction_in_input_bool| to true
+% so that the correct unit is printed.
+%
+% Since v.1.10(alpha) it also prints the minus sign (hopefully correct).
+% \begin{macrocode}
+\cs_new:Npn \@@_print_fractions:nnn #1#2#3
+ {
+ \bool_if:NT \l_@@_minus_bool { \c_@@_minus_tl }
+ \tl_if_empty:nF {#1}
+ {
+ #1
+ \@@_dim_horizontal:N \l_@@_mixed_frac_dim
+ }
+ \@@_frac:nn {#2} {#3}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{ \@@_print_ranges:NN }
+% \begin{macrocode}
+\cs_new:Npn \@@_print_ranges:NN #1#2
+ {
+ \@@_print_input:N #1
+ \bool_if:NTF \l_@@_using_cutext_bool
+ {
+% \tl_use:N \l_@@_cutext_range_sign_tl
+ \tl_if_empty:NTF \l_@@_cutext_range_sign_tl
+ { \@@_translate:nV { cutext-range-sign } \c_@@_postfix_unitname_tl }
+ { \tl_use:N \l_@@_cutext_range_sign_tl }
+ \bool_set_false:N \l_@@_cutext_uppercase_word_bool
+ }
+ { \tl_use:N \l_@@_cunum_range_sign_tl }
+ \@@_print_input:N #2
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%
+% \subsection {Parsing and checking numbers}
+%
+% This subsection contains macros for splitting an checking the input.
+%
+% \begin{macro}{\@@_create_error:n, \@@_create_error_and_stop:n , \@@_create_error:nn }
+% \begin{macrocode}
+\cs_new:Npn \@@_create_error:n #1
+ {
+ \bool_set_true:N \l_@@_error_bool
+ \msg_error:nnV { cooking-units } {#1} \l_@@_given_amount_tl
+ }
+\cs_new:Npn \@@_create_error_and_stop:n #1
+ {
+ \bool_set_true:N \l_@@_error_bool
+ \msg_error:nnV { cooking-units } {#1} \l_@@_given_amount_tl
+ \use_none_delimit_by_q_nil:w
+ }
+\cs_new:Npn \@@_create_error:nn #1#2
+ {
+ \bool_set_true:N \l_@@_error_bool
+ \msg_error:nnnV { cooking-units } {#1} {#2} \l_@@_given_amount_tl
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{ \@@_parse_input:n }
+% Rescans the input to get rid of spaces and to make \_ and ? inactive
+% (french with babel makes |?| active and changes the definition of it).
+% \lstinline|--| is replaced by \lstinline|\q_@@_range| and the input is parsed
+% (if not empty). Afterwards the units are printed.
+% \begin{macrocode}
+\cs_new:Npn \@@_parse_input:n #1
+ {
+ \bool_if:NTF \l_@@_fourty_two_bool
+ { \tl_clear:N \l_@@_given_amount_tl }
+ { \@@_set_amount:Nn \l_@@_given_amount_tl {#1} }
+ \tl_set_rescan:NnV \l_@@_given_amount_tl
+ {
+ \char_set_catcode_letter:N \_ %
+ \char_set_catcode_ignore:N \ %
+ \char_set_catcode_other:N ? %
+ } \l_@@_given_amount_tl
+ \bool_lazy_or:nnTF
+ { \l_@@_draft_bool }
+ { \tl_if_empty_p:N \l_@@_given_amount_tl }
+ {
+ \bool_if:NTF \l_@@_fourty_two_bool
+ { 42 }
+ { \l_@@_given_amount_tl }
+ }{
+ \tl_set_eq:NN \l_@@_tmpa_tl \l_@@_given_amount_tl
+ \@@_split_input:N \l_@@_tmpa_tl
+ \@@_process_and_print_input:
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{ \@@_split_input:N , \@@_process_and_print_input: , \@@_process_tmp: }
+% I would need to check for |/| and |_| anyway. So let's do it here
+% and use the booleans for error-checking.
+% \begin{macrocode}
+\cs_new:Npn \@@_split_input:N #1
+ {
+ \tl_if_in:NVT #1 \l_@@_input_range_sign_tl
+ {
+ \tl_replace_once:NVn #1 \l_@@_input_range_sign_tl { \q_@@_range }
+ \bool_set_true:N \l_@@_range_in_input_bool
+ }
+ \tl_if_in:NnT #1 { / }
+ {
+ \bool_set_true:N \l_@@_lokal_fraction_bool
+ \bool_if:NT \l_@@_range_in_input_bool
+ { \@@_create_error_and_stop:n { fraction-not-allowed-with-range } }
+ }
+ \tl_if_in:NnT #1 { _ }
+ {
+ \bool_set_true:N \l_@@_lokal_mixed_fraction_bool
+ \bool_if:NF \l_@@_lokal_fraction_bool
+ { \@@_create_error_and_stop:n { missing-slash } }
+ }
+ \@@_split:N #1
+ \use_none_delimit_by_q_nil:w \q_nil
+ }
+% \end{macrocode}
+% If an error was raised during parsing, just print the input. Else, go to the next set
+% of commands.
+% \begin{macrocode}
+\cs_new:Npn \@@_process_tmp: { }
+\cs_new:Npn \@@_process_and_print_input:
+ {
+ \bool_if:NTF \l_@@_error_bool
+ { \l_@@_given_amount_tl }
+ { \@@_process_tmp: }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{ \@@_split_input:}
+% Splits the input into fractions or ranges.
+% Errors are already checked at this point.
+% \begin{macrocode}
+\cs_new:Npn \@@_split:N #1
+ {
+ \bool_if:NTF \l_@@_lokal_fraction_bool
+ { \@@_split_fraction:V }
+ {
+ \bool_if:NTF \l_@@_range_in_input_bool
+ { \@@_split_range:V }
+ { \@@_split_number:V }
+ }
+ #1
+ }
+% \end{macrocode}
+% \begin{macrocode}
+\cs_new:Npn \@@_split_number:n #1
+ {
+ \cs_set_eq:NN \@@_process_tmp: \@@_process_number_in_input:
+ \@@_parse_input_and_safe_in:nN {#1} \l_@@_number_tmpa_tl
+ }
+% \end{macrocode}
+% \begin{macrocode}
+\cs_new:Npn \@@_split_range:n #1
+ {
+ \cs_set_eq:NN \@@_process_tmp: \@@_process_range_in_input:
+ \@@_split_range_aux:ww #1 \q_stop
+ }
+\cs_new:Npn \@@_split_range_aux:ww #1 \q_@@_range #2 \q_stop
+ {
+ \@@_parse_input_and_safe_in:nN {#1} \l_@@_number_tmpa_tl
+ \@@_parse_input_and_safe_in:nN {#2} \l_@@_number_tmpb_tl
+ }
+% \end{macrocode}
+% \begin{macrocode}
+\cs_new:Npn \@@_split_fraction:n #1
+ {
+ \bool_if:NTF \l_@@_lokal_mixed_fraction_bool
+ {
+ \cs_set_eq:NN \@@_process_tmp: \@@_process_mixed_fraction_in_input:
+ \@@_split_fraction_mixed:ww
+ }{
+ \cs_set_eq:NN \@@_process_tmp: \@@_process_fraction_in_input:
+ \@@_split_fraction_frac:ww
+ }
+ #1 \q_stop / \q_recursion_tail \q_stop
+ \q_recursion_stop
+ \bool_lazy_or:nnT
+ { \l_@@_lokal_persons_bool }{ \l_@@_eval_fractions_bool }
+ { \bool_set_false:N \l_@@_lokal_fraction_bool }
+ }
+\cs_new:Npn \@@_split_fraction_frac:ww #1 / #2 \q_stop
+ {
+ \quark_if_recursion_tail_stop_do:nn {#2}
+ { \@@_create_error:n { fraction-wrong-order } }
+ \@@_parse_input_and_safe_in:nN {#1} \l_@@_number_tmpa_tl
+ \@@_parse_input_and_safe_in:nN {#2} \l_@@_number_tmpb_tl
+ \use_none_delimit_by_q_recursion_stop:w
+ }
+\cs_new:Npn \@@_split_fraction_mixed:ww #1 _ #2 \q_stop
+ {
+ \@@_parse_input_and_safe_in:nN {#1} \l_@@_mixed_fraction_tl
+ \@@_split_fraction_frac:ww #2 \q_stop
+ }
+% \end{macrocode}
+% \begin{macrocode}
+\cs_generate_variant:Nn \@@_split_number:n { V }
+\cs_generate_variant:Nn \@@_split_range:n { V }
+\cs_generate_variant:Nn \@@_split_fraction:n { V }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{ \@@_parse_input_and_safe_in:nN }
+% Used to check the input. \lstinline|\l_@@_tmpa_tl| is cleared
+% at the beginning. At first it checks if the first token
+% is a sign or not. The parsed input is stored into \lstinline|\l_@@_tmpa_tl|.
+% \begin{macrocode}
+\cs_new:Npn \@@_parse_input_and_safe_in:nN #1 #2
+ {
+ \tl_clear:N \l_@@_tmpa_tl
+ \bool_set_false:N \l_@@_check_decimal_bool
+ \cs_set_eq:NN \@@_parse:N \@@_start_loop:N
+ \tl_map_function:nN {#1} \@@_parse:N
+ \bool_if:NTF \l_@@_error_bool
+ { \use_none_delimit_by_q_nil:w }
+ { \tl_set_eq:NN #2 \l_@@_tmpa_tl }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{ \@@_start_loop:Nw }
+% This function seperates the input into two parts with the first
+% part being the first token. This token is checked whetever or not
+% it is a sign. If it is a sign it is put into
+% \lstinline|\l_@@_tmpa_tl|, if not it is checked normally by
+% \lstinline|\@@_parse_input_loop_aux:N|. \#2 (the other
+% tokens) is then given to \lstinline|\tl_map_function:nN|. This
+% also works if the input only conists of one token with \#2 being
+% empty (hopefully).
+% \begin{macrocode}
+\cs_new:Npn \@@_start_loop:N #1
+ {
+ \cs_set_eq:NN \@@_parse:N \@@_parse_input_loop_aux:N
+ \tl_if_in:NnTF \l_@@_input_value_signs_tl {#1}
+ { \tl_put_right:Nn \l_@@_tmpa_tl {#1} }
+ {
+ \tl_map_function:nN {#1} \@@_parse:N
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{ \@@_parse_input_loop_aux:N }
+% Parses the input. It also is more or less (more less then more) copied from
+% \texttt{siunitx}. Checks if the input consists only of numbers,
+% one decimal-sign and the allowed special input. If an allowed
+% token is found the boolean \lstinline|\l_@@_special_sign_bool| is
+% set to true.
+% \begin{macrocode}
+\cs_new:Npn \@@_parse_input_loop_aux:N #1
+ {
+ \tl_if_in:NnTF \l_@@_input_digits_tl {#1}
+ { \tl_put_right:Nn \l_@@_tmpa_tl {#1} }
+ {
+ \tl_if_in:NnTF \l_@@_input_decimal_mark_tl {#1}
+ {
+ \@@_check_repitition:N \l_@@_check_decimal_bool
+ \tl_put_right:Nn \l_@@_tmpa_tl { . }
+ }{
+ \tl_if_in:NnTF \l_@@_input_allowed_special_signs_tl {#1}
+ {
+ \bool_set_true:N \l_@@_special_sign_bool
+ \tl_put_right:Nn \l_@@_tmpa_tl {#1}
+ }{
+ \bool_set_true:N \l_@@_error_bool
+ \@@_check_error:n {#1}
+ }
+ }
+ }
+ }
+% \end{macrocode}
+% The idea behind this error checking is the following:
+% At this point I already split the input. This means, a fraction
+% is already split into nominator and denominator and as such, all allowed
+% |/| in the input are already removed. The same goes for |_| (an error message
+% for |_| without |/| would happen before parsing starts). Therefore
+% all |/| and |_| in the input \emph{must} (hopefully) be inside a second time.
+% \begin{macrocode}
+\cs_new:Npn \@@_check_error:n #1
+ {
+ \tl_if_in:NnTF \l_@@_input_fraction_sign_tl {#1}
+ { \@@_create_error:n { Second-fraction-sign-not-allowed } }
+ {
+ \tl_if_in:NnTF \l_@@_input_mixed_fraction_sign_tl {#1}
+ { \@@_create_error:n { Second-mixed-fraction-sign-not-allowed } }
+ { \@@_create_error:nn { Token-not-allowed } {#1} }
+ }
+ }
+% \end{macrocode}
+% \begin{macrocode}
+\cs_new:Npn \@@_check_repitition:N #1
+ {
+ \bool_if:NTF #1
+ { \@@_create_error:n { Second-decimal-sign-not-allowed } }
+ { \bool_set_true:N #1 }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\@@_process_number_in_input:}
+% If no fractions and ranges are used this macro activated.
+% It just checks the input, stores the checked (and a bit
+% changed) input into a macro. This macro is given to another
+% function to calculate the input and print it.
+% \begin{macrocode}
+\cs_new:Npn \@@_process_number_in_input:
+ {
+ \@@_process_and_print_number_in_input:N \l_@@_number_tmpa_tl
+ }
+\cs_new:Npn \@@_process_and_print_number_in_input:N #1
+ {
+ \@@_pre_process_input:NN #1 \q_no_value
+ \@@_calculate_and_store_in:N #1
+ \@@_post_process_input:NN #1 \q_no_value
+ \@@_print_input:N #1
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{ \@@_process_range_in_input: }
+% Is used if a \lstinline|\q_@@_range| is found inside the input.
+% Seperates the input, checks it and prints it (after calculating
+% it). Furthermore a boolean is set to true, is used to check for
+% errors (ergo if fractions are used).
+%
+% Set |\l_@@_cutext_uppercase_word_bool| to false
+% so that the second numeral is not capitalized.
+% \begin{macrocode}
+\cs_new:Npn \@@_process_range_in_input:
+ {
+ \@@_pre_process_input:NN \l_@@_number_tmpa_tl \l_@@_number_tmpb_tl
+ \@@_calculate_and_store_in:N \l_@@_number_tmpa_tl
+ \@@_calculate_and_store_in:N \l_@@_number_tmpb_tl
+ \@@_post_process_input:NN \l_@@_number_tmpa_tl \l_@@_number_tmpb_tl
+ \@@_print_ranges:NN \l_@@_number_tmpa_tl \l_@@_number_tmpb_tl
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{ \@@_process_fraction_in_input: }
+% If a \lstinline|/| (but no \lstinline|_|) is found inside the input.
+% Well \dots\ does the same as the functions before.
+% If fractions should be evaluated the input is \dots\ well,
+% evaluated and printed. Otherwise the input is given to
+% another function which prints the fractions. Note that the empty
+% argument in \lstinline|\@@_print_fractions:nnn| indicates a
+% \enquote{normal} fraction.
+% \begin{macrocode}
+\cs_new:Npn \@@_process_fraction_in_input:
+ {
+ \bool_lazy_or:nnTF
+ { \l_@@_lokal_fraction_bool }
+ { \l_@@_special_sign_bool }
+ {
+ \@@_tl_if_in_remove_and_set_bool:NnN \l_@@_number_tmpa_tl { - } \l_@@_minus_bool
+ \@@_tl_if_in_remove_and_reverse_bool:NnN \l_@@_number_tmpb_tl { - } \l_@@_minus_bool
+ \@@_print_fractions:nnn
+ { }
+ { \l_@@_number_tmpa_tl }
+ { \l_@@_number_tmpb_tl }
+ }{
+ \fp_compare:nNnT { \l_@@_number_tmpb_tl } = { 0 }
+ { \msg_error:nnV { cooking-units } { Division-by-zero } \l_@@_given_amount_tl }
+ \@@_tl_eval:Nn \l_@@_number_tmpa_tl
+ { \l_@@_number_tmpa_tl / \l_@@_number_tmpb_tl }
+ \@@_process_and_print_number_in_input:N \l_@@_number_tmpa_tl
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{ \@@_process_mixed_fraction_in_input: }
+% The same procedure as last function? The same procedure as every
+% function!
+%
+% If it should be evaluated it is important to check if the mixed-fraction
+% part is positive or negative. That's why the minuses are removed \emph{before}
+% checking if there is a fraction (in opposite to the command before).
+%
+% \begin{align}
+% \cuam{1_2/3} &= 1 + 2/3 \\
+% \cuam{-1_2/3} &= -1 - 2/3
+% \end{align}
+%
+% \begin{macrocode}
+\cs_new:Npn \@@_process_mixed_fraction_in_input:
+ {
+ \@@_tl_if_in_remove_and_set_bool:NnN \l_@@_mixed_fraction_tl { - } \l_@@_minus_bool
+ \@@_tl_if_in_remove_and_reverse_bool:NnN \l_@@_number_tmpa_tl { - } \l_@@_minus_bool
+ \@@_tl_if_in_remove_and_reverse_bool:NnN \l_@@_number_tmpb_tl { - } \l_@@_minus_bool
+ \bool_lazy_or:nnTF
+ { \l_@@_lokal_fraction_bool }
+ { \l_@@_special_sign_bool }
+ {
+ \@@_print_fractions:nnn
+ { \l_@@_mixed_fraction_tl }
+ { \l_@@_number_tmpa_tl }
+ { \l_@@_number_tmpb_tl }
+ }{
+ \fp_compare:nNnT { \l_@@_number_tmpb_tl } = { 0 }
+ { \msg_error:nnV { cooking-units } { Division-by-zero } \l_@@_given_amount_tl }
+ \@@_tl_eval:Nn \l_@@_number_tmpa_tl
+ {
+ \bool_if:NTF \l_@@_minus_bool
+ { - \l_@@_mixed_fraction_tl - }
+ { \l_@@_mixed_fraction_tl + }
+ \l_@@_number_tmpa_tl / \l_@@_number_tmpb_tl
+ }
+ \@@_process_and_print_number_in_input:N \l_@@_number_tmpa_tl
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%
+%
+% \subsection {Formatiere \& Calculiere}
+%
+% \begin{macro}{ \@@_calculate_and_store_in:N }
+%
+% \changes {v0.98a} {2016/06/11} {Added warning to show if an unknown value is used.}
+%
+% After parsing the input, it is given to this function. If a not
+% allowed token is found (and \lstinline|\l_@@_error_bool| is set to
+% true) it just prints the input. Otherwise it checks if a allowed sign was
+% found. If so it is just stored inside \lstinline|\l_@@_tmpa_tl|,
+% otherwise it is calulcated and stored in \lstinline|\l_@@_tmpa_tl|. The input
+% \#1 can be either a token or a number.
+% \begin{macrocode}
+\cs_new:Npn \@@_calculate_and_store_in:N #1
+ {
+ \bool_if:NTF \l_@@_special_sign_bool
+ {
+ \msg_warning:nnV { cooking-units } { amount-not-known } #1
+ }{
+ \bool_lazy_and:nnTF
+ { \l_@@_using_cutext_bool } { \l_@@_cutext_keep_unit_bool }
+ { \tl_set_eq:NN \l_@@_tmpa_tl #1 }
+ { \@@_calculate_input_and_store_in:nN {#1} \l_@@_tmpa_tl }
+ \@@_calc_references:NN \l_@@_tmpa_tl \l_@@_tmpa_tl
+ \@@_round_calculated_input:NV \l_@@_tmpa_tl \l_@@_tmpa_tl
+ \@@_check_temperature_limit:N \l_@@_tmpa_tl
+ \tl_set_eq:NN #1 \l_@@_tmpa_tl
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{ \@@_calculate_input_and_store_in:nN }
+% Well \dots\ this function calculates the input. First checks if the
+% wanted conversion contains a \lstinline|\l_@@_tmpa_fp| (ergo a \#1 in
+% the key definition). If true the conversion token (which already has
+% \lstinline|\l_@@_tmpa_fp| in its input) is executed, else the input
+% number is multiplicated with the conversion token.
+% \begin{macrocode}
+\cs_new:Npn \@@_calculate_input_and_store_in:nN #1#2
+ {
+ \fp_set:Nn \l_@@_tmpa_fp {#1}
+ \tl_if_in:cnTF { l_@@_unit_change_ \l_@@_given_unit_tl _tl } { \l_@@_tmpa_fp }
+ {
+ \@@_tl_eval:Nv #2 { l_@@_unit_change_ \l_@@_given_unit_tl _tl }
+ }{
+ \@@_tl_eval:Nn #2
+ { \l_@@_tmpa_fp * \tl_use:c { l_@@_unit_change_ \l_@@_given_unit_tl _tl } }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{ \@@_calc_references:NN,\@@_calc_references_aux:NN }
+% As comparing integers is faster then checking if something is inside
+% the sequence, first (after the boolean) check if there needs to be a calculation
+% at all.
+% \begin{macrocode}
+\cs_new:Npn \@@_calc_references:NN #1#2
+ {
+ \bool_if:NT \l_@@_lokal_persons_bool
+ {
+ \int_compare:nNnF
+ { \l_@@_wanted_number_of_persons_int }
+ =
+ { \l_@@_local_number_of_persons_int }
+ {
+% \@@_change_unit:TF
+% { \tl_set_eq:NN \l_@@_tmpb_tl \l_@@_option_unit_tl }
+% { \tl_set_eq:NN \l_@@_tmpb_tl \l_@@_given_unit_tl }
+ \tl_set_eq:NN \l_@@_tmpb_tl \l_@@_given_unit_tl
+ \seq_if_in:NVTF \l_@@_curef_do_not_change_seq \l_@@_tmpb_tl
+ { \msg_error:nnV { cooking-units } { curef-forbidden-unit } \l_@@_tmpb_tl }
+ { \@@_calc_references_aux:NN #1 #2 }
+ }
+ }
+ }
+% \end{macrocode}
+% I hope that by putting |#2| to the front of the calculation, it will increase the
+% precision of the calculation (not that it is necessary). I don't really know if this
+% makes sense, but \dots\ eh.
+% \begin{macrocode}
+\cs_new:Npn \@@_calc_references_aux:NN #1#2
+ {
+ \@@_tl_eval:Nn #1
+ {
+ #2 *
+ \l_@@_wanted_number_of_persons_int /
+ \l_@@_local_number_of_persons_int
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_check_number_for_rounding:n,\@@_check_number_after_dot_aux:ww}
+% Check if rounding is needed. The auxilary function splits the number into
+% the integer and non-integer part ($12.45$ to $12$ and $45$).
+%
+% If the non-integer part exists its number of digits $n$ are counted checked
+% if it is smaller then $a$, which depends on |\l_@@_round_to_int_bool|.
+%
+% \begin{macrocode}
+\cs_new:Npn \@@_check_number_for_rounding:n #1
+ {
+ \bool_set_false:N \l_@@_round_number_bool
+ \@@_check_number_after_dot_aux:ww #1 . \q_recursion_tail .
+ \q_recursion_stop
+ }
+\cs_new:Npn \@@_check_number_after_dot_aux:ww #1 . #2 .
+ {
+ \quark_if_recursion_tail_stop_do:nn {#2}
+ {
+ \bool_lazy_or:nnF
+ { \l_@@_round_precision_positive_bool }
+ { \l_@@_round_to_int_bool }
+ { \bool_set_true:N \l_@@_round_number_bool }
+ }
+ \int_compare:nNnT
+ { \tl_count:n {#2} } >
+ {
+ \bool_if:NTF \l_@@_round_to_int_bool
+ { 0 }
+ { \l_@@_round_precision_int }
+ }
+ { \bool_set_true:N \l_@@_round_number_bool }
+ \use_none_delimit_by_q_recursion_stop:w
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{ \@@_round_calculated_input:Nn,\@@_round_calculated_input:NV }
+% After calculating the numbers are rounded (if needed, safed inside \cs{l_tmpa_bool}).
+% We test at first if
+% the input needs to be rounded by comparing the number of tokens after the
+% decimal with the round precision. Afterwards the
+% input is expanded and stored in \#1. If rounding needs to be done it happens now.
+% \begin{macrocode}
+\cs_new:Npn \@@_round_calculated_input:Nn #1#2
+ {
+ \@@_check_number_for_rounding:n {#2}
+ \bool_if:NTF \l_@@_round_number_bool
+ { \@@_tl_eval:Nn #1 { round ( \@@_rounding_function:n {#2} ) } }
+ { \tl_set:Nn #1 {#2} }
+% \tl_set:Nf #1
+% {
+% \bool_if:NTF \l_@@_round_number_bool
+% { \fp_eval:n { round ( \@@_rounding_function:n {#2} ) } }
+% {#2}
+% }
+ }
+\cs_generate_variant:Nn \@@_round_calculated_input:Nn { NV }
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%
+%
+%
+%
+% \begin{macro}{\@@_check_temperature_limit:N}
+% If \lstinline|check_temperature_bool| is set to true it now checks
+% if the value is below the absolute temperature. \lstinline|\clist_if_in:nVT|
+% is needed due to \myunit{Re}, a \lstinline|\tl_if_in:nVT| would also check for \myunit{R}
+% and \myunit{e} instead of only \myunit{Re}.
+% \begin{macrocode}
+\cs_new:Npn \@@_check_temperature_limit:N #1
+ {
+ \bool_if:NT \l_@@_check_temperature_bool
+ {
+ \seq_if_in:NVT \l_@@_temperatures_to_check_seq \l_@@_option_unit_tl
+ {
+ \fp_compare:vNnT
+ { c_@@_ \l_@@_option_unit_tl _min_fp } > {#1}
+ {
+ \msg_error:nnxx { cooking-units }
+ { Temperature-too-low }
+ { #1 \space \l_@@_option_unit_tl }
+ {
+ \fp_use:c { c_@@_ \l_@@_option_unit_tl _min_fp }
+ \space \l_@@_option_unit_tl
+ }
+ }
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%
+%
+%
+%
+%
+%
+%
+%
+% \begin{macrocode}
+\cs_new_nopar:Npn \@@_grab_arrows_for_safety_do_afterwards:nN #1#2
+ {
+ \str_if_eq:nnTF {#2} { > }
+ {
+ \tl_put_right:Nx \l_@@_tmpa_tl { \tl_to_str:N > }
+ \exp_last_unbraced:NV #1 \l_@@_tmpa_tl
+ }{
+ \tl_put_right:Nn \l_@@_tmpa_tl {#2}
+ \@@_grab_arrows_for_safety_do_afterwards:nN {#1}
+ }
+ }
+\cs_new_nopar:Npn \@@_if_arrow_grab_until_close_do:nnTF #1#2#3#4
+ {
+ \str_if_eq:nnTF {#1} { < }
+ {
+ \tl_if_in:NoT \l_@@_input_allowed_special_signs_tl { < }
+ { \msg_error:nn { cooking-units } { <-not-allowed-as-special-sign } }
+ \tl_clear:N \l_@@_tmpa_tl
+ \tl_put_right:Nx \l_@@_tmpa_tl { \tl_to_str:N < }
+ \@@_grab_arrows_for_safety_do_afterwards:nN
+ {#3} #2
+ }
+ {#4}
+ }
+% \end{macrocode}
+%
+%
+%
+% \subsection {\mycs{cunum}}
+%
+%
+% \begin{macro}{ \cunum }
+% The main command of this package.
+% \begin{macrocode}
+\NewDocumentCommand \cunum { d<> O{} m O{} m }
+ {
+ \@@_if_arrow_grab_until_close_do:nnTF {#3} {#5}
+ { \cunum }
+ {
+ \group_begin:
+ \@@_cunum:nnnnn {#1} {#2} {#3} {#4} {#5}
+ \group_end:
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{ \@@_cunum:nnnnn }
+% \begin{macrocode}
+\cs_new:Npn \@@_cunum:nnnnn #1#2#3#4#5
+ {
+ \@@_cunum_initialise:nnnnn {#1} {#2} {#3} {#4} {#5}
+ \l_@@_cunum_hook_tl
+ \@@_parse_input:n {#3}
+ \@@_print_correct_unit:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{ \@@_cunum_initialise:nnnn }
+% Lots of things to do in this function. It checks if the unit is defined or not,
+% sets the keys for converting the unit and sets the optional unit (the unit
+% our input is converted to) accordingly, sets the options again (to get the
+% option-specific options) and \dots\ yeah.
+%
+% First parses the change of unit ('set groups'), afterwards set
+% the predefined options for the new unit. Afterwards
+% set the 'normal' options given by the optional argument.
+%
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_cunum_initialise:nnnnn #1#2#3#4#5
+ {
+ \@@_set_process_and_print_for_cunum:
+ \tl_set:Nn \l_@@_phantom_tl {#4}
+ \@@_initialise_default:n {#5}
+ \@@_initialise_unit_change:n {#2}
+ \@@_initialise_after_unit_change:nn {#1} {#2}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+% \begin{macro}{ \@@_cunum_print_correct_unit: }
+% The invisible space is added by a \lstinline|\phantom|, afterwards
+% \lstinline|value_unit_space_tl| is used (which is set to
+% \lstinline|\thinspace| by default) and if either special signs or
+% fractions are parsed the input-unit is printed else the converted
+% unit is.
+% \begin{macrocode}
+\cs_new:Npn \@@_cunum_print_correct_unit:
+ {
+ \tl_if_empty:NF \l_@@_phantom_tl { \phantom { \l_@@_phantom_tl } }
+ \tl_use:N \l_@@_value_unit_space_tl
+ \@@_change_unit:TF
+ { \@@_translate:VV \l_@@_option_unit_tl \c_@@_postfix_unit_tl }
+ { \@@_translate:VV \l_@@_given_unit_tl \c_@@_postfix_unit_tl }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \section { cutext \& Cutext }
+%
+%
+% A better implemantation of \opt{cutext-to-cunum}, but
+% sufficient for now.
+% \begin{macrocode}
+\NewDocumentCommand \cutext { d<> O{} m m }
+ {
+ \@@_if_arrow_grab_until_close_do:nnTF {#3} {#4}
+ { \cutext }
+ {
+ \group_begin:
+ \@@_change_cutext_to_cunum:nTF {#2}
+ { \@@_cunum:nnnnn {#1} {#2} {#3} { } {#4} }
+ {
+ \bool_set_false:N \l_@@_cutext_uppercase_word_bool
+ \@@_cutext:nnnn {#1} {#2} {#3} {#4}
+ }
+ \group_end:
+ }
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\NewDocumentCommand \Cutext { d<> O{} m m }
+ {
+ \@@_if_arrow_grab_until_close_do:nnTF {#3} {#4}
+ { \Cutext }
+ {
+ \group_begin:
+ \@@_change_cutext_to_cunum:nTF {#2}
+ { \@@_cunum:nnnnn {#1} {#2} {#3} { } {#4} }
+ {
+ \bool_set_true:N \l_@@_cutext_uppercase_word_bool
+ \@@_cutext:nnnn {#1} {#2} {#3} {#4}
+ }
+ \group_end:
+ }
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_cutext_initialise:nnn #1#2#3
+ {
+ \bool_set_true:N \l_@@_using_cutext_bool
+ \@@_set_process_and_print_for_cutext:
+ \@@_initialise_default:n {#3}
+ \@@_initialise_unit_change:n {#2}
+ \bool_if:NT \l_@@_cutext_keep_unit_bool
+ { \tl_set_eq:NN \l_@@_option_unit_tl \l_@@_given_unit_tl }
+ \@@_initialise_after_unit_change:nn {#1} {#2}
+ \bool_if:NT \l_@@_fourty_two_bool
+ { \tl_set:Nn \l_@@_cutext_last_value_tl { 42 } }
+ }
+% \end{macrocode}
+%
+% #1: label, #2: Options, #3: Values, #4: unit
+% \begin{macrocode}
+\cs_new:Npn \@@_cutext:nnnn #1#2#3#4
+ {
+ \@@_cutext_initialise:nnn {#1} {#2} {#4}
+ \bool_if:NTF \l_@@_cutext_uppercase_word_bool
+ { \l_@@_Cutext_hook_tl }
+ { \l_@@_cutext_hook_tl }
+ \bool_if:NTF \l_@@_cutext_old_bool
+ { \@@_old_cutext:nnn {#2} {#3} {#4} }
+ { \@@_parse_input:n {#3} }
+ \@@_print_correct_unit:
+ }
+% \end{macrocode}
+%
+%
+%
+% \begin{macro} {\@@_cutext_print_input:Nn , \@@_cutext_print_input:NV}
+% \changes {2016/06/11} {0.99} {New.}
+%
+%
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_cutext_print_input:Nn #1#2
+ {
+ \bool_if:NTF \l_@@_lokal_numeral_bool
+ {
+ \@@_int_if_equal_one:nTF {#1}
+ {
+ \@@_translate_one_and_check_existance:Nx \l_@@_translation_tmpa_tl {#2}
+ \bool_if:NTF \l_@@_cutext_uppercase_word_bool
+ {
+ \exp_args:Nx \tl_upper_case:n { \tl_head:V \l_@@_translation_tmpa_tl }
+ \tl_tail:V \l_@@_translation_tmpa_tl
+ }
+ { \l_@@_translation_tmpa_tl }
+ }{
+ \bool_if:NTF \l_@@_cutext_uppercase_word_bool
+ { \@@_print_Numeral:n {#1} }
+ { \@@_print_numeral:n {#1} }
+ }
+ }
+ { \@@_print_numerical_input:N #1 }
+ }
+\cs_generate_variant:Nn \@@_cutext_print_input:Nn { NV }
+\cs_new_protected:Npn \@@_cutext_print_input:N #1
+ {
+ \@@_change_unit:TF
+ { \@@_cutext_print_input:NV #1 \l_@@_option_unit_tl }
+ { \@@_cutext_print_input:NV #1 \l_@@_given_unit_tl }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+\cs_new:Npn \@@_cutext_print_correct_unitname:
+ {
+ \l_@@_cutext_space_tl
+ \@@_change_unit:TF
+ {
+ \@@_fp_if_equal_one:nTF { \l_@@_cutext_last_value_tl }
+ { \@@_translate:VV \l_@@_option_unit_tl \c_@@_postfix_unitname_tl }
+ { \@@_translate:VV \l_@@_option_unit_tl \c_@@_postfix_unitname_pl_tl }
+ }
+ { \@@_translate:VV \l_@@_given_unit_tl \c_@@_postfix_unitname_pl_tl }
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_new:Npn \@@_cutext_pre_process_input:NN #1#2
+ {
+ \@@_change_unit:TF
+ { \tl_set_eq:NN \l_@@_tmpb_tl \l_@@_option_unit_tl }
+ { \tl_set_eq:NN \l_@@_tmpb_tl \l_@@_given_unit_tl }
+ \@@_unitname_get:NxF \l_@@_tmpa_tl \l_@@_tmpb_tl
+ {
+ \msg_warning:nnx
+ { cooking-units }
+ { cutext-no-translation-available }
+ \l_@@_tmpb_tl
+ \bool_set_false:N \l_@@_using_cutext_bool
+ \@@_set_process_and_print_for_cunum:
+ }
+ }
+% \end{macrocode}
+%
+%
+%
+% \begin{macrocode}
+\cs_new:Npn \@@_cutext_post_process_input:NN #1#2
+ {
+ \bool_if:NF \l_@@_special_sign_bool
+ {
+ \@@_cutext_post_process_input_aux:NN #1#2
+ }
+ }
+% \end{macrocode}
+% \begin{macrocode}
+\cs_new:Npn \@@_cutext_post_process_input_aux:NN #1#2
+ {
+ \bool_if:NTF \l_@@_range_in_input_bool
+ { \tl_set_eq:NN \l_@@_cutext_last_value_tl #2 }
+ { \tl_set_eq:NN \l_@@_cutext_last_value_tl #1 }
+ \bool_if:NT \l_@@_lokal_numeral_bool
+ { \@@_cutext_post_process_input_numerals:NN #1#2 }
+ }
+\cs_new:Npn \@@_cutext_post_process_input_numerals:NN #1#2
+ {
+ \@@_bool_set_if_integers:NNN \l_@@_tmpa_bool #1 #2
+ \bool_if:NTF \l_@@_tmpa_bool
+ {
+ \bool_if:NTF \l_@@_range_in_input_bool
+ {
+ \bool_lazy_and:nnF
+ { \int_compare_p:nNn {#1} < { \l_@@_print_numerals_below_int } }
+ { \int_compare_p:nNn {#2} < { \l_@@_print_numerals_below_int } }
+ { \bool_set_false:N \l_@@_lokal_numeral_bool }
+ }{
+ \int_compare:nNnF {#1} < { \l_@@_print_numerals_below_int }
+ { \bool_set_false:N \l_@@_lokal_numeral_bool }
+ }
+ }
+ { \bool_set_false:N \l_@@_lokal_numeral_bool }
+ }
+% \end{macrocode}
+%
+%
+%
+%
+%
+%
+%
+%
+%
+% \section{cuam}
+%
+% \begin{macrocode}
+\tl_const:Nn \c_@@_cuam_marker_tl { @@_cunum }
+\tl_new:c { l_@@_unit_change_ \c_@@_cuam_marker_tl _tl }
+\tl_set:cn { l_@@_unit_change_ \c_@@_cuam_marker_tl _tl } { 1.0 }
+\clist_new:c { l_@@_predefined_option_ \c_@@_cuam_marker_tl _clist }
+% \end{macrocode}
+%
+% Replaces and extends \mycs{cufrac}.
+% \begin{macro}{\cuam}
+% \begin{macrocode}
+\NewDocumentCommand \cuam { d<> O{} m }
+ {
+ \@@_if_arrow_grab_until_close_do:nnTF {#3} { }
+ { \cuam }
+ {
+ \group_begin:
+ \@@_cuam:nnn {#1} {#2} {#3}
+ \group_end:
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+\cs_new:Npn \@@_cuam:nnn #1#2#3
+ {
+ \@@_cuam_initialise:nn {#1} {#2}
+ \l_@@_cuam_hook_tl
+ \bool_if:NTF \l_@@_cuam_old_bool
+ { \@@_cuam_old:n {#3} }
+ {
+ \@@_parse_input:n {#3}
+ \@@_print_correct_unit:
+ }
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_cuam_initialise:nn #1#2
+ {
+ \@@_set_process_and_print_for_cuam:
+ \tl_set_eq:NN \l_@@_given_unit_tl \c_@@_cuam_marker_tl
+ \tl_set_eq:NN \l_@@_option_unit_tl \c_@@_cuam_marker_tl
+ \bool_set_false:N \l_@@_lokal_phrase_bool
+ \@@_initialise_after_unit_change:nn {#1} {#2}
+ }
+% \end{macrocode}
+%
+% Important thing is: This whole process must not acticate if a
+% special sign is in the input. This is due to mathematical comparisons.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_cuam_post_process_input:NN #1#2
+ {
+ \bool_if:NF \l_@@_special_sign_bool
+ { \@@_cuam_post_process_input_aux:NN #1 #2 }
+ }
+% \end{macrocode}
+%
+% Just a helper macro to tidy up the main macro. The first thing to
+% do is to check if the nummerical input consits of integers. This
+% is done both both numerical values (if a range exists).
+% Afterwards check if phrases are used and can be used at all. This needs
+% to be done before the numeral check as it can change the input.
+% \begin{macrocode}
+\cs_new:Npn \@@_cuam_post_process_input_aux:NN #1#2
+ {
+ \@@_bool_set_if_integers:NNN \l_@@_tmpa_bool #1 #2
+ \bool_lazy_and:nnT
+ { \l_@@_use_phrases_bool } { \l_@@_tmpa_bool }
+ { \@@_cuam_post_process_input_phrases:NN #1#2 }
+ \bool_if:NT \l_@@_lokal_numeral_bool
+ { \@@_cuam_post_process_input_numerals:NN #1#2 }
+ }
+% \end{macrocode}
+%
+% This command is more or less straightforward. Does a list of phrases exist
+% for the current language? If yes, parse the input and check if phrases are used.
+% It is important for ranges to check both values and then decide if phrases
+% are used or not.
+% \begin{macrocode}
+\cs_new:Npn \@@_cuam_post_process_input_phrases:NN #1#2
+ {
+ \@@_get_phrase_for_current_langauge:NNT
+ \l_@@_phrase_prop
+ \l_@@_phrase_numbers_seq
+ {
+ \@@_cuam_post_process_input_phrases_aux:NNN
+ #1 \l_@@_tmpa_int \l_@@_phrase_number_tl
+ \bool_if:NT \l_@@_lokal_phrase_bool
+ {
+ \bool_if:NTF \l_@@_range_in_input_bool
+ {
+ \bool_if:NF \l_@@_phrase_negative_bool
+ {
+ \@@_cuam_post_process_input_phrases_range:NN
+ #2 \l_@@_tmpb_int
+ \bool_if:NT \l_@@_lokal_phrase_bool
+ {
+ \tl_set:NV #1 \l_@@_tmpa_int
+ \tl_set:NV #2 \l_@@_tmpb_int
+ \@@_cuam_get_phrase_name:NVN
+ \l_@@_phrase_phrase_tl \l_@@_phrase_number_tl \l_@@_tmpb_int
+ }
+ }
+ }{
+ \tl_set:NV #1 \l_@@_tmpa_int
+ \@@_cuam_get_phrase_name:NVN
+ \l_@@_phrase_phrase_tl \l_@@_phrase_number_tl \l_@@_tmpa_int
+ }
+ }
+ }
+ }
+% \end{macrocode}
+% \begin{macrocode}
+\cs_new:Npn \@@_cuam_post_process_input_phrases_aux:NNN #1#2#3
+ {
+ \bool_set_false:N \l_@@_lokal_phrase_bool
+ \seq_map_inline:Nn \l_@@_phrase_numbers_seq
+ {
+ \int_compare:nNnF { \int_abs:n {##1} } > {#1}
+ {
+ \int_compare:nNnTF {##1} < { 0 }
+ {
+ \bool_set_true:N \l_@@_phrase_negative_bool
+ \int_set:Nn \l_tmpa_int { 1 }
+ }
+ { \int_set:Nn \l_tmpa_int { \int_div_truncate:nn {#1} {##1} } }
+ \int_compare:nNnT { \int_abs:n {##1} * \l_tmpa_int } = {#1}
+ {
+ \int_set_eq:NN #2 \l_tmpa_int
+ \tl_set:Nn #3 {##1}
+ \bool_set_true:N \l_@@_lokal_phrase_bool
+ \seq_map_break:
+ }
+ }
+ }
+ }
+\cs_new:Npn \@@_cuam_post_process_input_phrases_range:NN #1#2
+ {
+ \int_set:Nn \l_tmpa_int { \int_div_truncate:nn {#1} { \l_@@_phrase_number_tl } }
+ \int_compare:nNnTF { \l_@@_phrase_number_tl * \l_tmpa_int } = {#1}
+ {
+ \int_set_eq:NN #2 \l_tmpa_int
+ \bool_set_true:N \l_@@_lokal_phrase_bool
+ }{
+ \bool_set_false:N \l_@@_lokal_phrase_bool
+ }
+ }
+\cs_new:Npn \@@_cuam_get_phrase_name:NnN #1#2#3
+ {
+ \@@_int_if_equal_one:nTF {#3}
+ { \prop_get:NnN \l_@@_phrase_prop {#2} #1 }
+ { \prop_get:NnN \l_@@_phrase_prop { #2-pl } #1 }
+ }
+\cs_generate_variant:Nn \@@_cuam_get_phrase_name:NnN { NVN }
+% \end{macrocode}
+%
+%
+% Processing numerals. This function only happens if numerals are used
+% and because numerals have to be integers I can set the numeral boolean
+% false if there is no integer.
+%
+% Furthermore, due to knowing that we have integers we can use
+% |\int_compare_p:nNn| instead of the |fp|-equivalent.
+% \begin{macrocode}
+\cs_new:Npn \@@_cuam_post_process_input_numerals:NN #1#2
+ {
+ \bool_if:NTF \l_@@_tmpa_bool
+ {
+ \bool_if:NTF \l_@@_range_in_input_bool
+ {
+ \bool_lazy_and:nnF
+ { \int_compare_p:nNn {#1} < { \l_@@_print_numerals_below_int } }
+ { \int_compare_p:nNn {#2} < { \l_@@_print_numerals_below_int } }
+ { \bool_set_false:N \l_@@_lokal_numeral_bool }
+ }{
+ \int_compare:nNnF {#1} < { \l_@@_print_numerals_below_int }
+ { \bool_set_false:N \l_@@_lokal_numeral_bool }
+ }
+ }
+ { \bool_set_false:N \l_@@_lokal_numeral_bool }
+ }
+% \end{macrocode}
+%
+%
+% Note: This command checks if \emph{both} a phrase and a numeral is
+% used to decide whetever or not to print numerals. This is due to
+% the $1$ being dependent (in some languages) depending on the gender
+% of the following word. Currently testing only |\l_@@_lokal_numeral_bool| doesn't
+% work due to the $1$ having a special parsing.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_cuam_print_numerical_input:N #1
+ {
+ \bool_lazy_and:nnTF
+ { \l_@@_lokal_phrase_bool }
+ { \l_@@_lokal_numeral_bool }
+ {
+ \@@_int_if_equal_one:nTF {#1}
+ {
+ \@@_translate_one_and_check_existance:Nx
+ \l_@@_translation_tmpa_tl
+ { \l_@@_phrase_number_tl -phrase-gender }
+ \l_@@_translation_tmpa_tl
+ }
+ { \exp_args:NV \@@_print_numeral:n #1 }
+ }{ \@@_print_numerical_input:N #1 }
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_new:Npn \@@_cuam_print_correct_unitphrase:
+ {
+ \bool_if:NT \l_@@_lokal_phrase_bool
+ {
+ \l_@@_cuphrase_space_tl
+ \l_@@_phrase_phrase_tl
+ }
+ }
+% \end{macrocode}
+%
+%
+%
+%
+%
+%
+% \section {cukeys}
+%
+% \subsection {Define Keys}
+%
+% \begin{macro}{ \cudefinekeys }
+% Defining keys.
+% \begin{macrocode}
+\NewDocumentCommand \cudefinekeys { m m }
+ {
+ \bool_set_false:N \l_@@_single_key_bool
+ \@@_cukeys_define_keys_and_single_keys:nn {#1} {#2}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{ \cudefinesinglekey }
+% Again, but with the boolean set to true.
+% \begin{macrocode}
+\NewDocumentCommand \cudefinesinglekey { m m }
+ {
+ \bool_set_true:N \l_@@_single_key_bool
+ \@@_cukeys_define_keys_and_single_keys:nn {#1} {#2}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{ \@@_cukeys_define_keys_and_single_keys:nn }
+% First checks whetever the unit is defined or not, then clears some macros
+% which are needed later. Further procession depends on the boolean.
+% If more than one key is created, the value \lstinline|\l_@@_tmpa_fp| is set to one.
+% This is important for adding keys where \lstinline|\l_@@_tmpa_fp| is changed accordingly.
+% \begin{macrocode}
+\cs_new:Npn \@@_cukeys_define_keys_and_single_keys:nn #1#2
+ {
+ \@@_error_if_unit_not_defined:n {#1}
+ \tl_if_blank:nF {#2}
+ {
+ \seq_clear:N \l_@@_tmpa_seq
+ \prop_clear:N \l_@@_tmpa_prop
+ \bool_if:NTF \l_@@_single_key_bool
+ {
+ \@@_cukeys_parse_and_create_single_key:nn {#1} {#2}
+ }{
+ \fp_set:Nn \l_@@_tmpa_fp { 1.0 }
+ \tl_set:Nn \l_@@_given_unit_tl {#1}
+ \@@_cukeys_parse_and_create_keys:nn {#1}
+ {
+ {#1} { 1.0 } #2
+ }
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{ \@@_cukeys_parse_and_create_keys:nn }
+% A simple parsing function using quarks (which are pretty handy).
+% At first parses the input, then creates the property lists for each key
+% (containing all the values) and at last defines the keys.
+% \begin{macrocode}
+\cs_new:Npn \@@_cukeys_parse_and_create_keys:nn #1#2
+ {
+ \@@_cukeys_parse_input:nn #2
+ \q_recursion_tail \q_recursion_tail \q_recursion_stop
+ \@@_cukeys_create_key_prop:n {#1}
+ \clist_set_from_seq:NN \l_@@_tmpa_clist \l_@@_tmpa_seq
+ \@@_cukeys_define_keys:V \l_@@_tmpa_clist
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{ \@@_cukeys_parse_input:nn }
+% Yeah \dots\ \lstinline|\l_@@_tmpa_clist| stores all the used unit-keys, while
+% the property list saves the relation to each other. This cycle is repeated until an
+% recursion tail is found. If you define a new key, \verb|\l_@@_tmpa_fp| is set to
+% 1 and changed later if a new key is added.
+% \begin{macrocode}
+\cs_new:Npn \@@_cukeys_parse_input:nn #1#2
+ {
+ \quark_if_recursion_tail_stop:n {#1}
+ \quark_if_recursion_tail_stop_do:nn {#2}
+ { \msg_error:nn { cooking-units } { missing-argument } }
+ \@@_error_if_unit_not_defined:n {#1}
+ \seq_put_right:Nn \l_@@_tmpa_seq {#1}
+ \prop_put:Nnx \l_@@_tmpa_prop {#1} { \fp_eval:n { (#2) / \l_@@_tmpa_fp } }
+ \@@_cukeys_parse_input:nn
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{ \@@_cukeys_create_key_prop:n }
+%
+% \changes {2016/09/22} {1.02f} {Save 'Liste', 'prop' and 'Erstes Ding' to \cs{l_tmpb_prop} and set the unit-prop lists equal to \cs{l_tmpb_prop}.}
+% \changes {2016/09/22} {1.02g} {Do not need \cs{tl_clear_new:c} as token list is already defined.}
+%
+% All linked unit-keys are stored within \lstinline|\l_@@_tmpa_clist| and are mapped
+% one after another. At first a property list is created (or cleared), this property list
+% stores the units linked to this unit, saves the created property list which contains the
+% numerical relation of each unit. \lstinline|Erstes Ding| (firsth thing) stores
+% the first unit used for defining the keys, it is needed later for adding keys.
+%
+% For each unit the other units are added in the cleared or newly created property list
+% as keys with their value being the correct numerical relation. For example:
+%
+% \begin{align*}
+% \SI{1}{\kg}&= \SI{1}{\kg} \\
+% \SI{1}{\kg}&= \SI{100}{\deka\gram} \\
+% \SI{1}{\kg}&= \SI{1000}{\g} \\
+% \SI{1}{\kg}&= \SI{35.27399}{oz}
+% \end{align*}
+%
+% Therefore the property list for \lstinline|kg| contains the keys and values:
+% \myunit{kg}=\myunit{1}
+% \myunit{dag}=\myunit{100}, \myunit{g}=\myunit{1000} and \myunit{oz}= \myunit{35.27399}.
+%
+% For the next unit (\myunit{dag} in this case) a new property list is created, relation above
+% stored inside etc. The condition now is that \myunit{dag}=\texttt{1}, therefore every number
+% is divided the the number \texttt{100}:
+%
+% \begin{align*}
+% \SI{1}{\deka\gram}&= \SI{0.01}{\kg} \\
+% \SI{1}{\deka\gram}&= \SI{1}{\deka\gram} \\
+% \SI{1}{\deka\gram}&= \SI{10}{\g} \\
+% \SI{1}{\deka\gram}&= \SI{0.3527399}{\oz}
+% \end{align*}
+%
+% Same for \myunit{g}:
+%
+% \begin{align*}
+% \SI{1}{\g}&= \SI{0.001}{\kg} \\
+% \SI{1}{\g}&= \SI{0.1}{\deka\gram} \\
+% \SI{1}{\g}&= \SI{1}{\g} \\
+% \SI{1}{\g}&= \SI{0.03527399}{oz}
+% \end{align*}
+%
+% and \myunit{oz}
+%
+% \begin{align*}
+% \SI{1}{oz}&= \SI{0.0283495}{\kg} \\
+% \SI{1}{oz}&= \SI{2.83495}{\deka\gram} \\
+% \SI{1}{oz}&= \SI{28.3495}{\g} \\
+% \SI{1}{oz}&= \SI{1}{oz}
+% \end{align*}
+%
+% \begin{macrocode}
+\cs_new:Npn \@@_cukeys_create_key_prop:n #1
+ {
+ \prop_clear:N \l_@@_tmpb_prop
+ \prop_put:NnV \l_@@_tmpb_prop { Liste } \l_@@_tmpa_seq
+ \prop_put:NnV \l_@@_tmpb_prop { prop } \l_@@_tmpa_prop
+ \prop_put:NnV \l_@@_tmpb_prop { Erstes Ding } \l_@@_given_unit_tl
+ \seq_map_inline:Nn \l_@@_tmpa_seq
+ {
+ \prop_set_eq:cN { l_@@_cukeys_ ##1 _prop } \l_@@_tmpb_prop
+ \tl_set:cn { l_@@_unit_change_ ##1 _tl } { 1.0 }
+ \seq_map_inline:Nn \l_@@_tmpa_seq
+ {
+ \prop_put:cnx { l_@@_cukeys_ ##1 _prop }
+ {####1}
+ {
+ \fp_eval:n
+ {
+ ( \prop_item:Nn \l_@@_tmpa_prop {####1} ) /
+ ( \prop_item:Nn \l_@@_tmpa_prop {##1} )
+ }
+ }
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{ \@@_cukeys_define_keys:n , \@@_cukeys_define_keys:V }
+% Defining the keys: It maps through the list of unit-keys and creates a
+% unit-key respectively.
+% \begin{macrocode}
+\cs_new:Npn \@@_cukeys_define_keys:n #1
+ {
+ \seq_map_inline:Nn \l_@@_tmpa_seq
+ {
+ \seq_if_in:NnF \l_@@_list_of_defined_keys_seq {##1}
+ { \seq_put_right:Nn \l_@@_list_of_defined_keys_seq {##1} }
+ \keys_define:nn { cooking-units }
+ {
+ ##1 .choices:Vn =
+ \l_@@_tmpa_clist
+ {
+ \@@_cukeys_define_keys_and_single_key_aux:n {##1}
+ } ,
+ ##1 / unknown .code:n=
+ {
+ \seq_set_split:Nnn \l_tmpa_seq { , } {#1}
+ \msg_error:nnxxx
+ { cooking-units }
+ { key-choice-unknown }
+ {##1}
+ {####1}
+ { \seq_use:Nnnn \l_tmpa_seq { ',~ ' } { ',~ ' } { ' ~ and ~ ' } }
+ } ,
+ ##1 .default:n = {##1} ,
+ ##1 .groups:n = { change-unit }
+ }
+ }
+ }
+\cs_generate_variant:Nn \@@_cukeys_define_keys:n { V }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_cukeys_define_keys_and_single_key_aux:n}
+%
+% \begin{macrocode}
+\cs_new:Npn \@@_cukeys_define_keys_and_single_key_aux:n #1
+ {
+ \prop_get:cVc
+ { l_@@_cukeys_#1_prop }
+ \l_keys_choice_tl
+ { l_@@_unit_change_ #1_tl }
+ \prop_put:NnV \l_@@_change_unit_prop {#1} \l_keys_choice_tl
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macrocode}
+\cs_new:Npn \@@_cukeys_parse_and_create_single_key:nn #1#2
+ {
+ \tl_set_rescan:Nnn \l_@@_tmpa_tl
+ {
+ \char_set_catcode_letter:N \# %
+ \char_set_catcode_ignore:N\ %
+ } { {#1} { 1.0 } #2 }
+ \@@_cusinglekeys_parse_input:V \l_@@_tmpa_tl
+ \@@_cusinglekeys_create_key_prop:n {#1}
+ \clist_set_from_seq:NN \l_@@_tmpa_clist \l_@@_tmpa_seq
+ \@@_cukeys_define_singlekey:nV {#1} \l_@@_tmpa_clist
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_new:Npn \@@_cusinglekeys_parse_input:n #1
+ {
+ \@@_cusinglekeys_parse_input_aux:nn #1
+ \q_recursion_tail \q_recursion_tail \q_recursion_stop
+ }
+\cs_generate_variant:Nn \@@_cusinglekeys_parse_input:n { V }
+%
+\cs_new:Npn \@@_cusinglekeys_parse_input_aux:nn #1#2
+ {
+ \quark_if_recursion_tail_stop:n {#1}
+ \quark_if_recursion_tail_stop_do:nn {#2}
+ { \msg_error:nn { cooking-units } { missing-argument } }
+ \@@_error_if_unit_not_defined:n {#1}
+ \seq_put_right:Nn \l_@@_tmpa_seq {#1}
+ \tl_set:Nn \l_@@_tmpa_tl {#2}
+ \tl_replace_all:NVn \l_@@_tmpa_tl \c_@@_input_str_hash_one_tl { \l_@@_tmpa_fp }
+ \prop_put:NnV \l_@@_tmpa_prop {#1} \l_@@_tmpa_tl
+ \@@_cusinglekeys_parse_input_aux:nn
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_new:Npn \@@_cusinglekeys_create_key_prop:n #1
+ {
+ \tl_set:cn { l_@@_unit_change_ #1 _tl } { 1.0 }
+ \prop_set_eq:cN { l_@@_cukeys_ #1 _prop } \l_@@_tmpa_prop
+ \prop_put:cnn { l_@@_cukeys_ #1 _prop } { Erstes Ding } {#1}
+ \prop_put:cnV { l_@@_cukeys_ #1 _prop } { Liste } \l_@@_tmpa_seq
+ \prop_put:cnV { l_@@_cukeys_ #1 _prop } { prop } \l_@@_tmpa_prop
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_new:Npn \@@_cukeys_define_singlekey:nn #1#2
+ {
+ \seq_if_in:NnF \l_@@_list_of_defined_keys_seq {#1}
+ { \seq_put_right:Nn \l_@@_list_of_defined_keys_seq {#1} }
+ \keys_define:nn { cooking-units }
+ {
+ #1 .choices:Vn =
+ \l_@@_tmpa_clist
+ {
+ \@@_cukeys_define_keys_and_single_key_aux:n {#1}
+ } ,
+ #1 / unknown .code:n=
+ {
+ \seq_set_split:Nnn \l_tmpa_seq { , } {#2}
+ \msg_error:nnxxx
+ { cooking-units }
+ { key-choice-unknown }
+ {#1}
+ {##1}
+ { \seq_use:Nnnn \l_tmpa_seq { ',' } { ',' } { ' ~ and ~ ' } }
+ } ,
+ #1 .default:n = {#1} ,
+ #1 .groups:n = { change-unit } ,
+ }
+ }
+\cs_generate_variant:Nn \@@_cukeys_define_singlekey:nn { nV }
+% \end{macrocode}
+%
+%
+% \section {Adding Keys}
+%
+% Question to me: Why do we need \cs{l_tmpa(b)_tl}?
+% Maybe due to \cs{cuaddtokeys}?
+% \begin{macrocode}
+\NewDocumentCommand \cuaddkeys { m m }
+ {
+ \bool_set_false:N \l_@@_single_key_bool
+ \@@_cukeys_add_keys_or_single_keys:nn {#1} {#2}
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\NewDocumentCommand \cuaddsinglekeys { m m }
+ {
+ \bool_set_true:N \l_@@_single_key_bool
+ \@@_cukeys_add_keys_or_single_keys:nn {#1} {#2}
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\NewDocumentCommand \cuaddtokeys { m m m }
+ {
+ \bool_set_false:N \l_@@_single_key_bool
+ \tl_set:Nn \l_@@_tmpb_tl { {#2} { \fp_eval:n { 1.0 / (#3) } } }
+ \@@_cukeys_add_keys_or_single_keys:nV {#1} \l_@@_tmpb_tl
+ }
+% \end{macrocode}
+%
+%
+%
+% \begin{macrocode}
+\cs_new:Npn \@@_cukeys_add_keys_or_single_keys:nn #1#2
+ {
+ \@@_error_if_unit_not_defined:n {#1}
+ \seq_if_in:NnF \l_@@_list_of_defined_keys_seq {#1}
+ { \msg_error:nnn { cooking-units } { Key-not-defined } {#1} }
+ \tl_if_blank:nF {#2}
+ {
+ \@@_cukeys_add_keys_and_single_key_aux:n {#1}
+ \bool_if:NTF \l_@@_single_key_bool
+ { \@@_cukeys_parse_and_create_single_key:nn {#1} {#2} }
+ { \@@_cukeys_parse_and_create_keys:nn {#1} {#2} }
+ }
+ }
+\cs_generate_variant:Nn \@@_cukeys_add_keys_or_single_keys:nn { nV }
+% \end{macrocode}
+%
+%
+% \begin{macrocode}
+\cs_new:Npn \@@_cukeys_add_keys_and_single_key_aux:n #1
+ {
+ \prop_get:cnN { l_@@_cukeys_ #1 _prop } { Liste } \l_@@_tmpa_seq
+ \prop_get:cnN { l_@@_cukeys_ #1 _prop } { prop } \l_@@_tmpa_prop
+ \prop_get:cnN { l_@@_cukeys_ #1 _prop } { Erstes Ding } \l_@@_given_unit_tl
+ \prop_get:cVN { l_@@_cukeys_ #1 _prop } \l_@@_given_unit_tl \l_@@_tmpa_fp
+ }
+% \end{macrocode}
+%
+%
+% \section {Creating New Units}
+%
+%
+%\begin{macro}{ \declarecookingunit , \newcookingunit , \providecookingunit }
+% \begin{macrocode}
+\NewDocumentCommand \declarecookingunit { o m }
+ {
+ \seq_if_in:NnTF \g_@@_list_of_defined_units_seq {#2}
+ { \msg_info:nnn { cooking-units } { redefine-unit } {#2} }
+ { \@@_new_cooking_unit:nn {#1} {#2} }
+ \@@_set_cooking_unit:nn {#1} {#2}
+ }
+\NewDocumentCommand \newcookingunit { o m }
+ {
+ \@@_new_cooking_unit:nn {#1} {#2}
+ \@@_set_cooking_unit:nn {#1} {#2}
+ }
+\NewDocumentCommand \providecookingunit { o m }
+ {
+ \seq_if_in:NnF \g_@@_list_of_defined_units_seq {#2}
+ {
+ \@@_new_cooking_unit:nn {#1} {#2}
+ \@@_set_cooking_unit:nn {#1} {#2}
+ }
+ }
+% \end{macrocode}
+%\end{macro}
+%
+% \begin{macrocode}
+\cs_new:Npn \@@_new_cooking_unit:nn #1#2
+ {
+ \seq_if_in:NnTF \g_@@_list_of_defined_units_seq {#2}
+ { \msg_error:nnn { cooking-units } { unit-already-defined } {#2} }
+ {
+ \tl_map_inline:nn {#2}
+ {
+ \tl_if_in:NnT \l_@@_unit_letter_not_allowed_tl {##1}
+ { \msg_error:nnn { cooking-units } { character-not-allowed } {#2} }
+ }
+ \seq_put_right:Nn \g_@@_list_of_defined_units_seq {#2}
+ \tl_new:c { l_@@_unit_change_ #2 _tl }
+ \tl_set:cn { l_@@_unit_change_ #2 _tl } { 1.0 }
+ \clist_new:c { l_@@_predefined_option_#2_clist }
+ \keys_define:nn { cooking-units }
+ {
+ set-option-for-#2 .clist_set:c = { l_@@_predefined_option_#2_clist } ,
+ add-option-for-#2 .code:n =
+ { \clist_put_right:cn { l_@@_predefined_option_#2_clist } {##1} },
+ }
+ \prop_new:c { l_@@_cukeys_ #2 _prop }
+ \tl_new:c { l_@@_default_unit_ #2 _tl }
+ }
+ }
+\cs_new:Npn \@@_set_cooking_unit:nn #1#2
+ {
+ \IfNoValueTF {#1}
+ {
+ \tl_set:cn { l_@@_default_unit_ #2 _tl } {#2}
+ \@@_deftranslation_base:xxn {#2} \c_@@_postfix_unit_tl {#2}
+ }{
+ \tl_set:cn { l_@@_default_unit_ #2 _tl } {#1}
+ \@@_deftranslation_base:xxn {#2} \c_@@_postfix_unit_tl {#1}
+ }
+ \@@_deftranslation_base:xxn {#2} \c_@@_postfix_unitname_tl { \q_@@_no_translation }
+ \@@_deftranslation_base:xxn {#2} \c_@@_postfix_unitname_pl_tl { \q_@@_no_translation }
+ \@@_deftranslation_base:xxn {#2} \c_@@_postfix_gender_tl { m }
+ }
+% \end{macrocode}
+%
+%
+%
+% \section {Names}
+%
+% Stolen from \pkg{l3keys.dtx}
+% \begin{macrocode}
+\tl_new:N \l_@@_sanitise_tl
+\cs_new_protected:Npn \@@_sanitise_aux:w #1 \q_mark
+ { \tl_set:Nn \l_@@_sanitise_tl {#1} }
+\group_begin:
+ \char_set_catcode_active:n { `\< }
+ \char_set_catcode_active:n { `\> }
+ \cs_new:Npn \@@_sanitize_open_arrow:
+ {
+ \exp_after:wN \@@_sanitize_open_arrow_auxi:w \l_@@_sanitise_tl
+ \q_mark < \q_nil <
+ \exp_after:wN \@@_sanitise_aux:w \l_@@_sanitise_tl
+ }
+ \cs_new_protected:Npn \@@_sanitize_open_arrow_auxi:w #1 <
+ {
+ \tl_set:Nn \l_@@_sanitise_tl {#1}
+ \@@_sanitize_open_arrow_auxii:w
+ }
+ \cs_new_protected:Npn \@@_sanitize_open_arrow_auxii:w #1 <
+ {
+ \quark_if_nil:nF {#1}
+ {
+ \tl_set:Nx \l_@@_sanitise_tl
+ {
+ \exp_not:V \l_@@_sanitise_tl
+ \token_to_str:N <
+ \exp_not:n {#1}
+ }
+ \exp_after:wN \@@_sanitize_open_arrow_auxii:w
+ }
+ }
+ \cs_new:Npn \@@_sanitize_close_arrow:
+ {
+ \exp_after:wN \@@_sanitize_close_arrow_auxi:w \l_@@_sanitise_tl
+ \q_mark > \q_nil >
+ \exp_after:wN \@@_sanitise_aux:w \l_@@_sanitise_tl
+ }
+ \cs_new_protected:Npn \@@_sanitize_close_arrow_auxi:w #1 >
+ {
+ \tl_set:Nn \l_@@_sanitise_tl {#1}
+ \@@_sanitize_close_arrow_auxii:w
+ }
+ \cs_new_protected:Npn \@@_sanitize_close_arrow_auxii:w #1 >
+ {
+ \quark_if_nil:nF {#1}
+ {
+ \tl_set:Nx \l_@@_sanitise_tl
+ {
+ \exp_not:V \l_@@_sanitise_tl
+ \token_to_str:N >
+ \exp_not:n {#1}
+ }
+ \exp_after:wN \@@_sanitize_close_arrow_auxii:w
+ }
+ }
+\group_end:
+\cs_new_protected:Npn \@@_sanitize_arrows:n #1
+ {
+ \tl_set:Nn \l_@@_sanitise_tl {#1}
+ \@@_sanitize_open_arrow:
+ \@@_sanitize_close_arrow:
+ }
+% \end{macrocode}
+%
+%
+% \begin{macrocode}
+\NewDocumentCommand \cudefinename { m m }
+ {
+ \tl_set:Nn \l_@@_language_tl {#1}
+ \@@_sanitize_arrows:n {#2}
+ \exp_last_unbraced:NV
+ \@@_cuname_parse_input:n \l_@@_sanitise_tl
+ \q_recursion_tail \q_recursion_tail \q_recursion_stop
+ }
+% \end{macrocode}
+%
+%
+% \begin{macrocode}
+\cs_new:Npn \@@_cuname_parse_input:n #1
+ {
+ \peek_meaning_ignore_spaces:NTF [
+ {
+ \@@_cuname_parse_unit_symbol:nw {#1}
+ }{
+ \seq_if_in:NnTF \g_@@_allowed_special_keys_seq {#1}
+ { \@@_cuname_parse_input_aux:nn {#1} }
+ { \@@_cuname_parse_unit_symbol:nw {#1} [ \q_no_value ] }
+ }
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_new:Npn \@@_cuname_parse_unit_symbol:nw #1 [#2]
+ {
+ \quark_if_recursion_tail_stop:n {#1}
+ \quark_if_recursion_tail_stop_do:nn {#2}
+ { \msg_error:nn { cooking-units } { missing-argument } }
+ \@@_error_if_unit_not_defined:n {#1}
+ \quark_if_no_value:nTF {#2}
+ {
+ \@@_deftranslation_to:Vxxv
+ \l_@@_language_tl {#1}
+ \c_@@_postfix_unit_tl
+ { l_@@_default_unit_ #1 _tl }
+ }{
+ \@@_deftranslation_to:Vxxn
+ \l_@@_language_tl {#1}
+ \c_@@_postfix_unit_tl {#2}
+ }
+ \@@_cuname_parse_input_aux:nn {#1}
+ }
+% \end{macrocode}
+%
+%
+% \begin{macrocode}
+\cs_new:Npn \@@_cuname_parse_input_aux:nn #1#2
+ {
+ \quark_if_recursion_tail_stop:n {#1}
+ \quark_if_recursion_tail_stop_do:nn {#2}
+ { \msg_error:nn { cooking-units } { missing-argument } }
+ \seq_if_in:NnF \g_@@_allowed_special_keys_seq {#1}
+ { \@@_error_if_unit_not_defined:n {#1} }
+ \@@_deftranslation_to:Vxxn
+ \l_@@_language_tl {#1}
+ \c_@@_postfix_unitname_tl {#2}
+ \peek_meaning_ignore_spaces:NTF [
+ { \@@_cuname_parse_bracket:nw {#1} }
+ { \@@_cuname_parse_bracket:nw {#1} [#2] }
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_new:Npn \@@_cuname_parse_bracket:nw #1 [#2]
+ {
+ \seq_if_in:NnF \g_@@_allowed_special_keys_seq {#1}
+ {
+ \@@_deftranslation_to:Vxxn \l_@@_language_tl {#1}
+ \c_@@_postfix_unitname_pl_tl {#2}
+ }
+ \peek_meaning_ignore_spaces:NTF <
+ { \@@_cuname_parse_gender:nw {#1} }
+ { \@@_cuname_parse_gender:nw {#1} <m> }
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_new:Npn \@@_cuname_parse_gender:nw #1 <#2>
+ {
+ \@@_check_if_correct_gender_input:n {#2}
+ \@@_deftranslation_to:Vxxn
+ \l_@@_language_tl {#1}
+ \c_@@_postfix_gender_tl {#2}
+ \@@_cuname_parse_input:n
+ }
+% \end{macrocode}
+%
+%
+%
+% \subsection {cudefinesymbol}
+%
+%
+% \begin{macrocode}
+\NewDocumentCommand \cudefinesymbol { m m }
+ {
+ \tl_set:Nn \l_@@_language_tl {#1}
+ \@@_cuprint_define_printed_unit:nn #2
+ \q_recursion_tail \q_recursion_tail \q_recursion_stop
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_new:Npn \@@_cuprint_define_printed_unit:nn #1#2
+ {
+ \quark_if_recursion_tail_stop:n {#1}
+ \quark_if_recursion_tail_stop_do:nn {#2}
+ { \msg_error:nn { cooking-units } { missing-argument } }
+ \seq_if_in:NnTF \g_@@_allowed_special_keys_seq {#1}
+ {
+ \@@_deftranslation_to:Vxxn \l_@@_language_tl {#1}
+ \c_@@_postfix_unitname_tl {#2}
+ }{
+ \@@_error_if_unit_not_defined:n {#1}
+ \@@_deftranslation_to:Vxxn
+ \l_@@_language_tl {#1}
+ \c_@@_postfix_unit_tl {#2}
+ }
+ \@@_cuprint_define_printed_unit:nn
+ }
+% \end{macrocode}
+%
+%
+%
+% \subsection {Phrases}
+%
+%
+% \begin{macrocode}
+\@@_newtranslation_base:nVn { phrase-prop } \c_@@_postfix_phrase_tl { \q_@@_no_translation }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\prg_new_conditional:Npnn \@@_phrase_list_get_for:NN #1#2 { TF }
+ {
+ \@@_translate_let:VNnV #2 #1 { phrase-prop } \c_@@_postfix_phrase_tl
+ \tl_if_eq:NNTF #1 \q_@@_no_translation
+ { \prg_return_false: }
+ { \prg_return_true: }
+ }
+\prg_new_conditional:Npnn \@@_get_phrase_for_current_langauge:NN #1#2 { T }
+ {
+ \@@_translate_let:NnV #1 { phrase-prop } \c_@@_postfix_phrase_tl
+ \tl_if_eq:NNTF #1 \q_@@_no_translation
+ { \prg_return_false: }
+ {
+ \@@_translate_let:NnV #2 { phrase-clist } \c_@@_postfix_phrase_tl
+ \prg_return_true:
+ }
+ }
+% \end{macrocode}
+% \begin{macrocode}
+\NewDocumentCommand \cudefinephrase { m m }
+ {
+ \@@_cuphrase:nn {#1} {#2}
+ }
+\cs_new:Npn \@@_cuphrase:nn #1#2
+ {
+ \tl_set:Nn \l_@@_language_tl {#1}
+% \end{macrocode}
+% \begin{macrocode}
+ \@@_phrase_list_get_for:NNTF \l_@@_phrase_prop \l_@@_language_tl
+ {
+ \@@_translate_let:VNnV \l_@@_language_tl \l_@@_phrase_numbers_seq
+ { phrase-clist } \c_@@_postfix_phrase_tl
+ }{
+ \prop_clear:N \l_@@_phrase_prop
+ \seq_clear:N \l_@@_phrase_numbers_seq
+ }
+% \end{macrocode}
+% \begin{macrocode}
+ \@@_sanitize_arrows:n {#2}
+ \exp_last_unbraced:NV
+ \@@_cuphrase_parse:n \l_@@_sanitise_tl
+ \q_recursion_tail \q_recursion_tail \q_recursion_stop
+% \end{macrocode}
+% \begin{macrocode}
+ \seq_sort:Nn \l_@@_phrase_numbers_seq
+ {
+ \int_compare:nNnTF { \int_abs:n {##1} } < { \int_abs:n {##2} }
+ { \sort_return_swapped: }
+ {
+ \int_compare:nNnTF { \int_abs:n {##1} } = { \int_abs:n {##2} }
+ {
+ \int_compare:nNnTF {##1} < {##2}
+ { \sort_return_same: }
+ { \sort_return_swapped: }
+ }{ \sort_return_same: }
+ }
+ }
+% \end{macrocode}
+% \begin{macrocode}
+ \@@_deftranslation_to:VxxV
+ \l_@@_language_tl { phrase-prop }
+ \c_@@_postfix_phrase_tl
+ \l_@@_phrase_prop
+ \@@_deftranslation_to:VxxV
+ \l_@@_language_tl { phrase-clist }
+ \c_@@_postfix_phrase_tl \l_@@_phrase_numbers_seq
+ }
+% \end{macrocode}
+%
+%
+% \begin{macrocode}
+\cs_new:Npn \@@_cuphrase_parse:n #1
+ {
+ \quark_if_recursion_tail_stop:n {#1}
+ \@@_if_integer:nF {#1}
+ { \msg_error:nnn { cooking-units} { phrase-unit-not-an-integer } {#1} }
+ \peek_meaning_remove_ignore_spaces:NTF *
+ {
+ \int_set:Nn \l_@@_tmpa_int {-#1}
+ \@@_cuphrase_parse_normal:Vn \l_@@_tmpa_int
+ }{
+ \int_set:Nn \l_@@_tmpa_int {#1}
+ \@@_cuphrase_parse_normal:Vn \l_@@_tmpa_int
+ }
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_new:Npn \@@_cuphrase_parse_normal:nn #1#2
+ {
+ \quark_if_recursion_tail_stop_do:nn {#2}
+ { \msg_error:nn { cooking-units } { missing-argument } }
+ \prop_put:Nnn \l_@@_phrase_prop {#1} {#2}
+ \seq_if_in:NnF \l_@@_phrase_numbers_seq {#1}
+ { \seq_push:Nn \l_@@_phrase_numbers_seq {#1} }
+ \peek_meaning_ignore_spaces:NTF [
+ {
+ \@@_chuphrase_parse_plural:nw {#1}
+ }{
+ \@@_chuphrase_parse_plural:nw {#1} [#2]
+ }
+ }
+\cs_generate_variant:Nn \@@_cuphrase_parse_normal:nn { V }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_new:Npn \@@_chuphrase_parse_plural:nw #1 [#2]
+ {
+ \prop_put:Nnn \l_@@_phrase_prop { #1-pl } {#2}
+ \peek_meaning_ignore_spaces:NTF <
+ {
+ \@@_chuphrase_parse_gender:nw {#1}
+ }{
+ \@@_chuphrase_parse_gender:nw {#1} < m >
+ }
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_new:Npn \@@_chuphrase_parse_gender:nw #1 <#2>
+ {
+ \@@_check_if_correct_gender_input:n {#2}
+ \@@_deftranslation_to:Vxxn
+ \l_@@_language_tl { #1-phrase-gender }
+ \c_@@_postfix_gender_tl {#2}
+ \@@_cuphrase_parse:n
+ }
+% \end{macrocode}
+%
+%
+%
+%
+% \subsection{Old stuff}
+%
+% \begin{macro} { }
+% \begin{macrocode}
+\cs_new:Npn \@@_old_cutext:nnn #1#2#3
+ {
+ \tl_set_eq:NN \l_@@_option_unit_tl \l_@@_given_unit_tl
+ \@@_old_cutext_default:nnn {#1} {#2} {#3}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \begin{macro} { \@@_old_cutext_default:nnn }
+% \changes {2016/06/11} {0.98a} { New command }
+% \begin{macrocode}
+\cs_new:Npn \@@_old_cutext_default:nnn #1#2#3
+ {
+ \bool_if:NTF \l_@@_draft_bool
+ {#2}
+ {
+ \tl_set:Nn \l_@@_cutext_last_value_tl {#2}
+ \tl_if_in:NVTF \l_@@_cutext_last_value_tl \l_@@_input_range_sign_tl
+ {
+ \tl_replace_once:NVn \l_@@_cutext_last_value_tl
+ \l_@@_input_range_sign_tl { \q_@@_range }
+ \@@_old_cutext_parse_range:Vn \l_@@_cutext_last_value_tl {#3}
+ }{
+ \@@_old_cutext_print_input:Nn \l_@@_cutext_last_value_tl {#3}
+ }
+ }
+ }
+% \end{macrocode}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_old_cutext_print_input:Nn #1#2
+ {
+ \@@_old_cutext_if_numeral_is_int_and_parse_and_smaller_then_print_numerals:NTF #1
+ {
+ \@@_int_if_equal_one:nTF {#1}
+ {
+ \@@_translate_one_and_check_existance:Nx \l_@@_translation_tmpa_tl {#2}
+ \bool_if:NTF \l_@@_cutext_uppercase_word_bool
+ {
+ \exp_args:Nx \tl_upper_case:n { \tl_head:V \l_@@_translation_tmpa_tl }
+ \tl_tail:V \l_@@_translation_tmpa_tl
+ }
+ { \l_@@_translation_tmpa_tl }
+ }{
+ \bool_if:NTF \l_@@_cutext_uppercase_word_bool
+ { \@@_print_Numeral:n {#1} }
+ { \@@_print_numeral:n {#1} }
+ }
+ }
+ { \@@_print_numerical_input:N #1 }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro} {\@@_old_cutext_if_numeral_is_int_and_parse_and_smaller_then_print_numerals:N}
+% \begin{macrocode}
+\prg_new_conditional:Npnn \@@_old_cutext_if_numeral_is_int_and_parse_and_smaller_then_print_numerals:N #1 { TF }
+ {
+ \bool_if:NTF \l_@@_lokal_numeral_bool
+ {
+ \@@_if_integer:VTF #1
+ {
+ \int_compare:nNnTF {#1} < { \l_@@_print_numerals_below_int }
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }{ \prg_return_false: }
+ }{ \prg_return_false: }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+\cs_new:Npn \@@_old_cutext_parse_range:nn #1 #2
+ {
+ \@@_old_cutext_parse_range_aux:nww {#2} #1 \q_stop
+ }
+\cs_generate_variant:Nn \@@_old_cutext_parse_range:nn { V }
+\cs_new:Npn \@@_old_cutext_parse_range_aux:nww #1 #2 \q_@@_range #3 \q_stop
+ {
+ \tl_set:Nn \l_@@_tmpa_tl {#2}
+ \tl_set:Nn \l_@@_cutext_last_value_tl {#3}
+ \@@_old_cutext_print_input:Nn \l_@@_tmpa_tl {#1}
+ \tl_use:N \l_@@_cutext_range_sign_tl
+ \@@_old_cutext_print_input:Nn \l_@@_cutext_last_value_tl {#1}
+ }
+% \end{macrocode}
+%
+%
+% \begin{macro}{\@@_cuam_old:n}
+% \begin{macrocode}
+\cs_new:Npn \@@_cuam_old:n #1
+ {
+ \tl_set_rescan:Nnn \l_@@_tmpa_tl
+ {
+ \char_set_catcode_letter:N \_ %
+ \char_set_catcode_ignore:N\ %
+ } {#1}
+ \bool_if:NTF \l_@@_draft_bool
+ { \l_@@_tmpa_tl }
+ { \@@_cuam_old_parse:V \l_@@_tmpa_tl }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_cuam_old_parse:n #1
+ {
+ \tl_if_in:nVTF {#1} \l_@@_input_range_sign_tl
+ {
+ \tl_set:Nn \l_@@_tmpa_tl {#1}
+ \tl_replace_once:NVn \l_@@_tmpa_tl \l_@@_input_range_sign_tl { \q_@@_range }
+ \@@_cuam_old_parse_range:V \l_@@_tmpa_tl
+ }{
+ \tl_if_in:nnTF {#1} { / }
+ {
+ \tl_if_in:nnTF {#1} { _ }
+ { \@@_cuam_old_parse_mixed_frac:www #1 \q_stop }
+ { \@@_cuam_old_parse_frac:ww #1 \q_stop }
+ }{
+ \tl_if_in:nnTF {#1} { _ }
+ { \msg_error:nnn { cooking-units } { missing-slash } {#1} }
+ { \@@_cuam_old_parse_scale:n {#1} }
+ }
+ }
+ }
+\cs_generate_variant:Nn \@@_cuam_old_parse:n { V }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_new:Npn \@@_cuam_old_parse_range:n #1
+ {
+ \@@_cuam_old_parse_range_aux:ww #1 \q_nil
+ }
+\cs_generate_variant:Nn \@@_cuam_old_parse_range:n { V }
+\cs_new:Npn \@@_cuam_old_parse_range_aux:ww #1 \q_@@_range #2 \q_nil
+ {
+ #1 \l_@@_cunum_range_sign_tl #2
+ }
+% \end{macrocode}
+%
+%
+% \begin{macrocode}
+\cs_new:Npn \@@_cuam_old_parse_scale:n #1 {#1}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_new:Npn \@@_cuam_old_parse_frac:ww #1/#2 \q_stop
+ { \@@_frac:nn {#1} {#2} }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_new:Npn \@@_cuam_old_parse_mixed_frac:www #1_#2/#3 \q_stop
+ {
+ #1
+ \@@_dim_horizontal:N \l_@@_mixed_frac_dim
+ \@@_frac:nn {#2} {#3}
+ }
+% \end{macrocode}
+%
+%
+% \subsubsection {cufrac}
+%
+% Obsolete.
+% \begin{macrocode}
+\NewDocumentCommand \cufrac { O{} m }
+ {
+ \msg_error:nnnn { cooking-units } { obsolete-command } { \cufrac } { \cuam }
+ \group_begin:
+ \tl_if_empty:nF {#1}
+ { \keys_set:nn { cooking-units } {#1} }
+ \@@_cufrac:n {#2}
+ \group_end:
+ }
+\cs_new:Npn \@@_cufrac:n #1
+ {
+ \tl_set_rescan:Nnn \l_@@_tmpa_tl
+ {
+ \char_set_catcode_letter:N \_ %
+ \char_set_catcode_ignore:N\ %
+ } {#1}
+ \@@_cufrac_parse:V \l_@@_tmpa_tl
+ }
+\cs_new:Npn \@@_cufrac_parse:n #1
+ {
+ \tl_if_in:nnTF {#1} { / }
+ {
+ \tl_if_in:nnTF {#1} { _ }
+ { \@@_cufrac_parse_mixed_frac:www #1 \q_stop }
+ { \@@_cufrac_parse_frac:ww #1 \q_stop }
+ }{
+ \tl_if_in:nnTF {#1} { _ }
+ { \msg_error:nnn { cooking-units } { missing-slash } {#1} }
+ { \@@_cufrac_parse_scale:n {#1} }
+ }
+ }
+\cs_generate_variant:Nn \@@_cufrac_parse:n { V }
+\cs_new:Npn \@@_cufrac_parse_scale:n #1 {#1}
+\cs_new:Npn \@@_cufrac_parse_frac:ww #1/#2 \q_stop
+ { \@@_frac:nn {#1} {#2} }
+\cs_new:Npn \@@_cufrac_parse_mixed_frac:www #1_#2/#3 \q_stop
+ {
+ #1
+ \@@_dim_horizontal:N \l_@@_mixed_frac_dim
+ \@@_frac:nn {#2} {#3}
+ }
+% \end{macrocode}
+%
+%
+%
+%
+% \subsection {cusetup}
+%
+% \begin{macrocode}
+\NewDocumentCommand \cusetup { m }
+ {
+ \keys_set:nn { cooking-units } {#1}
+ }
+% \end{macrocode}
+%
+%
+%
+% \subsection{Definitions et all}
+%
+% \begin{macrocode}
+\newcookingunit { kg }
+\newcookingunit { dag }
+\newcookingunit { g }
+\newcookingunit { oz }
+\newcookingunit { lb }
+\newcookingunit { stick }
+\newcookingunit [ \ensuremath{ \@@_frac:nn { eV } { c^2 } } ] { eVc-2 }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\newcookingunit { K }
+\newcookingunit [ \ensuremath{ {} ^ { \circ } } \kern-\scriptspace C ] { C }
+\newcookingunit [ \ensuremath{ {} ^ { \circ } } \kern-\scriptspace F ] { F }
+\newcookingunit [ \ensuremath{ {} ^ { \circ } } \kern-\scriptspace R\'{e} ] { Re }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\newcookingunit { d }
+\newcookingunit { h }
+\newcookingunit { min }
+\newcookingunit { s }
+\newcookingunit [ \ensuremath{ \@@_frac:nn { \hbar } { eV } } ] { hbareV-1 }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\newcookingunit { m }
+\newcookingunit { cm }
+\newcookingunit { dm }
+\newcookingunit { mm }
+\newcookingunit { in }
+\newcookingunit [ \ensuremath{ \@@_frac:nn { c\hbar } { eV } } ] { chbareV-1 }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\newcookingunit { l }
+\newcookingunit { dl }
+\newcookingunit { cl }
+\newcookingunit { ml }
+\newcookingunit [ \ensuremath { \@@_frac:nn { c^3 \hbar^3 } { eV^3 } } ] { (chbareV-1)3 }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\newcookingunit { cal }
+\newcookingunit { kcal }
+\newcookingunit { J }
+\newcookingunit { kJ }
+\newcookingunit { eV }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\newcookingunit [ pinch ] { pn }
+\newcookingunit { EL }
+\newcookingunit { TL }
+\newcookingunit [ ssp. ] { ssp } %% saltspoonful
+\newcookingunit [ csp. ] { csp } %% coffeespoonful
+\newcookingunit [ dsp. ] { dsp }
+\newcookingunit [ Msp. ] { Msp }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\DeclareLanguageAlias { AmericanEnglish } { American }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cudefinename { German }
+ {
+ { kg } { Kilogramm } < n >
+ { dag } { Dekagramm } < n >
+ { g } { Gramm } < n >
+ { oz } { Unze } < f >
+ { lb } { Pfund } < n >
+% \end{macrocode}
+% \begin{macrocode}
+ { d } { Tag } [ Tage ]
+ { h } { Stunde } [ Stunden ] < f >
+ { min } { Minute } [ Minuten ] < f >
+ { s } { Sekunde } [ Sekunden ] < f >
+% \end{macrocode}
+% \begin{macrocode}
+ { C } { Grad \space Celsius }
+ { K } { Kelvin } < n >
+ { F } { Grad \space Fahrenheit }
+ { Re } { Grad \space R\'{e}amur }
+% \end{macrocode}
+% \begin{macrocode}
+ { m } { Meter } < n >
+ { dm } { Dezimeter } < n >
+ { cm } { Centimeter } < n >
+ { mm } { Millimeter } < n >
+ { in } { Zoll }
+% \end{macrocode}
+% \begin{macrocode}
+ { l } [ l ] { Liter }
+ { dl } { Deziliter }
+ { cl } { Centiliter }
+ { ml } { Milliliter }
+% \end{macrocode}
+% \begin{macrocode}
+ { cal } { Kalorie } [ Kalorien ] < f >
+ { kcal } { Kilokalorie } [ Kilokalorien ] < f >
+ { J } { Joule }
+ { kJ } { Kilojoule }
+ { eV } { Elektronenvolt } < n >
+% \end{macrocode}
+% \begin{macrocode}
+ { Msp } [ Msp. ] { Messerspitze } [ Messerspitzen ] < f >
+ { pn } [ Prise ] { Prise } [ Prisen ] < f >
+ { EL } [ EL ] { Essl{\"o}ffel }
+ { TL } [ TL ] { Teel{\"o}ffel }
+ { csp } [ KL ] { Mokkal{\"o}ffel }
+% \end{macrocode}
+% \begin{macrocode}
+ { decimal-mark } { , }
+ { one (m) } { ein }
+ { one (f) } { eine }
+ { one (n) } { ein }
+ }
+% \end{macrocode}
+%
+%
+% \begin{macrocode}
+\cudefinename { English }
+ {
+ { kg } { kilogramme }
+ { dag } { decagramme }
+ { g } { gramme }
+ { oz } { ounce }
+ { lb } { pound } [ pounds ]
+ { stick } { stick } [ sticks ]
+% \end{macrocode}
+% \begin{macrocode}
+ { d } { day } [ days ]
+ { h } { hour } [ hours ]
+ { min } { minute } [ minutes ]
+ { s } { second } [ seconds ]
+% \end{macrocode}
+% \begin{macrocode}
+ { C } { degree \space Celsius } [ degrees \space Celsius ]
+ { F } { degree \space Fahrenheit } [ degrees \space Fahrenheit ]
+ { K } { kelvin }
+ { Re } { degree \space R\'{e}aumur } [ degrees \space R\'{e}aumur ]
+% \end{macrocode}
+% \begin{macrocode}
+ { m } { metre } [ metres ]
+ { dm } { decimetre } [ decimetres ]
+ { cm } { centimetre } [ centimetres ]
+ { mm } { millimitre } [ millimitres ]
+ { in } { inch } [ inches ]
+% \end{macrocode}
+% \begin{macrocode}
+ { l } [ \ensuremath { \ell } ] { litre } [ litres ]
+ { dl } { decilitre } [ decilitres ]
+ { cl } { centilitre } [ centilitres ]
+ { ml } { millilitre } [ millilitres ]
+% \end{macrocode}
+% \begin{macrocode}
+ { cal } { calorie } [ calories ]
+ { kcal } { kilocalorie } [ kilocalories ]
+ { J } { joule } [ joules ]
+ { kJ } { kilojoule } [ kilojoules ]
+ { eV } { electron \space volt }
+% \end{macrocode}
+% \begin{macrocode}
+% { Msp } [ pinch ] { pinch } [ pinches ]
+% { Msp } { Messerspitze } [ Messerspitzen ] <f>
+ { pn } [ pinch ] { pinch } [ pinches ]
+ { EL } [ tbsp. ] { tablespoon } [ tablespoons ]
+ { TL } [ tsp. ] { teaspoon } [ teaspoons ]
+ { dsp } { dessertspoonful }
+ { csp } { coffeespoonful }
+ { ssp } { saltspoonful }
+% \end{macrocode}
+% \begin{macrocode}
+ { decimal-mark } { . }
+ { one (m) } { one }
+ { one (f) } { one }
+ { one (n) } { one }
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cudefinename { AmericanEnglish }
+ {
+ { kg } { kilogram }
+ { dag } { decagram }
+ { g } { gram }
+ { oz } { ounce }
+% \end{macrocode}
+% \begin{macrocode}
+ { m } { meter } [ meters ]
+ { dm } { decimeter } [ decimeters ]
+ { cm } { centimeter } [ centimeters ]
+ { mm } { millimiter } [ millimiters ]
+ { in } { inch } [ inches ]
+% \end{macrocode}
+% \begin{macrocode}
+ { l } [ \ensuremath { \ell } ] { liter } [ liters ]
+ { dl } { deciliter } [ deciliters ]
+ { cl } { centiliter } [ centiliters ]
+ { ml } { milliliter } [ milliliters ]
+% \end{macrocode}
+% \begin{macrocode}
+% { Msp } { Messerspitze } [ Messerspitzen ] <f>
+ { pn } [ pn. ] { pinch } [ pinches ]
+ }
+% \end{macrocode}
+%
+%
+% \begin{macrocode}
+\cudefinename { French }
+ {
+ { kg } { kilogramme } [ kilogrammes ]
+ { dag } { d\'{e}cagramme } [ d\'{e}cagrammes]
+ { g } { gramme } [ gramme ]
+ { oz } { once } < f >
+ { lb } { livre } [ livres ] < f >
+% \end{macrocode}
+% \begin{macrocode}
+ { d } { jour } [ jours ]
+ { h } { heure } [ heures ] < f >
+ { min } { minute } [ minutes ] < f >
+ { s } { seconde } [ secondes ] < f >
+% \end{macrocode}
+% \begin{macrocode}
+ { C } { degr\'{e} \space Celsius } [ degr\'{e}s \space Celsius ]
+ { K } { degr\'{e} \space Fahrenheit } [ degr\'{e}s \space Fahrenheit ]
+ { F } { kelvin } [ kelvins ]
+ { Re } { \'{e}chelle \space R\'{e}aumur } [ degr\'{e}s \space R\'{e}aumur ]
+% \end{macrocode}
+% \begin{macrocode}
+ { m } { m\`{e}tre } [ m\`{e}tres ]
+ { dm } { d\'{e}cim\`{e}tre } [ d\'{e}cim\`{e}tres ]
+ { cm } { centim\`{e}tre } [ centim\`{e}tres ]
+ { mm } { millim\`{e}tre } [ millim\`{e}tres ]
+ { in } [ po ] { pouce } [ pouces ]
+% \end{macrocode}
+% \begin{macrocode}
+ { l } [ L ] { litre } [ litres ]
+ { dl } [ dL ] { d\'{e}cilitre } [ d\'{e}cilitres ]
+ { cl } [ cL ] { centilitre } [ centilitres ]
+ { ml } [ mL ] { millilitre } [ millilitres ]
+% \end{macrocode}
+% \begin{macrocode}
+ { cal } { calorie } [ calorie ]
+ { kcal } { kilocalorie } [ kilocalories ]
+ { J } { joule } [ joules ]
+ { kJ } { kilojoule } [ kilojoules ]
+ { eV } { \'{e}lectron-volt } [ \'{e}lectron-volts ]
+% \end{macrocode}
+% \begin{macrocode}
+ { pn } { pinc\'{e}e } < f >
+ { EL } [c.\`{a}.s.] { cuill\`{e}re \space \`{a} \space soupe } < f >
+ { TL } [c.\`{a}.c.] { cuill\`{e}re \space \`{a} \space caf\'{e} } < f >
+% \end{macrocode}
+% \begin{macrocode}
+ { decimal-mark } { . }
+ { one (m) } { un }
+ { one (f) } { une }
+ { one (n) } { un }
+ }
+% \end{macrocode}
+%
+%
+%
+% \begin{macrocode}
+\cudefinekeys { kg }
+ {
+ { dag }{ 100 }
+ { g } { 1000 }
+ { oz } { 35.27399 }
+ { lb } { 2.2046226 } %% 2.204 622 6
+ { stick } { 8.81849 }
+ { eVc-2 } { 560958865.0e+27 } %% 560958865.0 +- 3.5 e+27
+ }
+% \end{macrocode}
+% \begin{macrocode}
+\cudefinekeys { d }
+ {
+ { h } { 24 }
+ { min }{ 1440 }
+ { s } { 86400 }
+ { hbareV-1 } { 151926746.1e+7 * 86400 } %% 151926746.1 +- 2.1 e+7
+ }
+%\cuaddtokeys { s } { hbareV-1 } { 6.582119514e-16 }
+% \end{macrocode}
+% \begin{macrocode}
+\cudefinekeys { m }
+ {
+ { dm } { 10 }
+ { cm } { 100 }
+ { mm } { 1000 }
+ { in } { 39.370079 }
+ { chbareV-1 } { 5067730.759 } %% 5067730.759 +- 0.070
+ }
+%\cuaddtokeys { m } { chbareV-1 } { 1.97326972e-7 }
+% \end{macrocode}
+% \begin{macrocode}
+\cudefinekeys { l }
+ {
+ { dl } { 10 }
+ { cl } { 100 }
+ { ml }{ 1000 }
+ { (chbareV-1)3 } { 130148929.5e+12 * 1e-3 } %% (130148929.5 +- 5.4 e+12)*1e-3
+ }
+% \end{macrocode}
+% \begin{macrocode}
+\cudefinekeys { J }
+ {
+ { kJ }{ 1e-3 }
+ { cal }{ 0.2388459 }
+ { kcal }{ 0.2388459e-3 }
+ { eV }{ 624150912.6e+10 } %% 624150912.6 +- 3.9 e+10
+ }
+%\cuaddtokeys { J } { eV } { 1.6021766208e-19 }
+% \end{macrocode}
+% \begin{macrocode}
+\fp_const:Nn \c_@@_kb_eV_fp { 8.617 330 3 e-5 }
+\cudefinesinglekey { C }
+ {
+ { K } { #1 + 273.15 }
+ { F } { #1 * 1.8 + 32 }
+ { Re } { #1 * 0.8 }
+ { eV } { ( #1 + 273.15 ) * \c_@@_kb_eV_fp }
+ }
+\cudefinesinglekey { F }
+ {
+ { C } { ( #1 - 32 ) * 5/9 }
+ { K } { ( #1 + 459.67 ) * 5/9 }
+ { Re } { ( #1 - 32 ) * 4/9 }
+ { eV } {( #1 + 459.67 ) * 5/9 * \c_@@_kb_eV_fp }
+ }
+\cudefinesinglekey { K }
+ {
+ { C } { #1 - 273.15 }
+ { F } { #1 * 1.8 - 459.67 }
+ { Re } { ( #1 - 273.15 ) * 0.8 }
+ { eV } { #1 * \c_@@_kb_eV_fp }
+ }
+\cudefinesinglekey { Re }
+ {
+ { K } { #1 * 1.25 + 273.15 }
+ { C } { #1 * 1.25 }
+ { F } { #1 * 2.25 + 32 }
+ { eV } { ( #1 * 1.25 + 273.15 ) * \c_@@_kb_eV_fp }
+ }
+% \end{macrocode}
+%
+%
+% \begin{macrocode}
+\cudefinephrase { German }
+ {
+% { 6 } * { halbes \ Dutzend } < n >
+% { 6 } { efkjwefjkl \ Dutzend } < n >
+ { 12 } { Dutzend } < n >
+% { 60 } { Schock } < n >
+% { 1728 } { Gro{\ss}gros } < n >
+% { 144 } { Gros } < n >
+ }
+% \end{macrocode}
+%
+%
+% \subsection{Finish}
+%
+% \begin{macrocode}
+\cusetup
+ {
+ set-option-for-F = { round-to-int = true } ,
+ set-option-for-C = { round-to-int = true } ,
+ set-option-for-K = { round-to-int = true } ,
+ set-option-for-Re = { round-to-int = true } ,
+ curef-add-forbidden-unit = { F , C , K , Re } ,
+ add-temperature-to-check =
+ {
+ K = 0,
+ C = -273.15 ,
+ F = -459.67 ,
+ Re = -218.52
+ } ,
+ round-precision = 2 ,
+ }
+% \end{macrocode}
+%
+%
+%
+%
+%
+%
+%
+%
+%
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+%
+%
+% \begin{thebibliography}{}
+% \bibitem{Gattopardo}
+% Guiseppe Tomasi di Lampedusa, \enquote{Der Gattopardo},
+% Piper, Volume~8 (2018), ISBN~978-3-492-24586-9
+%
+% \bibitem{Sh:3}
+% Sir Arthur Conan Doyle, \enquote{Sherlock Holmes The Complete Novels and Stories Volume~II},
+% Bantam Books
+%
+%
+% \end{thebibliography}
+%
+%
+%
+% \endinput
+%
+%
+%
+%
+% Local Variables:
+% mode: doctex
+% TeX-master: t
+% End: \ No newline at end of file
diff --git a/macros/latex/contrib/cooking-units/cooking-units.ins b/macros/latex/contrib/cooking-units/cooking-units.ins
new file mode 100644
index 0000000000..d023c107e9
--- /dev/null
+++ b/macros/latex/contrib/cooking-units/cooking-units.ins
@@ -0,0 +1,54 @@
+%%
+%% This is file `cooking-units.ins',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% cooking-units.dtx (with options: `install')
+%% Copyright (C) 2016--2018 by Ben Vitecek (current Maintainer)
+%%
+%% This file may be distributed and/or modified under the
+%% conditions of the LaTeX Project Public License, either
+%% version 1.3c of this license or (at your option) any later
+%% version. The latest version of this license is in:
+%%
+%% https://ctan.org/license/lppl1.3c
+%%
+%% and version 1.3c or later is part of all distributions of
+%% LaTeX version 2008-05-04 or later.
+%%
+%% This work has the LPPL maintenance status `maintained'.
+%%
+%% This work consists of the files README.md, cooking-units.dtx and cooking-units.ins
+%% and the derived file cooking-units.sty.
+%%
+\input l3docstrip.tex
+\askforoverwritefalse
+\preamble
+Copyright (C) 2016--2018 by Ben Vitecek (current Maintainer)
+
+This file may be distributed and/or modified under the
+conditions of the LaTeX Project Public License, either
+version 1.3c of this license or (at your option) any later
+version. The latest version of this license is in:
+
+https://ctan.org/license/lppl1.3c
+
+and version 1.3c or later is part of all distributions of
+LaTeX version 2008-05-04 or later.
+
+This work has the LPPL maintenance status `maintained'.
+
+This work consists of the files README.md, cooking-units.dtx and cooking-units.ins
+and the derived file cooking-units.sty.
+
+\endpreamble
+
+\usedir{tex/latex/cooking-units}
+\generate{
+ \file{\jobname.sty}{\from{\jobname.dtx}{package}}
+}
+\endbatchfile
+\endinput
+%%
+%% End of file `cooking-units.ins'.
diff --git a/macros/latex/contrib/cooking-units/cooking-units.pdf b/macros/latex/contrib/cooking-units/cooking-units.pdf
new file mode 100644
index 0000000000..948ebcfe7f
--- /dev/null
+++ b/macros/latex/contrib/cooking-units/cooking-units.pdf
Binary files differ