From e0c6872cf40896c7be36b11dcc744620f10adf1d Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Mon, 2 Sep 2019 13:46:59 +0900 Subject: Initial commit --- macros/latex/contrib/cooking-units/README.md | 61 + .../latex/contrib/cooking-units/cooking-units.dtx | 8246 ++++++++++++++++++++ .../latex/contrib/cooking-units/cooking-units.ins | 54 + .../latex/contrib/cooking-units/cooking-units.pdf | Bin 0 -> 658095 bytes 4 files changed, 8361 insertions(+) create mode 100644 macros/latex/contrib/cooking-units/README.md create mode 100644 macros/latex/contrib/cooking-units/cooking-units.dtx create mode 100644 macros/latex/contrib/cooking-units/cooking-units.ins create mode 100644 macros/latex/contrib/cooking-units/cooking-units.pdf (limited to 'macros/latex/contrib/cooking-units') 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 +% +%<*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. + +% +%<*internal> +\fi +\def\nameofplainTeX{plain} +\ifx\fmtname\nameofplainTeX\else + \expandafter\begingroup +\fi +% +%<*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}} +} +% +%\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 +% +%<*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} +% +% \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{10--20}{dag} & flour, \\ +% \cunum{1/2}{l} & water, \\ +% \cutext[ref=recipe]{10}{g} & nuts, \\ +% \cuam{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{10--20}{dag} & flour, \\ +% \cunum{1/2}{l} & water, \\ +% \cutext[ref=recipe]{10}{g} & nuts, \\ +% \cuam{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} +% {oz} {Unze} +% {d} {Tag} [Tage] +% {h} {Stunde} [Stunden] +% {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} +% { 6 }* {halbes\ Dutzend} +% } +% +% +% \begin{lstlisting} +% \cudefinephrase {German} +% { +% { 12 } {Dutzend} %% implemented by default +% { 60 } {Schock} +% { 6 }* {halbes\ Dutzend} +% } +% \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}{} +% \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}{} +% \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-,add-option-for-} +% \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-}. +% \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{1}{kg}\\ +% \cuam{1}\\ +% \cutext{1}{kg}\\ +% \curef{anotherrecipe}~persons \\ @ +% \cusetup{ recalculate-amount = true } @ +% \curef{anotherrecipe}~persons \\ +% \cunum{1}{kg}\\ +% \cuam{1}\\ +% \cutext{1}{kg}\\ +% \Cutext[ref=anotherrecipe]{10}{kg}\\ @ +% \cusetup { set-number-of-persons = 3 } @ +% \curef{anotherrecipe}~persons \\ +% \cunum{1}{kg}\\ +% \cuam{1}\\ +% \cutext{1}{kg}\\ +% \Cutext[ref=anotherrecipe]{10}{kg}\\ @ +% \cusetup { set-number-of-persons = 2 } @ +% \curef{anotherrecipe}~persons \\ +% \cunum{1}{kg}\\ +% \cuam{1}\\ +% \cutext{1}{kg}\\ +% \Cutext[ref=anotherrecipe]{10}{kg}\\ @ +% \cusetup { set-number-of-persons = 1 } @ +% \curef{anotherrecipe}~person \\ +% \cunum{1}{kg}\\ +% \cuam{1}\\ +% \cutext{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{2} \\ +% \cunum{2}{dag} \\ +% \cusetup { recalculate-amount = true } @ +% \curef{Toast}~persons \\ +% \cuam{2} \\ +% \cunum{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 [m=dm]{1}{m} \\ +% \cunum[ref=Kaese,m=dm]{1}{m} \\ +% \cusetup { recalculate-amount = true } @ +% \cunum[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{1}{m} \\ +% \cunum{1}{kg} \\ +% \cunum[ref=check]{1}{C} \\ +% \cusetup { curef-add-forbidden-unit = { m, kg } } @ +% \cunum[m]{1}{m} \\ +% \cunum[m]{1}{kg} \\ +% \cunum[ref=check]{1}{C} \\ +% \cusetup { curef-remove-forbidden-unit = { C } } @ +% \cunum[m]{1}{m} \\ +% \cunum[m]{1}{kg} \\ +% \cunum[ref=check]{1}{C} \\ +% \cusetup { curef-clear-forbidden-units = true } @ +% \cunum[m]{1}{m} \\ +% \cunum[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} } + } +% \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 ] + { 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 ] + { 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} +% +% \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 Binary files /dev/null and b/macros/latex/contrib/cooking-units/cooking-units.pdf differ -- cgit v1.2.3