summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/cooking-units
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2021-06-11 03:00:56 +0000
committerNorbert Preining <norbert@preining.info>2021-06-11 03:00:56 +0000
commitd6b2eaba6fe47c24603040934903c73535ff09ba (patch)
treee608eb7c4afe8e8f2dd739dda2dd79d375f32da0 /macros/latex/contrib/cooking-units
parent2bd77f5a4d02b0d1649589aa7a548e79b198f6af (diff)
CTAN sync 202106110300
Diffstat (limited to 'macros/latex/contrib/cooking-units')
-rw-r--r--macros/latex/contrib/cooking-units/cooking-units.dtx6209
-rw-r--r--macros/latex/contrib/cooking-units/cooking-units.ins4
-rw-r--r--macros/latex/contrib/cooking-units/cooking-units.pdfbin700306 -> 748443 bytes
3 files changed, 3861 insertions, 2352 deletions
diff --git a/macros/latex/contrib/cooking-units/cooking-units.dtx b/macros/latex/contrib/cooking-units/cooking-units.dtx
index 0e01884a27..ee29c982c3 100644
--- a/macros/latex/contrib/cooking-units/cooking-units.dtx
+++ b/macros/latex/contrib/cooking-units/cooking-units.dtx
@@ -82,7 +82,7 @@ for the details of that license.
%\keepsilent
\askforoverwritefalse
\preamble
-Copyright (C) 2016--2020 by Ben Vitecek (current Maintainer)
+Copyright (C) 2016--2021 by Ben Vitecek (current Maintainer)
This file may be distributed and/or modified under the
conditions of the LaTeX Project Public License, either
@@ -182,7 +182,14 @@ and the derived file cooking-units.sty.
\NewDocumentCommand \cookingunitsToDo { m }
{
-% \marginpar { \textcolor{red}{#1} }
+ \marginpar { \textcolor{red}{#1} }
+ }
+\NewDocumentCommand \cookingunitsTODO { m } { \cookingunitsToDo {#1} }
+\NewDocumentCommand \cookingunitsContinue { } { \cookingunitsToDo {Continue} }
+\NewDocumentCommand \cookingunitsCONTINUE { } { \cookingunitsContinue }
+\NewDocumentCommand \cookingunitsChecked { }
+ {
+ \cookingunitsToDo{Checked}
}
@@ -210,7 +217,10 @@ and the derived file cooking-units.sty.
declarecookingderivatives ,
cufrac ,
cusetoptionfor, cuaddoptionfor, cuclearoptionfor,
- cudeclareunitgroup, cuaddtounitgroup, cuclearunitgroup
+ cudeclareunitgroup, cuaddtounitgroup, cuclearunitgroup ,
+ cudefinekeys ,
+ , cudefinekeychain , cuaddtokeychain
+ , cudeclareunitgroup
}
\NewDocumentCommand \mycs { m }
@@ -219,9 +229,9 @@ and the derived file cooking-units.sty.
{
\cs_if_exist:cTF {#1}
{ \cs{\textcolor{blue}{#1}} }
- { \mycsERRORII }
+ { \tl_show:n {#1}\mycsERRORII }
}
- { \mycsERROR }
+ { \tl_show:n {#1} \mycsERROR }
}
\newcommand\opt{\texttt}
\newcommand\myunit{\texttt}
@@ -233,14 +243,12 @@ and the derived file cooking-units.sty.
%: \PrintUnit
\NewDocumentCommand \PrintUnit { o m }
{
- \SaveTranslation \l_tmpa_tl { #2 (cu-unitname) }
+ \__cookingunits_culang_let:nnN { name } {#2} \l_tmpa_tl
\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 }
+ \PrintUnitSymbol {#2}
}
\NewDocumentCommand \PrintUnitSymbol { m }
{
@@ -258,7 +266,6 @@ and the derived file cooking-units.sty.
\msg_redirect_name:nnn { cooking-units } { curef-forbidden-unit } { warning }
}
-
%% Allyourwhitespacearebelongtous (too long)
%% 42
%% Miep!
@@ -272,16 +279,18 @@ and the derived file cooking-units.sty.
{
\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
+ \hbadness=10000
+ \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}
+ \hbadness=10000
\ttfamily
\tl_set_rescan:Nno \l_tmpa_tl
{
@@ -289,6 +298,7 @@ and the derived file cooking-units.sty.
\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
@@ -297,46 +307,27 @@ and the derived file cooking-units.sty.
{
\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 }
- { \\ }
- }
- }
+ { \textbackslash \textcolor{blue}{\cs_to_str:N ##1} }
+ }{
+ \token_if_letter:NTF ##1
+ {##1}
{
- \token_if_active:NTF ##1
- {##1}
+ \str_case:nnF {##1}
{
- \token_if_parameter:NTF ##1
- {
- \int_compare:nNnTF { \l_tmpa_int } = { 0 }
+ { @ } { \\ }
+ { & } { \space }
+ }{
+ \token_if_active:NTF ##1
+ {##1}
+ {
+ \token_if_parameter:NTF ##1
{
- \c_hash_str
- \int_incr:N \l_tmpa_int
+ \int_compare:nNnTF { \l_tmpa_int } = { 0 }
+ { \c_hash_str \int_incr:N \l_tmpa_int }
+ { \int_zero:N \l_tmpa_int }
}
- { \int_zero:N \l_tmpa_int }
+ { ##1 {} }
}
- { ##1 {} }
}
}
}
@@ -417,7 +408,7 @@ and the derived file cooking-units.sty.
}
\cs_new_eq:NN \__table_default_midrule: \__table_midrule:
-\cs_new:Npn \_cook_use:n #1
+\cs_new:Npn \__cu_use:n #1
{ \cs_if_exist_use:cF { __cookingunits_#1 } {\ERRORcommandNOTexist} }
\NewDocumentCommand \CreateTableForLanguages { s >{\TrimSpaces} m }
@@ -445,55 +436,64 @@ and the derived file cooking-units.sty.
{ 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 }
+ \__cookingunits_doc_print_table_row:nn {#1} {##1}
}
}
}
-\NewDocumentCommand \CreateTableForPhrases { >{\TrimSpaces} m }
+\cs_new:Npn \__cookingunits_doc_print_table_row:nn #1#2
{
- \tl_set:Nn \l_tmpa_tl {#1}
- \__cookingunits_phrase_list_get_for:NNTF \l_tmpa_prop \l_tmpa_tl
+ \texttt{#2}
+ &
+ \clist_if_in:NnTF \l_list_of_textunits_clist {#2}
+ { \l_translation_does_not_exist_tl }
+ {
+ \__cu_use:n { culang_let_for:nnnN } {#1} { unit-symbol } {#2} \l_tmpa_tl
+ \tl_if_in:NnTF \l_tmpa_tl \q__cookingunits_no_translation
+ { \l_translation_does_not_exist_tl }
+ { \l_tmpa_tl }
+ }
+ &
+ \__cu_use:n { culang_let_for:nnnN } {#1} { name } {#2} \l_tmpa_tl
+ \tl_if_in:NnTF \l_tmpa_tl \q__cookingunits_no_translation
+ { \l_translation_does_not_exist_tl }
+ { \l_tmpa_tl }
+ &
+ \__cu_use:n { culang_let_for:nnnN } {#1} { name } {#2} \l_tmpa_tl
+ \__cu_use:n { culang_let_for:nnnN } {#1} { name-pl } {#2} \l_tmpb_tl
+ \str_if_eq:NNF \l_tmpa_tl \l_tmpb_tl
{
- \__cookingunits_translate_let:VNnV \l_tmpa_tl \l_tmpa_seq
- { phrase-clist } \c__cookingunits_postfix_phrase_tl
+ \tl_if_in:NnTF \l_tmpb_tl \q__cookingunits_no_translation
+ { \l_translation_does_not_exist_tl }
+ { (\l_tmpb_tl) }
+ }
+ &
+ \__cu_use:n { culang_let_for:nnnN } {#1} { gender } {#2} \l_tmpa_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 }
+ {
+ \seq_clear:N \l_tmpa_seq
+ \__cu_use:n { culang_let_for:nnnN } {#1} { phrase } { phrase-prop } \l_tmpa_prop
+ \prop_if_exist:NTF \l_tmpa_prop
+ {
+ \tl_if_eq:NNTF \q__cooking_units_no_translation \l_tmpa_prop
+ { \ERRORCreateTablePhraseII }
+ {
+ \prop_get:NnN \l_tmpa_prop { seq } \l_tmpa_seq
+ }
}
- { \ERRORCreateTable }
+ { \ERRORCreateTablePhraseI }
\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
+ \begin{tabular}{ l l l l l }
+ \toprule
+ \meta{Phrase-key} & phrase & (plural) & gender
\CreatePhraseTableRow {#1}
- \end{tabular}
+ \end{tabular}
}
\NewDocumentCommand \CreatePhraseTableRow { m }
@@ -507,16 +507,15 @@ and the derived file cooking-units.sty.
}{
\__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
+ &
+ \prop_get:NnN \l_tmpa_prop {##1} \l_tmpa_tl
+ \tl_gset:NV \l_tmpa_tl \l_tmpa_tl %% Damit global
+ \l_tmpa_tl
+ &
+ \prop_get:NnN \l_tmpa_prop {##1-pl} \l_tmpb_tl
+ \tl_if_eq:NNF \l_tmpa_tl \l_tmpb_tl { \l_tmpb_tl }
+ &
+ \prop_get:NnN \l_tmpa_prop {##1-gender} \l_tmpa_tl
\l_tmpa_tl
}
}
@@ -593,29 +592,41 @@ and the derived file cooking-units.sty.
culabel,
curef,
cudefinephrase,
- declarecookingderivatives
+ declarecookingderivatives,
+ , cudefinekeychain
+ , cuaddtokeychain
+ , cudeclareunitgroup
+ , cusetoptionfor
+ , usepackage
}
}
-\newcommand\eneunit[3]{\sfrac{#1\,#2${}^2$}{#3${}^2$}}
-%% Can overflow and takes too long, hard code it
-%\declarecookingderivatives{kg,m,s}{#1*#2-#3}{ (#1)*(#2)^2/(#3)^2 } {\eneunit{#1}{#2}{#3}}
-\newcookingunit[\eneunit{kg}{m}{s}]{kg*m-s}
-\newcookingunit[\eneunit{oz}{in}{min}]{oz*in-min}
\newcookingunit {st}
\newcookingunit [\ensuremath{ {} ^ { \circ } }\kern-\scriptspace R{\text{\o}}] {Ro}
\newcookingunit {ft}
+\newcookingunit {km}
-\cuaddkeys {lb}
- {
- {st} { 1/14 } %% 1 lb are 1/14 st
- }
+%\cuaddkeys {lb}
+% {
+% {st} { 1/14 } %% 1 lb are 1/14 st
+% }
+\cuaddtokeychain
+ {
+ {lb} { 14 }
+ {st} { 1 }
+ }
\cuaddtokeys {m} {ft} {0.3048}
+\cuaddtokeys {m} {km} {1000}
\cuaddsinglekeys {C}
{
{Ro} { #1*21/40 + 7.5 }
}
+\newcommand\eneunit[3]{\sfrac{#1\,#2${}^2$}{#3${}^2$}}
+%% Can overflow and takes too long, hard code it
+\declarecookingderivatives{kg,m,s}{#1*#2:#3}{ (#1)*(#2)^2/(#3)^2 } {\eneunit{#1}{#2}{#3}}
+\declarecookingderivatives{m,s}{#1:#2}{ (#1)/(#2) } {\sfrac{#1}{#2}}
+
\cusetup
@@ -772,7 +783,7 @@ and the derived file cooking-units.sty.
% \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} {Change order of boolean testing for |\@@_calc_references_and_store_in:N|.}
% \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).}
%
@@ -782,6 +793,16 @@ and the derived file cooking-units.sty.
% \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).}
%
+% \changes {2021/03/21} {2.00} {Overall reworking of internal code.}
+% \changes {2021/03/21} {2.00} {Much better error handling.}
+% \changes {2021/03/21} {2.00} {Remove exhaustive expansion from translations. Shouldn't really change anything.}
+% \changes {2021/03/21} {2.00} {New options: \opt{definition/symbol}, \opt{definition/gender}, \opt{definition/set-option}, \opt{definition/add-to-group}. }
+% \changes {2021/03/21} {2.00} {Adding keys to unit definition.}
+% \changes {2021/03/21} {2.00} {Updatet |\declarecookingderivatives|.}
+% \changes {2021/03/21} {2.00} {New commands: |\cudefinekeychain|, |\cuaddtokeychain|}
+% \changes {2021/03/21} {2.00} {New joke options: \opt{nothing-special}, \opt{going-bonkers}, \opt{fully-bonkers} and \opt{xD-lol}.}
+% \changes {2021/03/21} {2.00} {New commands to define keys: \mycs{cudefinekeychain} and \mycs{cuaddtokeychain}.}
+% \changes {2021/03/21} {2.00} {Using commands as unit-keys now works.}
%
%
%
@@ -798,26 +819,26 @@ and the derived file cooking-units.sty.
%
% \maketitle
%
+%
% \begin{documentation}
% \begin{abstract}
% This package enables user to globally format units, to switch
% between them and change your recipes to a given
% number of persons.
%
-% For not implemented units or differences between Imperial and U.S.\ unit
-% you may have a look at \cref{sec:other-units}.
+% For not implemented units or differences between Imperial and U.S.\ unit
+% you may have a look at \cref{sec:other-units}.
%
% It should be used for light-hearted things like
% cookery books (and not e.g. scientific texts; use e.g.\ \pkg{siunitx} for those).
%
-% Please read through the section \enquote{Important Changes}
+% ^^A Please read through the section \enquote{Important Changes}
% \end{abstract}
%
% \tableofcontents
%
% \section{Introduction}
%
-%
% While writing on a cookery book I used -- for some reasons whatsoever --
% three different units for weight: kilogram (kg), gram (g) and
% decagram (dag, or older: dkg). Later my mother told me that she
@@ -830,30 +851,10 @@ and the derived file cooking-units.sty.
% more pleasant than \LaTeXe) and here it is.
%
%
-% \begin{comment}
-% \subsection{Overview}
-% \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}
-% \end{comment}
%
%
%
% \subsection{Supported languages}
-% \cookingunitsToDo{Passt.}
% \begin{itemize}
% \item German
% \item English
@@ -865,9 +866,9 @@ and the derived file cooking-units.sty.
%
% \section {The Commands}
% \label{sec:commands}
-% \cookingunitsToDo{Passt.}
+%
%
-% This package offers the following commands for unit printing (and
+% This package offers the following commands for number/unit printing (and
% converting):
%
% \begin{itemize}
@@ -885,7 +886,7 @@ and the derived file cooking-units.sty.
% 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
+% amounts and raises a warning to remind you 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|.
@@ -932,7 +933,6 @@ and the derived file cooking-units.sty.
%^^A \lstinline|\Cutext| capitalizing the first letter (using package
%^^A \pkg{fmtcount}).
%
-%
% \begin{cuexamplecode}
% \cutext{1}{l} \\
% \Cutext{1}{l} \\
@@ -940,7 +940,7 @@ and the derived file cooking-units.sty.
% \cutext{12}{l} \\
% \Cutext{13}{l}
% \end{cuexamplecode}
-% and using (e.g.) package option \opt{use-fmtcount-numerals=true}
+% and using (e.g.)\ package option \opt{use-fmtcount-numerals=true}
% \cusetup{print-numerals=true}
% \begin{cuexamplecode}
% \cutext{1}{l} \\
@@ -984,8 +984,9 @@ and the derived file cooking-units.sty.
% 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}
+%^^A \begin{myde}
% \begin{cuexamplecode}
+% \selectlanguage{ngerman} @
% \cusetup{use-phrases=true} @
% \cuam{11} \\
% \cuam{12} \\
@@ -996,12 +997,12 @@ and the derived file cooking-units.sty.
% \cuam{18} \\
% \cuam{60}
% \end{cuexamplecode}
-% \end{myde}
+%^^A \end{myde}
%
%
% \section{Label \& refs: Changing the amount of the recipe}
% \label{sec:labeletref}
-% \cookingunitsToDo{Also not much to change}
+%
%
% 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?
@@ -1061,86 +1062,18 @@ and the derived file cooking-units.sty.
%
%
%
-% \begin{comment}
-% \section{Some Interesting options}
-% \cookingunitsToDo{This section is horrible, change or delete as a whole, but later}
-% 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-fmtcount-numerals, use-numerals-below, print-numerals}
-% As seen above, you can use the \emph{package}-option
-% \opt{use-fmtcount-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-fmtcount-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-fmtcount-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-fmtcount-numerals} is
-% supported. Furthermore this feature is only available for \mycs{cuam}.
-% \end{cunote}
-%
-% \end{cuinterest}
-%
-% \end{comment}
-%
-%
%
%
%
%
%
%\subsection{Rounding temperatures}
+%
%
% By default temperatures are rounded to integers (using \opt{round-precision=0}).
-% Since 1.30 it is possible to round amounts to a negative precision.
+% Since v1.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}).
+% example (\mycs{cusetoptionfor} is described in \cref{sec:opt:unit-spec}).
%
% \begin{cuexamplecode}
% \cunum{182}{C} \\
@@ -1148,10 +1081,6 @@ and the derived file cooking-units.sty.
% \cunum[C=Re]{180}{C} \\
% \cunum[C=K]{180}{C} \\
% \cusetoptionfor{C,F,K,Re}{ round-precision = -1 } @
-%^^A \cusetup{set-option-for-C = { round-precision = -1 } } @
-%^^A \cusetup{set-option-for-F = { round-precision = -1 } } @
-%^^A \cusetup{set-option-for-Re = { round-precision = -1 } } @
-%^^A \cusetup{set-option-for-K = { round-precision = -1 } } @
% \cunum{182}{C} \\
% \cunum[C=F]{180}{C} \\
% \cunum[C=Re]{180}{C} \\
@@ -1160,38 +1089,27 @@ and the derived file cooking-units.sty.
%
% \section{Predefined units \& some notes}
% \label{sec:pred-units}
-% \cookingunitsToDo{Passt.}
-% \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}.
+% (which cannot be used for transformations) are shown in \cref{tab:some-more-units}.
% \Cref{tab:strange-units} pretty much exists just for fun.
%
%
-% \begin{table}[htbp]
+% \begin{table}[htb]
% \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\
+% no translation is defined for the given language. 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
+% \toprule
% description & key & default & description & key & default \\ \midrule
% \PrintUnit {kg} & \PrintUnit{m} \\
% \PrintUnit {dag} & \PrintUnit{dm} \\
@@ -1216,14 +1134,16 @@ and the derived file cooking-units.sty.
% \label{tab:def-units}
% \end{table}
%
-% \begin{table}[htbp]
+% \begin{table}[htb]
% \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.}
+% units known to you. For \enquote{tablespoon} and \enquote{teaspoon}
+% I used the german abbreviations \enquote{EL} and \enquote{TL} (because I forgot to
+% change them initially).}
% \smallskip
% \begin{tabular}{ lll }
% \toprule
@@ -1240,7 +1160,7 @@ and the derived file cooking-units.sty.
% \label{tab:some-more-units}
% \end{table}
%
-% \begin{table}[htbp]
+% \begin{table}[htb]
% \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).}
@@ -1261,50 +1181,85 @@ and the derived file cooking-units.sty.
%
% \section{Defining units}
% \label{sec:def-units}
-% \cookingunitsToDo{Passt.}
+%
+%
% New units can be defined using
% \begin{itemize}
-% \item \mycs{declarecookingunit}\oarg{symbol}\marg{unit-key}
-% \item \mycs{newcookingunit}\oarg{symbol}\marg{new-unit-key}
-% \item \mycs{providecookingunit}\oarg{symbol}\marg{new-unit-key}
-% \end{itemize}
+% \item \mycs{declarecookingunit}\oarg{symbol/key-val-list}\marg{unit-key}
+% \item \mycs{newcookingunit}\oarg{symbol/key-val-list}\marg{unit-key}
+% \item \mycs{providecookingunit}\oarg{symbol/key-val-list}\marg{unit-key}
+% \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{unit-key}
+% \mycs{declarecookingunit}\oarg{symbol/key-val-list}\marg{unit-key}
+% \mycs{newcookingunit}\oarg{symbol/key-val-list}\marg{unit-key}
+% \mycs{providecookingunit}\oarg{symbol/key-val-list}\marg{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} can neither contain |/| nor |,|.
%
-% Please note due to the current implementation catcodes may cause
-% trouble. For example using |:| inside \meta{unit-key} may cause
-% the key to \enquote{not be defined} in the document. If that happens
-% try removing or changing the \meta{unit-key}.
+% These commands define the unit \meta{unit-key}. Note that \meta{unit-key}
+% can neither contain |/| nor |,|; but it is allowed to be a command since v2.00
+% (see examples below).
%
+% If the key is not the same as the printed symbol use the optional argument.
+% It can either contain the symbol you want printed or a key-value list (see below)
+% for more advanced adjustments.
+%
% \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.
+% All units have male gender |m| by default (unless you change it using a key below).
%
% Some examples:
-% \begin{lstlisting}
+% \begin{lstlisting}[commentstyle=\color{black}]
% \declarecookingunit{kg}
% \declarecookingunit{g}
% \declarecookingunit[Msp.] {Msp}
% \declarecookingunit[\ensuremath{{}^{\circ}}\kern-\scriptspace C] {C}
+% \declarecookingunit{\%} % can use commands now
% \end{lstlisting}
%
% \end{function}
+%
% \begin{cunote}
% The definition of the printed degree Celsius is
% copied and pasted from (a maybe older version of) \pkg{siunitx}.
% \end{cunote}
%
+% \begin{function}{symbol, gender, set-option, add-to-group, natural-unit}
+%
+% \begin{syntax}
+% symbol = \marg{symbol}
+% gender = \marg{m/f/n}
+% set-option = \marg{key-val-list}
+% add-to-group = \marg{group}
+% natural-unit = \marg{true/false}
+% \end{syntax}
+%
+% Those keys can only be used in the optional argument of
+% \mycs{declarecookingunit}, \mycs{newcookingunit} or \mycs{providecookingunit}.
+% They can be used to define some properties of the unit during its initialization.
+%
+% \opt{symbol} allows you to set the printed symbol of the unit. A similar effect can be
+% achieved by just using the optional argument. Use this option if you want to
+% use other keys during the definition. This symbol is used as a fallback for all
+% langauges, if no explicit symbol is found for said langauge.
+%
+% \opt{gender} sets the gender of the unit (default ist |m|). Allowed is |m|, |f| or |n|.
+% Note that this sets the default gender for all languages.
+%
+% \opt{set-option} allows to add some key-vals to the specific unit which are
+% activated once the unit is used. See \cpageref{code:set-option}.
+%
+% \opt{add-to-group} adds the unit defined to \meta{group}. See \cref{sec:opt:unit-spec}
+% for more information.
+%
+% \opt{natural-unit} is a simple true/false switch. If |true| the unit will be specified to be
+% a \enquote{natural-unit}. This is more or less a joke option.
+% \end{function}
+%
%
%
% \begin{function}{\declarecookingderivatives}
@@ -1314,7 +1269,7 @@ and the derived file cooking-units.sty.
% \end{syntax}
%
% \emph{This function is experimental}. Defines new units which are a combination
-% of the units given in \meta{unit-list} \emph{and} their linked-units.
+% of the units given in \meta{unit-list} \emph{and} their key-chain.
% \meta{unit-key}, \meta{mathematical-relation} and \meta{unit-symbol}
% accept |#1| to |#n| as arguments with $n$ being the number of units
% given in \meta{unit-list}. $n$ \emph{cannot} be greater than $8$ (and it will
@@ -1326,91 +1281,97 @@ and the derived file cooking-units.sty.
%
% \end{function}
%
-% \begin{cunote}
-% Due to catcodes (and my inability to deal with them properly)
-% there can be problems when using |:|
-% (and probably other signs) inside \meta{unit-key}.
-% \end{cunote}
-%
% \begin{cuexample}
% Your homework is to change the unit of energy \si{\kg\m\squared\per\s\squared}
% into \si{\ounce\inch\squared\per\minute\squared}. To check if you are correct
% you use \mycs{declarecookingderivatives}:
% \begin{lstlisting}
-% \declarecookingderivatives{kg,m,s}{#1*#2-#3}
+% \declarecookingderivatives{kg,m,s}{#1*#2:#3}
% { (#1)*(#2)^2/(#3)^2 } {\sfrac{#1\,#2${}^2$}{#3${}^2$}}
% \end{lstlisting}
%
-% Using |\cunum[kg*m-s=oz*in-min]{1}{kg*m-s}| shows that
-% \cunum{1}{kg*m-s} is equal to \cunum{196829101.34}{oz*in-min}.
-% (Note: This is \emph{really} experimental and it can easily happen that
-% an \enquote{overflow-error} occurs) (like for me which is why I hard-coded the
-% results after testing).
+% Using |\cunum[kg*m:s=oz*in:min]{1}{kg*m:s}| shows that
+% \cunum{1}{kg*m:s} is equal to \cunum[kg*m:s=oz*in:min]{1}{kg*m:s}.
+%^^A\cunum{196829101.34}{oz*in:min}
+%
+%^^A \cunum[m:s=km:h]{1}{m:s}
%
% \end{cuexample}
%
+% \begin{cunote}
+% As this is a bit more experimental and can easily lead to overflow-errors,
+% no actual \LaTeX\ keys are created with \mycs{declarecookingderivatives}.
+% Internally the keys and possible values are stored in a \emph{huge} property list.
+% If an unknown key is encountered, it checks if said key can be found in the
+% property list.
+% \end{cunote}
+%
+%
+%
%
%
% \section{Defining options to change units}
% \label{sec:defining-opt}
-% \cookingunitsToDo{Passt.}
-% Options (to change units) can be newly defined or added to already existing keys (units)
+%
+%
+%
+% Options (to change units) can be newly defined or added to already existing ones
% using
% \begin{itemize}
-% \item \mycs{cudefinekeys}
+% \item \mycs{cudefinekeychain}
+%^^A \item \mycs{cudefinekeys}
% \item \mycs{cudefinesinglekey}
-% \item \mycs{cuaddkeys}
+% \item \mycs{cuaddtokeychain}
+%^^A \item \mycs{cuaddkeys}
% \item \mycs{cuaddsinglekeys}
-% \item \mycs{cuaddtokeys}
+%^^A \item \mycs{cuaddtokeys}
% \end{itemize}
-% I apologize for the (name) inconsistency between \mycs{cudefinekeys} and
-% \mycs{cudefinesinglekey} (although they are named similarly, they work differently).
%
-% \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}
+%
+%
+% \begin{function}{\cudefinekeychain, \cudefinesinglekey }
+% \begin{syntax}
+% \mycs{cudefinekeychain}
+% \ \ \{
+% \ \ \ \ \marg{unit-key-1} \marg{value}
+% \ \ \ \ \marg{unit-key-2} \marg{... unit-key-2 are \meta{value} unit-key-1}
+% \ \ \ \ \marg{unit-key-3} \marg{... unit-key-3 are \meta{value} unit-key-1}
% \ \ \ \ \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}
-%
+% \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| or \lstinline|\cudefinesinglekey| respectively to
-% define new keys.
+% them to already existing keys you may use
+% \mycs{cudefinekeychain} or \mycs{cudefinesinglekey} respectively to
+% define new key-chains or single keys.
+%
+% \mycs{cudefinekeychain} collects the unit-key's given and defines a key-chain.
+% This allows you to change every unit into every other unit given in the list.
+% So \meta{unit-key-1} can take \meta{unit-key-1}, \meta{unit-key-2}, \meta{unit-key-3},
+% \dots\ as values; \meta{unit-key-2} can take \meta{unit-key-1}, \meta{unit-key-2},
+% \meta{unit-key-3}, \dots\ as values, etc. Please note that \meta{\dots} has to
+% be a number.
%
-% \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
+% \mycs{cudefinesinglekey}. As the name says it defines
+% \emph{only} a single 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}.
+% numerical input of \mycs{cunum}, etc.\ can be placed explicitly using \texttt{\#1}.
+% \end{function}
%
%
-% \end{function}
%
-% \begin{cuexample}
%
+% \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},
@@ -1421,8 +1382,6 @@ and the derived file cooking-units.sty.
% \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*}
@@ -1433,22 +1392,41 @@ and the derived file cooking-units.sty.
% \SI{1}{\kg}&= \SI{2.204 622 6}{\pound}
% \end{align*}
% \begin{lstlisting}
-% \cudefinekeys {kg}
+% \cudefinekeychain
% {
+% {kg} { 1 }
% {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}
+% \cudefinekeychain
% {
+% {d} { 1 }
% {h} { 24 } %% 1 day are 24 hours
% {min}{ 1440 } %% 1 day are 1440 minutes
% {s} { 86400 } %% 1 day are 86400 seconds
% }
% \end{lstlisting}
+% \end{cuexample}
+%
+% \begin{cunote}
+% The value of the first item can be something different from $1$.
+% So something like this is also possible:
+% \begin{lstlisting}
+% \cudefinekeychain
+% {
+% {kg} { 0.4535924 }
+% {dag}{ 45.35924 }
+% {g} { 453,5924 }
+% {oz} { 16 }
+% {lb} { 1 }
+% }
+% \end{lstlisting}
+% \end{cunote}
%
+% \begin{cuexample}
% To convert degree Fahrenheit to degree Celsius, kelvin and degree R\'eamur one
% needs the formulas\footnote{See Wikipedia.}
% \begin{align*}
@@ -1459,7 +1437,7 @@ and the derived file cooking-units.sty.
% 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:
+% \myunit{C}, \myunit{K} and \myunit{Re} is defined by:
%
% \begin{lstlisting}
% \cudefinesinglekey {F}
@@ -1477,14 +1455,13 @@ and the derived file cooking-units.sty.
%
%
%
-% \begin{function}{\cuaddkeys,\cuaddsinglekeys}
-%
+% \begin{function}{\cuaddtokeychain,\cuaddsinglekeys}
% \begin{syntax}
-% \mycs{cuaddkeys}\marg{unit-key-1}
+% \mycs{cuaddtokeychain}
% \ \ \{
-% \ \ \ \ \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}
+% \ \ \ \ \marg{unit-key-1} \marg{value}
+% \ \ \ \ \marg{unit-key-2} \marg{... unit-key-2 are \meta{value} unit-key-1}
+% \ \ \ \ \marg{unit-key-3} \marg{... unit-key-3 are \meta{value} unit-key-1}
% \ \ \ \ \dots
% \ \ \}
%
@@ -1496,28 +1473,27 @@ and the derived file cooking-units.sty.
% \ \ \}
% \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}.
+% \mycs{cuaddtokeychain} first parses through its unit-list and searches for
+% a base unit key which is already in a key-chain
+% (aka.\ was defined by \mycs{cudefinekeychain}). The other units, not yet
+% part of a key-chain, are added to the same key-chain as the base unit.
+% So the newly added units are available as a key and a value for the other
+% units in the same key-chain. Note that \meta{...} must be a number.
%
%
% 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}.
+% using \myunit{\#1} (see \mycs{cudefinesinglekey}). This
+% command neither defines new keys nor does it add values to
+% keys other 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,
@@ -1529,10 +1505,11 @@ and the derived file cooking-units.sty.
% 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
-% }
+% \cuaddtokeychain
+% {
+% {lb} { 14 } %% unit already in a key-chain.
+% {st} { 1 } %% new unit. 1st = 14lb
+% }
% \end{lstlisting}
% \begin{cuexamplecode}
% \cunum[lb=st]{1}{lb} \\
@@ -1544,6 +1521,17 @@ and the derived file cooking-units.sty.
% \end{cuexamplecode}
% \end{cuexample}
%
+% \begin{cunote}
+% Of course using
+% \begin{lstlisting}
+% \cuaddtokeychain
+% {
+% {st} { 1/14 } %% 1lb = 1/14st
+% {lb} { 1 } %% unit already in a key-chain.
+% }
+% \end{lstlisting}
+% is also possible
+% \end{cunote}
%
% \begin{cuexample}
% Now you want to add degree R{\o}mer and convert Celsius to degree
@@ -1555,14 +1543,11 @@ and the derived file cooking-units.sty.
% \begin{lstlisting}
% %% defining new unit 'degree R{\o}mer'
% \newcookingunit [\ensuremath{ {} ^ { \circ } }\kern-\scriptspace R{\o}] {Ro}
-% \cuaddsinglekeys {C} %% adds value 'Ro' to 'C'.
+% \cuaddsinglekeys {C} %% adds value 'Ro' to key 'C'.
% {
% {Ro} { #1 * 21/40 + 7.5 }
% }
-% \cusetup %% round to integer automatically
-% {
-% set-option-for-Ro = { round-precision = 0 }
-% }
+% \cusetoptionfor{Ro}{ round-precision = 0 } %% round to integer automatically
% \end{lstlisting}
% \begin{cuexamplecode}
% \cunum{10}{C} \\
@@ -1578,55 +1563,65 @@ and the derived file cooking-units.sty.
%
%
%
+%
%
%
-% \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}.
+% \subsection{Obsolete Commands}
%
-% 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}
+% \begin{function}{cudefinekeys}
+% \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
+% \ \ \}
+% \end{syntax}
%
+% \emph{This command is going to be obsolete at one point. It is advised to use
+% \mycs{cudefinekeychain} instead.}
%
+% \mycs{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.
+% \end{function}
%
%
%
+% \begin{function}{\cuaddkeys,\cuaddtokeys}
+% \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{cuaddtokeys} \marg{unit-key-1} \marg{unit-key-2} \marg{$1$ unit-key-2 are \dots\ unit-key-1}
+% \end{syntax}
%
+% \emph{Those commands are going to be obsolete at one point. It is advised to use
+% \mycs{cuaddtokeychain} instead.}
+%
+%
+% \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}.
+%
+% Works similar to \mycs{cuaddkeys} regarding the definition of keys.
+% \end{function}
%
%
%
@@ -1636,7 +1631,7 @@ and the derived file cooking-units.sty.
%
% \section{Language support}
% \label{sec:language}
-% \cookingunitsToDo{Passt.}
+%
%
% Unit names and symbols depend on the language. To change the
% name and symbol for given language you can use \lstinline|\cudefinename|;
@@ -1658,11 +1653,10 @@ and the derived file cooking-units.sty.
% you may also use the keys \opt{one(m)}, \opt{one(f)} and
% \opt{one(n)}. 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
+% problem is that the written-out \enquote{1} depends on the
% gender of the word following (e.g. \enquote{ein Baum} (m),
-% \enquote{eine Pflanze} (f) and \enquote{ein Auto} (n)). To set the
-% written-out \enquote{1} to be correct with the gender of the used unit, use
-% these keys (see also examples below)
+% \enquote{eine Pflanze} (f) and \enquote{ein Auto} (n)). Use those keys
+% to set the specific gender of \enquote{1} (see also examples below).
% \end{function}
%
% \begin{function}{\cudefinename}
@@ -1688,7 +1682,7 @@ and the derived file cooking-units.sty.
% \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.
+% \texttt{n} (neutrum). If not given, \texttt{m} is used as default.
% \end{function}
%
% \begin{lstlisting}
@@ -1807,7 +1801,7 @@ and the derived file cooking-units.sty.
%
% 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}:
+% command to be used by \mycs{cuam}:
%
% \begin{function}{\cudefinephrase}
% \begin{syntax}
@@ -1821,11 +1815,12 @@ and the derived file cooking-units.sty.
%
% 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
+% with \marg{phrase-1} (\& \meta{phrase-1-plural} and \meta{gender-1}).
+% Afterwards the package can check if an 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}
+% star \texttt{*}.
%
% \meta{gender} can be \opt{m}, \opt{f} or \opt{n}. It is \opt{m} by default.
%
@@ -1833,9 +1828,6 @@ and the derived file cooking-units.sty.
% 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
@@ -1857,17 +1849,20 @@ and the derived file cooking-units.sty.
% }
% \end{lstlisting}
% Let's just use them (german language activated!):
-% \begin{myde}
+%^^A \begin{myde}
% \begin{cuexamplecode}
+% \selectlanguage{ngerman} @
% \cusetup{use-phrases=true} @
% \cuam{12} \\
% \cuam{24} \\
+% \cuam{25} \\
% \cuam{60} \\
% \cuam{120} \\
+% \cuam{121} \\
% \cuam{6} \\
% \cuam{18}
% \end{cuexamplecode}
-% \end{myde}
+%^^A \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
@@ -1880,7 +1875,6 @@ and the derived file cooking-units.sty.
% \section{Options}
% \label{sec:options}
%
-% \cookingunitsToDo{Done. Passr.}
%
% Options in \pkg{cooking-units} can mostly be set globally using
% \lstinline|\cusetup| or locally using the optional argument of the
@@ -1897,7 +1891,7 @@ and the derived file cooking-units.sty.
%
%
% \begin{function}{\cusetoptionfor,\cuaddoptionfor,\cuclearoptionfor}
-%
+% \label{code:set-option}
% \begin{syntax}
% \mycs{cusetoptionfor}\marg{unit-list}\marg{options}
% \mycs{cuaddoptionfor}\marg{unit-list}\marg{options}
@@ -2044,7 +2038,7 @@ and the derived file cooking-units.sty.
% \mycs{cudeclareunitgroup} \marg{group-name} \marg{unit-list}
% \end{syntax}
% Defines the group \meta{group-name} containing the list \meta{unit-list}.
-% This allows the usage of |\meta{group-name}=\meta{unit-key}| to
+% This allows the usage of \texttt{\meta{group-name}=\meta{unit-key}} to
% change all units in the group \meta{group-name} to \meta{unit-key}
% (which has to be part of \meta{unit-list}).
% \end{function}
@@ -2090,33 +2084,34 @@ and the derived file cooking-units.sty.
% \ \dots
% \ \}
% \end{syntax}
+% \emph{This option is going to be obsolete at one point.}
% Adds each \meta{unit-key} in \meta{unit-keys-list} to \meta{group}.
% The key-val equivalent of \mycs{cuaddtounitgroup}.
% \end{function}
-% \begin{cuexample}
-% The same as above:
-% 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}
+%^^A \begin{cuexample}
+%^^A The same as above:
+%^^A This example adds the unit \myunit{st} to the group \mygroup{weight}
+%^^A and \myunit{Ro} to \mygroup{temperature}.
+%^^A \begin{lstlisting}
+%^^A \cusetup
+%^^A {
+%^^A add-unit-to-group = { weight = {st} , temperature = {Ro} }
+%^^A }
+% ^^A\end{lstlisting}
+%^^A
+%^^A \cusetup{ add-unit-to-group = { weight = {st} } }
+%^^A
+%^^A \begin{cuexamplecode}
+%^^A \cusetup{weight=g} @
+%^^A \cunum{1}{kg} \\
+%^^A \cunum{1}{dag} \\
+%^^A \cunum{1}{g} \\
+%^^A \cunum{1}{oz} \\
+%^^A \cunum{1}{lb} \\
+%^^A \cunum{1}{stick} \\
+%^^A \cunum{1}{st}
+%^^A \end{cuexamplecode}
+%^^A \end{cuexample}
%
%
%
@@ -2125,6 +2120,7 @@ and the derived file cooking-units.sty.
% set-option-for-\meta{unit-key} = \marg{ key1 = value1, \dots\ }
% add-option-for-\meta{unit-key} = \marg{ key1 = value1, \dots\ }
% \end{syntax}
+% \emph{This option is going to be obsolete at one point.}
% 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
@@ -2147,24 +2143,23 @@ and the derived file cooking-units.sty.
%
% \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-precision = 0 } ,
-% set-option-for-C = { round-precision = 0 } ,
-% set-option-for-K = { round-precision = 0 } ,
-% set-option-for-Re = { round-precision = 0 }
-% }
-% \end{lstlisting}
-% although note that it would be easier to simply write
-% \begin{lstlisting}
-% \cusetoptionfor {F,C,K,Re} { round-precision = 0 }
-% \end{lstlisting}
-%
-% \end{cuexample}
+%^^A \begin{cuexample}
+%^^A The following rounds the values to integers for \myunit{F}, \myunit{C},
+%^^A \myunit{K} and \myunit{Re}:
+%^^A \begin{lstlisting}
+%^^A \cusetup
+%^^A {
+%^^A set-option-for-F = { round-precision = 0 } ,
+%^^A set-option-for-C = { round-precision = 0 } ,
+%^^A set-option-for-K = { round-precision = 0 } ,
+%^^A set-option-for-Re = { round-precision = 0 }
+%^^A }
+%^^A \end{lstlisting}
+%^^A although note that it would be easier to simply write
+%^^A \begin{lstlisting}
+%^^A \cusetoptionfor {F,C,K,Re} { round-precision = 0 }
+%^^A \end{lstlisting}
+%^^A \end{cuexample}
%
%
% \begin{function}{set-option-for, add-option-for}
@@ -2182,6 +2177,7 @@ and the derived file cooking-units.sty.
% \ \dots
% \ \}
% \end{syntax}
+% \emph{This option is going to be obsolete at one point.}
% 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.
@@ -2190,27 +2186,28 @@ and the derived file cooking-units.sty.
% \mycs{cuaddoptionfor}.
% \end{function}
%
-% \begin{cuexample}
-% The following example does the same as the example above:
-% \begin{lstlisting}
-% \cusetup
-% {
-% set-option-for =
-% {
-% F = { round-precision = 0 } ,
-% C = { round-precision = 0 } ,
-% K = { round-precision = 0 } ,
-% Re = { round-precision = 0 }
-% }
-% }
-% \end{lstlisting}
-% \end{cuexample}
+%^^A \begin{cuexample}
+%^^A The following example does the same as the example above:
+%^^A \begin{lstlisting}
+%^^A \cusetup
+%^^A {
+%^^A set-option-for =
+%^^A {
+%^^A F = { round-precision = 0 } ,
+%^^A C = { round-precision = 0 } ,
+%^^A K = { round-precision = 0 } ,
+%^^A Re = { round-precision = 0 }
+%^^A }
+%^^A }
+%^^A \end{lstlisting}
+%^^A \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}
+% \emph{This option is going to be obsolete at one point.}
% Erase options added to units. \opt{erase-all-options} erases all options
% for \emph{all} \meta{unit-key}s.
%
@@ -2222,18 +2219,18 @@ and the derived file cooking-units.sty.
%
% \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}
-% It's the same as
-% \begin{lstlisting}
-% \cuclearoptionfor {C, F, K, Re}
-% \end{lstlisting}
-% \end{cuexample}
+%^^A \begin{cuexample}
+%^^A The following code erases all attached options from \myunit{C}, \myunit{F},
+%^^A \myunit{K} and \myunit{Re}:
+%^^A
+%^^A \begin{lstlisting}
+%^^A \cusetup{ erase-all-options-for = {C, F, K, Re} }
+%^^A \end{lstlisting}
+%^^A It's the same as
+%^^A \begin{lstlisting}
+%^^A \cuclearoptionfor {C, F, K, Re}
+%^^A \end{lstlisting}
+%^^A \end{cuexample}
%
%
%
@@ -2395,7 +2392,8 @@ and the derived file cooking-units.sty.
% \begin{syntax}
% set-cutext-translation-message = \meta{error/warning/none}
% \end{syntax}
-% If a translation for \cCutext\ is not available the commands are replaced
+% If a translation for \cCutext\ is not available for the language,
+% 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.
@@ -2406,14 +2404,14 @@ and the derived file cooking-units.sty.
% print-numerals = \meta{true/false}
% \end{syntax}
%
-% Prints numerals for integers smaller then \opt{use-numerals-below} if
+% Prints numerals for integers smaller than \opt{use-numerals-below} if
% set to \true. If set to \false\ no numerals are printed.
%
% If you use the package option \opt{use-fmtcount-numerals} this option
% is automatically set to \true.
%
% If you want to use another package, just set this option to \true\ and
-% use \opt{numeral-function} and \opt{Numeral-function}.
+% use \opt{numeral-function} and \opt{Numeral-function}).
%
%^^A If the package option \opt{use-fmtcount-numerals} is set to \true\ you can
%^^A deactivate the printing of numerals by setting \opt{print-numerals} to
@@ -2526,7 +2524,7 @@ and the derived file cooking-units.sty.
%
%
%
-% \begin{function}{range-sign}
+% \begin{function}{range-sign, cunum-range-sign, cutext-range-sign}
% \begin{syntax}
% range-sign = \marg{string}
% cunum-range-sign = \marg{string}
@@ -2542,7 +2540,7 @@ and the derived file cooking-units.sty.
% 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}
+% Since version 1.45 there also exists 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.
%
@@ -2583,9 +2581,10 @@ and the derived file cooking-units.sty.
% \end{function}
%
% \begin{cuexample}
-% \begin{myde}
+%^^A \begin{myde}
% For the German language:
% \begin{cuexamplecode}
+% \selectlanguage{ngerman} @
% \cuam{12} \\
% \cuam{12--24} \\
% \cuam{36} \\
@@ -2598,7 +2597,7 @@ and the derived file cooking-units.sty.
% \cuam{12--24} \\
% \cuam{36} \\
% \end{cuexamplecode}
-% \end{myde}
+%^^A \end{myde}
% \end{cuexample}
%
%
@@ -2610,8 +2609,7 @@ and the derived file cooking-units.sty.
% \end{syntax}
% Rounds the amount automatically to \meta{integer} digits after the
% colon. Note that units like \myunit{C}, \myunit{F}, \myunit{K} and
-% \myunit{Re} are still rounded to integers due to
-% \texttt{set-option-for-<unit-key>}.
+% \myunit{Re} are still rounded to integers due to \mycs{cusetoptionfor}.
% \end{function}
%
%
@@ -2631,7 +2629,7 @@ and the derived file cooking-units.sty.
% \end{cuexamplecode}
%
% \begin{cunote}
-% Also negative numbers are allowed.
+% Negative numbers are also allowed.
% \begin{cuexamplecode}
% \cusetoptionfor{C,F}{round-precision=-1} @
% \cunum{-271,2}{C} \\
@@ -2710,7 +2708,7 @@ and the derived file cooking-units.sty.
% \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} \\
+% \cunum[kg=g]{1_2/?}{kg} \\
% \end{cuexamplecode}
%
%
@@ -2731,7 +2729,7 @@ and the derived file cooking-units.sty.
% \cunum[kg=g]{1/3}{kg} \\
% \cunum{1_1/2}{kg} \\
% \cunum[kg=g]{1_1/2}{kg} \\
-% \cunum[kg=g]{1_?/2}{kg} \\
+% \cunum[kg=g]{1_?/3}{kg} \\
% \end{cuexamplecode}
%
%
@@ -2813,13 +2811,12 @@ and the derived file cooking-units.sty.
% 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.
+% when using \cCutext. By default it is set an unbreakable space |~|.
% \end{function}
% \begin{cuexamplecode}
% \cutext{1}{kg}\\
% \Cutext{10}{kg}\\
-% \cusetup { cutext-space = ~ } @
+% \cusetup { cutext-space = \space } @
% \cutext{1}{kg}\\
% \Cutext{10}{kg}\\
% \cusetup { cutext-space = {} } @
@@ -2836,16 +2833,17 @@ and the derived file cooking-units.sty.
% 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.
+% while using \mycs{cuam}. By default it is set to the unbreakable space |~|. Use this option
+% if you want to e.g.\ insert a normal space.
% \end{function}
-% \begin{myde}
+%^^A \begin{myde}
% \cusetup{use-phrases=true}
% (Switching to german)
% \begin{cuexamplecode}
+% \selectlanguage{ngerman} @
% \cuam{12}\\
% \cuam{144}\\
-% \cusetup { phrase-space = ~ } @
+% \cusetup { phrase-space = \space } @
% \cuam{12}\\
% \cuam{144}\\
% \cusetup { phrase-space = {} } @
@@ -2856,7 +2854,7 @@ and the derived file cooking-units.sty.
% \cuam{144}\\
% \end{cuexamplecode}
% \cusetup{use-phrases=false}
-% \end{myde}
+%^^A \end{myde}
%
% \begin{function}{amount-unit-space}
% \begin{syntax}
@@ -2909,32 +2907,31 @@ and the derived file cooking-units.sty.
% \curef{anotherrecipe}~persons \\
% \cunum<anotherrecipe>{1}{kg}\\
% \cuam<anotherrecipe>{1}\\
-% \cutext<anotherrecipe>{1}{kg}\\
-% \curef{anotherrecipe}~persons \\ @
+% \Cutext[ref=anotherrecipe]{10}{kg}\\
+% &
% \cusetup{ recalculate-amount = true } @
% \curef{anotherrecipe}~persons \\
% \cunum<anotherrecipe>{1}{kg}\\
% \cuam<anotherrecipe>{1}\\
-% \cutext<anotherrecipe>{1}{kg}\\
-% \Cutext[ref=anotherrecipe]{10}{kg}\\ @
-% \cusetup { set-number-of-persons = 3 } @
+% \Cutext[ref=anotherrecipe]{10}{kg}\\
+% &
+% \cusetup { set-number-of-persons = 3 } @
% \curef{anotherrecipe}~persons \\
-% \cunum<anotherrecipe>{1}{kg}\\
-% \cuam<anotherrecipe>{1}\\
-% \cutext<anotherrecipe>{1}{kg}\\
-% \Cutext[ref=anotherrecipe]{10}{kg}\\ @
+% \cunum<anotherrecipe>{1}{kg} \\
+% \cuam<anotherrecipe>{1} \\
+% \Cutext[ref=anotherrecipe]{10}{kg}\\
+% &
% \cusetup { set-number-of-persons = 2 } @
% \curef{anotherrecipe}~persons \\
% \cunum<anotherrecipe>{1}{kg}\\
% \cuam<anotherrecipe>{1}\\
-% \cutext<anotherrecipe>{1}{kg}\\
-% \Cutext[ref=anotherrecipe]{10}{kg}\\ @
+% \cutext<anotherrecipe>{10}{kg}\\
+% &
% \cusetup { set-number-of-persons = 1 } @
-% \curef{anotherrecipe}~person \\
+% \curef{anotherrecipe}~persons \\
% \cunum<anotherrecipe>{1}{kg}\\
-% \cuam<anotherrecipe>{1}\\
-% \cutext<anotherrecipe>{1}{kg}\\
-% \Cutext[ref=anotherrecipe]{10}{kg}\\
+% \cuam<anotherrecipe>{1}\\
+% \Cutext[ref=anotherrecipe]{10}{kg}\\
% \end{cuexamplecode}
%
%
@@ -2972,7 +2969,7 @@ and the derived file cooking-units.sty.
% \curef{Schinken} \\
% \cusetup { recalculate-amount = true } @
% \cusetup{get-label=Schinken} \\
-% \curef{Schinken} \\
+% \curef{Schinken}
% \end{cuexamplecode}
%
% \begin{cunote}
@@ -3124,7 +3121,7 @@ and the derived file cooking-units.sty.
% 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
+% 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
@@ -3143,6 +3140,7 @@ and the derived file cooking-units.sty.
% \cunum{1}{s}
% \end{cuexamplecode}
%
+%
% \begin{function}{add-natural-unit}
% \begin{syntax}
% add-natural-unit = \meta{unit-key}
@@ -3167,12 +3165,39 @@ and the derived file cooking-units.sty.
% \cunum[kg=g]{1}{kg} \\
% \cunum{1.5}{J} \\
% \cunum{180}{C} \\
-% \cunum{15}{s}
+% \cunum{15/4}{s} \\
+% \cunum{1--2}{min} \\
+% \cunum{?}{l}
% \end{cuexamplecode}
%
%
+% \begin{function}{nothing-special, going-bonkers, fully-bonkers, xD-lol}
+% \begin{syntax}
+% nothing-special = \meta{true/false}
+% going-bonkers = \meta{true/false}
+% fully-bonkers = \meta{true/false}
+% xD-lol = \meta{true/false}
+% \end{syntax}
+% Options that do \dots\ stuff. The four stages of madness in option for.
+%
+% \begin{description}
+% \item[nothing-special] is your default. The package behaves as intended.
+%
+% \item[going-bonkers] is a bit more strange. It converts an unit into another random unit
+% (if it can) and does so throughout the document. So if |unit-A| is converted
+% into |unit-B|, it is going to be converted this way the entire document through.
+% For an unit to be converted it must have a key, see \cref{sec:defining-opt}.
+%
%
+% \item[fully-bonkers] converts one unit into another random unit (if it can) and does so for
+% each unit it encounters. So |unit-A| might be converted into |unit-B| the first time,
+% but |unit-C| the second. Each conversion picks a random unit for the conversion
+% (but the conversion itself makes sense, e.g.\ |kg| into |g|, but not into |cm|).
%
+% \item[xD-lol] is pure insanity. A unit is transformed into another, if it makes sense
+% or not, and its value is replaced by a random number.
+% \end{description}
+% \end{function}
%
%
%
@@ -3222,6 +3247,7 @@ and the derived file cooking-units.sty.
%\clearpage
%
% \section{Bens Einheitensammelsurium (Bens unit Almanac)}
+% \label{sec: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
@@ -3246,21 +3272,6 @@ and the derived file cooking-units.sty.
% 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}
%
@@ -3355,13 +3366,6 @@ and the derived file cooking-units.sty.
% \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}
-%
%
%
%
@@ -3525,8 +3529,8 @@ and the derived file cooking-units.sty.
%\end{center}
%
%
-%
-%
+% If you ever encounter in a german cookery book the word \enquote{Packerl},
+% check out its entry in \cref{sec:unit-almanac}.
%
%
%
@@ -3657,7 +3661,7 @@ and the derived file cooking-units.sty.
%
%
%
-% \end{documentation}
+%\end{documentation}
%
%
%
@@ -3699,14 +3703,14 @@ and the derived file cooking-units.sty.
% \begin{macrocode}
\ProvidesExplPackage
{cooking-units}
- {2020/01/13}
- {1.46}
+ {2021/05/16}
+ {2.00}
{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 }
+\@ifpackagelater { expl3 } { 2021/05/07 }
{ }
{
\PackageError { cooking-units } { Support~package~expl3~too~old }
@@ -3727,7 +3731,7 @@ and the derived file cooking-units.sty.
%
% Checking if \pkg{translations} is up-to-date, otherwise abort the loading of the package.
% \begin{macrocode}
-\@ifpackagelater { translations } { 2017/08/31 }
+\@ifpackagelater { translations } { 2021/01/17 }
{ }
{
\PackageError { cooking-units } { Support~package~translations~too~old }
@@ -3748,6 +3752,12 @@ and the derived file cooking-units.sty.
Please \ replace \ the \ option.
\msg_see_documentation_text:n { cooking-units }
}
+\msg_new:nnnn { cooking-units } { key-unknown }
+ { The~key~'#1'~is~unknown~and~is~being~ignored. }
+ {
+ The~module~'#2'~does~not~have~a~key~called~'#1'.\\
+ Check~that~you~have~spelled~the~key~name~correctly.
+ }
% \end{macrocode}
% \begin{macrocode}
\bool_new:N \g_@@_opt_numeral_bool
@@ -3761,6 +3771,9 @@ and the derived file cooking-units.sty.
use-numerals .default:n = { false },
use-fmtcount-numerals .bool_gset:N = \g_@@_opt_numeral_bool ,
use-fmtcount-numerals .default:n = { false },
+ unknown .code:n = { \msg_error:nnxx { cooking-units } { key-unknown }
+ { \l_keys_path_str } { cooking-units }
+ }
}
% \end{macrocode}
% Now process the package options \dots
@@ -3778,9 +3791,9 @@ and the derived file cooking-units.sty.
use-numerals .code:n =
{
\msg_warning:nnnn { cooking-units } { Option-deprecated } { use-numerals } { use-fmtcount-numerals }
- \msg_error:nnn { cooking-units } { load-time-option } { fmtcount }
+ \msg_error:nnn { cooking-units } { load-time-option } { use-fmtcount-numerals }
} ,
- use-fmtcount-numerals .code:n = { \msg_error:nnn { cooking-units } { load-time-option } { fmtcount } } ,
+ use-fmtcount-numerals .code:n = { \msg_error:nnn { cooking-units } { load-time-option } { use-fmtcount-numerals } } ,
}
% \end{macrocode}
%
@@ -3788,33 +3801,28 @@ and the derived file cooking-units.sty.
%
% \subsection {Defining Variables}
%
-% \begin{macro}
-% {
-% \tl_replace_all:NVn,
-% \tl_replace_once:NVn ,
-% \tl_if_in:nVTF ,
-% \tl_if_in:NVTF ,
-% \tl_if_in:NVT ,
-% \fp_compare:vNnT ,
-% \prop_get:cVc ,
-% \tl_set_rescan:NnV,
-% \msg_error:nnnV, \msg_error:nnV, \msg_warning:nnV,
-% \prop_put:cnx
-% }
+% \begin{macro} { cs variants }
% Some variations of commands we will need later.
% \begin{macrocode}
+\cs_generate_variant:Nn \msg_redirect_name:nnn { nnV }
\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 \prop_get:NnN { cVc, Nnc }
+\cs_generate_variant:Nn \prop_get:NnNF { Nnc }
\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 }
\cs_generate_variant:Nn \prop_put:Nnn { cnx }
+\cs_generate_variant:Nn \seq_remove_all:Nn { NV }
+\cs_generate_variant:Nn \prop_gput:Nnn { Nnv, Nxv }
+\cs_generate_variant:Nn \prop_get:NnN { cnc }
+\cs_generate_variant:Nn \prg_new_conditional:Npnn { c }
+\cs_generate_variant:Nn \text_uppercase:n { x }
% \end{macrocode}
% \end{macro}
%
@@ -3828,11 +3836,22 @@ and the derived file cooking-units.sty.
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\@@_set_amount:Nn,\@@_set_unit:Nn}
+% \begin{macro}{\l_@@_unit_argument_spec_tl , \l_@@_unit_argument_spec_tl }
% Allows for potential parsing of amount and or unit.
% \begin{macrocode}
+\tl_new:N \l_@@_unit_argument_spec_tl
+\tl_new:N \l_@@_expand_amount_tl
+\tl_set:Nn \l_@@_unit_argument_spec_tl { n }
+\tl_set:Nn \l_@@_expand_amount_tl { n }
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\@@_set_amount:Nn , \@@_set_unit:Nn , \@@_to_unit:n }
+% Definitions to set the amount and the unit. Made so that it can be changed globally.
+% By default, the amount is just taken as is while the unit is changed into a string.
+% \begin{macrocode}
\cs_new_eq:NN \@@_set_amount:Nn \tl_set:Nn
-\cs_new_eq:NN \@@_set_unit:Nn \tl_set:Nn
+\cs_new_eq:NN \@@_set_unit:Nn \str_set:Nn
+\cs_new_eq:NN \@@_to_unit:n \tl_to_str:n
% \end{macrocode}
% \end{macro}
%
@@ -3849,6 +3868,8 @@ and the derived file cooking-units.sty.
\cs_set_eq:NN \@@_print_numeral:n \numberstringnum
\cs_set_eq:NN \@@_print_Numeral:n \Numberstringnum
}
+\cs_generate_variant:Nn \@@_print_numeral:n { V }
+\cs_generate_variant:Nn \@@_print_Numeral:n { V }
% \end{macrocode}
% \end{macro}
%
@@ -3878,39 +3899,60 @@ and the derived file cooking-units.sty.
% \end{macrocode}
% \end{macro}
%
-%
+% \begin{macro} { \g_@@_convert_bonkers_remember_prop , \g_@@_convert_to_eV_remember_prop }
+% If the unit is changed in a \enquote{not normal} way, store
+% some things in one of the two lists. They are just used as shortcuts
+% to remember which unit is changed into which. They are one level above
+% |\g_@@_master_changer_prop|.
+% \begin{macrocode}
+\prop_new:N \g_@@_convert_to_eV_remember_prop
+\prop_new:N \g_@@_convert_bonkers_remember_prop
+% \end{macrocode}
+% \end{macro}
%
% \begin{macro}
% {
-% \l_@@_number_tmpa_tl,
-% \l_@@_number_tmpb_tl,
-% \l_@@_mixed_fraction_tl,
-% \l_@@_original_amount_tl,
-% \l_@@_original_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 ,
-% \g_@@_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_@@_phantom_tl,
-% \l_@@_phrase_phrase_tl,
-% \l_@@_unit_letter_not_allowed_tl,
-% \l_@@_input_fraction_sign_tl,
-% \l_@@_input_mixed_fraction_sign_tl,
-% \l_@@_list_of_units_tl,
-% \l_@@_list_of_values_tl,
-% \l_@@_cunum_hook_tl , \l_@@_cutext_hook_tl ,
-% \l_@@_Cutext_hook_tl , \l_@@_cuam_hook_tl
+% , \l_@@_number_tmpa_tl
+% , \l_@@_number_tmpb_tl
+% , \l_@@_mixed_fraction_tl
+% , \l_@@_original_amount_tl
+% , \l_@@_original_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
+% , \g_@@_input_str_hash_one_tl
+% , \l_@@_input_range_sign_tl
+% , \l_@@_cutext_space_tl
+% , \l_@@_cutext_numeral_space_tl
+% , \l_@@_cuphrase_space_tl
+% , \l_@@_translation_tmpa_tl
+% , \l_@@_cutext_last_value_tl
+% , \l_@@_phantom_tl
+% , \l_@@_phrase_text_tl
+% , \l_@@_unit_letter_not_allowed_tl
+% , \l_@@_input_fraction_sign_tl
+% , \l_@@_input_mixed_fraction_sign_tl
+% , \l_@@_list_of_units_tl
+% , \l_@@_list_of_values_tl
+% , \l_@@_allwed_integer_math_operators_tl
+% , \l_@@_curr_group_tl
+% , \l_@@_curr_unit_tl
+% , \l_@@_cmd_hook_tl
+% , \l_@@_cunum_hook_tl
+% , \l_@@_cutext_hook_tl
+% , \l_@@_Cutext_hook_tl
+% , \l_@@_cuam_hook_tl
+% , \l_@@_new_key_base_tl
+% , \l_@@_decided_unit_tl
+% , \l_@@_stored_units_tl
+% , \l_@@_stored_formula_tl
+% , \l_@@_base_tl
% }
% Quite a lot of tl's.
% \begin{macrocode}
@@ -3931,18 +3973,28 @@ and the derived file cooking-units.sty.
\tl_new:N \g_@@_input_str_hash_one_tl
\tl_new:N \l_@@_input_range_sign_tl
\tl_new:N \l_@@_cutext_space_tl
+\tl_new:N \l_@@_cutext_numeral_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_@@_phrase_text_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
\tl_new:N \l_@@_list_of_units_tl
\tl_new:N \l_@@_list_of_values_tl
+\tl_new:N \l_@@_allwed_integer_math_operators_tl
+\tl_new:N \l_@@_curr_group_tl
+\tl_new:N \l_@@_curr_unit_tl
+\tl_new:N \l_@@_new_key_base_tl
+\tl_new:N \l_@@_decided_unit_tl
+\tl_new:N \l_@@_stored_units_tl
+\tl_new:N \l_@@_stored_formula_tl
+\tl_new:N \l_@@_base_tl
% \end{macrocode}
% \begin{macrocode}
+\tl_new:N \l_@@_cmd_hook_tl
\tl_new:N \l_@@_cunum_hook_tl
\tl_new:N \l_@@_cutext_hook_tl
\tl_new:N \l_@@_Cutext_hook_tl
@@ -3964,16 +4016,19 @@ and the derived file cooking-units.sty.
\tl_set:Nn \l_@@_input_allowed_special_signs_tl { ? }
\tl_gset_rescan:Nnn \g_@@_input_str_hash_one_tl
{ \char_set_catcode_letter:N \# } {#1}
+\tl_set:Nn \l_@@_allwed_integer_math_operators_tl { +-()*/ }
% \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_@@_cutext_space_tl { ~ }
+\tl_set:Nn \l_@@_cutext_numeral_space_tl { \space }
\tl_set:Nn \l_@@_cuphrase_space_tl { \space }
\tl_set:Nn \l_@@_unit_letter_not_allowed_tl { , / }
% \end{macrocode}
%
+% \begin{macro}{\c_@@_minus_tl}
% Flat out stolen from \pkg{siunitx}.
% \begin{macrocode}
\AtBeginDocument {
@@ -4001,6 +4056,7 @@ and the derived file cooking-units.sty.
{ }
}
% \end{macrocode}
+% \end{macro}
%
% \begin{macro}{ \l_@@_mixed_frac_dim }
% The dimension between the fraction and the mixed fraction part is
@@ -4054,18 +4110,20 @@ and the derived file cooking-units.sty.
% \end{macro}
%
%
-% \begin{macro}{ \l_@@_phrase_number_tl }
-% Stores the current \enquote{phrase number}. For \enquote{Dutzend} this would
-% be \enquote{12}, etc.
+% \begin{macro}{ \l_@@_phrase_number_tl , \l_@@_phrase_gender_tl }
+% Stores the current \enquote{phrase number} (and gender).
+% For \enquote{Dutzend} this would
+% be \enquote{12}, etc. The second stores the gender (m, f or n)
% \begin{macrocode}
\int_new:N \l_@@_phrase_number_tl
+\int_new:N \l_@@_phrase_gender_tl
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{ \l_@@_list_of_defined_keys_clist , \g_@@_list_of_defined_units_clist }
-% Sequence of defined units and keys. Units are defined
+% 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.
+% (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
@@ -4093,27 +4151,35 @@ and the derived file cooking-units.sty.
% \end{macro}
%
%
-% \begin{macro}{\l_@@_number_of_iterations_seq, \l_@@_derivative_unit_list_seq ,
-% \l_@@_derivative_symbol_list_seq , \l_@@_derivative_value_list_seq
+% \begin{macro}{
+% , \g_@@_stored_derived_unit_symbol_seq
+% , \g_@@_stored_derived_formula_seq
+% , \g_@@_stored_derived_unit_print_seq
% }
% Variables used in \mycs{declarecookingderivatives}.
% \begin{macrocode}
-\seq_new:N \l_@@_number_of_iterations_seq
-\seq_new:N \l_@@_derivative_unit_list_seq
-\seq_new:N \l_@@_derivative_symbol_list_seq
-\seq_new:N \l_@@_derivative_value_list_seq
+\seq_new:N \g_@@_stored_derived_unit_symbol_seq
+\seq_new:N \g_@@_stored_derived_formula_seq
+\seq_new:N \g_@@_stored_derived_unit_print_seq
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\l_@@_max_depth_int, \l_@@_curr_depth_int}
-% Also some variables used in \mycs{declarecookingderivatives}.
+%
+% \begin{macro}{\l_@@_nr_of_units_int, \l_@@_depth_int}
+% Also some variables used in \mycs{declarecookingderivatives}. (And for one check during
+% definitions of keys).
% \begin{macrocode}
-\int_new:N \l_@@_max_depth_int
-\int_new:N \l_@@_curr_depth_int
+\int_new:N \l_@@_nr_of_units_int
+\int_new:N \l_@@_depth_int
% \end{macrocode}
% \end{macro}
%
-%
+% \begin{macro}{\g_@@_natural_units_seq }
+% Remembers which unit foes to which natural unit.
+% \begin{macrocode}
+\seq_new:N \g_@@_natural_units_seq
+% \end{macrocode}
+% \end{macro}
%
% \begin{macro} { \l_@@_temperatures_to_check_seq }
% \changes {1.02h} {New.}
@@ -4139,82 +4205,85 @@ and the derived file cooking-units.sty.
% \end{macrocode}
% \end{macro}
%
+% \begin{macro} { \l_@@_derived_units_prop }
+% Stores \emph{via} key-value all defined derived units as keys
+% and the formula to calculate the derived unit as value..
+% \begin{macrocode}
+\prop_new:N \l_@@_derived_units_prop
+% \end{macrocode}
+% \end{macro}
+%
%
%
% \begin{macro}
% {
-% \l_@@_minus_bool,
-% \l_@@_round_number_bool,
-% \l_@@_error_bool,
-% \l_@@_unit_error_bool,
-% \l_@@_eval_fractions_bool,
-% \l_@@_convert_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_@@_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,
-% \l_@@_print_numeral_bool,
-% \l_@@_lokal_numeral_bool,
-% \l_@@_round_precision_negative_bool,
-% \l_@@_fourty_two_bool,
-% \l_@@_phrase_negative_bool ,
-% \l_@@_range_in_input_bool, \l_@@_lokal_fraction_bool ,
-% \l_@@_print_fraction_bool, \l_@@_check_decimal_bool ,
+% , \l_@@_pckopt_eval_fractions_bool
+% , \l_@@_pckopt_convert_fractions_bool
+% , \l_@@_pckopt_draft_bool
+% , \l_@@_pckopt_round_to_int_bool
+% , \l_@@_pckopt_check_temperature_bool
+% , \l_@@_pckopt_convert_to_eV_bool
+% , \l_@@_pckopt_cuam_old_bool
+% , \l_@@_pckopt_recalculate_amount_bool
+% , \l_@@_pckopt_cutext_to_cunum_bool
+% , \l_@@_pckopt_cutext_old_bool
+% , \l_@@_pckopt_cutext_keep_unit_bool
+% , \l_@@_pckopt_round_commercial_bool
+% , \l_@@_pckopt_use_phrases_bool
+% , \l_@@_pckopt_round_precision_negative_bool
+% , \l_@@_pckopt_fourty_two_bool
+% , \l_@@_pckopt_bonkers_bool
+% , \l_@@_minus_bool
+% , \l_@@_round_number_bool
+% , \l_@@_single_key_bool
+% , \l_@@_cutext_uppercase_word_bool
+% , \l_@@_reference_given_bool
+% , \l_@@_lokal_recalc_for_people_bool
+% , \l_@@_lokal_phrase_bool
+% , \l_@@_lokal_change_unit_bool
+% , \l_@@_pckopt_print_numeral_bool
+% , \l_@@_lokal_numeral_bool
+% , \l_@@_phrase_negative_bool
+% , \l_@@_cutext_last_amount_equ_one_bool
+% , \l_@@_symbol_was_set_by_key_bool
+% , \l_@@_contains_valid_key_bool
+% , \l_@@_check_decimal_bool
+% , \l_@@_unit_error_bool
% }
% Some booleans we need later.
% \begin{macrocode}
+\bool_new:N \l_@@_pckopt_eval_fractions_bool
+\bool_new:N \l_@@_pckopt_convert_fractions_bool
+\bool_new:N \l_@@_pckopt_draft_bool
+\bool_new:N \l_@@_pckopt_round_to_int_bool
+\bool_new:N \l_@@_pckopt_check_temperature_bool
+\bool_new:N \l_@@_pckopt_convert_to_eV_bool
+\bool_new:N \l_@@_pckopt_cuam_old_bool
+\bool_new:N \l_@@_pckopt_recalculate_amount_bool
+\bool_new:N \l_@@_pckopt_cutext_to_cunum_bool
+\bool_new:N \l_@@_pckopt_cutext_old_bool
+\bool_new:N \l_@@_pckopt_cutext_keep_unit_bool
+\bool_new:N \l_@@_pckopt_round_commercial_bool
+\bool_new:N \l_@@_pckopt_use_phrases_bool
+\bool_new:N \l_@@_pckopt_round_precision_negative_bool
+\bool_new:N \l_@@_pckopt_fourty_two_bool
+\bool_new:N \l_@@_pckopt_bonkers_bool
\bool_new:N \l_@@_minus_bool
\bool_new:N \l_@@_round_number_bool
-\bool_new:N \l_@@_error_bool
-\bool_new:N \l_@@_unit_error_bool
-\bool_new:N \l_@@_eval_fractions_bool
-\bool_new:N \l_@@_convert_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_@@_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_@@_reference_given_bool
+\bool_new:N \l_@@_lokal_recalc_for_people_bool
\bool_new:N \l_@@_lokal_phrase_bool
-\bool_new:N \l_@@_print_numeral_bool
+\bool_new:N \l_@@_lokal_change_unit_bool
+\bool_new:N \l_@@_pckopt_print_numeral_bool
\bool_new:N \l_@@_lokal_numeral_bool
-\bool_new:N \l_@@_round_precision_negative_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_@@_cutext_last_amount_equ_one_bool
+\bool_new:N \l_@@_symbol_was_set_by_key_bool
+\bool_new:N \l_@@_contains_valid_key_bool
\bool_new:N \l_@@_check_decimal_bool
+\bool_new:N \l_@@_unit_error_bool
% \end{macrocode}
% \end{macro}
%
@@ -4222,8 +4291,8 @@ and the derived file cooking-units.sty.
%
% 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
+\bool_set_false:N \l_@@_pckopt_cutext_keep_unit_bool
+\bool_set_eq:NN \l_@@_pckopt_print_numeral_bool \g_@@_opt_numeral_bool
% \end{macrocode}
%
%
@@ -4238,20 +4307,30 @@ and the derived file cooking-units.sty.
% Checking value if a translation is avaiable.
% \begin{macrocode}
\quark_new:N \q_@@_no_translation
+%\cs_new:Npn \q_@@_no_translation { asdasd\ewhkerhjkwejhk }
% \end{macrocode}
%\end{macro}
%
%
% \begin{macro}{
-% \l_@@_tmpa_tl , \l_@@_tmpb_tl , \l_@@_tmp_unit_tl ,
-% \l_@@_tmpa_fp ,
-% \l_@@_tmpa_clist ,
-% \l_@@_tmpa_prop , \l_@@_tmpb_prop ,
-% \l_@@_tmpa_seq ,
-% \l_@@_tmpa_int , \l_@@_tmpb_int ,
+% , \l_@@_scrap_tl
+% , \l_@@_tmpa_tl
+% , \l_@@_tmpb_tl
+% , \l_@@_tmp_unit_tl
+% , \l_@@_tmpa_fp
+% , \l_@@_tmpa_clist
+% , \l_@@_tmpa_prop
+% , \l_@@_tmpb_prop
+% , \l_@@_tmpa_seq
+% , \l_@@_tmpb_seq
+% , \l_@@_tmpa_int
+% , \l_@@_tmpb_int
+% , \l_@@_tmpa_bool
+% , \l_@@_tmpb_bool
% }
% Some temporal stores which are used throughout the code.
% \begin{macrocode}
+\tl_new:N \l_@@_scrap_tl
\tl_new:N \l_@@_tmpa_tl
\tl_new:N \l_@@_tmpb_tl
\tl_new:N \l_@@_tmp_unit_tl
@@ -4260,8 +4339,11 @@ and the derived file cooking-units.sty.
\prop_new:N \l_@@_tmpa_prop
\prop_new:N \l_@@_tmpb_prop
\seq_new:N \l_@@_tmpa_seq
+\seq_new:N \l_@@_tmpb_seq
\int_new:N \l_@@_tmpa_int
\int_new:N \l_@@_tmpb_int
+\bool_new:N \l_@@_tmpa_bool
+\bool_new:N \l_@@_tmpb_bool
% \end{macrocode}
%\end{macro}
%
@@ -4322,8 +4404,9 @@ and the derived file cooking-units.sty.
% \begin{macrocode}
erase-all-options .code:n =
{
- \exp_args:Nx \cuclearoptionfor { \seq_use:Nn \g_@@_list_of_defined_units_seq { , } }
- },
+ \clist_set_from_seq:NN \l_@@_tmpa_clist \g_@@_list_of_defined_units_seq
+ \@@_clear_options_for:V \l_@@_tmpa_clist
+ },
erase-all-options .value_forbidden:n = { true } ,
% \end{macrocode}
% \end{macro}
@@ -4334,11 +4417,7 @@ and the derived file cooking-units.sty.
% \begin{macrocode}
erase-all-options-for .code:n =
{
- \cuclearoptionfor {#1}
-% \keyval_parse:NNn
-% \@@_erase_options_for:n
-% \@@_erase_options_for_error:nn
-% {#1}
+ \@@_clear_options_for:n {#1}
},
erase-all-options-for .value_required:n = { true } ,
% \end{macrocode}
@@ -4353,7 +4432,7 @@ and the derived file cooking-units.sty.
% 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 .bool_set:N = \l_@@_pckopt_cutext_to_cunum_bool ,
cutext-to-cunum .default:n = { false } ,
cutext-to-cunum .groups:n = { change-command } ,
% \end{macrocode}
@@ -4362,7 +4441,7 @@ and the derived file cooking-units.sty.
% \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 .bool_set_inverse:N = \l_@@_pckopt_cutext_keep_unit_bool ,
cutext-change-unit .default:n = { true } ,
cutext-change-unit .groups:n = { change-unit } ,
% \end{macrocode}
@@ -4377,21 +4456,23 @@ and the derived file cooking-units.sty.
{
\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 }
+ { 1 } { \bool_set_false:N \l_@@_pckopt_cuam_old_bool }
+ { 2 } { \bool_set_true:N \l_@@_pckopt_cuam_old_bool }
}
} ,
cuam-version .default:n = { new } ,
+ cuam-version .groups:n = { parse } ,
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 }
+ { 1 } { \bool_set_false:N \l_@@_pckopt_cutext_old_bool }
+ { 2 } { \bool_set_true:N \l_@@_pckopt_cutext_old_bool }
}
} ,
cutext-version .default:n = { new } ,
+ cutext-version .groups:n = { parse } ,
% \end{macrocode}
% \end{macro}
%
@@ -4400,26 +4481,29 @@ and the derived file cooking-units.sty.
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 }
+ \tl_set_eq:NN \l_@@_unit_argument_spec_tl \l_keys_choice_tl
+ \tl_set_eq:NN \l_@@_expand_amount_tl \l_keys_choice_tl
} ,
expand-both .default:n = { n } ,
+ expand-both .groups:n = { parse } ,
% \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 }
+ \tl_set_eq:NN \l_@@_expand_amount_tl \l_keys_choice_tl
} ,
expand-amount .default:n = { n } ,
+ expand-amount .groups:n = { parse } ,
% \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 }
+ \tl_set_eq:NN \l_@@_unit_argument_spec_tl \l_keys_choice_tl
} ,
expand-unit .default:n = { n } ,
+ expand-unit .groups:n = { parse } ,
% \end{macrocode}
% \end{macro}
%
@@ -4442,6 +4526,7 @@ and the derived file cooking-units.sty.
}
\use:n { \tl_set:Nn \l_@@_input_allowed_special_signs_tl {#1} }
} ,
+ set-special-sign .groups:n = { parse } ,
% \end{macrocode}
%\end{macro}
%\begin{macro}{ add-special-sign }
@@ -4460,6 +4545,7 @@ and the derived file cooking-units.sty.
}
} ,
add-special-sign .default:n = { } ,
+ add-special-sign .groups:n = { parse } ,
% \end{macrocode}
%\end{macro}
%
@@ -4470,21 +4556,21 @@ and the derived file cooking-units.sty.
set-unknown-message .choices:nn =
{ error , warning , none }
{
- \msg_redirect_name:nnn { cooking-units } { amount-not-known }
- { \l_keys_choice_tl }
+ \msg_redirect_name:nnV { cooking-units } { amount-not-known }
+ \l_keys_choice_tl
} ,
set-unknown-message .default:n = { warning } ,
% \end{macrocode}
%\end{macro}
%
-% \begin{macro}{ set-unknown-message }
+% \begin{macro}{ set-cutext-translation-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 }
+ \msg_redirect_name:nnV { cooking-units } { cutext-no-translation-available }
+ \l_keys_choice_tl
} ,
set-cutext-translation-message .default:n = { warning } ,
% \end{macrocode}
@@ -4494,7 +4580,7 @@ and the derived file cooking-units.sty.
% \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 .bool_set:N = \l_@@_pckopt_print_numeral_bool ,
print-numerals .default:n = { true } ,
% \end{macrocode}
% \end{macro}
@@ -4510,8 +4596,9 @@ and the derived file cooking-units.sty.
%\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 .bool_set_inverse:N = \l_@@_pckopt_draft_bool ,
parse-number .default:n= { true } ,
+ parse-number .groups:n = { parse } ,
% \end{macrocode}
%\end{macro}
%
@@ -4535,7 +4622,7 @@ and the derived file cooking-units.sty.
% \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 .bool_set:N = \l_@@_pckopt_use_phrases_bool ,
use-phrases .default:n = { true } ,
% \end{macrocode}
% \end{macro}
@@ -4555,7 +4642,7 @@ and the derived file cooking-units.sty.
\int_compare:nNnTF {#1} < { 0 }
{ \bool_set_true:N }
{ \bool_set_false:N }
- \l_@@_round_precision_negative_bool
+ \l_@@_pckopt_round_precision_negative_bool
} ,
round-precision .default:n = { 2 } ,
% \end{macrocode}
@@ -4564,7 +4651,7 @@ and the derived file cooking-units.sty.
%\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 .bool_set:N = \l_@@_pckopt_round_to_int_bool ,
round-to-int .choices:nn =
{ true , false }
{
@@ -4575,7 +4662,7 @@ and the derived file cooking-units.sty.
}{
}
- \use:c { bool_set_ \l_keys_choice_tl :N } \l_@@_round_to_int_bool
+ \use:c { bool_set_ \l_keys_choice_tl :N } \l_@@_pckopt_round_to_int_bool
} ,
round-to-int .default:n = { false } ,
% \end{macrocode}
@@ -4585,13 +4672,15 @@ and the derived file cooking-units.sty.
% Choosing between \enquote{normal} rounding to even
% and commercial rounding and sets the boolean accordingly.
% \begin{macrocode}
+% TODO: uodate doch und so
round-half .choices:nn =
- { default , commercial }
+ { default , commercial , up }
{
\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 }
+ { 1 } { \bool_set_false:N \l_@@_pckopt_round_commercial_bool }
+ { 2 } { \bool_set_true:N \l_@@_pckopt_round_commercial_bool }
+ { 3 } { \bool_set_true:N \l_@@_pckopt_round_commercial_bool }
}
},
round-half .default:n = { default },
@@ -4601,7 +4690,7 @@ and the derived file cooking-units.sty.
%\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 .bool_set:N = \l_@@_pckopt_eval_fractions_bool ,
eval-fraction .default:n = { false } ,
% \end{macrocode}
%\end{macro}
@@ -4609,7 +4698,7 @@ and the derived file cooking-units.sty.
%\begin{macro}{ convert-fraction }
% If set to true the fractions are evaluated \emph{if} the unit is transformed!
% \begin{macrocode}
- convert-fraction .bool_set:N = \l_@@_convert_fractions_bool ,
+ convert-fraction .bool_set:N = \l_@@_pckopt_convert_fractions_bool ,
convert-fraction .default:n = { true } ,
% \end{macrocode}
%\end{macro}
@@ -4645,11 +4734,20 @@ and the derived file cooking-units.sty.
%\end{macro}
%
% \begin{macro}{ cutext-space }
-% The space used in \mycs{cutext} between the number (or numeral)
+% The space used in \mycs{cutext} between the \emph{number}
% and unit.
% \begin{macrocode}
cutext-space .tl_set:N = \l_@@_cutext_space_tl ,
- cutext-space .default:n = { \space } ,
+ cutext-space .default:n = { ~ } ,
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{ cutext-space }
+% The space used in \mycs{cutext} between the \emph{numeral}
+% and unit.
+% \begin{macrocode}
+ cutext-numeral-space .tl_set:N = \l_@@_cutext_numeral_space_tl ,
+ cutext-numeral-space .default:n = { \space } ,
% \end{macrocode}
% \end{macro}
%
@@ -4657,7 +4755,7 @@ and the derived file cooking-units.sty.
% Same as before, but for phrases
% \begin{macrocode}
phrase-space .tl_set:N = \l_@@_cuphrase_space_tl ,
- phrase-space .default:n = { \space } ,
+ phrase-space .default:n = { ~ } ,
% \end{macrocode}
% \end{macro}
%
@@ -4679,7 +4777,7 @@ and the derived file cooking-units.sty.
% 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 .bool_set:N = \l_@@_pckopt_recalculate_amount_bool ,
recalculate-amount .default:n = { false } ,
% \end{macrocode}
% \end{macro}
@@ -4704,7 +4802,7 @@ and the derived file cooking-units.sty.
% \mycs{curef} as a key.
% \begin{macrocode}
get-label .code:n = \@@_curef:n {#1} ,
- label .value_required:n = { true } ,
+ get-label .value_required:n = { true } ,
% \end{macrocode}
% \end{macro}
%
@@ -4725,7 +4823,7 @@ and the derived file cooking-units.sty.
% 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 .bool_set:N = \l_@@_pckopt_check_temperature_bool ,
check-temperature .default:n = { true } ,
% \end{macrocode}
%
@@ -4751,9 +4849,9 @@ and the derived file cooking-units.sty.
% 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 .bool_set:N = \l_@@_pckopt_convert_to_eV_bool ,
convert-to-eV .default:n = { true } ,
- convert-to-eV .groups:n = { change-unit } ,
+% convert-to-eV .groups:n = { change-unit } ,
% \end{macrocode}
%\end{macro}
%
@@ -4764,10 +4862,10 @@ and the derived file cooking-units.sty.
\seq_set_from_clist:Nn \l_@@_tmpa_seq {#1}
\seq_map_inline:Nn \l_@@_tmpa_seq
{
- \@@_error_if_unit_not_defined:nF {##1}
+ \@@_error_if_unit_not_defined:nNF {##1} \l_@@_curr_unit_tl
{
- \seq_if_in:NnF \g_@@_natural_units_seq {##1}
- { \seq_gput_right:Nn \g_@@_natural_units_seq {##1} }
+ \seq_if_in:NVF \g_@@_natural_units_seq \l_@@_curr_unit_tl
+ { \seq_gput_right:NV \g_@@_natural_units_seq \l_@@_curr_unit_tl }
}
}
} ,
@@ -4778,9 +4876,10 @@ and the derived file cooking-units.sty.
% \begin{macro}{ 42 }
% \begin{macrocode}
42 .choice: ,
- 42 / true .code:n = { \bool_set_true:N \l_@@_fourty_two_bool } ,
+ 42 / true .code:n = { \bool_set_true:N \l_@@_pckopt_fourty_two_bool } ,
42 / false .code:n = { \msg_fatal:nnn { cooking-units } { 42-is-...-wrong? } } ,
42 .default:n = { true } ,
+ 42 .groups:n = { parse } ,
% \end{macrocode}
% \end{macro}
%
@@ -4808,6 +4907,7 @@ and the derived file cooking-units.sty.
% \begin{macrocode}
input-range-sign .tl_set:N = \l_@@_input_range_sign_tl ,
input-range-sign .default:n = { -- } ,
+ input-range-sign .groups:n = { parse } ,
% \end{macrocode}
%\end{macro}
%
@@ -4839,6 +4939,11 @@ and the derived file cooking-units.sty.
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} } ,
+ cunum-add-hook .groups:n = { parse } ,
+ cutext-add-hook .groups:n = { parse } ,
+ Cutext-add-hook .groups:n = { parse } ,
+ cuam-add-hook .groups:n = { parse } ,
+ commands-add-hook .groups:n = { parse } ,
% \end{macrocode}
% \end{macro}
%
@@ -4879,6 +4984,165 @@ and the derived file cooking-units.sty.
%
%
%
+% \begin{macro}{symbol}
+% To be implemented. Key used during definition of new units.
+% Defines the printed symbol of the unit (both do the same).
+% \begin{macrocode}
+ definition / symbol .code:n =
+ {
+ \bool_set_true:N \l_@@_contains_valid_key_bool
+ \bool_set_true:N \l_@@_symbol_was_set_by_key_bool
+ \tl_set:cn { l_@@_default_unit_ \l_@@_original_unit_tl _tl } {#1}
+ },
+ definition / symbol .value_required:n = { true } ,
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{gender}
+% To be implemented. Key used during definition of new units.
+% Defines the gender of the unit.
+% \begin{macrocode}
+ definition / gender .code:n =
+ {
+ \bool_set_true:N \l_@@_contains_valid_key_bool
+ \@@_if_gender_error:nTF {#1}
+ { \@@_culang_def_base:nVn { gender } \l_@@_original_unit_tl { m } }
+ { \@@_culang_def_base:nVn { gender } \l_@@_original_unit_tl {#1} }
+ },
+ definition / gender .value_required:n = { true } ,
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{set-option}
+% To be implemented. Key used during definition of new units.
+% Adds options to a specific key during definition of unit.
+% \begin{macrocode}
+ definition / set-option .code:n =
+ {
+ \bool_set_true:N \l_@@_contains_valid_key_bool
+ \@@_set_options_for:Vn \l_@@_original_unit_tl {#1}
+ },
+ definition / set-option .value_required:n = { true } ,
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{add-to-group}
+% To be implemented. Key used during definition of new units.
+% Adds unit to given group.
+% \begin{macrocode}
+ definition / add-to-group .code:n =
+ {
+ \bool_set_true:N \l_@@_contains_valid_key_bool
+ \@@_add_to_unit_group:nV {#1} \l_@@_original_unit_tl
+ },
+ definition / add-to-group .value_required:n = { true } ,
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{natural-unit}
+% To be implemented. Key used during definition of new units.
+% Defines this unit as a natural unit.
+% \begin{macrocode}
+ definition / natural-unit .code:n =
+ {
+ \bool_set_true:N \l_@@_contains_valid_key_bool
+ \seq_if_in:NVF \g_@@_natural_units_seq \l_@@_original_unit_tl
+ { \seq_gput_right:NV \g_@@_natural_units_seq \l_@@_original_unit_tl }
+ },
+ definition / natural-unit .default:n = { true } ,
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{unit-names}
+% To be implemented. Key used during definition of new units.
+% Defines written out unit name for \cCutext for given language.
+% Also suspended. Would need to give language and it would be too
+% complicated (I think)
+% \begin{macrocode}
+% definition / unit-names .code:n = { },
+% \end{macrocode}
+% \end{macro}
+%
+%
+% You get here during the definition of a new unit if you use the optional
+% argument. As symbols cannot contain |=| the argument |#1| is going
+% to be empty. I also assume that none of the above keys are used as an
+% unit-symbol. If |#1| is non-empty (aka.\ the key has a value) throw an error.
+% \begin{macrocode}
+ definition / unknown .code:n =
+ {
+ \tl_if_empty:nF {#1}
+ {
+ \msg_error:nnxx
+ { cooking-units }
+ { definition-key-mistyped? }
+ \l_keys_key_str
+ {#1}
+ }
+ },
+% \end{macrocode}
+%
+%
+%
+% \begin{macro}{nothing-special}
+% Stage 0 of being bonkers. Do nothing special in this one. Reset everything.
+% \begin{macrocode}
+ nothing-special .code:n =
+ {
+ \prop_gclear:N \g_@@_master_changer_prop
+ \prop_gclear:N \g_@@_convert_bonkers_remember_prop
+ \bool_set_false:N \l_@@_pckopt_bonkers_bool
+ \tl_set_eq:NN \l_@@_bonkers_state_tl \c_@@_bonkers_state_normal_tl
+ },
+ nothing-special .value_forbidden:n = { true } ,
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{going-bonkers}
+% Stage 1 of being bonkers.
+% \begin{macrocode}
+ going-bonkers .code:n =
+ {
+ \prop_gclear:N \g_@@_convert_bonkers_remember_prop
+ \bool_set_true:N \l_@@_pckopt_bonkers_bool
+ \tl_set_eq:NN \l_@@_bonkers_state_tl \c_@@_bonkers_state_going_tl
+ },
+ going-bonkers .value_forbidden:n = { true } ,
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{fully-bonkers}
+% Stage 2 of being bonkers.
+% \begin{macrocode}
+ fully-bonkers .code:n =
+ {
+ \prop_gclear:N \g_@@_master_changer_prop
+ \prop_gclear:N \g_@@_convert_bonkers_remember_prop
+ \bool_set_true:N \l_@@_pckopt_bonkers_bool
+ \tl_set_eq:NN \l_@@_bonkers_state_tl \c_@@_bonkers_state_fully_tl
+ },
+ fully-bonkers .value_forbidden:n = { true } ,
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{xD-lol}
+% Stage 3 of being bonkers.
+% \begin{macrocode}
+ xD-lol .code:n =
+ {
+ \prop_gclear:N \g_@@_master_changer_prop
+ \prop_gclear:N \g_@@_convert_bonkers_remember_prop
+ \bool_set_true:N \l_@@_pckopt_bonkers_bool
+ \tl_set_eq:NN \l_@@_bonkers_state_tl \c_@@_bonkers_state_xD_tl
+ },
+ xD-lol .value_forbidden:n = { true } ,
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%
%
%
%
@@ -4887,6 +5151,7 @@ and the derived file cooking-units.sty.
% Ending the definition of keys.
% \begin{macrocode}
}
+%\keys_set:nn { cooking-units } {#2}
% \end{macrocode}
% \end{macro}
%
@@ -4894,7 +5159,6 @@ and the derived file cooking-units.sty.
%
%
%
-%
% \subsection {Messages}
%
% Defining messages.
@@ -4977,6 +5241,18 @@ and the derived file cooking-units.sty.
\msg_see_documentation_text:n {cooking-units}
}
% \end{macrocode}
+%
+%
+% \begin{macrocode}
+\msg_new:nnnn { cooking-units } { symbol-and-special-keys-error }
+ { You \ cannot \ use \ special-key \ '#1' \ with \ symbol \ '#2' \ definitions. }
+ {
+ You \ cannot \ redefine \ a \ symbol \ of \ a \ special-key.
+ \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 }
@@ -5032,6 +5308,19 @@ and the derived file cooking-units.sty.
}
% \end{macrocode}
%
+% Error message for an undefined key.
+% \begin{macrocode}
+\msg_new:nnnn { cooking-units } { Key-chain-unit-not-found }
+ {
+ It \ appears \ that \ \token_to_str:N \cuaddtokeychain\ was \ not \ able \ to \ find
+ a \ key-chain-unit. Define \ key-chains \ first \ using \token_to_str:N \cudefinekeychain.
+ }
+ {
+ No \ key-chain-unit\ was \ found, \ 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}
@@ -5061,6 +5350,17 @@ and the derived file cooking-units.sty.
\msg_see_documentation_text:n {cooking-units}
}
% \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-no-knows-value }
+ {
+ It \ appears \ that \ the \ key \ '#1' \ does \ not \ accept \ the \ value
+ '#2'. \ Are \ you \ sure \ it \ is \ in \ the \ same \ key-chain?
+ }{
+ The \ key \ accepts \ only \ a \ fixed \ set \ of \ choices. \
+ \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 }
@@ -5137,6 +5437,17 @@ and the derived file cooking-units.sty.
% \end{macrocode}
%
% \begin{macrocode}
+\msg_new:nnnn { cooking-units } { Adding-single-to-multi-key-or-vice-verca }
+ {
+ You \ are \ trying \ to \ add \ a \ single-key \ to \ a \ multi-key \
+ or \ vice-versa.
+ }{
+ This \ is \ not \ allowed!
+ \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.
@@ -5258,6 +5569,16 @@ and the derived file cooking-units.sty.
}
% \end{macrocode}
%
+% \begin{macrocode}
+\msg_new:nnnn { cooking-units } { formula-in-non-singlekeys }
+ {
+ The \ conversion \ value \ '#1' \ seems \ to \ be \ a \ formula. \
+ This \ is \ not \ allowed \ for \ NON-\ singlekeys!
+ }{
+ \msg_see_documentation_text:n { cooking-units }
+ }
+% \end{macrocode}
+%
%
% \begin{macrocode}
\msg_new:nnnn { cooking-units } { <-not-allowed-as-special-sign }
@@ -5284,6 +5605,18 @@ and the derived file cooking-units.sty.
%
%
% \begin{macrocode}
+\msg_new:nnnn { cooking-units } { no-natural-unit-known }
+ {
+ It \ seems\ that \ I \ cannot \ convert \ '#1' \ in \ a \ natural \
+ unit \ as \ there \ is \ no \ conversion-factor \ defined.
+ }{
+ Not \ converting \ the \unit.
+ \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
@@ -5356,6 +5689,13 @@ and the derived file cooking-units.sty.
\msg_see_documentation_text:n { cooking-units }
}
%
+\msg_new:nnnn { cooking-units } { unknown-unit-option }
+ {
+ The \ unit-option \ '#1' \ is \ not \ defined.
+ }{
+ Please \ define \ the \ key \ '#1' \ via \ \newcukeysadd \ and \ friends.
+ \msg_see_documentation_text:n { cooking-units }
+ }
\msg_new:nnnn { cooking-units } { unknown-option }
{
The \ option \ '#1' \ is \ not \ defined.
@@ -5363,6 +5703,13 @@ and the derived file cooking-units.sty.
Perhaps \ you \ misspelled \ the \ option.
\msg_see_documentation_text:n { cooking-units }
}
+\msg_new:nnnn { cooking-units } { unknown-choice }
+ {
+ The \ choice \ '#2' \ for \ key \ '#1' \ is \ not \ defined.
+ }{
+ Perhaps \ you \ misspelled \ the \ choice.
+ \msg_see_documentation_text:n { cooking-units }
+ }
% \end{macrocode}
%
%
@@ -5371,52 +5718,102 @@ and the derived file cooking-units.sty.
{
This \ error \ shouldn't \ show. \ This \ means \ I
\ (the \ package \ author) \ screwed
- \ up. \ The \ error \ code \ is \ '#1'.
+ \ up. \ The \ error \ code \ is \ '#1'. \
+ Addition \ is \ '#2'.
}{
Please \ send \ me \ a \ bug \ report.
\msg_see_documentation_text:n { cooking-units }
}
% \end{macrocode}
+%
+%
+% \begin{macrocode}
+\msg_new:nnnn { cooking-units } { definition-key-mistyped? }
+ {
+ This \ message \ shows \ during \ the \ definition \ of \ unit-keys. \
+ You \ may \ have \ mistyped \ the \ key \ '#1'. \ You \ may \ see \
+ this \ message \ because \ you \ have \ used \ a \ '=' \ sign \ in \ the \
+ optional \ argument. \ If \ this \ is \ the \ case \ and \ you \ still \ want
+ \ to \ use \ '=' \ in \ a \ symbol, \ please \ wrap \ the \ symbol
+ \ in \ two \ braces: \ {{#1=#2}}.
+ }{
+ Or \ try \ using \ the \ 'symbol' \ option.
+ \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,
+% \@@_if_unit_defined:nN,
+% \@@_error_if_unit_not_defined:nNTF,
% \@@_error_if_unit_not_defined:nTF,
% \@@_error_if_unit_not_defined:VTF,
% }
% A little helper macro. Checks if the unit is defined, if not raise an error.
% \begin{macrocode}
-\prg_new_protected_conditional:Npnn \@@_error_if_unit_not_defined:n #1 { TF, T, F }
+\prg_new_protected_conditional:Npnn \@@_if_unit_defined:nN #1 #2 { TF , T }
+ {
+ \@@_set_unit:Nn #2 {#1}
+ \seq_if_in:NVTF \g_@@_list_of_defined_units_seq #2
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+\prg_new_protected_conditional:Npnn \@@_error_if_unit_not_defined:nN #1#2 { TF, T, F }
{
- \seq_if_in:NnTF \g_@@_list_of_defined_units_seq {#1}
+ \@@_if_unit_defined:nNTF {#1} #2
{ \prg_return_false: }
{
\msg_error:nnn { cooking-units } { unknown-unit } {#1}
\prg_return_true:
}
}
-\cs_new:Npn \@@_error_if_unit_not_defined:n #1
- { \@@_error_if_unit_not_defined:nTF {#1} { } { } }
+\prg_new_protected_conditional:Npnn \@@_error_if_unit_not_defined:n #1 { TF, T, F }
+ {
+ \@@_error_if_unit_not_defined:nNTF {#1} \l_@@_scrap_tl
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
\cs_generate_variant:Nn \@@_error_if_unit_not_defined:nTF { V }
% \end{macrocode}
%\end{macro}
%
%
+%
+% \begin{macro} { \@@_if_unit_has_a_key:n, \@@_if_unit_has_a_key:V }
+% A little helper macro. Checks if the unit is defined, if not raise an error.
+% \begin{macrocode}
+\prg_new_protected_conditional:Npnn \@@_if_unit_has_a_key:n #1 { T , F, TF }
+ {
+ \keys_if_exist:nnTF { cooking-units } {#1}
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+\prg_generate_conditional_variant:Nnn \@@_if_unit_has_a_key:n { V } { T, TF }
+% \end{macrocode}
+%\end{macro}
+%
+%
+% \begin{macro} { \@@_seq_use_msg:N, \@@_seq_use_msg:c }
+% Used in error messages for units. Prints the units in a comma-seperated list.
% \begin{macrocode}
\cs_new:Npn \@@_seq_use_msg:N #1
{ \seq_use:Nnnn #1 { ' , ~ ' } { ' , ~ ' } { ' ~ and ~ ' } }
\cs_generate_variant:Nn \@@_seq_use_msg:N { c }
% \end{macrocode}
+% \end{macro}
%
%
-%
-% \begin{macro}{ \@@_if_integer:n }
-% Checking if the input consists only of numbers.
+% \begin{macro}{ \@@_if_integer:n , \@@_if_integer:V , \@@_if_evaluation_is_integer:nN }
+% Checking if the input consists only of numbers; or only of numbers and
+% the allowed math operators
% \begin{macrocode}
\prg_new_protected_conditional:Npnn \@@_if_integer:n #1 { TF , F }
{
@@ -5424,71 +5821,115 @@ and the derived file cooking-units.sty.
{
\tl_if_in:NnF \l_@@_input_digits_tl {##1}
{
- \tl_map_break:n { \use_iii:nnn }
+ \tl_map_break:n { \use_i:nn \prg_return_false: }
}
}
- \use_i:nn \prg_return_true: \prg_return_false:
+ \prg_return_true:
}
\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
+\prg_new_protected_conditional:Npnn \@@_if_evaluation_is_integer:n #1 { TF , T , F }
{
- \@@_if_integer:VTF #2
- { \bool_set_true:N #1 }
- { \bool_set_false:N #1 }
- \bool_lazy_and:nnT
- { \l_@@_range_in_input_bool } {#1}
+ \tl_concat:NNN \l_@@_tmpa_tl
+ \l_@@_input_digits_tl \l_@@_allwed_integer_math_operators_tl
+ \tl_map_inline:nn {#1}
{
- \@@_if_integer:VF #3
- { \bool_set_false:N #1 }
+ \tl_if_in:NnF \l_@@_tmpa_tl {##1}
+ { \tl_map_break:n { \use_iii:nnn } }
}
+ \use_i:nn
+ { \prg_return_true: }
+ { \prg_return_false: }
}
% \end{macrocode}
% \end{macro}
%
%
%
-% \begin{macro}[TF]{ \@@_fp_if_equal_one:n}
-% \begin{macro}[TF]{ \@@_int_if_equal_one:n}
+% \begin{macro}{ \@@_if_integers:NNTF }
+% Checking if the input consists only of numbers, which works correctly for ranges.
% \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 }
+\prg_new_conditional:Npnn \@@_if_integers:NN #1#2 { TF }
{
- \int_compare:nNnTF {#1} = { 1 }
- { \prg_return_true: }
+ \@@_if_integer:VTF #1
+ {
+ \@@_if_print_type_equal:nTF { range }
+ {
+ \@@_if_integer:VTF #2
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+ { \prg_return_true: }
+ }
{ \prg_return_false: }
}
% \end{macrocode}
-% \end{macro} \end{macro}
+% \end{macro}
%
%
+% \begin{macro}{ \@@_if_contains_decimal:NTF , \@@_check_for_decimal:w }
+% A fast check if |#1| contains a decimal point. This is only
+% used for already parsed input, so the input is already safe to check.
+%
+% If |#1| does not contain a decimal point, |\@@_check_for_decimal:w|
+% |#2| is equal to |\q_nil|, the test is true and the false branch is executed.
%
-% \begin{macro}{}
+% If |#1| does contain a decimal point, |#2| is going equal to |<...>.\q_nil|
+% where |<...>| is the stuff after the decimal point. The test is false, thus the
+% true branch is ignored (ignoring all other tokens in |#2|).
% \begin{macrocode}
-\prg_new_conditional:Npnn \@@_change_cutext_to_cunum:n #1 { TF }
+\prg_new_conditional:Npnn \@@_if_contains_decimal:N #1 { TF }
{
- \keys_set_groups:nnn { cooking-units } { change-command } {#1}
- \bool_if:NTF \l_@@_cutext_to_cunum_bool
+ \exp_after:wN \@@_check_for_decimal:w #1 . \q_nil . \q_stop
+ }
+\cs_new:Npn \@@_check_for_decimal:w #1 . #2 . \q_stop
+ {
+ \if_meaning:w \q_nil #2
+ \exp_after:wN \prg_return_false:
+ \else:
+ \exp_after:wN \prg_return_true:
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\@@_if_contain_decimals:NNTF}
+% Same as |\@@_if_integers:NNTF| only for decimal points.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \@@_if_contain_decimals:NN #1#2 { TF }
+ {
+% \@@_if_contains_decimal:NTF #1
+% {
+% \@@_if_print_type_equal:nTF { range }
+% {
+% \@@_if_contains_decimal:NTF #2
+% { \prg_return_true: }
+% { \prg_return_false: }
+% }
+% { \prg_return_true: }
+% }
+% { \prg_return_false: }
+ \@@_if_contains_decimal:NTF #1
{ \prg_return_true: }
- { \prg_return_false: }
+ {
+ \@@_if_print_type_equal:nTF { range }
+ {
+ \@@_if_contains_decimal:NTF #2
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+ { \prg_return_false: }
+ }
}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{ \@@_check_if_correct_gender_input:n }
+%
+%
+%
+%
+%
+% \begin{macro}{ \@@_if_gender_error:n }
% \begin{macrocode}
-\prg_new_conditional:Npnn \@@_if_gender_error:n #1 { TF }
+\prg_new_conditional:Npnn \@@_if_gender_error:n #1 { TF, F , T }
{
\str_case:nnTF {#1}
{
@@ -5497,145 +5938,233 @@ and the derived file cooking-units.sty.
{ n } { }
}
{ \prg_return_false: }
- {
+ {
\msg_error:nnn { cooking-units } { unknown-gender } {#1}
\prg_return_true:
- }
+ }
}
-\cs_new:Npn \@@_check_if_correct_gender_input:n #1
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%
+%
+% \begin{macro}{\@@_error_if_group_not_defined:nN, \@@_error_if_group_not_defined:n}
+% \begin{macrocode}
+\prg_new_conditional:Npnn \@@_error_if_group_not_defined:nN #1#2 { F, T , TF }
{
- \str_case:nnF {#1}
- {
- { m } { }
- { f } { }
- { n } { }
- } { \msg_error:nnn { cooking-units } { unknown-gender } {#1} }
+ \@@_set_unit:Nn #2 {#1}
+ \seq_if_exist:cTF { l_@@_group_ #2 _seq }
+ { \prg_return_false: }
+ {
+ \msg_error:nn { cooking-units} { group-key-unknown }
+ \prg_return_true:
+ }
+ }
+\prg_new_conditional:Npnn \@@_error_if_group_not_defined:n #1 { F }
+ {
+ \seq_if_exist:cTF { l_@@_group_ \@@_to_unit:n {#1} _seq }
+ { \prg_return_false: }
+ {
+ \msg_error:nn { cooking-units} { group-key-unknown }
+ \prg_return_true:
+ }
}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\@@_define_clear_unit_group:nn,\@@_add_to_unit_group_error:n,\@@_add_to_unit_group:nn}
+%
+%
+% \begin{macro}{\@@_define_clear_unit_group:n}
% \begin{macrocode}
-\cs_new:Npn \@@_define_clear_unit_group:nn #1#2
+\cs_new:Npn \@@_define_clear_unit_group:n #1
{
- \seq_clear_new:c { l_@@_group_ #1 _seq }
- \keys_define:nn { cooking-units }
+ \@@_set_unit:Nn \l_@@_tmpa_tl {#1}
+ \seq_clear_new:c { l_@@_group_ \l_@@_tmpa_tl _seq }
+ \keys_define:nn { cooking-units }
{
#1 .code:n = { \@@_unit_group_convert_units:nn {#1} {##1} } ,
#1 .groups:n = { change-unit } ,
}
}
+% \end{macrocode}
+% \end{macro}
%
-\cs_new:Npn \@@_add_to_unit_group_error:n #1
- { \msg_error:nnn { cooking-units } { No-Value-given } { add-unit-to-group } }
%
-\cs_new:Npn \@@_add_to_unit_group:nn #1#2
+% \begin{macro}{\@@_unit_group_convert_units:nn}
+% \begin{macrocode}
+\cs_new:Npn \@@_unit_group_convert_units:nn #1#2
{
- \@@_error_if_group_not_defined:nF {#1}
+ \bool_set_true:N \l_@@_tmpa_bool
+ \@@_error_if_group_not_defined:nNT {#1} \l_@@_curr_group_tl
+ { \bool_set_false:N \l_@@_tmpa_bool }
+ \@@_error_if_unit_not_defined:nNT {#2} \l_@@_curr_unit_tl
+ { \bool_set_false:N \l_@@_tmpa_bool }
+ \bool_if:NT \l_@@_tmpa_bool
{
- \clist_map_inline:nn {#2}
+ \seq_if_in:cVTF { l_@@_group_ \l_@@_curr_group_tl _seq } \l_@@_curr_unit_tl
{
- \@@_error_if_unit_not_defined:nF {##1}
- {
- \seq_if_in:cnF { l_@@_group_ #1 _seq } {##1}
- { \seq_put_right:cn { l_@@_group_ #1 _seq } {##1} }
- }
+ \seq_map_inline:cn { l_@@_group_ \l_@@_curr_group_tl _seq }
+ { \@@_keys_set:nnn { cooking-units } {##1} {#2} }
+ }{
+ \msg_error:nnxxx
+ { cooking-units }
+ { group-choice-not-allowed }
+ { \l_@@_curr_group_tl } { \l_@@_curr_unit_tl }
+ { \@@_seq_use_msg:c { l_@@_group_ \l_@@_curr_group_tl _seq } }
}
}
}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\@@_error_if_group_not_defined:n}
+%
+%
+% \begin{macro}{\@@_add_to_unit_group_error:n , \@@_add_to_unit_group:nn }
% \begin{macrocode}
-\prg_new_conditional:Npnn \@@_error_if_group_not_defined:n #1 { F }
- {
- \seq_if_exist:cTF { l_@@_group_ #1 _seq }
- { \prg_return_false: }
- {
- \msg_error:nn { cooking-units} { group-key-unknown }
- \prg_return_true:
- }
- }
+\cs_new:Npn \@@_add_to_unit_group_error:n #1
+ { \msg_error:nnn { cooking-units } { No-Value-given } { add-unit-to-group } }
% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\@@_unit_group_convert_units:nn}
-% Didn't feel like intending the groups, as such use |\use_none:nnnnn(nnn)|.
-% (Always wanted to use those |\use_none:|)
% \begin{macrocode}
-\cs_new:Npn \@@_unit_group_convert_units:nn #1#2
+\cs_new:Npn \@@_add_to_unit_group:nn #1#2
{
- \@@_error_if_group_not_defined:nF {#1}
+ \@@_error_if_group_not_defined:nNF {#1} \l_@@_curr_group_tl
{
- \@@_error_if_unit_not_defined:nF {#2}
+ \clist_map_inline:nn {#2}
{
- \seq_if_in:cnTF { l_@@_group_ #1 _seq } {#2}
+ \@@_error_if_unit_not_defined:nNF {##1} \l_@@_curr_unit_tl
{
- \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_msg:c { l_@@_group_ #1 _seq } }
+ \seq_if_in:cVF { l_@@_group_ \l_@@_curr_group_tl _seq } \l_@@_curr_unit_tl
+ {
+ \seq_put_right:cV
+ { l_@@_group_ \l_@@_curr_group_tl _seq }
+ \l_@@_curr_unit_tl
+ }
}
}
}
}
+\cs_generate_variant:Nn \@@_add_to_unit_group:nn { nV }
% \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_gset_from_clist:Nn \g_@@_natural_units_seq
+\cs_new:Npn \@@_seq_get_overlap:NNTF #1#2 #3#4
{
- eV ,
- eVc-2 ,
- hbareV-1 ,
- chbareV-1 ,
- (chbareV-1)3 ,
+ \seq_map_inline:Nn #1
+ {
+ \seq_if_in:NnT #2 {##1}
+ { #3 \seq_map_break:n { \use_none:nn } }
+ }
+ \use:n {#4}
}
+% \end{macrocode}
+% \begin{macrocode}
\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:
+% \end{macrocode}
+% \begin{macrocode}
+\cs_new:Npn \@@_convert_to_eV:N #1
{
- \tl_set_eq:Nc \l_@@_tmp_unit_tl { l_@@_base_key_unit_ \l_@@_original_unit_tl _tl }
- \tl_if_empty:NF \l_@@_tmp_unit_tl
+ \prop_get:NVNTF \g_@@_convert_to_eV_remember_prop
+ #1 \l_@@_tmpa_tl
+ { \@@_keys_set:nVV { cooking-units } #1 \l_@@_tmpa_tl }
{
- \prop_get:NVNTF \g_@@_convert_to_eV_remember_prop
- \l_@@_original_unit_tl \l_@@_tmpa_tl
- { \@@_keys_set:nVV { cooking-units } \l_@@_original_unit_tl \l_@@_tmpa_tl }
+% #1 is already a string
+ \@@_if_unit_has_a_key:VTF #1
{
- \prop_get:cnNTF { l_@@_cukeys_ \l_@@_tmp_unit_tl _prop } { Liste } \l_@@_tmpa_seq
+ \tl_set_eq:Nc \l_@@_tmp_unit_tl { l_@@_base_key_unit_ #1 _tl }
+ \prop_get:cnNT { l_@@_new_cukeys_ \l_@@_tmp_unit_tl _prop }
+ { Liste } \l_@@_tmpa_seq
{
- \seq_map_inline:Nn \g_@@_natural_units_seq
+ \@@_seq_get_overlap:NNTF \g_@@_natural_units_seq \l_@@_tmpa_seq
{
- \seq_if_in:NnT \l_@@_tmpa_seq {##1}
- {
- \prop_gput:NVn \g_@@_convert_to_eV_remember_prop
- \l_@@_original_unit_tl {##1}
- \@@_keys_set:nVn { cooking-units } \l_@@_original_unit_tl {##1}
- \seq_map_break:
- }
+ \prop_gput:NVn \g_@@_convert_to_eV_remember_prop #1 {##1}
+ \@@_keys_set:nVn { cooking-units } #1 {##1}
}
+ { \msg_warning:nnx { cooking-units } { no-natural-unit-known } {#1} }
}
- { \msg_error:nnn { cooking-units } { internal-error } { convert-to-eV } }
}
+ { \msg_warning:nnx { cooking-units } { Key-not-defined } {#1} }
}
}
% \end{macrocode}
%\end{macro}
%
+% \begin{macrocode}
+\cs_new:Npn \@@_changing_unit_bonkers:N #1
+ {
+ \prop_get:NVNTF \g_@@_convert_bonkers_remember_prop
+ #1 \l_@@_tmpa_tl
+ { \@@_keys_set:nVV { cooking-units } #1 \l_@@_tmpa_tl }
+ {
+ \tl_case:NnF \l_@@_bonkers_state_tl
+ {
+ \c_@@_bonkers_state_going_tl { \@@_convert_going_bonkers:N #1 }
+ \c_@@_bonkers_state_fully_tl { \@@_convert_fully_bonkers:N #1 }
+ \c_@@_bonkers_state_xD_tl { \@@_convert_xD_bonkers:N #1 }
+ }
+ { \@@_create_internal_error:nN { going-bonkers } \l_@@_bonkers_state_tl }
+ }
+ }
+\cs_new:Npn \@@_convert_going_bonkers:N #1
+ {
+ \@@_if_unit_has_a_key:VT #1
+ {
+ \@@_prepare_going_bonkers:N #1
+ \keys_set:nn { cooking-units } { eval-fraction = true }
+ \@@_keys_set:nVV { cooking-units } #1 \l_@@_tmpa_tl
+ \prop_gput:NVV \g_@@_convert_bonkers_remember_prop #1 \l_@@_tmpa_tl
+ }
+ }
+\cs_new:Npn \@@_convert_fully_bonkers:N #1
+ {
+ \@@_if_unit_has_a_key:VT #1
+ {
+ \@@_prepare_going_bonkers:N #1
+ \keys_set:nn { cooking-units }
+ { eval-fraction = true , curef-clear-forbidden-units = true }
+ \prop_put:NVV \l_@@_change_unit_prop {#1} \l_@@_tmpa_tl
+ \@@_cukeys_calculate_change_value:VVV #1 \l_@@_tmpa_tl \l_@@_tmp_unit_tl
+ }
+ }
+\cs_new:Npn \@@_prepare_going_bonkers:N #1
+ {
+ \tl_set_eq:Nc \l_@@_tmp_unit_tl { l_@@_base_key_unit_ #1 _tl }
+ \prop_get:cnN { l_@@_new_cukeys_ \l_@@_tmp_unit_tl _prop } { Liste } \l_@@_tmpa_seq
+ \bool_set_false:N \l_@@_tmpa_bool
+ \bool_until_do:Nn \l_@@_tmpa_bool
+ {
+ \tl_set:Nf \l_@@_tmpa_tl { \seq_rand_item:N \l_@@_tmpa_seq }
+ \seq_if_in:NVF \g_@@_natural_units_seq \l_@@_tmpa_tl
+ { \bool_set_true:N \l_@@_tmpa_bool }
+ }
+ }
+\cs_new:Npn \@@_convert_xD_bonkers:N #1
+ {
+ \keys_set:nn { cooking-units } { eval-fraction = true , curef-clear-forbidden-units = true }
+ \bool_set_false:N \l_@@_tmpa_bool
+ \bool_until_do:Nn \l_@@_tmpa_bool
+ {
+ \tl_set:Nx \l_@@_tmpa_tl { \seq_rand_item:N \g_@@_list_of_defined_units_seq }
+ \@@_if_no_unit_marker:NF \l_@@_tmpa_tl
+ { \bool_set_true:N \l_@@_tmpa_bool }
+ }
+ \prop_put:NVV \l_@@_change_unit_prop {#1} \l_@@_tmpa_tl
+ \tl_set:cf { l_@@_unit_change_ #1 _tl } { \fp_eval:n { rand() * randint(255) } }
+ }
+% \end{macrocode}
%
%
%
@@ -5643,7 +6172,7 @@ and the derived file cooking-units.sty.
% 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 }
+\cs_generate_variant:Nn \@@_tl_eval:Nn { Nv, cn }
% \end{macrocode}
% \end{macro}
%
@@ -5653,16 +6182,15 @@ and the derived file cooking-units.sty.
% I am using this construction often enough, so \dots\ yeah.
% Note that if the evaluation is |true|, the path taken is the |false| one.
% \begin{macrocode}
-\prg_new_conditional:Npnn \@@_change_unit: { TF , T }
+\prg_new_conditional:Npnn \@@_change_unit: { TF }
{
- \bool_lazy_any:nTF
- {
- { \l_@@_lokal_fraction_bool }
- { \l_@@_special_sign_bool }
- { \l_@@_draft_bool }
- }
+ \@@_if_print_type_equal:nTF { fraction }
{ \prg_return_false: }
- { \prg_return_true: }
+ {
+ \@@_if_state_equal:nTF { special_sign }
+ { \prg_return_false: }
+ { \prg_return_true: }
+ }
}
% \end{macrocode}
% \end{macro}
@@ -5681,43 +6209,36 @@ and the derived file cooking-units.sty.
}
\cs_new:Npn \@@_temperatures_to_check_define:nn #1#2
{
- \@@_error_if_unit_not_defined:nF {#1}
+ \@@_error_if_unit_not_defined:nNF {#1} \l_@@_curr_unit_tl
{
- \fp_if_exist:cTF { l_@@_ #1 _min_fp }
- {
-% \msg_warning:nnn { cooking-units } { Minimum-already-defined } {#1}
- \fp_set:cn { l_@@_ #1 _min_fp } {#2}
- }{
- \seq_put_right:Nn \l_@@_temperatures_to_check_seq {#1}
- \fp_new:c { l_@@_ #1 _min_fp }
- \fp_set:cn { l_@@_ #1 _min_fp } {#2}
+ \fp_if_exist:cF { l_@@_ \l_@@_curr_unit_tl _min_fp }
+ {
+ \seq_put_right:NV \l_@@_temperatures_to_check_seq \l_@@_curr_unit_tl
+ \fp_new:c { l_@@_ \l_@@_curr_unit_tl _min_fp }
}
+ \fp_set:cn { l_@@_ \l_@@_curr_unit_tl _min_fp } {#2}
}
}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{ \@@_set_options_for_error:n , \@@_set_options_for:nn }
+% \begin{macro}{ \@@_set_options_for_error:n }
% \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
- { \cusetoptionfor {#1} {#2} }
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{ \@@_add_options_for_error:n , \@@_add_options_for:nn }
+% \begin{macro}{ \@@_add_options_for_error:n }
% \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
- { \cuaddoptionfor {#1} {#2} }
% \end{macrocode}
% \end{macro}
%
@@ -5728,7 +6249,7 @@ and the derived file cooking-units.sty.
{
#1
, \l_@@_round_precision_int
- \bool_if:NT \l_@@_round_commercial_bool
+ \bool_if:NT \l_@@_pckopt_round_commercial_bool
{ , #1 }
}
% \end{macrocode}
@@ -5738,12 +6259,9 @@ and the derived file cooking-units.sty.
% \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}
- }
+ \str_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}
@@ -5760,13 +6278,13 @@ and the derived file cooking-units.sty.
\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} }
{
- \msg_error:nnn { cooking-units } { label-already-defined } {#1}
- }{
- \@@_if_integer:nTF {#2}
+ \@@_if_evaluation_is_integer:nTF {#2}
{
+ \int_set:Nn \l_@@_tmpa_int {#2}
\int_new:c { g_@@_number_of_persons_ #1 _int }
- \int_gset:cn { g_@@_number_of_persons_ #1 _int } {#2}
+ \int_gset_eq:cN { g_@@_number_of_persons_ #1 _int } \l_@@_tmpa_int
}
{ \msg_error:nnn { cooking-units } { Number-of-persons-is-not-an-integer } {#2} }
}
@@ -5780,7 +6298,7 @@ and the derived file cooking-units.sty.
{
\int_if_exist:cTF { g_@@_number_of_persons_ #1 _int }
{
- \bool_set_true:N \l_@@_calc_because_ref_was_given_bool
+ \bool_set_true:N \l_@@_reference_given_bool
\int_set_eq:Nc \l_@@_local_number_of_persons_int
{ g_@@_number_of_persons_ #1 _int }
}
@@ -5795,7 +6313,7 @@ and the derived file cooking-units.sty.
{
\int_if_exist:cTF { g_@@_number_of_persons_ #1 _int }
{
- \bool_if:NTF \l_@@_change_number_of_persons_bool
+ \bool_if:NTF \l_@@_pckopt_recalculate_amount_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} }
@@ -5813,27 +6331,21 @@ and the derived file cooking-units.sty.
%
%
%
-% \begin{macro}{ \@@_bool_reverse:N, \@@_check_minus_remove_and_reverse:NN }
+% \begin{macro}{ \@@_check_minus_remove_and_reverse:NN }
% Can probably optimize this as the sign is always at the first place
% (this is done after cheking the input, so the assumption is safe), but yeah \dots
% \begin{macrocode}
-\cs_new:Npn \@@_bool_reverse:N #1
- {
- \bool_if:NTF #1
- { \bool_set_false:N }
- { \bool_set_true:N }
- #1
- }
\cs_new:Npn \@@_check_minus_remove_and_reverse:NN #1#2
{
\quark_if_nil:NF #2
{
+ %% Maybe simplify by a command?
\tl_if_in:NnT #2 { - }
{
\tl_remove_once:Nn #2 { - }
- \@@_bool_reverse:N #1
+ \bool_if:NTF #1 { \bool_set_false:N } { \bool_set_true:N } #1
}
- \@@_check_minus_remove_and_reverse:NN #1
+ \@@_check_minus_remove_and_reverse:NN #1
}
}
% \end{macrocode}
@@ -5841,108 +6353,306 @@ and the derived file cooking-units.sty.
%
%
%
-% \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 ) }
+\cs_new:Npn \@@_add_forbidden_unit:n #1
+ {
+ \seq_set_from_clist:Nn \l_@@_tmpa_seq {#1}
+ \seq_map_inline:Nn \l_@@_tmpa_seq
+ {
+ \@@_error_if_unit_not_defined:nNF {##1} \l_@@_curr_unit_tl
+ {
+ \seq_if_in:NVF \l_@@_curef_do_not_change_seq \l_@@_curr_unit_tl
+ { \seq_put_right:NV \l_@@_curef_do_not_change_seq \l_@@_curr_unit_tl }
+ }
+ }
+ }
+\cs_new:Npn \@@_remove_forbidden_unit:n #1
+ {
+ \seq_set_from_clist:Nn \l_@@_tmpa_seq {#1}
+ \seq_map_inline:Nn \l_@@_tmpa_seq
+ {
+ \@@_error_if_unit_not_defined:nNF {##1} \l_@@_curr_unit_tl
+ {
+ \seq_if_in:NVTF \l_@@_curef_do_not_change_seq \l_@@_curr_unit_tl
+ { \seq_remove_all:NV \l_@@_curef_do_not_change_seq \l_@@_curr_unit_tl }
+ {
+ \msg_warning:nnnn { cooking-units } { curef-not-inside-list } {##1}
+ { \@@_seq_use_msg:N \l_@@_curef_do_not_change_seq }
+ }
+ }
+ }
+ }
+\cs_new:Npn \@@_clear_forbidden_unit:
+ { \seq_clear:N \l_@@_curef_do_not_change_seq }
% \end{macrocode}
%
-% \begin{macro}{\@@_deftranslation_base:nnn, \@@_deftranslation_base:xVn }
-% \begin{macro}{\@@_deftranslation_to:nnnn , \@@_deftranslation_to:VxVv,\@@_deftranslation_to:VxVV,\@@_deftranslation_to:VxVn}
+%
+%
+%
+%
+%
% \begin{macrocode}
-\cs_new:Npn \@@_deftranslation_base:nnn #1#2#3
+\NewDocumentCommand \cudeclareunitgroup { m m }
{
- \declaretranslationfallback { #1 #2 } {#3}
+ \@@_define_clear_unit_group:n {#1}
+ \@@_add_to_unit_group:nn {#1} {#2}
}
-\cs_new:Npn \@@_deftranslation_to:nnnn #1#2#3#4
+\NewDocumentCommand \cuaddtounitgroup { m m }
{
- \declaretranslation {#1} { #2 #3 } {#4}
+ \@@_add_to_unit_group:nn {#1} {#2}
+ }
+\NewDocumentCommand \cuclearunitgroup { m }
+ {
+ \@@_error_if_group_not_defined:nF {#1}
+ { \@@_define_clear_unit_group:n {#1} }
}
-\cs_generate_variant:Nn \@@_deftranslation_base:nnn { xV }
-\cs_generate_variant:Nn \@@_deftranslation_to:nnnn { VxVv, VxVV , VxVn }
% \end{macrocode}
-% \end{macro}
-% \end{macro}
%
%
%
-% \begin{macro}{\@@_newtranslation:xxn }
-% \begin{macro}{\@@_newtranslation:nxxn }
+%
+%
+%
+%
+%
+% \begin{macro}{ \cusetoptionfor , \cuaddoptionfor , \cuclearoptionfor}
+% \pkg{cooking-units} allows to attach options to units. Every time the unit
+% is used, the option is executed (technically it is similar or equal to a hook).
+% Using these commands, one can set (overwrites all previous options),
+% add or clear options for a unit or a list of units.
% \begin{macrocode}
-\cs_new:Npn \@@_newtranslation_base:nnn #1#2#3
+\NewDocumentCommand \cusetoptionfor { m m }
+ { \@@_set_options_for:nn {#1} {#2} }
+\NewDocumentCommand \cuaddoptionfor { m m }
+ { \@@_add_options_for:nn {#1} {#2} }
+\NewDocumentCommand \cuclearoptionfor { m }
+ { \@@_clear_options_for:n {#1} }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_set_options_for:nn , \@@_add_options_for:nn , \@@_clear_options_for:n}
+% These commands are quite similar, excpet for a few details.
+% First, store the unit or list of units |#1| and the list of options |#2|.
+% At the end, for each unit in |#1| a clist will be created (if not already existing)
+% where the options will be put \emph{via} |\clist_set:cn|, |\clist_put_right:cn|
+% or will be cleared (see there).
+%
+% E.g.\ |\clist_set:cn| will get something like |\clist_set:cV {...unit...clist} \clist_containing_options_clist|.
+% As |\clist_clear:c| does not take a second argument, we will eat it \emph{via}
+% |\use_i_ii:nnn|.
+% \begin{macrocode}
+\cs_new:Npn \@@_set_options_for:nn #1#2
+ {
+ \@@_map_trough_valid_unit_options:nnn {#1} {#2} { \clist_set:cV }
+ }
+\cs_new:Npn \@@_add_options_for:nn #1#2
{
- \definetranslationfallback { #1 #2 } {#3}
+ \@@_map_trough_valid_unit_options:nnn {#1} {#2} { \clist_put_right:cV }
}
-\cs_new:Npn \@@_newtranslation_to:nnnn #1#2#3#4
+\cs_new:Npn \@@_clear_options_for:n #1
{
- \definetranslation {#1} { #2 #3 } {#4}
+ \@@_map_trough_valid_unit_options:nnn {#1} { \q_no_value } { \clist_clear:c }
}
-\cs_generate_variant:Nn \@@_newtranslation_base:nnn { nVn }
-\cs_generate_variant:Nn \@@_newtranslation_to:nnnn { nnVn }
+\cs_generate_variant:Nn \@@_set_options_for:nn { V }
+\cs_generate_variant:Nn \@@_clear_options_for:n { V }
% \end{macrocode}
% \end{macro}
+%
+% \begin{macro}{\@@_map_trough_valid_unit_options:nnn}
+% The first thing is command does is to map through the given unit list |#1|
+% and check if the unit(s) exist or not. If they exist, store them in the sequence
+% |\l_@@_tmpa_seq| for later use. Else, ignore it and print a warning.
+%
+% If |#2| is a |\q_no_value| we know that there is no need to map through |#2|.
+% Whatever the command |#3| does, it does so only to the clist
+% |l_@@_unit_option_ <unit> _clist|.
+%
+% If |#2| is anything else, follow the |else| branch. After veryfing that |#2|
+% is non-empty map through the option list given in |#2|. All valid keys
+% (and their agrument) is stored in |\l_@@_tmpa_clist|.
+% Afterwards, the clist for each unit in |\l_@@_tmpa_seq| is modified by the command
+% in |#3| and is given the list of options |\l_@@_tmpa_clist| as an argument.
+% (Note: |\l_@@_tmpa_clist| can be empty).
+% \begin{macrocode}
+\cs_new:Npn \@@_map_trough_valid_unit_options:nnn #1#2 #3
+ {
+ \seq_clear:N \l_@@_tmpa_seq
+ \clist_clear:N \l_@@_tmpa_clist
+ \clist_map_inline:nn {#1}
+ {
+ \@@_error_if_unit_not_defined:nNF {##1} \l_@@_curr_unit_tl
+ { \seq_put_right:NV \l_@@_tmpa_seq \l_@@_curr_unit_tl }
+ }
+ \quark_if_no_value:nTF {#2}
+ {
+ \seq_map_inline:Nn \l_@@_tmpa_seq
+ { #3 { l_@@_unit_option_ ##1 _clist } }
+ }{
+ \tl_if_empty:nF {#2}
+ { \@@_unit_options_check_validity:n {#2} }
+ \seq_map_inline:Nn \l_@@_tmpa_seq
+ { #3 { l_@@_unit_option_ ##1 _clist } \l_@@_tmpa_clist }
+ }
+ }
+% \end{macrocode}
% \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{macro}{ \@@_unit_options_check_validity:n }
+% If the list of options is non-empty, we parse over them using
+% |\keyval_parse:NNn|. For this we need two commands, one for keys
+% with argument, one without arguments. All the commands do is to check
+% if the key given does exist. And if they do, store them in |\l_@@_tmpa_clist|.
% \begin{macrocode}
-\cs_new:Npn \@@_translate:nn #1#2
+\cs_new:Npn \@@_unit_options_check_validity:n #1
{
- \GetTranslation { #1 #2 }
+ \keyval_parse:NNn
+ \@@_unit_options_check_validity_aux_i:n
+ \@@_unit_options_check_validity_aux_ii:nn
+ {#1}
}
-\cs_new:Npn \@@_translate_let:Nnn #1#2#3
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{ \@@_unit_options_check_validity_aux_i:n ,
+% \@@_unit_options_check_validity_aux_ii:nn }
+% Check if the key exist; if it is then put it in |\l_@@_tmpa_clist| (just the key, or with the value).
+% Sadly, checking if the value |#2| can be accepted by the key is not really testable.
+% \begin{macrocode}
+\cs_new:Npn \@@_unit_options_check_validity_aux_i:n #1
{
- \SaveTranslation {#1} { #2 #3 }
+ \keys_if_exist:nnTF { cooking-units } {#1}
+ { \clist_put_right:Nn \l_@@_tmpa_clist {#1} }
+ { \msg_error:nnn { cooking-units } { unknown-option } {#1} }
}
-\cs_new:Npn \@@_translate_let:nNnn #1#2#3#4
+\cs_new:Npn \@@_unit_options_check_validity_aux_ii:nn #1#2
{
- \SaveTranslationFor {#2} {#1} { #3 #4 }
+ \keys_if_exist:nnTF { cooking-units } {#1}
+ {
+ \clist_put_right:Nn \l_@@_tmpa_clist { #1= {#2} }
+% \keys_if_choice_exist:nnnTF { cooking-units } {#1} {#2}
+% { \clist_put_right:Nn \l_@@_tmpa_clist { #1= {#2} } }
+% { \msg_error:nnnn { cooking-units } { unknown-choice } {#1} {#2} }
+ }
+ { \msg_error:nnn { cooking-units } { unknown-option } {#1} }
}
-\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}
+%
+%
+%
+%
+%
+%
+%
+%
+%
+%
+% \subsection{Language Macros}
+%
+%
+% The following commands are just wrapper around the commands from the
+% \pkg{translations} package.
+%
+% \begin{macro}{ \@@_culang_def_base:nnn , \@@_culang_def_base:nnv , \@@_culang_def_base:nVn}
+% \begin{macrocode}
+\cs_new:Npn \@@_culang_def_base:nnn #1#2#3
+ { \declaretranslationfallback { #2 - #1 (@@) } {#3} }
+\cs_generate_variant:Nn \@@_culang_def_base:nnn { nnv, nVn }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{ \@@_culang_def_for:nnnn, \@@_culang_def_for:VnnV , \@@_culang_def_for:Vnnn }
+% \begin{macrocode}
+\cs_new:Npn \@@_culang_def_for:nnnn #1#2#3#4
+ { \declaretranslation {#1} { #3 - #2 (@@) } {#4} }
+\cs_generate_variant:Nn \@@_culang_def_for:nnnn { VnnV, V }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{ \@@_culang_print:nn , \@@_culang_print:nV }
+% \begin{macrocode}
+\cs_new:Npn \@@_culang_print:nn #1#2
+ { \GetTranslation { #2 - #1 (@@) } }
+\cs_generate_variant:Nn \@@_culang_print:nn { nV }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{ \@@_culang_let:nnN }
+% \begin{macrocode}
+\cs_new:Npn \@@_culang_let:nnN #1#2#3
+ { \SaveTranslation #3 { #2 - #1 (@@) } }
+% \end{macrocode}
% \end{macro}
+%
+% \begin{macro}{ \@@_culang_let_for:nnnN , \@@_culang_let_for:VnnN }
+% \begin{macrocode}
+\cs_new:Npn \@@_culang_let_for:nnnN #1#2#3#4
+ { \SaveTranslationFor #4 {#1} { #3-#2 (@@) } }
+\cs_generate_variant:Nn \@@_culang_let_for:nnnN { V }
+% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[TF]{\@@_unitname_get:Nn,\@@_unitname_get:Nx }
+% \begin{macro}[TF]{ \@@_culang_if_translation_exists_for:nnn, \@@_culang_if_translation_exists_for:Vnn}
% \begin{macrocode}
-\prg_new_conditional:Npnn \@@_unitname_get:Nn #1#2 { F }
+\cs_new:Npn \@@_culang_if_translation_exists_for:nnnTF #1#2#3
+ { \IfTranslation {#1} { #3 - #2 (@@) } }
+\cs_generate_variant:Nn \@@_culang_if_translation_exists_for:nnnTF { V }
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%
+% \begin{macro}[TF, F]{\@@_culang_unitname_let:Nn , \@@_culang_unitname_let:NV }
+% \begin{macrocode}
+\prg_new_conditional:Npnn \@@_culang_unitname_let:Nn #1#2 { TF, F , T }
{
- \@@_translate_let:NnV #1 {#2} \c_@@_postfix_unitname_tl
+ \@@_culang_let:nnN { name } {#2} #1
\tl_if_eq:NNTF #1 \q_@@_no_translation
{ \prg_return_false: }
{ \prg_return_true: }
}
-\cs_generate_variant:Nn \@@_unitname_get:NnF { Nx }
+\cs_generate_variant:Nn \@@_culang_unitname_let:NnTF { NV, Nx }
+\cs_generate_variant:Nn \@@_culang_unitname_let:NnT { 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{macro}{ \@@_culang_one_let:Nn , \@@_culang_one_let:NV ,
+% \@@_culang_one_let_by_gender:Nn , \@@_culang_one_let_by_gender:NV
+% }
% \begin{macrocode}
-\cs_new:Npn \@@_translate_one_and_check_existance:Nn #1#2
+\prg_new_conditional:Npnn \@@_culang_one_let:Nn #1#2 { T }
{
- \@@_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) }
+ \@@_culang_let:nnN { gender } {#2} \l_@@_tmpa_tl
+ \@@_culang_one_let_by_gender:NVTF #1 \l_@@_tmpa_tl
+ { \prg_return_true: }
+ {
+ \tl_set:Nn #1 { 1 }
+ \prg_return_false:
}
}
-\cs_generate_variant:Nn \@@_translate_one_and_check_existance:Nn { Nx }
+\cs_generate_variant:Nn \@@_culang_one_let:NnT { NV }
+\prg_new_conditional:Npnn \@@_culang_one_let_by_gender:Nn #1#2 { TF }
+ {
+ \@@_culang_unitname_let:NnTF #1 { one (#2) }
+ { \prg_return_true: }
+ {
+ \msg_error:nnx { cooking-units } { Translation-not-available } { one (#2) }
+ \prg_return_false:
+ }
+ }
+\cs_generate_variant:Nn \@@_culang_one_let_by_gender:NnTF { NV }
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{ decimal-mark, one(m), one(f), one(n) }
+% \begin{macro}{ \g_@@_allowed_special_keys_seq }
% Defining the translation for the decimal-mark. Note that those
% 'phrases' are stored inside
% \verb|\g_@@_allowed_special_keys_seq|.
@@ -5950,6 +6660,7 @@ and the derived file cooking-units.sty.
% \begin{macrocode}
\seq_gset_from_clist:Nn \g_@@_allowed_special_keys_seq
{
+ cutext-range-sign ,
decimal-mark ,
one (m) ,
one (f) ,
@@ -5957,36 +6668,37 @@ and the derived file cooking-units.sty.
}
% \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 { , }
+\@@_culang_def_base:nnn { name } { decimal-mark } { . }
+\@@_culang_def_base:nnn { name-pl } { decimal-mark } { \q_@@_no_translation }
+\@@_culang_def_for:nnnn { German } { name-pl } { decimal-mark } { , }
% \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 }
+\@@_culang_def_base:nnn { name } { one (m) } { \q_@@_no_translation }
+\@@_culang_def_base:nnn { name } { one (f) } { \q_@@_no_translation }
+\@@_culang_def_base:nnn { name } { one (n) } { \q_@@_no_translation }
+\@@_culang_def_base:nnn { name-pl } { one (m) } { \q_@@_no_translation }
+\@@_culang_def_base:nnn { name-pl } { one (f) } { \q_@@_no_translation }
+\@@_culang_def_base:nnn { name-pl } { one (n) } { \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 }
+\@@_culang_def_for:nnnn { English } { name } { one (m) } { one }
+\@@_culang_def_for:nnnn { English } { name } { one (f) } { one }
+\@@_culang_def_for:nnnn { English } { name } { one (n) } { 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 }
+\@@_culang_def_for:nnnn { German } { name } { one (m) } { ein }
+\@@_culang_def_for:nnnn { German } { name } { one (f) } { eine }
+\@@_culang_def_for:nnnn { German } { name } { one (n) } { 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~ }
+\@@_culang_def_base:nnn { name } { cutext-range-sign } { -- }
+\@@_culang_def_base:nnn { name-pl } { cutext-range-sign } { \q_@@_no_translation }
+\@@_culang_def_for:nnnn { German } { name } { cutext-range-sign } { ~bis~ }
+\@@_culang_def_for:nnnn { English } { name } { cutext-range-sign } { ~to~ }
% \end{macrocode}
%
%
@@ -5996,130 +6708,622 @@ and the derived file cooking-units.sty.
% (\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:
+% \subsection{Enums \& States}
+%
+% These variables decide what the main commands (\cs{cunum}, etc.) should do.
+% Is there an error? Special-sign? Fraction? Range? Which command is used?
+% This is defined here.
+%
+% \begin{macro}{ \@@_def_new_type:nnn , \@@_def_new_type_aux:cnn , \@@_def_new_type_aux:Nnn}
+% Defines my variants, all in one handy command (well, two commands).
+% |#1| is the base name of the new state. |#2| are the conditions for
+% |\prg_new_conditional|. |#3| are the possible states, given as a comma list.
% \begin{macrocode}
-\cs_new_protected:Npn \@@_initialise_default:n #1
+\cs_new:Npn \@@_def_new_type:nnn #1#2#3
{
- \@@_set_unit:Nn \l_@@_original_unit_tl {#1}
- \bool_set_false:N \l_@@_error_bool
- \@@_error_if_unit_not_defined:VTF \l_@@_original_unit_tl
+ \tl_new:c { l_@@_ #1 _tl }
+ \clist_map_inline:nn {#3}
+ { \tl_const:cn { c_@@_ #1 _ ##1 _tl } {##1} }
+ \@@_def_new_type_aux:cnn { l_@@_ #1 _tl } {#1} {#2}
+ }
+% \end{macrocode}
+% Defines the commands |@@_set_<base name>_to:n| and (if wanted)
+% |@@_if_ <base name> _equal:n|. For maybe optimization (not sure why)
+% I decided that |#1| is the token varable which stores the state we are currently
+% in.
+% \begin{macrocode}
+\cs_new:Npn \@@_def_new_type_aux:Nnn #1#2#3
+ {
+ \cs_new:cpn { @@_set_ #2 _to:n } ##1
{
- \bool_set_true:N \l_@@_unit_error_bool
- \cs_set_eq:NN \@@_print_correct_unit: \@@_print_default_unit:
- }
- { \bool_set_false:N \l_@@_unit_error_bool }
- \bool_set_false:N \l_@@_special_sign_bool
- \bool_set_false:N \l_@@_range_in_input_bool
- \bool_set_false:N \l_@@_lokal_fraction_bool
- \bool_set_false:N \l_@@_minus_bool
+ \tl_if_exist:cF { c_@@_#2_ ##1 _tl } { \tl_show:n { ERROR-set-#2-##1 } }
+ \tl_set_eq:Nc #1 { c_@@_#2_ ##1 _tl }
+ }
+ \tl_if_empty:nF {#3}
+ {
+ \prg_new_conditional:cpnn { @@_if_ #2 _equal:n } ##1 {#3}
+ {
+ \tl_if_exist:cF { c_@@_#2_ ##1 _tl } { \tl_show:n { ERROR-check-#2-##1 } }
+ \tl_if_eq:NcTF #1 { c_@@_#2_ ##1 _tl }
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+ }
}
+\cs_generate_variant:Nn \@@_def_new_type_aux:Nnn { c }
+% \end{macrocode}
+% \end{macro}
+%
+% Defining some states.
+% \begin{macrocode}
+\@@_def_new_type:nnn { state } { TF , T , F , p }
+ { normal , special_sign , 42 , error }
+\@@_def_new_type:nnn { cmd_type } { TF , T , p }
+ { cunum , cCutext , cuam }
+\@@_def_new_type:nnn { parse_and_process_type } { TF , T }
+ { number , range , fraction }
+\@@_def_new_type:nnn { print_type } { TF , T }
+ { unknown , number , range , fraction }
+\@@_def_new_type:nnn { bonkers_state } { }
+ { normal , going , fully , xD }
% \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.
+% Setting a default state..
% \begin{macrocode}
-\cs_new_protected:Npn \@@_initialise_unit_change:n #1
+\tl_set_eq:NN \l_@@_bonkers_state_tl \c_@@_bonkers_state_normal_tl
+% \end{macrocode}
+%
+%
+% \subsection{The main stuff}
+%
+% \begin{macro} { \@@_expand_unit_input:Nn , \@@_expand_amount_input:Nn }
+% \begin{macrocode}
+\cs_new:Npn \@@_expand_unit_input:Nn #1#2
{
- \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_@@_original_unit_tl \l_@@_option_unit_tl
- { \tl_set_eq:NN \l_@@_option_unit_tl \l_@@_original_unit_tl }
+ \cs_if_exist_use:c { exp_args:NN \l_@@_unit_argument_spec_tl }
+ \@@_set_unit:Nn #1 {#2}
+ }
+\cs_new:Npn \@@_expand_amount_input:Nn #1#2
+ {
+ \cs_if_exist_use:c { exp_args:NN \l_@@_expand_amount_tl }
+ \@@_set_amount:Nn #1 {#2}
}
% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \begin{macro}{ \@@_do_the_stuff:nnnnn , \@@_do_the_stuff:nnnnn }
+% Main command shared by |\cunum|, etc.\ It reads the input
+% parses options and decides (depending on which command was used)
+% what to do with the stuff and how to print it.
% \begin{macrocode}
-\cs_new_protected:Npn \@@_initialise_after_unit_change:nn #1#2
+\bool_new:N \l_@@_skip_first_part_bool
+\cs_new:Npn \@@_do_the_stuff:nnnnnn #1#2#3#4#5#6
{
+% #1 -- label
+% #2 -- options
+% #3 -- amount
+% #4 -- space
+% #5 -- unit
+ \@@_initialice_accordingly:nnnn {#1} {#4} {#2} {#5}
+ \@@_use_hook_accordingly:
+ \@@_parse_the_amount:n {#3}
+ \@@_general_checkups:
+ \@@_if_state_equal:nTF { normal }
+ { \@@_process_amount_normally:n {#2} }
+ { \@@_process_amount_special: }
+ \@@_new_print_amount_correctly:
+ \@@_new_print_unit_correctly:
+ }
+\cs_generate_variant:Nn \@@_do_the_stuff:nnnnnn { nnnnV }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_initialice_accordingly:nnnn , \@@_initialice_addon_cutext: }
+% This cs first initializes stuff that is equal for all commands, then
+% does command-specific things. The default stuff includes checking if the
+% unit is valid, setting some bools, sets options (including change of units), etc.
+%
+% For |\cunum| we set the space used for |\phantom|, for |\cuam| we do nothing.
+% \begin{macrocode}
+\cs_new:Npn \@@_initialice_accordingly:nnnn #1#2#3#4
+ {
+ \@@_initialize_new_default:nnn {#1} {#3} {#4}
+ \@@_initialize_new_default_units:
+ \tl_case:NnF \l_@@_cmd_type_tl
+ {
+ \c_@@_cmd_type_cunum_tl { \tl_set:Nn \l_@@_phantom_tl {#2} }
+ \c_@@_cmd_type_cCutext_tl { \@@_initialice_addon_cutext: }
+ \c_@@_cmd_type_cuam_tl { }
+ }
+ { \@@_create_internal_error:nN { init-acc } \l_@@_cmd_type_tl }
+ }
+% \end{macrocode}
+% For \cCutext\ we first check if the user wants to use \cCutext\ at all.
+% If not, change it to |\cunum|.
+% \begin{macrocode}
+\cs_new:Npn \@@_initialice_addon_cutext:
+ {
+ \bool_if:NT \l_@@_pckopt_cutext_to_cunum_bool
+ { \@@_set_cmd_type_to:n { cunum } }
+ \bool_set_false:N \l_@@_cutext_last_amount_equ_one_bool
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{ \@@_initialize_new_default:nnn , \@@_initialize_new_default:nnV ,
+% \@@_intialize_new_default_units:
+% }
+% Shared by all commands and (nearly) first thing done. Sets the options,
+% sets the unit (and expands it if necessary), checks if unit is defined.
+% For |\cuam| the unit is a special |\c_@@_no_unit_marker_tl|. I could just check
+% if |\cuam| is used, but I think this is more general. If the marker is used
+% we do nothing, else we we check how the units change.
+% \begin{macrocode}
+\cs_new:Npn \@@_initialize_new_default:nnn #1#2#3
+ {
+ \tl_clear:N \l_@@_option_unit_tl
+ \tl_if_empty:nF {#2} { \keys_set:nn { cooking-units } {#2} }
\IfNoValueF {#1}
{ \@@_reference_label_and_persons:n {#1} }
- \clist_if_empty:cF { l_@@_unit_option_ \l_@@_option_unit_tl _clist }
+ \@@_expand_unit_input:Nn \l_@@_original_unit_tl {#3}
+ \@@_error_if_unit_not_defined:VTF \l_@@_original_unit_tl
+ {
+ \@@_set_state_to:n { error }
+ \bool_set_true:N \l_@@_unit_error_bool
+ }
+ { \@@_set_state_to:n { normal } }
+ \@@_set_parse_and_process_type_to:n { number }
+ \@@_set_print_type_to:n { unknown }
+ \tl_clear:N \l_@@_phantom_tl
+ \@@_initialize_new_default_units:
+ }
+% \end{macrocode}
+% First, convert the original unit to eV or a bonkers unit if necessary.
+% If we have an unit-change, store the wanted unit in |\l_@@_option_unit_tl|.
+% \begin{macrocode}
+\cs_new:Npn \@@_initialize_new_default_units:
+ {
+ \@@_if_no_unit_marker:NTF \l_@@_original_unit_tl
+ { \tl_set_eq:NN \l_@@_option_unit_tl \l_@@_original_unit_tl }
+ { \@@_intialize_new_default_units_aux: }
+ }
+\cs_new:Npn \@@_intialize_new_default_units_aux:
+ {
+ \bool_if:NTF \l_@@_pckopt_bonkers_bool
+ { \@@_changing_unit_bonkers:N \l_@@_original_unit_tl }
+ {
+ \bool_if:NT \l_@@_pckopt_convert_to_eV_bool
+ { \@@_convert_to_eV:N \l_@@_original_unit_tl }
+ }
+ \prop_get:NVNF \l_@@_change_unit_prop \l_@@_original_unit_tl \l_@@_option_unit_tl
+ { \tl_set_eq:NN \l_@@_option_unit_tl \l_@@_original_unit_tl }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_initialise_new_after_parsing:n}
+% As the name suggests, this one is used \emph{after} parsing the amount.
+% This is done in order to know if there is an error, if the unit needs
+% to be changed and if this command needs to be called at all.
+%
+% It is kinda difficult to decide which unit is the correct one, as it may change
+% due to unit-options. In theory this could lead to an infinite loop,
+% so I decide in this place how things are printed and which unit
+% is used.
+%
+% Well, in the end I only decide if a fraction is printed or not. The case of error or
+% special signs were already sorted out.
+%
+% To make sure the lokal options override the unit-options, we set
+% the options again after unit-options.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_initialise_new_after_parsing:n #1
+ {
+ \clist_if_empty:cF { l_@@_unit_option_ \l_@@_decided_unit_tl _clist }
{
\keys_set_filter:nnv
{ cooking-units }
{ change-unit }
- { l_@@_unit_option_ \l_@@_option_unit_tl _clist }
+ { l_@@_unit_option_ \l_@@_decided_unit_tl _clist }
+ \tl_if_empty:nF {#1} { \keys_set:nn { cooking-units } {#1} }
}
- \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_set_eq:NN \l_@@_lokal_numeral_bool \l_@@_print_numeral_bool
+ \bool_set_eq:NN \l_@@_lokal_numeral_bool \l_@@_pckopt_print_numeral_bool
}
+\cs_new:Npn \@@_decide_unit:
+ {
+ \@@_change_unit:TF
+ { \tl_set_eq:NN \l_@@_decided_unit_tl \l_@@_option_unit_tl }
+ { \tl_set_eq:NN \l_@@_decided_unit_tl \l_@@_original_unit_tl }
+ }
% \end{macrocode}
% \end{macro}
%
+% \begin{macro}{\@@_new_setup_bools_for_process_and_prints:}
+% Determines some stuff for later use in the processing/printing department.
+% It checks if the amount needs to be recalculated; and if fractions should be
+% printed or not.
+% \begin{macrocode}
+\cs_new:Npn \@@_new_setup_bools_for_process_and_prints:
+ {
+ \bool_set_false:N \l_@@_lokal_recalc_for_people_bool
+ \bool_lazy_and:nnT
+ { \l_@@_reference_given_bool }
+ { \l_@@_pckopt_recalculate_amount_bool }
+ {
+ \int_compare:nNnF
+ { \l_@@_wanted_number_of_persons_int }
+ =
+ { \l_@@_local_number_of_persons_int }
+ { \bool_set_true:N \l_@@_lokal_recalc_for_people_bool }
+ }
+ \@@_if_print_type_equal:nT { fraction }
+ {
+ \bool_lazy_or:nnTF
+ { \l_@@_pckopt_eval_fractions_bool }
+ { \l_@@_lokal_recalc_for_people_bool }
+ { \@@_set_print_type_to:n { number } }
+ {
+% "Convert" fractions \emph{only} if a unit change is requested.
+ \bool_lazy_and:nnT
+ { \l_@@_pckopt_convert_fractions_bool }
+ { ! \tl_if_eq_p:NN \l_@@_option_unit_tl \l_@@_original_unit_tl }
+ { \@@_set_print_type_to:n { number } }
+ }
+ }
+ }
+% \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_@@_original_unit_tl} (the unit given in the second argument of
-% \mycs{cutext} or \mycs{Cutext}) by default.
+% \begin{macro}{ \@@_use_hook_accordingly: }
+% Hooks are straightforward. I know which command I used and thus set the
+% respective hook.
% \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
+\cs_new:Npn \@@_use_hook_accordingly:
+ {
+ \l_@@_cmd_hook_tl
+ \tl_case:NnF \l_@@_cmd_type_tl
+ {
+ \c_@@_cmd_type_cunum_tl { \l_@@_cunum_hook_tl }
+ \c_@@_cmd_type_cCutext_tl
+ {
+ \bool_if:NTF \l_@@_cutext_uppercase_word_bool
+ { \l_@@_Cutext_hook_tl }
+ { \l_@@_cutext_hook_tl }
+ }
+ \c_@@_cmd_type_cuam_tl { \l_@@_cuam_hook_tl }
+ }
+ { \@@_create_internal_error:nN { use-hook-acc } \l_@@_cmd_type_tl }
+ }
% \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{macro}{ \@@_general_checkups: }
+% Doing some general stuff and tests which are done before further processing
+% the amount.
% \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:Npn \@@_general_checkups:
+ {
+ \tl_set_eq:NN \l_@@_print_type_tl \l_@@_parse_and_process_type_tl
+ \@@_if_state_equal:nT { normal }
+ { \@@_new_setup_bools_for_process_and_prints: }
+ \@@_decide_unit:
+ \@@_if_cmd_type_equal:nT { cCutext }
+ { \@@_cutext_check_if_translation_available: }
}
-\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
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \begin{macro}{\@@_process_amount_normally:n}
+% This command is called after parsing the amount if no special-sign, error
+% or so is encountered. First, initialize some stuff that is going to be important.
+% Afterwards, if \cCutext\ is used, check if a translation is available.
+% Then process the input depending on which case (number, range, fraction) we had.
+% \begin{macrocode}
+\cs_new:Npn \@@_process_amount_normally:n #1
+ {
+ \@@_initialise_new_after_parsing:n {#1}
+ \tl_case:NnF \l_@@_parse_and_process_type_tl
+ {
+ \c_@@_parse_and_process_type_number_tl \@@_new_process_number_in_input:
+ \c_@@_parse_and_process_type_range_tl \@@_new_process_range_in_input:
+ \c_@@_parse_and_process_type_fraction_tl \@@_new_process_fraction_in_input:
+ }
+ { \@@_create_internal_error:nN { process_the_input } \l_@@_parse_and_process_type_tl }
}
-\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}
+% This is called if the state is not \enquote{normal}. So the whole \enquote{process}
+% part is skipped. If a special sign was detected, print a warining. If
+% the 42-bool is true, change the amount accordingly. Nothing else is done.
+% \begin{macrocode}
+\cs_new:Npn \@@_process_amount_special:
+ {
+ \@@_if_state_equal:nT { special_sign }
+ { \msg_warning:nnV { cooking-units } { amount-not-known } \l_@@_original_amount_tl }
+ \bool_if:NT \l_@@_pckopt_fourty_two_bool
+ { \@@_prepare_fourty_two_amount: }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{ \@@_prepare_fourty_two_amount: }
+% Simply replaces all variables with |42|. We can change all (except for the mixed fraction tl)
+% as we know if we are going to print a \enquote{number}, \enquote{range} or
+% \enquote{fraction}.
+% \begin{macrocode}
+\cs_new:Npn \@@_prepare_fourty_two_amount:
+ {
+ \tl_set:Nn \l_@@_number_tmpa_tl { 42 }
+ \tl_set:Nn \l_@@_number_tmpb_tl { 42 }
+ \tl_if_empty:NF \l_@@_mixed_fraction_tl
+ { \tl_set:Nn \l_@@_mixed_fraction_tl { 42 } }
+ \@@_if_state_equal:nT { special_sign }
+ {
+ \tl_put_right:Nn \l_@@_number_tmpa_tl { (!) }
+ \tl_put_right:Nn \l_@@_number_tmpb_tl { (!) }
+ \tl_if_empty:NF \l_@@_mixed_fraction_tl
+ { \tl_put_right:Nn \l_@@_mixed_fraction_tl { (!) } }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \subsubsection{Process the input}
+%
+% \begin{macro}{ \@@_new_process_number_in_input: }
+% Straightforward. The number only consists of a number. Thus
+% calculate the things necessary and post process it depending on the command
+% (|\cunum|, etc.)\ used.
+% \begin{macrocode}
+\cs_new:Npn \@@_new_process_number_in_input:
+ {
+ \@@_calculate_and_store_in:N \l_@@_number_tmpa_tl
+ \@@_post_process_accordingly:NN \l_@@_number_tmpa_tl \q_no_value
}
% \end{macrocode}
% \end{macro}
%
+% \begin{macro}{ \@@_new_process_range_in_input: }
+% Same as before, this time with two variables.
+% \begin{macrocode}
+\cs_new:Npn \@@_new_process_range_in_input:
+ {
+ \@@_calculate_and_store_in:N \l_@@_number_tmpa_tl
+ \@@_calculate_and_store_in:N \l_@@_number_tmpb_tl
+ \@@_post_process_accordingly:NN \l_@@_number_tmpa_tl \l_@@_number_tmpb_tl
+ }
+% \end{macrocode}
+% \end{macro}
%
+% \begin{macro}{ \@@_new_process_range_in_input: }
+% Here we are a bit more complicated, but not much.
+% For fractions, we generally do not calculate the several numbers.
%
+% First, remove the minus signs from the numbers (if any).
+% Afterwards check if the printing type is a \enquote{number} (\enquote{range} is
+% not possible). If a \enquote{number} is requested, convert the fraction
+% to a number (simply by calculating the fraction). If we have a fraction, nothing
+% else needs to be done.
+% \begin{macrocode}
+\cs_new:Npn \@@_new_process_fraction_in_input:
+ {
+ \@@_process_and_remove_minus_in_fraction:NNNN \l_@@_minus_bool
+ \l_@@_mixed_fraction_tl
+ \l_@@_number_tmpa_tl
+ \l_@@_number_tmpb_tl
+ \@@_if_print_type_equal:nT { number }
+ {
+ \@@_convert_fraction_to_number_in_input:NNN
+ \l_@@_mixed_fraction_tl
+ \l_@@_number_tmpa_tl
+ \l_@@_number_tmpb_tl
+ }
+ }
+% \end{macrocode}
+% This command loops over each variable, removes the minus and reverses the
+% bool if needed.
+% \begin{macrocode}
+\cs_new:Npn \@@_process_and_remove_minus_in_fraction:NNNN #1 #2#3#4
+ {
+ \bool_set_false:N #1
+ \@@_check_minus_remove_and_reverse:NN
+ #1 #2#3#4
+ \q_nil
+ }
+% \end{macrocode}
+% Convert a fraction to a number. Check if the denominator is 0, if so, print an
+% error. Else, simply evaluate the fraction. If the minus bool is true,
+% add a minus sign on the left. Afterwards, process it as a number.
+% \begin{macrocode}
+\cs_new:Npn \@@_convert_fraction_to_number_in_input:NNN #1#2#3
+ {
+ \fp_compare:nNnTF {#3} = { 0 }
+ { \@@_create_error:n { Division-by-zero } }
+ {
+ \@@_tl_eval:Nn \l_@@_number_tmpa_tl { #1 + #2 / #3 }
+ \bool_if:NT \l_@@_minus_bool
+ { \tl_put_left:Nn \l_@@_number_tmpa_tl { - } }
+ \@@_new_process_number_in_input:
+ }
+ }
+% \end{macrocode}
+% \end{macro}
%
%
-% \begin{macro}{ \@@_print_numerical_input:N }
-% Prints the numerical output (if it is not a fraction).
+% \begin{macro}{ \@@_new_print_amount_correctly: }
+% After parsing, processing, etc.\ it is time to print the amount.
+% If an error was raised, simply print the \enquote{unparsed} original amount.
+%
+% Else, print the amount depending on \enquote{number}, \enquote{range}
+% or \enquote{fraction}. \enquote{number} and \enquote{range} are printed
+% according to the command used (|\cunum|, etc.). Fractions are printed
+% indipendently from the commands.
+% \begin{macrocode}
+\cs_new:Npn \@@_new_print_amount_correctly:
+ {
+ \@@_if_state_equal:nTF { error }
+ { \l_@@_original_amount_tl }
+ {
+ \tl_case:NnF \l_@@_print_type_tl
+ {
+ \c_@@_print_type_number_tl
+ {
+ \@@_print_number_accordingly:N
+ \l_@@_number_tmpa_tl
+ }
+ \c_@@_print_type_range_tl
+ {
+ \@@_print_range_accordingly:NN
+ \l_@@_number_tmpa_tl
+ \l_@@_number_tmpb_tl
+ }
+ \c_@@_print_type_fraction_tl
+ {
+ \@@_culang_let:nnN { name } { decimal-mark } \l_@@_translation_tmpa_tl
+ \tl_replace_once:Nnn \l_@@_mixed_fraction_tl { . } \l_@@_translation_tmpa_tl
+ \tl_replace_once:Nnn \l_@@_number_tmpa_tl { . } \l_@@_translation_tmpa_tl
+ \tl_replace_once:Nnn \l_@@_number_tmpb_tl { . } \l_@@_translation_tmpa_tl
+ \@@_print_fractions:Nnn
+ \l_@@_mixed_fraction_tl
+ \l_@@_number_tmpa_tl
+ \l_@@_number_tmpb_tl
+ }
+ }
+ { \@@_create_internal_error:nN { print_the_input } \l_@@_print_type_tl }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{ \@@_new_print_unit_correctly: , \@@_print_unit_in_case_of_error: }
+% Prints the unit. In case of error, print the unit more or less directly.
+% Even in case of error there needs to be the correct spacing, etc.
+%
+% Else, parse the unit depending on the command used. For |\cuam| no unit
+% is printed, but a phrase can be required.
+% \begin{macrocode}
+\cs_new:Npn \@@_new_print_unit_correctly:
+ {
+ \@@_if_state_equal:nTF { error }
+ { \@@_print_unit_in_case_of_error: }
+ {
+ \tl_case:NnF \l_@@_cmd_type_tl
+ {
+ \c_@@_cmd_type_cunum_tl { \@@_cunum_print_correct_unit: }
+ \c_@@_cmd_type_cCutext_tl { \@@_cutext_print_correct_unitname: }
+ \c_@@_cmd_type_cuam_tl { \@@_cuam_print_correct_unitphrase: }
+% \c_@@_cmd_type_cucomp_tl { \@@_cunum_print_correct_unit: }
+ }
+ { \@@_create_internal_error:nN { print-unit-acc } \l_@@_cmd_type_tl }
+ }
+ }
+% \end{macrocode}
+% Prints the unit in case of error. Make sure the unit is printed correctly
+% with the correct spacing. If the unit is unknown, just print the input.
+% \begin{macrocode}
+\cs_new:Npn \@@_print_unit_in_case_of_error:
+ {
+ \tl_if_empty:NF \l_@@_phantom_tl { \phantom { \l_@@_phantom_tl } }
+ \tl_use:N \l_@@_value_unit_space_tl
+ \bool_if:NTF \l_@@_unit_error_bool
+ { \l_@@_original_unit_tl }
+ { \@@_culang_print:nV { unit-symbol } \l_@@_original_unit_tl }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro} { \@@_print_number_accordingly:N }
+% Prints the input |#1| according to the used command.
+% This command is
+% also used in ranges.
+% \begin{macrocode}
+\cs_new:Npn \@@_print_number_accordingly:N #1
+ {
+ \tl_case:NnF \l_@@_cmd_type_tl
+ {
+ \c_@@_cmd_type_cunum_tl { \@@_print_numerical_input:N #1 }
+ \c_@@_cmd_type_cCutext_tl { \@@_cutext_print_input:N #1 }
+ \c_@@_cmd_type_cuam_tl { \@@_cuam_print_numerical_input:N #1 }
+ }
+ { \@@_create_internal_error:nN { print-input-acc } \l_@@_cmd_type_tl }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro} { \@@_print_range_accordingly:NN , \@@_print_range_sign: }
+% Prints ranges. It simply prints the numbers twice, inbetween a range sign.
+% \begin{macrocode}
+\cs_new:Npn \@@_print_range_accordingly:NN #1#2
+ {
+ \@@_print_number_accordingly:N #1
+ \@@_print_range_sign:
+ \@@_print_number_accordingly:N #2
+ }
+% \end{macrocode}
+% \begin{macrocode}
+\cs_new:Npn \@@_print_range_sign:
+ {
+ \@@_if_cmd_type_equal:nTF { cunum }
+ { \tl_use:N \l_@@_cunum_range_sign_tl }
+ {
+ \bool_lazy_or:nnTF
+ { \@@_if_cmd_type_equal_p:n { cCutext } }
+ { \l_@@_lokal_numeral_bool }
+ {
+ \bool_set_false:N \l_@@_cutext_uppercase_word_bool
+ \tl_if_empty:NTF \l_@@_cutext_range_sign_tl
+ { \@@_culang_print:nn { name } { cutext-range-sign } }
+ { \tl_use:N \l_@@_cutext_range_sign_tl }
+ }
+ { \tl_use:N \l_@@_cunum_range_sign_tl }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
%
-% Changed \lstinline|\l_@@_tmpa_tl| by |\l_@@_translation_tmpa_tl|, it's better that way.
+% \begin{macro}{ \@@_post_process_accordingly:NN }
+% After evaluating and changing the amounts (due to unit changing, rounding, etc.)
+% we post process the input (only for numbers and ranges). For |\cunum| nothing
+% needs to be done. For \cCutext\ and |\cuam| we post process the values accordingly
+% (checking if integer, etc.)
+% \begin{macrocode}
+\cs_new:Npn \@@_post_process_accordingly:NN #1#2
+ {
+ \tl_case:NnF \l_@@_cmd_type_tl
+ {
+ \c_@@_cmd_type_cunum_tl { }
+ \c_@@_cmd_type_cCutext_tl { \@@_cutext_post_process_input:NN #1#2 }
+ \c_@@_cmd_type_cuam_tl { \@@_cuam_post_process_input:NN #1#2 }
+% \c_@@_cmd_type_cucomp_tl { }
+ }{
+ \@@_create_internal_error:nN { post-process } \l_@@_cmd_type_tl
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{ \@@_print_numerical_input:N }
+% The base printing command for numbers. Makes sure the minus sign
+% and decimal-mark are correct.
% \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
+ \@@_culang_let:nnN { name } { decimal-mark } \l_@@_translation_tmpa_tl
\tl_replace_once:Nnn #1 { . } { \l_@@_translation_tmpa_tl }
}
\tl_replace_once:Nnn #1 { - } \c_@@_minus_tl
@@ -6158,88 +7362,48 @@ and the derived file cooking-units.sty.
% \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.
+% This subsection contains macros for splitting and checking the input.
%
% \begin{macro}{\@@_create_error:n, \@@_create_error_and_stop:n , \@@_create_error:nn }
+% Create error messages and set case to \enquote{error}.
% \begin{macrocode}
+\cs_new:Npn \@@_create_internal_error:nN #1#2
+ {
+ \@@_set_case_to:n { error }
+ \msg_error:nnnV { cooking-units } { internal-error } {#1} #2
+ }
\cs_new:Npn \@@_create_error:n #1
{
- \bool_set_true:N \l_@@_error_bool
+ \@@_set_case_to:n { error }
\msg_error:nnV { cooking-units } {#1} \l_@@_original_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_@@_original_amount_tl
+ \@@_create_error:n {#1}
\use_none_delimit_by_q_nil:w
}
\cs_new:Npn \@@_create_error:nn #1#2
{
- \bool_set_true:N \l_@@_error_bool
+ \@@_set_case_to:n { error }
\msg_error:nnnV { cooking-units } {#1} {#2} \l_@@_original_amount_tl
}
% \end{macrocode}
% \end{macro}
%
-% The following command is needed after the parsing. It further processes
-% the parsed input and prints. The actual parsing and printing process (|\@@_process_tmp|)
-% depends on the command (|\cunum|, etc.) used.
+% \begin{macro} { \@@_parse_the_amount:n }
+% Does what the name suggests. |#1| is the input given by the user without changes.
+% It is then stored in |\l_@@_original_amount_tl| (which can be expanded, etc.).
+% Afterwards we rescan the input to remove spaces and make sure \_ and ? have
+% correct catcodes (last one can be active; screws some stuff up if it is so).
+% Then decides what's supposed to happen next.
% \begin{macrocode}
-\cs_new:Npn \@@_process_tmp: { }
-\cs_new:Npn \@@_process_and_print_input:
+\cs_new:Npn \@@_parse_the_amount:n #1
{
- \bool_lazy_or:nnTF
- { \l_@@_error_bool }
- { \l_@@_unit_error_bool }
- { \l_@@_original_amount_tl }
- { \@@_process_tmp: }
- }
-% \end{macrocode}
-% If there is an error or there is a special case (like \opt{42=true}) these commands
-% are used.
-% \begin{macrocode}
-\cs_new:Npn \@@_process_default: { \l_@@_original_amount_tl }
-\cs_new:Npn \@@_print_default_unit:
- {
- \tl_if_empty:NF \l_@@_phantom_tl { \phantom { \l_@@_phantom_tl } }
- \,\l_@@_original_unit_tl
- }
-% \end{macrocode}
-%
-% \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
- {
- \@@_set_amount:Nn \l_@@_original_amount_tl {#1}
+ \@@_expand_amount_input:Nn \l_@@_original_amount_tl {#1}
\tl_set_rescan:NnV \l_@@_original_amount_tl
{
\char_set_catcode_letter:N \_ %
@@ -6248,114 +7412,144 @@ and the derived file cooking-units.sty.
} \l_@@_original_amount_tl
\bool_lazy_any:nTF
{
- { \l_@@_fourty_two_bool }
- { \l_@@_draft_bool }
{ \tl_if_empty_p:N \l_@@_original_amount_tl }
- }{
- \cs_set_eq:NN \@@_process_tmp: \@@_process_default:
- \tl_if_empty:NT \l_@@_original_amount_tl
- { \msg_error:nnV { cooking-units } { empty-amount } \l_@@_original_amount_tl }
- \bool_if:NT \l_@@_fourty_two_bool
- { \tl_set:Nn \l_@@_original_amount_tl { 42 } }
- }{
- \tl_set_eq:NN \l_@@_tmpa_tl \l_@@_original_amount_tl
- \@@_split_input:N \l_@@_tmpa_tl
+ { \l_@@_pckopt_draft_bool }
}
+ { \@@_prepare_just_print_input: }
+ { \@@_split_and_parse_input: }
+ }
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\@@_split_and_parse_input: }
+% If the weitd option \opt{42} is used, set the state to \enquote{42}.
+% Copy the original amount and prepapre to split the input.
+% \begin{macrocode}
+\cs_new:Npn \@@_split_and_parse_input:
+ {
+ \bool_if:NT \l_@@_pckopt_fourty_two_bool
+ { \@@_set_state_to:n { 42 } }
+ \tl_set_eq:NN \l_@@_tmpa_tl \l_@@_original_amount_tl
+ \@@_prepare_to_split_input:N \l_@@_tmpa_tl
+ }
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\@@_prepare_just_print_input: }
+% If we decide the input is just to be printed, set it to \enquote{error}
+% (because I am lazy and do not want to create another case to check).
+% \begin{macrocode}
+\cs_new:Npn \@@_prepare_just_print_input:
+ {
+ \@@_set_state_to:n { error }
+ \tl_if_empty:NT \l_@@_original_amount_tl
+ { \@@_create_error:nn { cooking-units } { empty-amount } }
}
% \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{macro}{ \@@_prepare_to_split_input:N}
+% Adapts the state into \enquote{range} or \enquote{fraction} if needed.
+% By default it is set to \enquote{number}. Ranges and Fractions are not allowed
+% together. Afterwards, split the input. If we encounter an error, we can use
+% |\use_none_delimit_by_q_nil:w| during the code to jump to this point.
+% This makes bailing out from the command more easy.
% \begin{macrocode}
-\cs_new:Npn \@@_split_input:N #1
+\cs_new:Npn \@@_prepare_to_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
+ \@@_set_parse_and_process_type_to:n { range }
}
\tl_if_in:NnT #1 { / }
{
- \bool_set_true:N \l_@@_lokal_fraction_bool
- \bool_if:NT \l_@@_range_in_input_bool
+ \@@_if_parse_and_process_type_equal:nT { range }
{ \@@_create_error_and_stop:n { fraction-not-allowed-with-range } }
+ \@@_set_parse_and_process_type_to:n { fraction }
}
- \@@_split:N #1
+ \@@_split_and_parse:N #1
\use_none_delimit_by_q_nil:w \q_nil
}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{ \@@_split_input:}
-% Splits the input into fractions or ranges.
-% Errors are already checked at this point.
+%
+% \begin{macro}{ \@@_split_and_parse:}
+% Splits the input into fractions or ranges (or numbers).
% \begin{macrocode}
-\cs_new:Npn \@@_split:N #1
+\cs_new:Npn \@@_split_and_parse:N #1
{
- \bool_if:NTF \l_@@_lokal_fraction_bool
- { \@@_split_fraction:V }
+ \tl_case:NnF \l_@@_parse_and_process_type_tl
{
- \bool_if:NTF \l_@@_range_in_input_bool
- { \@@_split_range:V }
- { \@@_split_number:V }
- }
+ \c_@@_parse_and_process_type_number_tl { \@@_split_and_parse_number:V }
+ \c_@@_parse_and_process_type_range_tl { \@@_split_and_parse_range:V }
+ \c_@@_parse_and_process_type_fraction_tl { \@@_split_and_parse_fraction:V }
+ }
+ { \@@_create_internal_error:nN { split } \l_@@_parse_and_process_type_tl }
#1
}
% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{ \@@_split_and_parse_number:n }
+% Gets the input , parses it and stores it into |\l_@@_number_tmpa_tl|.
% \begin{macrocode}
-\cs_new:Npn \@@_split_number:n #1
+\cs_new:Npn \@@_split_and_parse_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}
+% \end{macro}
+%
+% \begin{macro}{ \@@_split_and_parse_range:n , \@@_split_and_parse_range_aux:ww }
+% Splits the input along |\q_@@_range|, parses the two parts and that's it.
% \begin{macrocode}
-\cs_new:Npn \@@_split_range:n #1
+\cs_new:Npn \@@_split_and_parse_range:n #1
{
- \cs_set_eq:NN \@@_process_tmp: \@@_process_range_in_input:
- \@@_split_range_aux:ww #1 \q_stop
+ \@@_split_and_parse_range_aux:ww #1 \q_stop
}
-\cs_new:Npn \@@_split_range_aux:ww #1 \q_@@_range #2 \q_stop
+\cs_new:Npn \@@_split_and_parse_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}
+% \end{macro}
+%
+% \begin{macro}{ \@@_split_and_parse_fraction:n , \@@_split_and_parse_fraction_mixed:ww , \@@_split_and_parse_fraction_frac:ww }
+% A bit more tricky. We check first if a mixed fraction part exists. If not the function
+% get's |\q_nil|. Then we read the nominator and denominator. Inbetween we check
+% for errors
% \begin{macrocode}
-\cs_new:Npn \@@_split_fraction:n #1
+\cs_new:Npn \@@_split_and_parse_fraction:n #1
{
- \cs_set_eq:NN \@@_process_tmp: \@@_process_generel_fraction_in_input:
- \@@_split_fraction_mixed:ww
+ \@@_split_and_parse_fraction_mixed:ww
#1 \q_stop / \q_recursion_tail _ \q_nil \q_stop
\q_recursion_stop
-% \end{macrocode}
-% At this point we have all information we need to determine whatever or not
-% the fractions should be evaluated or if the units should be changed.
-% \begin{macrocode}
- \bool_lazy_or:nnT
- { \l_@@_lokal_persons_bool }{ \l_@@_eval_fractions_bool }
- { \bool_set_false:N \l_@@_lokal_fraction_bool }
- \bool_if:NT \l_@@_convert_fractions_bool
- {
- \tl_if_eq:NNF \l_@@_original_unit_tl \l_@@_option_unit_tl
- { \bool_set_false:N \l_@@_lokal_fraction_bool }
- }
}
+% \end{macrocode}
+% Gets the mixed fraction part (if it exists). If |#2| is |\q_nil| the part does not
+% exist. |#1| must then be of part |a/b|.
%
-\cs_new:Npn \@@_split_fraction_mixed:ww #1 _ #2 \q_stop
+% If |#2| is \emph{not} |\q_nil| it contains the fraction part with |a/b|.
+% Parse the mixed fraction part and store it. Seperate |#2|.
+% \begin{macrocode}
+\cs_new:Npn \@@_split_and_parse_fraction_mixed:ww #1 _ #2 \q_stop
{
\quark_if_nil:nTF {#2}
{
\tl_clear:N \l_@@_mixed_fraction_tl
- \@@_split_fraction_frac:ww #1 \q_stop
+ \@@_split_and_parse_fraction_frac:ww #1 \q_stop
}{
\@@_parse_input_and_safe_in:nN {#1} \l_@@_mixed_fraction_tl
- \@@_split_fraction_frac:ww #2 \q_stop
+ \@@_split_and_parse_fraction_frac:ww #2 \q_stop
}
}
-\cs_new:Npn \@@_split_fraction_frac:ww #1 / #2 \q_stop
+% \end{macrocode}
+% Seperates nominator and denominator. If |#2| is equal to |\q_recursion_tail|
+% we probably had a construction like |a/b_c|, which is wrong. If so, create an error.
+% If everything is correct, parse the input and store it.
+% \begin{macrocode}
+\cs_new:Npn \@@_split_and_parse_fraction_frac:ww #1 / #2 \q_stop
{
\quark_if_recursion_tail_stop_do:nn {#2}
{ \@@_create_error:n { fraction-wrong-order } }
@@ -6364,17 +7558,21 @@ and the derived file cooking-units.sty.
\use_none_delimit_by_q_recursion_stop:w
}
% \end{macrocode}
+% \end{macro}
+% \begin{macro}{ \@@_split_and_parse_number:V ,
+% \@@_split_and_parse_range:V , \@@_split_and_parse_fraction:V }
+% Some variants.
% \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 }
+\cs_generate_variant:Nn \@@_split_and_parse_number:n { V }
+\cs_generate_variant:Nn \@@_split_and_parse_range:n { V }
+\cs_generate_variant:Nn \@@_split_and_parse_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|.
+% Parses through |#1| and makes sure it is correct. This includes checking if there
+% is only one decimal sign and other stuff. The \enquote{correct}
+% parsed stuff is stored in |\l_@@_tmpa_tl|.
% \begin{macrocode}
\cs_new:Npn \@@_parse_input_and_safe_in:nN #1 #2
{
@@ -6382,21 +7580,20 @@ and the derived file cooking-units.sty.
\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
- { }
+ \@@_if_state_equal:nF { error }
{ \tl_set_eq:NN #2 \l_@@_tmpa_tl }
}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{ \@@_start_loop:Nw }
+% \begin{macro}{ \@@_start_loop:N }
% This function seperates the input into two parts with the first
-% part being the first token. This token is checked whetever or not
+% part being the first token. This token is checked if or if 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
+% also works if the input only consists of one token with \#2 being
% empty (hopefully).
% \begin{macrocode}
\cs_new:Npn \@@_start_loop:N #1
@@ -6404,19 +7601,18 @@ and the derived file cooking-units.sty.
\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
- }
+ { \tl_map_function:nN {#1} \@@_parse:N }
}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{ \@@_parse_input_loop_aux:N }
+% \begin{macro}{ \@@_parse_input_loop_aux:N , \@@_check_which_error:n , \@@_check_repitition: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.
+% one decimal-sign and the allowed special input.
+% In other cases, raise an error. Note that the state special-sign
+% can only be set if there is no error.
+%
% \begin{macrocode}
\cs_new:Npn \@@_parse_input_loop_aux:N #1
{
@@ -6429,13 +7625,12 @@ and the derived file cooking-units.sty.
\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
+ {
+ \@@_if_state_equal:nF { error }
+ { \@@_set_state_to:n { special_sign } }
\tl_put_right:Nn \l_@@_tmpa_tl {#1}
- }{
- \bool_set_true:N \l_@@_error_bool
- \@@_check_error:n {#1}
}
+ { \@@_check_which_error:n {#1} }
}
}
}
@@ -6447,14 +7642,14 @@ and the derived file cooking-units.sty.
% 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
+\cs_new:Npn \@@_check_which_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}
{
- \bool_if:NTF \l_@@_lokal_fraction_bool
+ \@@_if_parse_and_process_type_equal:nTF { fraction }
{ \@@_create_error:n { Second-mixed-fraction-sign-not-allowed } }
{ \@@_create_error:n { missing-slash } }
}
@@ -6462,6 +7657,8 @@ and the derived file cooking-units.sty.
}
}
% \end{macrocode}
+% Back then this contained more checks, but now it just checks
+% if we have a second error decimal sign.
% \begin{macrocode}
\cs_new:Npn \@@_check_repitition:N #1
{
@@ -6473,196 +7670,91 @@ and the derived file cooking-units.sty.
% \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_generel_fraction_in_input: }
-% This function prints both mixed and normal fractions. Those was done
-% by two functions beforehand, but they shared mostly the same code, so I
-% managed to fuse them.
-%
-% The first part removes the minus sign. It cycles through the variables
-% (|\l_@@_mixed_fraction_tl| can be emtpy) and removes the minus signs.
-% It furthermore saves how many minuses are used by reversing a bool.
-% If a minus sign is found, the bool is reversed to true (from false). Another
-% minus: minus and minus is plus, reverse bool again (to false this time), etc.
-%
-% Afterwards: Is a fraciton printed, or is the input evaluated. Printing is
-% straight forward.
-%
-% Due to how mixed fractions are evaluated, one can just evaluate the
-% absolute values of the inputs and add a minus sign on the left side afterwards
-% (if necessary).
-% \begin{align}
-% \cuam{1_2/3} &= 1 + 2/3 \\
-% \cuam{-1_2/3} &= -1 - 2/3 = - ( 1 + 2/3 )
-% \end{align}
-%
-% If |\l_@@_mixed_fraction_tl| is empty the calculation just evaluates to
-% |+\l_@@_number_tmpa_tl / \l_@@_number_tmpb_tl|, which is also valid.
%
-% \begin{macrocode}
-\cs_new:Npn \@@_process_generel_fraction_in_input:
- {
- \@@_check_minus_remove_and_reverse:NN
- \l_@@_mixed_fraction_tl
- \l_@@_number_tmpa_tl
- \l_@@_number_tmpb_tl
- \q_nil
- \bool_lazy_or:nnTF
- { \l_@@_lokal_fraction_bool }
- { \l_@@_special_sign_bool }
- {
- \bool_if:NT \l_@@_special_sign_bool
- {
- \msg_warning:nnV { cooking-units } { amount-not-known } \l_@@_original_amount_tl
- }
- \@@_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_@@_original_amount_tl }
- \@@_tl_eval:Nn \l_@@_number_tmpa_tl
- {
- \l_@@_mixed_fraction_tl +
- \l_@@_number_tmpa_tl / \l_@@_number_tmpb_tl
- }
- \bool_if:NT \l_@@_minus_bool
- { \tl_put_left:Nn \l_@@_number_tmpa_tl { - } }
- \@@_process_and_print_number_in_input:N \l_@@_number_tmpa_tl
- }
- }
-% \end{macrocode}
-% \end{macro}
%
-%
%
+% \subsection {Formatiere \& Calculiere}
%
%
%
-% \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.
+% The main calculation command. The split amount is given to this
+% command. It is seperated into several smaller macros. Unit-changing
+% the amount, referencing, rounding and temperature checks are done
+% here. Note that we are only here if the state is \enquote{normal}.
% \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
- }
+ \@@_calculate_input_and_store_in:N #1
+ \@@_calc_references_and_store_in:N #1
+ \@@_round_calculated_input_and_store_in:N #1
+ \@@_check_temperature_limit:N #1
}
% \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{macro}{ \@@_calculate_input_and_store_in:NN }
+% Well \dots\ this function calculates the input.
+% First check if the units need to be changes at all (if no unit change
+% is wanted, |\l_@@_option_unit_tl| is set to |\l_@@_original_unit_tl| at the
+% beginning. If we are in one case were no unit change is happening
+% (\enquote{special-sign}, \enquote{error}, \enquote{fraction}) we wouldn't be
+% here in the first place, so need to worry about this.
+%
+% As the input is parsed and good for evaluation, store it in
+% |\l_@@_tmpa_fp|.
+%
+% If the key definition contained a |#1| (aka, is a single key),
+% it was replaced by |\l_@@_tmpa_fp|.
+% Thus simply evaluate the tl if one or more |\l_@@_tmpa_fp| are inside.
+%
+% If no |\l_@@_tmpa_fp| is found, we have a simple multiplication with the
+% current amount.
% \begin{macrocode}
-\cs_new:Npn \@@_calculate_input_and_store_in:nN #1#2
+\cs_new:Npn \@@_calculate_input_and_store_in:N #1
{
- \fp_set:Nn \l_@@_tmpa_fp {#1}
- \tl_if_in:cnTF { l_@@_unit_change_ \l_@@_original_unit_tl _tl } { \l_@@_tmpa_fp }
- {
- \@@_tl_eval:Nv #2 { l_@@_unit_change_ \l_@@_original_unit_tl _tl }
- }{
- \@@_tl_eval:Nn #2
- { \l_@@_tmpa_fp * \tl_use:c { l_@@_unit_change_ \l_@@_original_unit_tl _tl } }
+ \tl_if_eq:NNF \l_@@_decided_unit_tl \l_@@_original_unit_tl
+ {
+ \fp_set:Nn \l_@@_tmpa_fp {#1}
+ \tl_if_in:cnTF { l_@@_unit_change_ \l_@@_original_unit_tl _tl } { \l_@@_tmpa_fp }
+ {
+ \@@_tl_eval:Nv #1 { l_@@_unit_change_ \l_@@_original_unit_tl _tl }
+ }{
+ \@@_tl_eval:Nn #1
+ { \l_@@_tmpa_fp * \tl_use:c { l_@@_unit_change_ \l_@@_original_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{macro}{ \@@_calc_references_and_store_in:N,\@@_calc_references_and_store_in_aux:N }
+% All necessary checks were already done at the beginning.
+% so we know that a reference was given and that the wanted number of
+% persons is different then the one given by |\culabel|. Before
+% evaluation, check if the unit is one of those that cannot be changed.
% \begin{macrocode}
-\cs_new:Npn \@@_calc_references:NN #1#2
+\cs_new:Npn \@@_calc_references_and_store_in:N #1
{
- \bool_if:NT \l_@@_lokal_persons_bool
+ \bool_if:NT \l_@@_lokal_recalc_for_people_bool
{
- \int_compare:nNnF
- { \l_@@_wanted_number_of_persons_int }
- =
- { \l_@@_local_number_of_persons_int }
- {
- \tl_set_eq:NN \l_@@_tmpb_tl \l_@@_original_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 }
- }
+ \seq_if_in:NVTF \l_@@_curef_do_not_change_seq \l_@@_decided_unit_tl
+ { \msg_error:nnV { cooking-units } { curef-forbidden-unit } \l_@@_decided_unit_tl }
+ { \@@_calc_references_and_store_in_aux:N #1 }
}
}
% \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.
+% Just calculate the stuff
% \begin{macrocode}
-\cs_new:Npn \@@_calc_references_aux:NN #1#2
+\cs_new:Npn \@@_calc_references_and_store_in_aux:N #1
{
\@@_tl_eval:Nn #1
{
- #2 *
+ #1 *
\l_@@_wanted_number_of_persons_int /
\l_@@_local_number_of_persons_int
}
@@ -6670,13 +7762,33 @@ and the derived file cooking-units.sty.
% \end{macrocode}
% \end{macro}
%
+%
+% \begin{macro}{ \@@_round_calculated_input_and_store_in:Nn,\@@_round_calculated_input_and_store_in:NV }
+% After calculation, the numbers are rounded (if needed).
+% If the rounding precision is negative (can be), just set the bool to true and go
+% to the rounding function.
+% Else check if the number needs rounding at all.
+% Afterwards, round if necessary
+% \begin{macrocode}
+\cs_new:Npn \@@_round_calculated_input_and_store_in:N #1
+ {
+ \bool_if:NTF \l_@@_pckopt_round_precision_negative_bool
+ { \bool_set_true:N \l_@@_round_number_bool }
+ { \@@_check_number_for_rounding:V #1 }
+ \bool_if:NT \l_@@_round_number_bool
+ { \@@_tl_eval:Nn #1 { round ( \@@_rounding_function:n {#1} ) } }
+ }
+% \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|.
-%
+%
+% Set |\l_@@_round_number_bool| to |false| in case of no decimal places found.
+%
+% If the rounding precision is positive, use the helper function to split the
+% amount.
% \begin{macrocode}
\cs_new:Npn \@@_check_number_for_rounding:n #1
{
@@ -6684,39 +7796,26 @@ and the derived file cooking-units.sty.
\@@_check_number_after_dot_aux:ww #1 . \q_recursion_tail .
\q_recursion_stop
}
+\cs_generate_variant:Nn \@@_check_number_for_rounding:n { V }
+% \end{macrocode}
+% The function splitting the amount. So $a.b$ is split into $a$ and $b$.
+% If $b$ does not exist (so the amount is an integer), no rounding is needed.
+% If $b$ does exist, count how many tokens it conists of (e.g.\ $12$ = 2 tokens;
+% $1755$ = 4 tokens). If the number of tokens is larger then the wanted round precision,
+% round the input.
+% \begin{macrocode}
\cs_new:Npn \@@_check_number_after_dot_aux:ww #1 . #2 .
{
- \quark_if_recursion_tail_stop_do:nn {#2}
- {
- \bool_if:NT \l_@@_round_precision_negative_bool
- { \bool_set_true:N \l_@@_round_number_bool }
- }
- \int_compare:nNnT
- { \tl_count:n {#2} } >
- { \l_@@_round_precision_int }
- { \bool_set_true:N \l_@@_round_number_bool }
+ \quark_if_recursion_tail_stop:n {#2}
+ \int_compare:nNnT
+ { \tl_count:n {#2} } >
+ { \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} }
- }
-\cs_generate_variant:Nn \@@_round_calculated_input:Nn { NV }
-% \end{macrocode}
-% \end{macro}
%
%
%
@@ -6727,25 +7826,24 @@ and the derived file cooking-units.sty.
%
% \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}.
+% if the value is below the absolute temperature. Maybe this should be done
+% before rounding?
% \begin{macrocode}
\cs_new:Npn \@@_check_temperature_limit:N #1
{
- \bool_if:NT \l_@@_check_temperature_bool
+ \bool_if:NT \l_@@_pckopt_check_temperature_bool
{
- \seq_if_in:NVT \l_@@_temperatures_to_check_seq \l_@@_option_unit_tl
+ \seq_if_in:NVT \l_@@_temperatures_to_check_seq \l_@@_decided_unit_tl
{
\fp_compare:vNnT
- { l_@@_ \l_@@_option_unit_tl _min_fp } > {#1}
- {
+ { l_@@_ \l_@@_decided_unit_tl _min_fp } > {#1}
+ {
\msg_error:nnxx { cooking-units }
{ Temperature-too-low }
- { #1 \space \l_@@_option_unit_tl }
+ { #1 \space \l_@@_decided_unit_tl }
{
- \fp_use:c { l_@@_ \l_@@_option_unit_tl _min_fp }
- \space \l_@@_option_unit_tl
+ \fp_use:c { l_@@_ \l_@@_decided_unit_tl _min_fp }
+ \space \l_@@_decided_unit_tl
}
}
}
@@ -6763,35 +7861,39 @@ and the derived file cooking-units.sty.
%
%
%
+% \subsection {Main commands helper}
%
-%
+% \begin{macro}{ \@@_if_arrow_grab_until_close_do:nnTF ,
+% \@@_grab_arrows_for_safety_do_afterwards:nN }
+% I really do not like this constuction, but due to catcodes it can happen
+% that the main commands are unable to get the first command inside <>.
+% In order to fix this, I use this bloody construction.
% \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
+ \@@_grab_arrows_for_safety_do_afterwards:nN {#3} #2
}
{#4}
}
+\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}
+ }
+ }
% \end{macrocode}
-%
+% \end{macro}
%
%
% \subsection {\mycs{cunum}}
@@ -6815,44 +7917,19 @@ and the derived file cooking-units.sty.
%
%
% \begin{macro}{ \@@_cunum:nnnnn }
+% The \enquote{helper} command. It essentially only sets
+% the command type to \enquote{cunum} and calls the command that does
+% everything else.
% \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}
- \@@_process_and_print_input:
- \@@_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}
+ \@@_set_cmd_type_to:n { cunum }
+ \@@_do_the_stuff:nnnnnn {#1} {#2} {#3} {#4} {#5} { }
}
% \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
@@ -6864,9 +7941,7 @@ and the derived file cooking-units.sty.
{
\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_@@_original_unit_tl \c_@@_postfix_unit_tl }
+ \@@_culang_print:nV { unit-symbol } \l_@@_decided_unit_tl
}
% \end{macrocode}
% \end{macro}
@@ -6875,8 +7950,10 @@ and the derived file cooking-units.sty.
% \section { cutext \& Cutext }
%
%
-% A better implemantation of \opt{cutext-to-cunum}, but
-% sufficient for now.
+% \begin{macro}{\cutext}
+% The other main command It is essentially similar to \mycs{cunum},
+% only that we also need to take care of uppercasing the word if necessary
+% (which it is not for this command).
% \begin{macrocode}
\NewDocumentCommand \cutext { d<> O{} m m }
{
@@ -6884,17 +7961,16 @@ and the derived file cooking-units.sty.
{ \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}
- }
+ \bool_set_false:N \l_@@_cutext_uppercase_word_bool
+ \@@_cutext:nnnn {#1} {#2} {#3} {#4}
\group_end:
}
}
% \end{macrocode}
+% \end{macro}
%
+% \begin{macro}{\Cutext}
+% Here we do need the uppercasing.
% \begin{macrocode}
\NewDocumentCommand \Cutext { d<> O{} m m }
{
@@ -6902,159 +7978,185 @@ and the derived file cooking-units.sty.
{ \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}
- }
+ \bool_set_true:N \l_@@_cutext_uppercase_word_bool
+ \@@_cutext:nnnn {#1} {#2} {#3} {#4}
\group_end:
}
}
% \end{macrocode}
+% \end{macro}
%
-% \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_@@_original_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}
%
-%^^A #1: label, #2: Options, #3: Values, #4: unit
+% \begin{macro}{ \@@_cutext:nnnn }
+% Same as the \mycs{cunum} equivalent, just setting the command to
+% \enquote{cCutext}.
% \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}
- \@@_process_and_print_input:
- }
- \@@_print_correct_unit:
+ \@@_set_cmd_type_to:n { cCutext }
+ \@@_do_the_stuff:nnnnnn {#1} {#2} {#3} { } {#4} { }
}
% \end{macrocode}
+% \end{macro}
%
%
%
-% \begin{macro} {\@@_cutext_print_input:Nn , \@@_cutext_print_input:NV}
+% \begin{macro} {\@@_cutext_print_input:N , \@@_cutext_print_input_aux:Nn , \@@_cutext_print_input_aux:NV }
% \changes {2016/06/11} {0.99} {New.}
%
-%
+% This prints the amount for the \enquote{cCutext} commands.
+% At first, check if a numeral should be used (\enquote{1} to \enquote{one}, etc.).
+% If not, just print the number. If a numeral should be used, make sure the correct
+% unit is used and go to the next command.
% \begin{macrocode}
-\cs_new_protected:Npn \@@_cutext_print_input:Nn #1#2
+\cs_new_protected:Npn \@@_cutext_print_input:N #1
{
\bool_if:NTF \l_@@_lokal_numeral_bool
{
- \@@_int_if_equal_one:nTF {#1}
+ \@@_cutext_print_input_aux:NV #1 \l_@@_decided_unit_tl
+ }
+ { \@@_print_numerical_input:N #1 }
+ }
+% \end{macrocode}
+% If a numeral is used, make sure the correct one is printed.
+% If the amount is equal to \enquote{1}, get the gender correct \enquote{one}.
+% Else, print the numeral either in upperacse of lowercase.
+%
+% As we could be in a range, we cannot check via a bool if |#1| is 1.
+%
+% Furthermore, make sure the translation of \enquote{1} exists. If not,
+% set input it set to \enquote{1}.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_cutext_print_input_aux:Nn #1#2
+ {
+ \int_compare:nNnTF {#1} = { 1 }
+ {
+ \@@_culang_one_let:NnT \l_@@_translation_tmpa_tl {#2}
{
- \@@_translate_one_and_check_existance:Nx \l_@@_translation_tmpa_tl {#2}
- \bool_if:NTF \l_@@_cutext_uppercase_word_bool
+ \bool_if:NT \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
+ \text_uppercase:x { \tl_head:V \l_@@_translation_tmpa_tl }
+ \tl_tail:V
}
- { \l_@@_translation_tmpa_tl }
- }{
- \bool_if:NTF \l_@@_cutext_uppercase_word_bool
- { \@@_print_Numeral:n {#1} }
- { \@@_print_numeral:n {#1} }
}
+ \l_@@_translation_tmpa_tl
+ }{
+ \bool_if:NTF \l_@@_cutext_uppercase_word_bool
+ { \@@_print_Numeral:V #1 }
+ { \@@_print_numeral:V #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_@@_original_unit_tl }
}
+\cs_generate_variant:Nn \@@_cutext_print_input_aux:Nn { NV }
% \end{macrocode}
% \end{macro}
%
+% \begin{macro}{\@@_cutext_print_correct_unitname:}
+% As the name suggests, it prints the unitname. At this point we already
+% know that a translation exists, so no bother checking again.
% \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_@@_original_unit_tl \c_@@_postfix_unitname_pl_tl }
+ \bool_if:NTF \l_@@_lokal_numeral_bool
+ { \l_@@_cutext_numeral_space_tl }
+ { \l_@@_cutext_space_tl }
+ \bool_if:NTF \l_@@_cutext_last_amount_equ_one_bool
+ { \@@_culang_print:nV { name } \l_@@_decided_unit_tl }
+ { \@@_culang_print:nV { name-pl } \l_@@_decided_unit_tl }
}
% \end{macrocode}
+% \end{macro}
%
+% \begin{macro}{ \@@_cutext_check_if_translation_available: }
+% Checks if a unitname of the current unit exists. If yes, continue.
+% here we can also decide if the unit should be kept the same or not
+% as we know that we stay in \enquote{cCutext}.
+% If not, change the command to \enquote{cunum}.
% \begin{macrocode}
-\cs_new:Npn \@@_cutext_pre_process_input:NN #1#2
+\cs_new:Npn \@@_cutext_check_if_translation_available:
{
- \@@_change_unit:TF
- { \tl_set_eq:NN \l_@@_tmpb_tl \l_@@_option_unit_tl }
- { \tl_set_eq:NN \l_@@_tmpb_tl \l_@@_original_unit_tl }
- \@@_unitname_get:NxF \l_@@_tmpa_tl \l_@@_tmpb_tl
- {
+ \bool_if:NTF \l_@@_pckopt_cutext_keep_unit_bool
+ { \tl_set_eq:NN \l_@@_curr_unit_tl \l_@@_original_unit_tl }
+ { \tl_set_eq:NN \l_@@_curr_unit_tl \l_@@_decided_unit_tl }
+ \@@_culang_unitname_let:NVTF \l_@@_scrap_tl \l_@@_curr_unit_tl
+ {
+ \bool_if:NT \l_@@_pckopt_cutext_keep_unit_bool
+ {
+ \tl_set_eq:NN \l_@@_decided_unit_tl \l_@@_original_unit_tl
+ \tl_set_eq:NN \l_@@_option_unit_tl \l_@@_original_unit_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:
+ \l_@@_curr_unit_tl
+ \@@_set_cmd_type_to:n { cunum }
+ \@@_decide_unit:
}
}
-% \end{macrocode}
+% \end{macrocode}
+% \end{macro}
%
%
+% \begin{macro}{ \@@_cutext_post_process_input:NN }
+% |#1| is always a number, |#2| only is valid if we have a range.
+% For later, check if either |#1| or |#2| is equal to one.
%
+% Then (Than?) check if a numeral is requested. If yes, |#1| (and if range also |#2|)
+% need to be integers. If they are not, numerals cannot be used. If one or both
+% are integers, if they are below |\l_@@_print_numerals_below_int|.
% \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
+ \@@_if_parse_and_process_type_equal:nTF { range }
+ { \@@_cutext_check_if_amount_single:N #2 }
+ { \@@_cutext_check_if_amount_single:N #1 }
+ \bool_if:NT \l_@@_lokal_numeral_bool
+ {
+ \@@_if_contain_decimals:NNTF #1#2
+ { \bool_set_false:N \l_@@_lokal_numeral_bool }
+ { \@@_check_if_integer_can_be_numerals:NN #1#2 }
}
}
% \end{macrocode}
+% \end{macro}
+% \begin{macro} { \@@_cutext_check_if_amount_single:N }
+% Check if the input is equal to |#1|. Use fp as it is not necessary an integer.
+% Set the boolean according to the result.
% \begin{macrocode}
-\cs_new:Npn \@@_cutext_post_process_input_aux:NN #1#2
+\cs_new:Npn \@@_cutext_check_if_amount_single:N #1
{
- \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 }
+ \fp_compare:nNnTF {#1} = { 1.0 }
+ { \bool_set_true:N } { \bool_set_false:N }
+ \l_@@_cutext_last_amount_equ_one_bool
}
-\cs_new:Npn \@@_cutext_post_process_input_numerals:NN #1#2
+% \end{macrocode}
+% \end{macro}
+% \begin{macro} { \@@_check_if_integer_can_be_numerals:NN }
+% At this point we know that we have integers, so check if they are
+% below |\l_@@_print_numerals_below_int|. If they are, fine. Else,
+% set the boolean to false.
+% \begin{macrocode}
+\cs_new:Npn \@@_check_if_integer_can_be_numerals:NN #1#2
{
- \@@_bool_set_if_integers:NNN \l_@@_tmpa_bool #1 #2
- \bool_if:NTF \l_@@_tmpa_bool
+ \@@_if_parse_and_process_type_equal:nTF { range }
{
- \bool_if:NTF \l_@@_range_in_input_bool
+ \bool_lazy_all:nF
{
- \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 }
+ { \int_compare_p:nNn {#1} < { \l_@@_print_numerals_below_int } }
+ { \int_compare_p:nNn {#2} < { \l_@@_print_numerals_below_int } }
+ { \int_compare_p:nNn {#1} > { 0 } }
+ { \int_compare_p:nNn {#2} > { 0 } }
}
+ { \bool_set_false:N \l_@@_lokal_numeral_bool }
+ }{
+ \bool_lazy_and:nnF
+ { \int_compare_p:nNn {#1} < { \l_@@_print_numerals_below_int } }
+ { \int_compare_p:nNn {#1} > { 0 } }
+ { \bool_set_false:N \l_@@_lokal_numeral_bool }
}
- { \bool_set_false:N \l_@@_lokal_numeral_bool }
}
% \end{macrocode}
+% \end{macro}
%
%
%
@@ -7066,15 +8168,25 @@ and the derived file cooking-units.sty.
%
% \section{cuam}
%
+% \begin{macro}{ \c_@@_no_unit_marker_tl , \@@_if_no_unit_marker:NTF }
+% A marker used for \mycs{cuam}. It essentially tells that no unit is used.
+% Define some commands to avoid some errors and add it to the unit list.
% \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_@@_unit_option_ \c_@@_cuam_marker_tl _clist }
+\tl_const:Nx \c_@@_no_unit_marker_tl { \@@_to_unit:n { @@_no_unit } }
+\prg_new_conditional:Npnn \@@_if_no_unit_marker:N #1 { TF , F }
+ {
+ \tl_if_eq:NNTF \c_@@_no_unit_marker_tl #1
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+\seq_gput_right:NV \g_@@_list_of_defined_units_seq \c_@@_no_unit_marker_tl
+\tl_new:c { l_@@_unit_change_ \c_@@_no_unit_marker_tl _tl }
+\tl_set:cn { l_@@_unit_change_ \c_@@_no_unit_marker_tl _tl } { 1.0 }
+\clist_new:c { l_@@_unit_option_ \c_@@_no_unit_marker_tl _clist }
% \end{macrocode}
%
-% Replaces and extends \mycs{cufrac}.
% \begin{macro}{\cuam}
+% Replaces and extends \mycs{cufrac}. Essentially the same as the other commands.
% \begin{macrocode}
\NewDocumentCommand \cuam { d<> O{} m }
{
@@ -7089,41 +8201,20 @@ and the derived file cooking-units.sty.
% \end{macrocode}
% \end{macro}
%
+% \begin{macro}{\@@_cuam:nnn}
+% Nothing really special happening here. Use |\c_@@_no_unit_marker_tl|
+% to tell the internal thing that we have a valid no-unit-exists case.
% \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}
- \@@_process_and_print_input:
- \@@_print_correct_unit:
- }
+ \@@_set_cmd_type_to:n { cuam }
+ \@@_do_the_stuff:nnnnVn {#1} {#2} {#3} { } \c_@@_no_unit_marker_tl { }
}
% \end{macrocode}
+% \end{macro}
%
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_cuam_initialise:nn #1#2
- {
- \@@_set_process_and_print_for_cuam:
- \tl_set_eq:NN \l_@@_original_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}
+% \begin{macro}{\@@_cuam_post_process_input}
%
-% 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
@@ -7131,53 +8222,59 @@ and the derived file cooking-units.sty.
% 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
+\cs_new_protected:Npn \@@_cuam_post_process_input: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 }
+ \@@_if_contain_decimals:NNTF #1#2
+ { \bool_set_false:N \l_@@_lokal_numeral_bool }
+ {
+ \bool_if:NT \l_@@_pckopt_use_phrases_bool
+ { \@@_cuam_post_process_input_phrases:NN #1#2 }
+ \bool_if:NT \l_@@_lokal_numeral_bool
+ { \@@_check_if_integer_can_be_numerals:NN #1#2 }
+ }
}
% \end{macrocode}
+% \end{macro}
+%\begin{macro}{ \@@_cuam_post_process_input_phrases:NN}
%
-% This command is more or less straightforward. Does a list of phrases exist
+% I really do not like this command, but I still do not have a bette idea
+% how to handle the whole thing.
+%
+% 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
+ \@@_culang_let:nnN { phrase } { phrase-prop } \l_@@_phrase_prop
+ \tl_if_eq:NNT \q_@@_no_translation \l_@@_phrase_prop
+ { \use_none_delimit_by_q_stop:w }
+ \prop_get:NnN \l_@@_phrase_prop { seq } \l_@@_phrase_numbers_seq
+%
+ \@@_cuam_post_process_input_phrases_aux:NNN
+ #1 \l_@@_tmpa_int \l_@@_phrase_number_tl
+ \bool_if:NF \l_@@_lokal_phrase_bool
+ { \use_none_delimit_by_q_stop:w }
+%
+ \@@_if_parse_and_process_type_equal:nTF { range }
{
- \@@_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
- }
- }
+ \bool_if:NT \l_@@_phrase_negative_bool
+ { \use_none_delimit_by_q_stop:w }
+ \@@_cuam_post_process_input_phrases_range:NN
+ #2 \l_@@_tmpb_int
+ \bool_if:NF \l_@@_lokal_phrase_bool
+ { \use_none_delimit_by_q_stop:w }
+ \tl_set:NV #1 \l_@@_tmpa_int
+ \tl_set:NV #2 \l_@@_tmpb_int
+ \@@_cuam_get_phrase_name:NVN
+ \l_@@_phrase_text_tl \l_@@_phrase_number_tl #2
+ }{
+ \tl_set:NV #1 \l_@@_tmpa_int
+ \@@_cuam_get_phrase_name:NVN
+ \l_@@_phrase_text_tl \l_@@_phrase_number_tl #1
}
+ \use_none_delimit_by_q_stop:w \q_stop
}
% \end{macrocode}
% \begin{macrocode}
@@ -7188,15 +8285,16 @@ and the derived file cooking-units.sty.
{
\int_compare:nNnF { \int_abs:n {##1} } > {#1}
{
- \int_compare:nNnTF {##1} < { 0 }
+ \prop_get:NnN \l_@@_phrase_prop { ##1-singlebool } \l_tmpa_tl
+ \int_compare:nNnTF { \l_tmpa_tl } = { 1 }
+ { \bool_set_true:N \l_@@_phrase_negative_bool }
{
- \bool_set_true:N \l_@@_phrase_negative_bool
- \int_set:Nn \l_tmpa_int { 1 }
+ \bool_set_false:N \l_@@_phrase_negative_bool
+ \tl_set:Nf \l_tmpa_tl { \int_div_truncate:nn {#1} {##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_compare:nNnT { \int_abs:n {##1} * \l_tmpa_tl } = {#1}
{
- \int_set_eq:NN #2 \l_tmpa_int
+ \tl_set_eq:NN #2 \l_tmpa_tl
\tl_set:Nn #3 {##1}
\bool_set_true:N \l_@@_lokal_phrase_bool
\seq_map_break:
@@ -7206,8 +8304,11 @@ and the derived file cooking-units.sty.
}
\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:Nn \l_tmpa_int
+ {
+ \int_div_truncate:nn {#1} { \int_abs:n {\l_@@_phrase_number_tl } }
+ }
+ \int_compare:nNnTF { \int_abs:n {\l_@@_phrase_number_tl} * \l_tmpa_int } = {#1}
{
\int_set_eq:NN #2 \l_tmpa_int
\bool_set_true:N \l_@@_lokal_phrase_bool
@@ -7217,78 +8318,114 @@ and the derived file cooking-units.sty.
}
\cs_new:Npn \@@_cuam_get_phrase_name:NnN #1#2#3
{
- \@@_int_if_equal_one:nTF {#3}
+ \int_compare:nNnTF {#3} = { 1 }
{ \prop_get:NnN \l_@@_phrase_prop {#2} #1 }
{ \prop_get:NnN \l_@@_phrase_prop { #2-pl } #1 }
+ \prop_get:NnN \l_@@_phrase_prop { #2-gender } \l_@@_phrase_gender_tl
}
\cs_generate_variant:Nn \@@_cuam_get_phrase_name:NnN { NVN }
% \end{macrocode}
+% \end{macro}
%
%
-% 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{macro}{\@@_cuam_print_numerical_input:N, \@@_cuam_print_numerical_input_aux:Nn, \@@_cuam_print_numerical_input_aux:NV }
+% Printing the numerical input for \mycs{cuam}. If both phrases and numerals
+% are requested, go to the helper macro. Else, just print the numerical input.
+% We need both to be true or else it can happen that numerals are used
+% without anything to follow it up (Instead of \enquote{zwei Dutzend} we simply would
+% have \enquote{zwei}).
% \begin{macrocode}
-\cs_new:Npn \@@_cuam_post_process_input_numerals:NN #1#2
+\cs_new_protected:Npn \@@_cuam_print_numerical_input:N #1
{
- \bool_if:NTF \l_@@_tmpa_bool
+ \bool_lazy_and:nnTF
+ { \l_@@_lokal_phrase_bool }
+ { \l_@@_lokal_numeral_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 }
- }
+ \@@_cuam_print_numerical_input_aux:NV #1\l_@@_phrase_number_tl
}
- { \bool_set_false:N \l_@@_lokal_numeral_bool }
+ { \@@_print_numerical_input:N #1 }
}
% \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.
+% Currently \mycs{cuam} only allows for lowercase numerals.
% \begin{macrocode}
-\cs_new_protected:Npn \@@_cuam_print_numerical_input:N #1
+\cs_new:Npn \@@_cuam_print_numerical_input_aux:Nn #1#2
{
- \bool_lazy_and:nnTF
- { \l_@@_lokal_phrase_bool }
- { \l_@@_lokal_numeral_bool }
+ \int_compare:nNnTF {#1} = { 1 }
{
- \@@_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
+ \@@_culang_one_let_by_gender:NVTF
+ \l_@@_translation_tmpa_tl \l_@@_phrase_gender_tl
+ { \l_@@_translation_tmpa_tl }
+ {
+ \@@_print_numeral:V #1
+ \bool_set_false:N \l_@@_lokal_numeral_bool
}
- { \exp_args:NV \@@_print_numeral:n #1 }
- }{ \@@_print_numerical_input:N #1 }
+ }
+ { \@@_print_numeral:V #1 }
}
+\cs_generate_variant:Nn \@@_cuam_print_numerical_input_aux:Nn { NV }
% \end{macrocode}
+% \end{macro}
%
+% \begin{macro} { \@@_cuam_print_correct_unitphrase: }
+% THis one is thankfully straightforward.
% \begin{macrocode}
\cs_new:Npn \@@_cuam_print_correct_unitphrase:
{
\bool_if:NT \l_@@_lokal_phrase_bool
{
\l_@@_cuphrase_space_tl
- \l_@@_phrase_phrase_tl
+ \l_@@_phrase_text_tl
}
}
% \end{macrocode}
+% \end{macro}
%
%
%
+% \subsection{\mycs{cucomp}}
+%
+%
+% \begin{macrocode}
+%\NewDocumentCommand \cucomp { d<> O{} m m m }
+% {
+% \group_begin:
+% \@@_cucomp:nnnnn {#1} {#2} {#3} {#4} {#5}
+% \group_end:
+% }
+% \end{macrocode}
+% \begin{macrocode}
+%\cs_new:Npn \@@_cucomp:nnnnn #1#2 #3#4#5
+% {
+% \group_begin:
+% \@@_set_cmd_type_to:n { cunum }
+% \@@_do_the_stuff:nnnnnn {#1} {#2} {#3} { } {#4} { }
+% /
+% \@@_do_the_stuff:nnnnnn {#1} {#4=#5} {#3} { } {#4} { }
+% \group_end:
+% }
+% \end{macrocode}
+%
+% \begin{macrocode}
+%\cs_new:Npn \@@_do_cucomp_stuff:nnnnn #1#2 #3#4#5
+% {
+% \group_begin:
+% \@@_set_cmd_to:n { cucomp }
+% \@@_do_the_stuff:nnnnnn {#1} {#2} {#3} { } {#4}
+% \@@_do_the_stuff:nnnnnn {#1} {#2} {#3} { } {#5}
+% \group_end:
+% }
+% \end{macrocode}
+%
+% \begin{macrocode}
+%\cs_new:Npn \@@_new_process_compare_in_input:
+% {
+% \tl_set_eq:NN \l_@@_number_tmpb_tl \l_@@_number_tmpa_tl
+% \tl_set_eq:NN \l_@@_tmpa_unit_tl \l_@@_option_unit_tl
+% \@@_calculate_and_store_in:N \l_@@_number_tmpa_tl
+% \@@_calculate_and_store_in:N \l_@@_number_tmpb_tl
+% \@@_post_process_accordingly:NN \l_@@_number_tmpa_tl \q_no_value
+% }
+% \end{macrocode}
%
%
%
@@ -7296,458 +8433,699 @@ and the derived file cooking-units.sty.
%
% \subsection {Define Keys}
%
-% \begin{macro}{ \cudefinekeys }
+% \begin{macro}{ }
% 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}
- }
+
+%% To be deleted. In order to remove error messages.
+%\newcommand \cudefinekeys {}
+%\newcommand \cudefinesinglekey {}
+%\newcommand \cuaddkeys {}
+%\newcommand \cuaddsinglekeys {}
+%\newcommand \cuaddtokeys {}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{ \cudefinesinglekey }
-% Again, but with the boolean set to true.
+%
+%
+%
+% \begin{macro}{ \cudefinekeys , \cudefinesinglekey }
+% Commands used for defining unit-keys. Their main differences
+% is in setting |\l_@@_single_key_bool| to the respective value
+% and for single-keys to rescan |#2| as it can contain |#1| in its argument.
+%
+% The other stuff is imply a intialization using the unit in |#1| as a base
+% and parsing the rest.
% \begin{macrocode}
+\NewDocumentCommand \cudefinekeys { m m }
+ {
+ \bool_set_false:N \l_@@_single_key_bool
+ \@@_initialice_cukeys_define:n {#1}
+ \@@_cukeys_prepare_parsing_keys:nn {#1} {#2}
+ }
\NewDocumentCommand \cudefinesinglekey { m m }
{
\bool_set_true:N \l_@@_single_key_bool
- \@@_cukeys_define_keys_and_single_keys:nn {#1} {#2}
+ \@@_initialice_cukeys_define:n {#1}
+ \tl_set_rescan:Nno \l_@@_tmpa_tl
+ { \char_set_catcode_letter:N \# } {#2}
+ \@@_cukeys_prepare_parsing_keys:nV {#1} \l_@@_tmpa_tl
}
% \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{macro}{ \@@_initialice_cukeys_define:n }
+% Using |#1| as the base unit for the following keys we set some variables.
+% |\l_@@_tmpa_seq| will contain the parsed units; |\l_@@_tmpb_seq| the values.
+% We also make sure the unit |#1| is defined, else create an error.
+% Also of importance is to set |\l_@@_new_key_base_tl| to $1$. This variable
+% is important while adding keys as it sets the base conversion value so to speak.
% \begin{macrocode}
-\cs_new:Npn \@@_cukeys_define_keys_and_single_keys:nn #1#2
+\cs_new:Npn \@@_initialice_cukeys_define:n #1
{
- \@@_error_if_unit_not_defined:nTF {#1}
- { \bool_set_true:N } { \bool_set_false:N }
- \l_@@_unit_error_bool
- \tl_if_blank:nF {#2}
- {
- \prop_gclear:N \g_@@_master_changer_prop
- \prop_gclear:N \g_@@_convert_to_eV_remember_prop
- \seq_clear:N \l_@@_tmpa_seq
- \prop_clear:N \l_@@_tmpa_prop
- \prop_clear_new:c { l_@@_cukeys_ #1 _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_@@_original_unit_tl {#1}
- \@@_cukeys_parse_and_create_keys:nn {#1}
- {
- {#1} { 1.0 } #2
- }
- }
- }
+ \@@_set_state_to:n { normal }
+ \seq_clear:N \l_@@_tmpa_seq
+ \seq_clear:N \l_@@_tmpb_seq
+ \prop_clear:N \l_@@_tmpa_prop
+ \tl_set:Nn \l_@@_new_key_base_tl { 1 }
+ \@@_error_if_unit_not_defined:nNT {#1} \l_@@_original_unit_tl
+ { \@@_set_state_to:n { error } }
}
% \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{macro}{\cudefinekeychain}
+% The command that is going to replace \mycs{cudefinekeys} and friends
+% (but \emph{not} the single key variants). Nothing going on here.
+% The biggest difference to \mycs{cudefinekeys} is that we do not know
+% the base key by default. Thus we make a short detour to grab the first unit
+% we encounter in |#1| (and its value) and the rest proceeeds as before.
% \begin{macrocode}
-\cs_new:Npn \@@_cukeys_parse_and_create_keys:nn #1#2
+\NewDocumentCommand \cudefinekeychain { m }
{
- \@@_cukeys_parse_input:nn #2
- \q_recursion_tail \q_recursion_tail \q_recursion_stop
- \bool_if:NF \l_@@_unit_error_bool
+ \bool_set_false:N \l_@@_single_key_bool
+ \@@_initialice_cukeychain_define:n {#1}
+ \@@_cukeys_prepare_parsing_keys:n {#1}
+ }
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\@@_initialice_cukeychain_define:n}
+% Initializing the key-chain. First, grab the first unit in |#1|. This needs to
+% be done as the old code expects us to already know a base unit. Here the first
+% unit that is encountered is taken as the base unit. Its value is stored in |\l_@@_base_tl|.
+% This is needed to normalice the values in relation to the base unit. Remember,
+% the base unit is defined to be exactly |1|, thus all further values need to be
+% changed to reflect that. The normalization factor is stored inside |\l_@@_new_key_base_tl|.
+% |\l_@@_curr_unit_tl| is cleared to remind me, that it is not a unit per se
+% (as it is not set \emph{via} |\@@_set_unit:Nn|.
+% \begin{macrocode}
+\cs_new:Npn \@@_initialice_cukeychain_define:n #1
+ {
+ \@@_cukeychain_get_first_unit_aux:nn #1
+ \q_recursion_tail \q_recursion_tail \q_recursion_stop
+ \@@_if_state_equal:nF { error }
{
- \@@_cukeys_create_key_prop:n {#1}
- \clist_set_from_seq:NN \l_@@_tmpa_clist \l_@@_tmpa_seq
- \@@_cukeys_define_keys:V \l_@@_tmpa_clist
+ \exp_args:NV \@@_initialice_cukeys_define:n \l_@@_curr_unit_tl
+ \@@_tl_eval:Nn \l_@@_new_key_base_tl { 1 / (\l_@@_base_tl) }
+ \tl_clear:N \l_@@_curr_unit_tl
}
}
-\cs_generate_variant:Nn \@@_cukeys_parse_and_create_keys:nn { Vn }
% \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{macro}{\@@_cukeychain_get_first_unit_aux:nn}
+% Nothing fancy here. Just grab the first unit and its value.
% \begin{macrocode}
-\cs_new:Npn \@@_cukeys_parse_input:nn #1#2
+\cs_new:Npn \@@_cukeychain_get_first_unit_aux:nn #1#2
{
- \quark_if_recursion_tail_stop:n {#1}
+ \quark_if_recursion_tail_stop_do:nn {#1}
+ { \@@_set_state_to:n { error } }
\quark_if_recursion_tail_stop_do:nn {#2}
- { \msg_error:nn { cooking-units } { missing-argument } }
- \@@_error_if_unit_not_defined:nF {#1}
{
- \seq_if_in:NnF \l_@@_tmpa_seq {#1}
- { \seq_put_right:Nn \l_@@_tmpa_seq {#1} }
- \prop_put:Nnx \l_@@_tmpa_prop {#1} { \fp_eval:n { (#2) * \l_@@_tmpa_fp } }
+ \msg_error:nn { cooking-units } { missing-argument }
+ \@@_set_state_to:n { error }
}
- \@@_cukeys_parse_input:nn
+ \tl_set:Nn \l_@@_curr_unit_tl {#1}
+ \tl_set:Nn \l_@@_base_tl {#2}
+ \use_none_delimit_by_q_recursion_stop:w
+ \@@_cukeychain_get_first_unit_aux: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*}
+% \begin{macro}{ \cuaddkeys , \cuaddtokeys , \cuaddsinglekeys }
+% Thanks to rewriting the code the |add| commands and the |define|
+% commands share a lot of code. The difference is the initialicing, which is a bit
+% different.
+% \begin{macrocode}
+\NewDocumentCommand \cuaddkeys { m m }
+ {
+ \bool_set_false:N \l_@@_single_key_bool
+ \@@_initialice_cukeys_add:n {#1}
+ \@@_cukeys_prepare_parsing_keys:nn {#1} {#2}
+ }
+\NewDocumentCommand \cuaddtokeys { m m m }
+ {
+ \bool_set_false:N \l_@@_single_key_bool
+ \@@_initialice_cukeys_add:n {#1}
+ \tl_set:Nn \l_@@_tmpa_tl { {#2} { \fp_eval:n { 1.0 / (#3) } } }
+ \@@_cukeys_prepare_parsing_keys:nV {#1} \l_@@_tmpa_tl
+ }
+\NewDocumentCommand \cuaddsinglekeys { m m }
+ {
+ \bool_set_true:N \l_@@_single_key_bool
+ \@@_initialice_cukeys_add:n {#1}
+ \tl_set_rescan:Nno \l_@@_tmpa_tl
+ { \char_set_catcode_letter:N \# } {#2}
+ \@@_cukeys_prepare_parsing_keys:nV {#1} \l_@@_tmpa_tl
+ }
+% \end{macrocode}
+% \end{macro}
%
-% Same for \myunit{g}:
+% \begin{macro}{ \@@_initialice_cukeys_add:n }
+% This one is quite different compared to |\@@_initialice_cukeys_define:n| as it
+% needs a bit more stuff to do.
%
-% \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*}
+% The beginning is checking if |#1| exists and later if |#1| is a key at all.
+% If it not a key already we cannot add keys, in either case print an error and
+% go to the end.
%
-% and \myunit{oz}
+% If the checks passed without error we go to the \enquote{retrieving} step.
+% As we are adding (potentially) new keys to existing ones we need to retrive
+% the values we stored and got during the definition of keys.
%
-% \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*}
+% First, get the |\l_@@_original_unit_tl|. This one is the unit given in the first argument
+% of either |cudefinekeys| or |\cudefinesinglekey|. It is the base unit
+% for those keys. Afterwards retrieve the other values. Get the property list
+% which stores the unit-value pairs, get the list of units we can transform the unit to
+% and -- to make sure -- make sure a single key is only added to a single key and vice versa.
%
+% Afterwards, this cs is done.
% \begin{macrocode}
-\cs_new:Npn \@@_cukeys_create_key_prop:n #1
+\cs_new:Npn \@@_initialice_cukeys_add:n #1
{
- \prop_set_eq:cN { l_@@_cukeys_ #1 _prop } \l_@@_tmpa_prop
- \prop_put:cnV { l_@@_cukeys_ #1 _prop } { Liste } \l_@@_tmpa_seq
- \seq_map_inline:Nn \l_@@_tmpa_seq
- {
- \tl_set_eq:cN { l_@@_base_key_unit_ ##1 _tl } \l_@@_original_unit_tl
- \tl_set:cn { l_@@_unit_change_ ##1 _tl } { 1.0 }
+ \seq_clear:N \l_@@_tmpa_seq
+ \seq_clear:N \l_@@_tmpb_seq
+ \@@_set_state_to:n { normal }
+ \@@_error_if_unit_not_defined:nNT {#1} \l_@@_curr_unit_tl
+ {
+ \@@_set_state_to:n { error }
+ \use_none_delimit_by_q_stop:w
+ }
+ \@@_if_unit_has_a_key:nF {#1}
+ {
+ \msg_error:nnx { cooking-units } { Key-not-defined } \l_@@_curr_unit_tl
+ \@@_set_state_to:n { error }
+ \use_none_delimit_by_q_stop:w
+ }
+ \tl_set_eq:Nc \l_@@_original_unit_tl { l_@@_base_key_unit_ \l_@@_curr_unit_tl _tl }
+ \prop_set_eq:Nc \l_@@_tmpa_prop { l_@@_new_cukeys_ \l_@@_original_unit_tl _prop }
+ \prop_get:NnN \l_@@_tmpa_prop {#1} \l_@@_new_key_base_tl
+ \prop_get:NnN \l_@@_tmpa_prop { Liste } \l_@@_tmpa_seq
+ \prop_get:NnN \l_@@_tmpa_prop { single } \l_@@_tmpa_tl
+ \int_compare:nNnF { \l_@@_single_key_bool } = { \l_@@_tmpa_tl }
+ {
+ \msg_error:nn { cooking-units } { Adding-single-to-multi-key-or-vice-verca }
+ \@@_set_state_to:n { error }
}
+ \use_none_delimit_by_q_stop:w \q_stop
}
+\cs_generate_variant:Nn \@@_initialice_cukeys_add:n { V }
% \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{macro}{\cuaddtokeychain}
+% This command is going to replace \mycs{cuaddkeys} and \mycs{cuaddtokeys}.
+% It is similar to \mycs{cudefinekeychain}. Just with some more hoops before the keys
+% can be defined.
% \begin{macrocode}
-\cs_new:Npn \@@_cukeys_define_keys:n #1
+\NewDocumentCommand \cuaddtokeychain { m }
{
- \seq_map_inline:Nn \l_@@_tmpa_seq
- {
- \@@_cukeys_keys_define:nn {##1} {#1}
- }
+ \bool_set_false:N \l_@@_single_key_bool
+ \@@_initialice_cukeys_keychain_add:n {#1}
+ \@@_cukeys_prepare_parsing_keys:n {#1}
}
-\cs_new:Npn \@@_cukeys_keys_define:nn #1#2
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_initialice_cukeys_keychain_add:n}
+% Initiliazing the key-chain. Like \mycs{cudefinekeychain} we first need to get
+% the base unit. Afterwards, the \enquote{normal} initialization command is used
+% (with the found base key) and |\l_@@_new_key_base_tl| is normalized.
+% \begin{macrocode}
+\cs_new:Npn \@@_initialice_cukeys_keychain_add:n #1
{
- \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 }
+ \@@_cukeys_keychain_get_first_valid_unit:n {#1}
+ \@@_if_state_equal:nF { error }
{
- #1 .choices:nn =
- {#2}
- {
- \@@_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_msg:N \l_tmpa_seq }
- } ,
- #1 .default:n = {#1} ,
- #1 .groups:n = { change-unit }
+ \@@_initialice_cukeys_add:V \l_@@_curr_unit_tl
+ \@@_tl_eval:Nn \l_@@_new_key_base_tl { (\l_@@_new_key_base_tl) / (\l_@@_base_tl) }
}
}
-\cs_generate_variant:Nn \@@_cukeys_define_keys:n { V }
% \end{macrocode}
% \end{macro}
+% \begin{macro}{\@@_cukeys_keychain_get_first_valid_unit:n
+% , \@@_cukeys_keychain_get_first_valid_unit_aux:nn
+% }
%
-% \begin{macro}{\@@_cukeys_define_keys_and_single_key_aux:n}
-%^^A <<
+% Just a wrapper for the loop.
% \begin{macrocode}
-\prg_new_conditional:Npnn \@@_prop_get_master:nnN #1#2#3 { F }
- {
- \prop_get:NnNTF \g_@@_master_changer_prop { #1 ~->~ #2 } #3
- { \prg_return_true: }
- { \prg_return_false: }
- }
-\cs_generate_variant:Nn \@@_prop_get_master:nnNF { nVc }
-%
-\cs_new:Npn \@@_prop_gput_master:nnn #1#2#3
+\cs_new:Npn \@@_cukeys_keychain_get_first_valid_unit:n #1
{
- \prop_gput:Nnn \g_@@_master_changer_prop { #1 ~->~ #2 } {#3}
+ \@@_cukeys_keychain_get_first_valid_unit_aux:nn #1
+ \q_recursion_tail \q_recursion_tail \q_recursion_stop
}
-\cs_generate_variant:Nn \@@_prop_gput_master:nnn { nVV, nVv }
-%
-\cs_new:Npn \@@_cukeys_define_keys_and_single_key_aux:n #1
+% \end{macrocode}
+% Finding the base unit is a bit more complex than just taking the first
+% one found, but not by much. The idea is simple: Loop through the units
+% till one is found that has an existing key. This allows the user to set the
+% new unit(s) first in the loop and the base unit at last place (or an arbitrary place).
+% We set this unit to be the |\l_@@_original_unit_tl| and its value as |\l_@@_base_tl|
+% (not evaluated at this place). If a unit is found, break the loop.
+% \begin{macrocode}
+\cs_new:Npn \@@_cukeys_keychain_get_first_valid_unit_aux:nn #1#2
{
- \@@_prop_get_master:nVcF {#1} \l_keys_choice_tl { l_@@_unit_change_ #1_tl }
+ \quark_if_recursion_tail_stop_do:nn {#1}
{
- \prop_if_exist:cTF { l_@@_cukeys_ #1 _prop }
- {
- \prop_get:cVc
- { l_@@_cukeys_ #1 _prop }
- \l_keys_choice_tl
- { l_@@_unit_change_ #1_tl }
- \@@_prop_gput_master:nVv {#1} \l_keys_choice_tl { l_@@_unit_change_ #1_tl }
- }{
- \tl_set_eq:Nc \l_@@_tmpa_tl { l_@@_base_key_unit_ #1 _tl }
- \prop_set_eq:Nc \l_@@_tmpa_prop { l_@@_cukeys_ \l_@@_tmpa_tl _prop }
- \@@_tl_eval:Nn \l_@@_tmpb_tl
- {
- (\exp_args:NNV\prop_item:Nn \l_@@_tmpa_prop \l_keys_choice_tl) /
- (\prop_item:Nn \l_@@_tmpa_prop {#1})
- }
- \@@_prop_gput_master:nVV {#1} \l_keys_choice_tl \l_@@_tmpb_tl
- \tl_set:cV { l_@@_unit_change_ #1 _tl } \l_@@_tmpb_tl
- }
+ \msg_error:nn { cooking-units } { Key-chain-unit-not-found }
+ \@@_set_state_to:n { error }
}
- \prop_put:NnV \l_@@_change_unit_prop {#1} \l_keys_choice_tl
+ \quark_if_recursion_tail_stop_do:nn {#2}
+ {
+ \msg_error:nn { cooking-units } { missing-argument }
+ \@@_set_state_to:n { error }
+ }
+ \@@_if_unit_has_a_key:nT {#1}
+ {
+ \@@_error_if_unit_not_defined:nNT {#1} \l_@@_curr_unit_tl
+ { \@@_set_state_to:n { error } }
+ \tl_set_eq:NN \l_@@_original_unit_tl \l_@@_curr_unit_tl
+ \tl_set:Nn \l_@@_base_tl {#2}
+ \use_none_delimit_by_q_recursion_stop:w
+ }
+ \@@_cukeys_keychain_get_first_valid_unit_aux:nn
}
% \end{macrocode}
% \end{macro}
%
%
+%
+%
+%
+% \begin{macro}{ \@@_cukeys_prepare_parsing_keys:n
+% , \@@_cukeys_prepare_parsing_keys:nn
+% }
+% Just a wrapper. |#1| is the base unit and thus defined to be |1|.
% \begin{macrocode}
-\cs_new:Npn \@@_cukeys_parse_and_create_single_key:nn #1#2
+\cs_new:Npn \@@_cukeys_prepare_parsing_keys: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
- \bool_if:NF \l_@@_unit_error_bool
+ \@@_cukeys_prepare_parsing_keys:n { {#1} { 1.0 } #2 }
+ }
+% After initialising the variables we go to this command.
+% At first it seperates the input in |#1| into unit-value pairs via |\@@_cukeys_parse_keys|.
+% If no error happened, we go to the definition of keys.
+%
+% As we add new keys and potentially change the values of old ones we need
+% to globally clear |\g_@@_master_changer_prop|.
+\cs_new:Npn \@@_cukeys_prepare_parsing_keys:n #1
+ {
+ \@@_cukeys_parse_keys:n {#1}
+ \bool_lazy_or:nnF
+ { \int_compare_p:nNn \l_@@_nr_of_units_int = 0 }
+ { \@@_if_state_equal_p:n { error } }
{
- \@@_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
+ \prop_gclear:N \g_@@_master_changer_prop
+ \@@_cukeys_prepare_lists:N \l_@@_original_unit_tl
+ \@@_new_cukeys_create_keys:V \l_@@_original_unit_tl
}
}
+\cs_generate_variant:Nn \@@_cukeys_prepare_parsing_keys:nn { nV }
% \end{macrocode}
+% \end{macro}
%
+% \begin{macro}{ \@@_cukeys_parse_keys:nn , \@@_cukeys_parse_keys_aux:nn}
+% Seperates the input into key-value pairs. This cs doesn't do much as the main
+% stuff is done in |\@@_cukeys_parse_keys_aux:nn|.
% \begin{macrocode}
-\cs_new:Npn \@@_cusinglekeys_parse_input:n #1
+\cs_new:Npn \@@_cukeys_parse_keys:n #1
{
- \@@_cusinglekeys_parse_input_aux:nn #1
- \q_recursion_tail \q_recursion_tail \q_recursion_stop
+ \int_zero:N \l_@@_nr_of_units_int
+ \@@_cukeys_parse_keys_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
+% \end{macrocode}
+%
+% Note for the beginning:
+% Keys used for definining (#1) are converted into strings!
+% No need to keep catcodes. Just string everything!
+%
+% This command does a lot. The first is the stopping condition, then two
+% checks for error messages. Either a \enquote{missing-argument} or a \enquote{unit
+% not defined} thingy.
+%
+% The value is stored in |\l_@@_tmpb_tl|. Afterwards check if a |##1| is found inside.
+% If it is, replace |##1| by |\l_@@_tmpa_fp|. So we do not store a command with an
+% argument, but rather a formula with a variable inside, which we can set.
+% If on ther other side it contains a |##1|, but is not a single key, we raise an error.
+%
+% Afterwards -- if nor error -- we calculate the value in |\l_@@_tmpb_tl| if we have no
+% single key. Here |\l_@@_new_key_base_tl| comes into play. The idea is the following:
+% the base key is \enquote{kg} with \enquote{1}, furthermore we have the key
+% \enquote{dag} with value \enquote{100}. Now we add \enquote{g} to \enquote{dag}
+% with \enquote{10} ($1$ dag equals 10 g). In order to have the correct relation betwen
+% the base key \enquote{kg} and \enquote{g}, we set |\l_@@_new_key_base_tl| during
+% the initialization to \enquote{100}. Then the relation between \enquote{kg} and
+% \enquote{g} is correct with \enquote{(10)*100=1000}.
+%
+% Add the unit to the list of units; add the unit-value to the propery-list.
+% \begin{macrocode}
+\cs_new:Npn \@@_cukeys_parse_keys_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:nF {#1}
+ {
+ \msg_error:nn { cooking-units } { missing-argument }
+ \@@_set_state_to:n { error }
+ }
+ \@@_error_if_unit_not_defined:nNT {#1} \l_@@_option_unit_tl
+ { \@@_set_state_to:n { error } }
+%
+ \tl_set:Nn \l_@@_tmpb_tl {#2}
+ \tl_if_in:NVT \l_@@_tmpb_tl \g_@@_input_str_hash_one_tl
+ {
+ \bool_if:NTF \l_@@_single_key_bool
+ { \tl_replace_all:NVn \l_@@_tmpb_tl \g_@@_input_str_hash_one_tl { \l_@@_tmpa_fp } }
+ {
+ \msg_error:nnx { cooking-units } { formula-in-non-singlekeys } \l_@@_tmpb_tl
+ \@@_set_state_to:n { error }
+ }
+ }
+ \@@_if_state_equal:nF { error }
{
- \seq_if_in:NnF \l_@@_tmpa_seq {#1}
- { \seq_put_right:Nn \l_@@_tmpa_seq {#1} }
- \tl_set:Nn \l_@@_tmpa_tl {#2}
- \tl_replace_all:NVn \l_@@_tmpa_tl \g_@@_input_str_hash_one_tl { \l_@@_tmpa_fp }
- \prop_put:NnV \l_@@_tmpa_prop {#1} \l_@@_tmpa_tl
+ \int_incr:N \l_@@_nr_of_units_int
+ \bool_if:NF \l_@@_single_key_bool
+ { \@@_tl_eval:Nn \l_@@_tmpb_tl { (\l_@@_tmpb_tl) * (\l_@@_new_key_base_tl) } }
+ \seq_if_in:NVF \l_@@_tmpa_seq \l_@@_option_unit_tl
+ { \seq_put_right:NV \l_@@_tmpa_seq \l_@@_option_unit_tl }
+ \prop_put:NnV \l_@@_tmpa_prop {#1} \l_@@_tmpb_tl
}
- \@@_cusinglekeys_parse_input_aux:nn
+ \@@_cukeys_parse_keys_aux:nn
}
% \end{macrocode}
+% \end{macro}
%
-% \begin{macrocode}
-\cs_new:Npn \@@_cusinglekeys_create_key_prop:n #1
- {
- \tl_set:cn { l_@@_unit_change_ #1 _tl } { 1.0 }
- \tl_set:cn { l_@@_base_key_unit_ #1 _tl } {#1}
- \prop_set_eq:cN { l_@@_cukeys_ #1 _prop } \l_@@_tmpa_prop
- \prop_put:cnV { l_@@_cukeys_ #1 _prop } { Liste } \l_@@_tmpa_seq
+% \begin{macro}{ \@@_cukeys_prepare_lists:N }
+% At this point we can assume everything to be correct.
+% |#1| the main unit aka.\ the \enquote{original unit} or \enquote{base unit}.
+%
+% First we clear/create new the property list which will contains the conversion values for
+% for each unit. There we will safe the the values we collected in the last step,
+% the list of units in this set and if the key is single or not.
+%
+% For simplification, each unit in the key-list always points to the \enquote{base unit},
+% so \enquote{g}, \enquote{kg}, \enquote{dag}, etc.\ will all show to \enquote{kg}.
+% This is not needed if we have a single-key (due to how single-keys work).
+% Furhtermore, if no single-key, set the default transformation value to \enquote{1};
+% not sure if the last step is necessary, but eh.
+% \begin{macrocode}
+\cs_new:Npn \@@_cukeys_prepare_lists:N #1
+ {
+ \prop_clear_new:c { l_@@_new_cukeys_ #1 _prop }
+ \prop_set_eq:cN { l_@@_new_cukeys_ #1 _prop } \l_@@_tmpa_prop
+ \prop_put:cnV { l_@@_new_cukeys_ #1 _prop } { Liste } \l_@@_tmpa_seq
+ \prop_put:cnV { l_@@_new_cukeys_ #1 _prop } { single } \l_@@_single_key_bool
+ \tl_set:cn { l_@@_unit_change_ #1 _tl } { 1 }
+ \tl_set_eq:cN { l_@@_base_key_unit_ #1 _tl } #1
+ \bool_if:NF \l_@@_single_key_bool
+ {
+ \seq_map_inline:Nn \l_@@_tmpa_seq
+ {
+ \tl_set_eq:cN { l_@@_base_key_unit_ ##1 _tl } #1
+ \tl_set:cn { l_@@_unit_change_ ##1 _tl } { 1 }
+ }
+ }
}
% \end{macrocode}
+% \end{macro}
%
+% \begin{macro}{ \@@_new_cukeys_create_keys:n , \@@_new_cukeys_create_keys:V }
+% Here we start creating the keys. If seperate into two cases:
+% Do we have a single-key or not. If yes, just create the key |#1|
+% and do what needs to be done. If not, we need to create a bunch of
+% keys for each unit in the list.
% \begin{macrocode}
-\cs_new:Npn \@@_cukeys_define_singlekey:nn #1#2
+\cs_new:Npn \@@_new_cukeys_create_keys:n #1
{
- \@@_cukeys_keys_define:nn {#1} {#2}
+% % #1: original_unit
+ \clist_set_from_seq:NN \l_@@_tmpa_clist \l_@@_tmpa_seq
+ \bool_if:NTF \l_@@_single_key_bool
+ {
+ \@@_new_cukeys_define_key:nVn
+ {#1} \l_@@_tmpa_clist {#1}
+ }{
+ \seq_map_inline:Nn \l_@@_tmpa_seq
+ {
+ \@@_new_cukeys_define_key:nVn
+ {##1} \l_@@_tmpa_clist {#1}
+ }
+ }
}
-\cs_generate_variant:Nn \@@_cukeys_define_singlekey:nn { nV }
+\cs_generate_variant:Nn \@@_new_cukeys_create_keys:n { V }
% \end{macrocode}
+% \end{macro}
%
+% \begin{macro}{ \@@_new_cukeys_define_key:nnn , \@@_new_cukeys_define_key:nVn }
+% Now we define some key(s). |#1| is the unit and key-to-be-defined.
+% As |#1| is not expanded, this can contain control sequences, etc. not need for worry
+% here.
%
-% \section {Adding Keys}
+% We define the key |#1| with a list of choices |#2| (which is the list of units
+% collected in the parse step). |#3| plays an important role as it is the
+% \enquote{base unit}. We mainly need this to do some shortcuts later on.
+% So instead of getting the the base unit for \enquote{g} \emph{via}
+% |l_@@_base_key_unit_g_tl| (which would be \enquote{kg}), we give \enquote{kg}
+% directly as the argument |#3|. It was made sure that |#3| \emph{not} a
+% control sequence, but text.
%
+% In order to remind the user which choices each key have, define an error
+% message for unknown keys.
% \begin{macrocode}
-\NewDocumentCommand \cuaddkeys { m m }
+\cs_new:Npn \@@_new_cukeys_define_key:nnn #1#2#3
{
- \bool_set_false:N \l_@@_single_key_bool
- \@@_cukeys_add_keys_or_single_keys:nn {#1} {#2}
+ \@@_if_unit_has_a_key:nF {#1}
+ { \seq_put_right:Nn \l_@@_list_of_defined_keys_seq {#1} }
+ \keys_define:nn { cooking-units }
+ {
+ #1 .choices:nn =
+ {#2}
+ { \@@_change_unit_from_to:nVn {#1} \l_keys_choice_tl {#3} } ,
+ #1 / unknown .code:n=
+ {
+ \seq_set_split:Nnn \l_tmpa_seq { , } {#2}
+ \msg_error:nnxxx
+ { cooking-units }
+ { key-choice-unknown }
+ {#1}
+ {##1}
+ { \@@_seq_use_msg:N \l_tmpa_seq }
+ } ,
+ #1 .default:n = {#1} ,
+ #1 .groups:n = { change-unit }
+ }
}
+\cs_generate_variant:Nn \@@_new_cukeys_define_key:nnn { nVn }
% \end{macrocode}
+% \end{macro}
%
-% \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{macro}{ \@@_change_unit_from_to:nnn }
+% Our main \enquote{get the conversion value} command.
+% |#1| is the current unit, |#2| is the unit it is converted into,
+% |#3| is the \enquote{base unit}, given in order to make some shortcuts.
%
+% |\l_@@_change_unit_prop| stores which unit should be converted into which by
+% a key-value list. If the unit is later used we restore the value from this property list.
+%
+% Now to the calculation. |\g_@@_master_changer_prop| stores the the conversion values
+% globally in a | <old-unit> ~->~ <new-unit>| way. If we already have a conversion
+% from |#1| to |#2| we simply restore this value and store it in |l_@@_unit_change_ #1_tl|.
+%
+% If the unit-change is requested for the first time we need to calculate the
+% conversion value first. Afterwards, store it (globally) into |\g_@@_master_changer_prop|
+% to not recalculate it in the future.
% \begin{macrocode}
-\NewDocumentCommand \cuaddtokeys { m m m }
+\cs_new:Npn \@@_change_unit_from_to:nnn #1#2#3
{
- \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
+ \prop_put:Nnn \l_@@_change_unit_prop {#1} {#2}
+ \prop_get:NncF
+ \g_@@_master_changer_prop
+ { #1 ~->~ #2 }
+ { l_@@_unit_change_ #1_tl }
+ {
+ \@@_cukeys_calculate_change_value:nnn {#1} {#2} {#3}
+ \prop_gput:Nnv \g_@@_master_changer_prop
+ { #1 ~->~ #2 }
+ { l_@@_unit_change_ #1 _tl }
+ }
}
+\cs_generate_variant:Nn \@@_change_unit_from_to:nnn { nVn }
% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{ \@@_cukeys_calculate_change_value:nnn }
+% Great, an unit-change is requested for the first time, thus calculate
+% the conversion value.
%
+% First we check if the old unit |#1| is the same as the \enquote{base unit}
+% |#3|. This is a nice shortcut, as the property list is stored with |#3| as a base,
+% so direct retrival of the value is possible in this case.
%
+% If |#1| and |#3| are different, we need to do some work. First, get the list
+% of key-values |l_@@_new_cukeys_ #3 _prop| and store it in |\l_@@_tmpa_prop|.
+% Now eval.
%
+% Having unit |a| and wanting unit |b|, we need the value to go from |a| to |b|
+% which is done by the realtion $|b|/|a|$. This is checked easily as $|a|*|b|/|a|=|b|$.
+% Replace this by |#1| and |#2| and we get: |#2|=|#1|*|#2|/|#1|, which we
+% evaluate and store in |l_@@_unit_change_ #1 _tl|.
% \begin{macrocode}
-\cs_new:Npn \@@_cukeys_add_keys_or_single_keys:nn #1#2
+\cs_new:Npn \@@_cukeys_calculate_change_value:nnn #1 #2 #3
{
- \@@_error_if_unit_not_defined:nF {#1}
+ \str_if_eq:nnTF {#1} {#3}
{
- \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}
+ \prop_get:cnc { l_@@_new_cukeys_ #1 _prop } {#2} { l_@@_unit_change_ #1 _tl }
+ }{
+ \prop_set_eq:Nc \l_@@_tmpa_prop { l_@@_new_cukeys_ #3 _prop }
+ \@@_tl_eval:cn { l_@@_unit_change_ #1 _tl }
{
- \prop_gclear:N \g_@@_master_changer_prop
- \@@_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:Vn \l_@@_original_unit_tl {#2} }
+ ( \prop_item:Nn \l_@@_tmpa_prop {#2} ) /
+ ( \prop_item:Nn \l_@@_tmpa_prop {#1} )
}
}
}
-\cs_generate_variant:Nn \@@_cukeys_add_keys_or_single_keys:nn { nV }
+\cs_generate_variant:Nn \@@_cukeys_calculate_change_value:nnn { VVV }
% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%
+%
+%
+%
+%
+%
+%
+%
+%
%
-%^^A ((((
-% Now this does the following: 1) get the \enquote{original unit} (the unit used
-% in the first argument of |\cudefinekeys|) 2) Get the list of units already in the
-% list (It is important that the units are alway in the same order and one cannot
-% rely on the order of the property-lists 3) Get the property list of the
-% \enquote{original unit}. In the old code I simply stored the whole property list inside
-% another property list, but this shouldn't be done this way. So \dots\ simply
-% copy the original one. 4) As there is a unit added the unit it is added to
-% might not be the \enquote{original unit}. As such we need the conversion factor.
-% \begin{macrocode}
-\cs_new:Npn \@@_cukeys_add_keys_and_single_key_aux:n #1
- {
- \tl_set_eq:Nc \l_@@_original_unit_tl { l_@@_base_key_unit_ #1 _tl }
- \prop_set_eq:Nc \l_@@_tmpa_prop { l_@@_cukeys_ \l_@@_original_unit_tl _prop }
- \prop_get:NnN\l_@@_tmpa_prop { Liste } \l_@@_tmpa_seq
- \prop_get:NnN \l_@@_tmpa_prop {#1} \l_@@_tmpa_fp
- }
-% \end{macrocode}
%
%
% \section {Creating New Units}
%
%
%\begin{macro}{ \declarecookingunit , \newcookingunit , \providecookingunit }
+% Defining new units. Defining an unit is split into two parts: defining
+% the necassary tl's and clist's and seq's; and setting them. Depending on which
+% command is used, things are handled differently.
+%
+% We always make sure that the unit |#1| is first converted into a string.
% \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}
+ \@@_if_unit_defined:nNTF {#2} \l_@@_original_unit_tl
+ { \msg_info:nnx { cooking-units } { redefine-unit } { \l_@@_original_unit_tl } }
+ { \@@_new_cooking_unit:V \l_@@_original_unit_tl }
+ \@@_set_cooking_unit:nnV {#1} {#2} \l_@@_original_unit_tl
}
\NewDocumentCommand \newcookingunit { o m }
{
- \@@_new_cooking_unit:nn {#1} {#2}
- \@@_set_cooking_unit:nn {#1} {#2}
+ \@@_if_unit_defined:nNTF {#2} \l_@@_original_unit_tl
+ { \msg_error:nnV { cooking-units } { unit-already-defined } \l_@@_original_unit_tl }
+ {
+ \@@_new_cooking_unit:V \l_@@_original_unit_tl
+ \@@_set_cooking_unit:nnV {#1} {#2} \l_@@_original_unit_tl
+ }
}
\NewDocumentCommand \providecookingunit { o m }
{
- \seq_if_in:NnF \g_@@_list_of_defined_units_seq {#2}
+ \@@_if_unit_defined:nNT {#2} \l_@@_original_unit_tl
{
- \@@_new_cooking_unit:nn {#1} {#2}
- \@@_set_cooking_unit:nn {#1} {#2}
+ \@@_new_cooking_unit:V \l_@@_original_unit_tl
+ \@@_set_cooking_unit:nnV {#1} {#2} \l_@@_original_unit_tl
}
}
% \end{macrocode}
%\end{macro}
%
+%\begin{macro}{ \@@_new_cooking_unit:n }
+% Creates the token and other lists for the unit |#1| (which at this point is a string).
+% Nothing really expectional here.
% \begin{macrocode}
-\cs_new:Npn \@@_new_cooking_unit:nn #1#2
+\cs_new:Npn \@@_new_cooking_unit:n #1
{
- \seq_if_in:NnTF \g_@@_list_of_defined_units_seq {#2}
- { \msg_error:nnn { cooking-units } { unit-already-defined } {#2} }
+ \tl_map_inline:nn {#1}
{
- \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_gput_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_@@_unit_option_ #2 _clist }
- \keys_define:nn { cooking-units }
- {
- set-option-for-#2 .code:n = { \cusetoptionfor {#2} {##1} } ,
- add-option-for-#2 .code:n = { \cuaddoptionfor {#2} {##1} },
- }
- \tl_new:c { l_@@_base_key_unit_ #2 _tl }
- \tl_new:c { l_@@_default_unit_ #2 _tl }
+ \tl_if_in:NnT \l_@@_unit_letter_not_allowed_tl {##1}
+ { \msg_error:nnn { cooking-units } { character-not-allowed } {#1} }
+ }
+ \seq_gput_right:Nn \g_@@_list_of_defined_units_seq {#1}
+ \tl_new:c { l_@@_unit_change_ #1 _tl }
+ \tl_new:c { l_@@_base_key_unit_ #1 _tl }
+ \tl_new:c { l_@@_default_unit_ #1 _tl }
+ \clist_new:c { l_@@_unit_option_ #1 _clist }
+ \tl_set:cn { l_@@_unit_change_ #1 _tl } { 1 }
+ \keys_define:nn { cooking-units }
+ {
+ set-unit-hook-#1 .code:n = { \@@_set_options_for:nn {#1} {##1} } ,
+ add-unit-hook-#1 .code:n = { \@@_add_options_for:nn {#1} {##1} },
+ set-option-for-#1 .meta:n = { set-unit-hook-#1 = {##1} } ,
+ add-option-for-#1 .meta:n = { add-unit-hook-#1 = {##1} } ,
}
}
-\cs_new:Npn \@@_set_cooking_unit:nn #1#2
+\cs_generate_variant:Nn \@@_new_cooking_unit:n { V }
+% \end{macrocode}
+% \end{macro}
+%
+%\begin{macro}{ \@@_set_cooking_unit:nnn , \@@_set_cooking_unit:nnV }
+% Here we set the in the last step defined lists to their respective value.
+% |#3| is the unit-string; |#2| is the unit given by the user (as it can be a command
+% like |/%]; |#1| is either the wanted unit-symbol \emph{or} a key-val
+% list. Depending on that, we either set the printed symbol to |#1| or parse the
+% key-val list.
+%
+% This is done in a three step procedure (if |#1| is a value): First, check if
+% the head of |#1| is a group. This happens if the user embraces |#1| in two
+% curly brace pairs (e.g.\ |{{Test}}|). This is only needed if the user really wants
+% the symbol to contain |=|.
+%
+% If |#1| is not protected by braces it is parsed as key(s)
+% \begin{macrocode}
+\cs_new:Npn \@@_set_cooking_unit:nnn #1#2#3
{
- \IfNoValueTF {#1}
+ \@@_set_cooking_unit_base_translation:n {#3}
+ \bool_set_false:N \l_@@_symbol_was_set_by_key_bool
+ \bool_set_false:N \l_@@_contains_valid_key_bool
+ \IfNoValueF {#1}
+ {
+ \tl_if_head_is_group:nF {#1}
+ { \keys_set:nn { cooking-units / definition } {#1} }
+ }
+ \bool_if:NF \l_@@_symbol_was_set_by_key_bool
{
- \tl_set:cn { l_@@_default_unit_ #2 _tl } {#2}
- \@@_deftranslation_base:xVn {#2} \c_@@_postfix_unit_tl {#2}
- }{
- \tl_set:cn { l_@@_default_unit_ #2 _tl } {#1}
- \@@_deftranslation_base:xVn {#2} \c_@@_postfix_unit_tl {#1}
+ \IfNoValueTF {#1}
+ { \tl_set:cn { l_@@_default_unit_ #3 _tl } {#2} }
+ {
+ \bool_if:NTF \l_@@_contains_valid_key_bool
+ { \tl_set:cn { l_@@_default_unit_ #3 _tl } {#2} }
+ { \tl_set:cn { l_@@_default_unit_ #3 _tl } {#1} }
+ }
}
- \@@_deftranslation_base:xVn {#2} \c_@@_postfix_unitname_tl { \q_@@_no_translation }
- \@@_deftranslation_base:xVn {#2} \c_@@_postfix_unitname_pl_tl { \q_@@_no_translation }
- \@@_deftranslation_base:xVn {#2} \c_@@_postfix_gender_tl { m }
+ \@@_culang_def_base:nnv { unit-symbol } {#3} { l_@@_default_unit_ #3 _tl }
}
+\cs_generate_variant:Nn \@@_set_cooking_unit:nnn { nnV }
% \end{macrocode}
+% \end{macro}
%
+%\begin{macro}{ \@@_set_cooking_unit_base_translation:n }
+% Just an auxilary command. Sets the base translations to their default value.
+% \begin{macrocode}
+\cs_new:Npn \@@_set_cooking_unit_base_translation:n #1
+ {
+ \@@_culang_def_base:nnn { name } {#1} \q_@@_no_translation
+ \@@_culang_def_base:nnn { name-pl } {#1} \q_@@_no_translation
+ \@@_culang_def_base:nnn { gender } {#1} { m }
+ }
+% \end{macrocode}
+% \end{macro}
+%
%
%
% \begin{macro}{\declarecookingderivatives}
@@ -7767,149 +9145,229 @@ and the derived file cooking-units.sty.
% \end{macrocode}
% \end{macro}
%
-% The idea is the following. The relation between the units are given as
-% |(#1)/(#2)| (e.g.). The idea is the following:
-% \begin{enumerate}
-% \item The derivative contains two units.
-% \item The mathematical relationship is given by |(#1)/(#2)|
-% \item Define |\@@_tmp:w| to be |(#1)/(#2)|.
-% \item Parse through all values and store them in a list (e.g. |\l_tmpa_t|) as | {value-1}{value-2} |
-% \item Use |\exp_after:wN \@@_tmp:w \l_tmpa_t | to expand to |\@@_tmp:w {value-1} {value-2} |
-% \item Let |\@@_tmp:w| do its job.
-% \end{enumerate}
%
-% \begin{macro}{\@@_tl_set_list:Nnn, \@@_tl_set_list:NnV, \@@_tl_set_list:NVV, \@@_tl_set_list_aux:Nnnnnnnnn }
-% The following argument creates the list. I am a bit lazy here and don't quite know how
-% to do it \enquote{correctly}. And I know, there are too many |\q_nil|.
-% \begin{macrocode}
-\cs_new:Npn \@@_tl_set_list:Nnn #1#2#3
- {
- \@@_tl_set_list_aux:Nnnnnnnnn #1 {#2} #3
- \q_nil \q_nil \q_nil \q_nil \q_nil \q_nil \q_nil \q_nil \q_nil
- \q_recursion_stop
- }
-\cs_generate_variant:Nn \@@_tl_set_list:Nnn { NnV, NVV }
-\cs_new:Npn \@@_tl_set_list_aux:Nnnnnnnnn #1#2#3#4#5#6#7#8#9
- {
- \tl_set:Nf #1
- {
- \int_case:nn { \l_@@_curr_depth_int }
- {
- { 1 } { }
- { 2 } { {#3} }
- { 3 } { {#3}{#4} }
- { 4 } { {#3}{#4}{#5} }
- { 5 } { {#3}{#4}{#5}{#6} }
- { 6 } { {#3}{#4}{#5}{#6}{#7} }
- { 7 } { {#3}{#4}{#5}{#6}{#7}{#8} }
- { 8 } { {#3}{#4}{#5}{#6}{#7}{#8}{#9} }
- }
- {#2}
- }
- \use_none_delimit_by_q_recursion_stop:w
- }
-% \end{macrocode}
-% \end{macro}
% \begin{macro} { \@@_declare_cooking_derivative:nnnn }
% This command has the following parts:
% \begin{enumerate}
-% \item Get list of units in |#1|, count their number and store in |\l_@@_max_depth_int|
+% \item Get list of units in |#1|, check if they are defined,
+% count their number and store in |\l_@@_nr_of_units_int|
% \item Use |\cs_generate_from_arg_count:NNnn| to create the commands
-% \item Define lists |l_@@_tmp_ 1 ... \l_@@_max_depth_int |, same for prop. I know
-% that there is a better way to do it, but this \emph{is} experimental. In the end, it
-% safes a bit of brain-power for me.
-% \item The main part: Map trough all units in the |l_@@_cukeys_ <unit> _prop| lists.
-% \item Create key-porperty and define keys.
+% that store the final parsed unit-keys, unit-symbols und unit-formulas inside.
+% \item Prepare for the following loop.
+% \item The main part: Do the loop.
+% \item Declare keys and store their formula relation into a property-list.
+% \item Clean up.
% \end{enumerate}
% \begin{macrocode}
\cs_new:Npn \@@_declare_cooking_derivative:nnnn #1#2#3#4
{
- \prop_gclear:N \g_@@_master_changer_prop
- \seq_set_from_clist:Nn \l_@@_tmpa_seq {#1}
- \seq_clear:N \l_@@_number_of_iterations_seq
- \seq_clear:N \l_@@_derivative_unit_list_seq
- \seq_clear:N \l_@@_derivative_symbol_list_seq
- \seq_clear:N \l_@@_derivative_value_list_seq
- \int_set:Nn \l_@@_max_depth_int { \seq_count:N \l_@@_tmpa_seq }
- \int_set:Nn \l_@@_curr_depth_int { 1 }
+ \seq_clear:N \l_@@_list_of_units_seq
+ \@@_set_state_to:n { normal }
+ \clist_map_inline:nn {#1}
+ {
+ \@@_if_unit_defined:nNTF {##1} \l_@@_tmpa_tl
+ {
+ \@@_if_unit_has_a_key:VTF \l_@@_tmpa_tl
+ { \seq_put_right:NV \l_@@_list_of_units_seq \l_@@_tmpa_tl }
+ {
+ \tl_show:n { Error-no-key-defined } {##1}
+ \@@_set_state_to:n { error }
+ }
+ } { \@@_set_state_to:n { error } }
+ }
+ \@@_if_state_equal:nT { error }
+ { \use_none_delimit_by_q_recursion_stop:w }
+ \int_set:Nn \l_@@_nr_of_units_int { \seq_count:N \l_@@_list_of_units_seq }
+% \end{macrocode}
+% Now we generate the functions. The first takes the unit-keys and plugs it into
+% the formula |#2| (unit-key) and |#4| (unit-symbol).
+% The second function get's the nummerical values and stores it in a sequcence.
+% Example: \\
+% Assuming |kg|, |m| and |s| with unit key |#1*#2-#3|, formula |#1*#2/#3|
+% and symbol |#1\,\sfrac{#2}{#3}|. Looping through the units, the first
+% function creates |kg*m-s|, |kg*m-min|, \dots, |oz*in-h|; and |kg\,\sfrac{m}{s}|,
+% \dots, |oz\,\sfrac{in}{h}|.
+%
+% The second function creates their nummerical relation: for |kg|, |m| and |s|
+% this would be |1*1/86400|. |kg|, |in|, |s| would be |1*(36/0.9144)/86400|.
+% If we then transform the first ones |kg*m-s| into the second one |kg*in-s|
+% we will later calculate $ \frac{1*(36/0.9144)/86400}{1*1/86400} $ which will get
+% us the correct transformation. May explanation my not be very good,
+% but it makes sense (later).
+% \begin{macrocode}
+ \cs_generate_from_arg_count:NNnn \@@_create_unit:w \cs_set:Npn
+ { \l_@@_nr_of_units_int }
+ {
+ \seq_gpush:Nn \g_@@_stored_derived_unit_symbol_seq {#2}
+ \seq_gpush:Nn \g_@@_stored_derived_unit_print_seq {#4}
+ }
+ \cs_generate_from_arg_count:NNnn \@@_create_formula:w \cs_set:Npn
+ { \l_@@_nr_of_units_int }
+ {
+ \seq_gpush:Nn \g_@@_stored_derived_formula_seq {#3}
+ }
% \end{macrocode}
+% Preparing and startidoingng the loop.
% \begin{macrocode}
- \cs_generate_from_arg_count:NNnn \@@_tmp_unit_and_symbol_list:w \cs_set:Npn
- { \l_@@_max_depth_int }
- {
- \seq_put_right:Nn \l_@@_derivative_unit_list_seq {#2}
- \seq_put_right:Nn \l_@@_derivative_symbol_list_seq {#4}
- }
- \cs_generate_from_arg_count:NNnn \@@_tmp_value_list:w \cs_set:Npn
- { \l_@@_max_depth_int }
- { \seq_put_right:Nx \l_@@_derivative_value_list_seq { \fp_eval:n {#3} } }
+ \@@_prepare_sequence_loop:
+ \@@_step_loop_start:n { }
% \end{macrocode}
+% Now we create new cooking-units with the unit-keys and unit-symbols
+% we created \emph{via} loop. As we need a \enquote{master unit} we use
+% the most right unit in the derived unit list. This is because the most right one
+% is created by the other base units.
% \begin{macrocode}
- \int_step_inline:nn { \l_@@_max_depth_int }
- {
- \tl_set_eq:Nc \l_@@_original_unit_tl
- { l_@@_base_key_unit_ \seq_item:Nn \l_@@_tmpa_seq {##1} _tl }
- \prop_set_eq:Nc \l_@@_tmpa_prop { l_@@_cukeys_ \l_@@_original_unit_tl _prop }
- \prop_get:NnN \l_@@_tmpa_prop { Liste } \l_@@_tmpb_seq
- \int_set:Nn \l_@@_tmpa_int { \seq_count:N \l_@@_tmpb_seq }
-% \end{macrocode}
-% \begin{macrocode}
- \seq_put_right:NV \l_@@_number_of_iterations_seq \l_@@_tmpa_int
- \seq_clear_new:c { l_@@_tmp_ ##1 _seq }
- \prop_clear_new:c { l_@@_tmp_ ##1 _prop }
- \seq_set_eq:cN { l_@@_tmp_ ##1 _seq } \l_@@_tmpb_seq
- \prop_set_eq:cN { l_@@_tmp_ ##1 _prop } \l_@@_tmpa_prop
- }
+ \seq_get_right:NN \g_@@_stored_derived_unit_symbol_seq \l_@@_curr_unit_tl
+ \seq_map_inline:Nn \g_@@_stored_derived_unit_symbol_seq
+ {
+ \seq_pop:NN \g_@@_stored_derived_formula_seq \l_@@_tmpb_tl
+ \prop_put:NnV \l_@@_derived_units_prop {##1} \l_@@_tmpb_tl
+ \seq_pop:NN \g_@@_stored_derived_unit_print_seq \l_@@_tmpa_tl
% \end{macrocode}
+% First create the unit, \emph{then} set the reference to the base unit.
+% (Else it is not yet defined)
% \begin{macrocode}
- \seq_map_function:cN
- { l_@@_tmp_ \int_use:N \l_@@_curr_depth_int _seq }
- \@@_seq_step_function:n
+ \exp_args:NNx \declarecookingunit [ {symbol={\l_@@_tmpa_tl}} ] {##1}
+ \tl_set_eq:cN { l_@@_base_key_unit_ ##1 _tl } \l_@@_curr_unit_tl
+ }
% \end{macrocode}
+% Clean-up. Do not know if this is necessary, but eh.
% \begin{macrocode}
- \seq_get_left:NN \l_@@_derivative_unit_list_seq \l_@@_original_unit_tl
- \prop_clear_new:c { l_@@_cukeys_ \l_@@_original_unit_tl _prop }
+ \seq_gclear:N \g_@@_stored_derived_unit_symbol_seq
+ \seq_gclear:N \g_@@_stored_derived_unit_print_seq
+ \seq_gclear:N \g_@@_stored_derived_formula_seq
+ \cs_undefine:N \@@_create_unit:w
+ \cs_undefine:N \@@_create_formula:w
% \end{macrocode}
+% If we had an error beforehand, we would jump to this place ignoring everything
+% inbetween.
% \begin{macrocode}
- \int_zero:N \l_@@_tmpa_int
- \clist_set_from_seq:NN \l_@@_tmpa_clist \l_@@_derivative_unit_list_seq
- \seq_map_inline:Nn \l_@@_derivative_unit_list_seq
- {
- \int_incr:N \l_@@_tmpa_int
- \tl_set:Nx \l_@@_tmpa_tl { \seq_item:Nn \l_@@_derivative_symbol_list_seq { \l_@@_tmpa_int } }
- \exp_after:wN \declarecookingunit \exp_after:wN [ \l_@@_tmpa_tl ] {##1}
- \prop_put:cnx
- { l_@@_cukeys_ \l_@@_original_unit_tl _prop }
- {##1}
- { \seq_item:Nn \l_@@_derivative_value_list_seq { \l_@@_tmpa_int } }
- \tl_clear_new:c { l_@@_base_key_unit_ ##1 _tl }
- \tl_set_eq:cN { l_@@_base_key_unit_ ##1 _tl } \l_@@_original_unit_tl
- \exp_args:NnV \@@_cukeys_keys_define:nn {##1} \l_@@_tmpa_clist
- }
+ \use_none_delimit_by_q_recursion_stop:w
+ \q_recursion_stop
}
% \end{macrocode}
% \end{macro}
%
+% \begin{macro} { \@@_declare_cooking_derivative:nnnn }
% \begin{macrocode}
-\cs_new:Npn \@@_seq_step_function:n #1
- {
- \@@_tl_set_list:NnV \l_@@_list_of_units_tl {#1} \l_@@_list_of_units_tl
- \prop_get:cnN { l_@@_tmp_ \int_use:N \l_@@_curr_depth_int _prop } {#1} \l_@@_tmpa_tl
- \@@_tl_set_list:NVV \l_@@_list_of_values_tl \l_@@_tmpa_tl \l_@@_list_of_values_tl
- \int_compare:nNnTF { \l_@@_curr_depth_int } = { \l_@@_max_depth_int }
+\cs_new:Npn \@@_prepare_sequence_loop:
+ {
+ \seq_map_indexed_inline:Nn \l_@@_list_of_units_seq
{
- \exp_after:wN \@@_tmp_unit_and_symbol_list:w \l_@@_list_of_units_tl
- \exp_after:wN \@@_tmp_value_list:w \l_@@_list_of_values_tl
+ \prop_clear_new:c { l_@@_keys_ ##1 _prop }
+ \seq_clear_new:c { l_@@_list_ ##1 _seq }
+ \tl_set_eq:Nc \l_@@_curr_unit_tl { l_@@_base_key_unit_ ##2 _tl }
+ \prop_set_eq:cc { l_@@_keys_ ##1 _prop }
+ { l_@@_new_cukeys_ \l_@@_curr_unit_tl _prop }
+ \prop_get:cnc { l_@@_keys_ ##1 _prop } { Liste } { l_@@_list_ ##1 _seq }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro} { \@@_declare_cooking_derivative:nnnn }
+% \begin{macrocode}
+\cs_new:Npn \@@_step_loop_start:n #1
+ {
+ \tl_clear:N \l_@@_stored_units_tl
+ \tl_clear:N \l_@@_stored_formula_tl
+ \int_set:Nn \l_@@_depth_int { 1 }
+ \seq_map_function:cN
+ { l_@@_list_ \int_use:N \l_@@_depth_int _seq } \@@_seq_recursive_loop_function:n
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro} { \@@_declare_cooking_derivative:nnnn }
+% \begin{macrocode}
+\cs_new:Npn \@@_seq_recursive_loop_function:n #1
+ {
+ \group_begin:
+ \tl_put_right:Nn \l_@@_stored_units_tl { {#1} }
+ \tl_set_eq:Nc \l_@@_original_unit_tl { l_@@_base_key_unit_ #1 _tl }
+ \tl_put_right:Nx \l_@@_stored_formula_tl
+ { { (
+ \exp_not:N \prop_item:Nn
+ \exp_not:c { l_@@_new_cukeys_ \l_@@_original_unit_tl _prop } {#1}
+ ) } }
+ \int_compare:nNnTF { \l_@@_depth_int } = { \l_@@_nr_of_units_int }
+ {
+ \exp_after:wN \@@_create_unit:w \l_@@_stored_units_tl
+ \exp_after:wN \@@_create_formula:w \l_@@_stored_formula_tl
}{
- \int_incr:N \l_@@_curr_depth_int
+ \int_incr:N \l_@@_depth_int
\seq_map_function:cN
- { l_@@_tmp_ \int_use:N \l_@@_curr_depth_int _seq }
- \@@_seq_step_function:n
- \int_decr:N \l_@@_curr_depth_int
+ { l_@@_list_ \int_use:N \l_@@_depth_int _seq } \@@_seq_recursive_loop_function:n
}
+ \group_end:
}
% \end{macrocode}
+% \end{macro}
%
+% \begin{macro} { \@@_declare_cooking_derivative:nnnn }
+% \begin{macrocode}
+\keys_define:nn { cooking-units }
+ {
+ unknown .code:n =
+ {
+ \@@_if_key_ais_derived_unit:VTF \l_keys_key_str
+ { \@@_convert_derived_unit:Vn \l_keys_key_str {#1} }
+ {
+ \msg_error:nnxx { cooking-units } { key-unknown }
+ { \l_keys_path_str } { cooking-units }
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro} { \@@_declare_cooking_derivative:nnnn }
+% \begin{macrocode}
+\prg_new_conditional:Npnn \@@_if_key_ais_derived_unit:n #1 { TF }
+ {
+ \tl_if_exist:cTF { l_@@_base_key_unit_ #1 _tl }
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+\cs_generate_variant:Nn \@@_if_key_ais_derived_unit:nTF { V }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro} { \@@_declare_cooking_derivative:nnnn }
+% The idea is the following. The relation between the units are given as
+% |(#1)/(#2)| (e.g.). The idea is the following:
+% \begin{enumerate}
+% \item The derivative contains two units.
+% \item The mathematical relationship is given by |(#1)/(#2)|
+% \item Define |\@@_tmp:w| to be |(#1)/(#2)|.
+% \item Parse through all values and store them in a list (e.g. |\l_tmpa_t|) as | {value-1}{value-2} |
+% \item Use |\exp_after:wN \@@_tmp:w \l_tmpa_t | to expand to |\@@_tmp:w {value-1} {value-2} |
+% \item Let |\@@_tmp:w| do its job.
+% \end{enumerate}
+% \begin{macrocode}
+\cs_new:Npn \@@_convert_derived_unit:nn #1#2
+ {
+ \tl_if_eq:ccTF
+ { l_@@_base_key_unit_ #1 _tl }
+ { l_@@_base_key_unit_ #2 _tl }
+ {
+ \prop_get:NnN \l_@@_derived_units_prop {#1} \l_@@_tmpa_tl
+ \prop_get:NnN \l_@@_derived_units_prop {#2} \l_@@_tmpb_tl
+ \prop_put:Nnn \l_@@_change_unit_prop {#1} {#2}
+ \@@_tl_eval:cn { l_@@_unit_change_ #1 _tl }
+ {
+ (\l_@@_tmpb_tl) / (\l_@@_tmpa_tl)
+ }
+ \prop_gput:Nnv \g_@@_master_changer_prop
+ { #1 ~->~ #2 }
+ { l_@@_unit_change_ #1 _tl }
+ }{
+ \msg_error:nnnn { cooking-units } { key-no-knows-value } {#1} {#2}
+ }
+ }
+\cs_generate_variant:Nn \@@_convert_derived_unit:nn { V }
+% \end{macrocode}
+% \end{macro}
%
%
%
@@ -7985,116 +9443,159 @@ and the derived file cooking-units.sty.
% \end{macrocode}
%
%
+% \begin{macro}{\cudefinename}
+% This command allows to (re)define \enquote{names} for units to be used
+% in \cCutext\ for given language. We need to sanitize the arrows (|<| and |>|)
+% in case they are active. Afterwards, parse through the list.
% \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
+ \exp_after:wN
+ \@@_parse_definename_start_cycle: \l_@@_sanitise_tl
+ \q_recursion_tail \q_recursion_tail \q_recursion_stop
}
% \end{macrocode}
+% \end{macro}
%
-%
+% \begin{macro}{\@@_parse_definename_start_cycle:}
+% Initializes the parse cycle. Set state to \enquote{normal} and clear some variables.
+% Start by grabbing the first argument which is the unit.
% \begin{macrocode}
-\cs_new:Npn \@@_cuname_parse_input:n #1
+\cs_new:Npn \@@_parse_definename_start_cycle:
+ {
+ \@@_set_state_to:n { normal }
+ \tl_clear:N \l_@@_curr_unit_tl
+ \prop_clear:N \l_@@_tmpa_prop
+ \bool_set_false:N \l_@@_tmpa_bool
+ \@@_parse_definename_unit:n
+ }
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{ \@@_parse_definename_unit:n }
+% Grab the unit. This can be either an actual unit (defined by |\newcookingunit| and Co.)
+% or it is one of the allowed \enquote{special-keys} like \enquote{decimal-marker},
+% etc. In case neither of those two is found, issue an error, but continue parsing
+% to catch more errors.
+%
+% The next optional argument is the unit-symbol, which can also be set by this
+% command. If it is not found, grab the next mandatory argument, which is the
+% unit-name.
+% \begin{macrocode}
+\cs_new:Npn \@@_parse_definename_unit:n #1
{
- \peek_meaning_ignore_spaces:NTF [
+ \quark_if_recursion_tail_stop:n {#1}
+ \seq_if_in:NnTF \g_@@_allowed_special_keys_seq {#1}
{
- \@@_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 ] }
+ \@@_set_unit:Nn \l_@@_curr_unit_tl {#1}
+ \bool_set_true:N \l_@@_tmpa_bool
+ }{
+ \@@_error_if_unit_not_defined:nNT {#1} \l_@@_curr_unit_tl
+ { \@@_set_state_to:n { error } }
}
+ \peek_meaning_ignore_spaces:NTF [
+ { \@@_parse_definename_optional_unitsymbol:w }
+ { \@@_parse_definename_singular:n }
}
% \end{macrocode}
+% \end{macro}
%
+% \begin{macro}{ \@@_parse_definename_optional_unitsymbol:w }
+% The frst optional argument has be found; it is thus the unit-symbol.
+% Changing the unit-symbol is only allowed for actual units, so no \enquote{special-keys}
+% allowed. If we have an unit, store it into |\l_@@_tmpa_prop|.
% \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:nT {#1}
- { \use_none_delimit_by_q_recursion_stop:w }
- \quark_if_no_value:nTF {#2}
+\cs_new:Npn \@@_parse_definename_optional_unitsymbol:w [#1]
+ {
+ \bool_if:NTF \l_@@_tmpa_bool
{
- \@@_deftranslation_to:VxVv
- \l_@@_language_tl {#1}
- \c_@@_postfix_unit_tl
- { l_@@_default_unit_ #1 _tl }
- }{
- \@@_deftranslation_to:VxVn
- \l_@@_language_tl {#1}
- \c_@@_postfix_unit_tl {#2}
+ \@@_set_state_to:n { error }
+ \msg_error:nnxn { cooking-units } { symbol-and-special-keys-error }
+ \l_@@_curr_unit_tl {#1}
}
- \@@_cuname_parse_input_aux:nn {#1}
+ { \prop_put:Nnn \l_@@_tmpa_prop { unit-symbol } {#1} }
+ \@@_parse_definename_singular:n
}
% \end{macrocode}
+% \end{macro}
%
-%
+% \begin{macro}{ \@@_parse_definename_singular:n }
+% Parses the \enquote{name} of the unit (or special key).
+% Do an error check, store the input in the property list and go to the
+% next one, which is the plural form. The next (optional) argument is
+% the plural form of the \enquote{name}. If there is none, also use |#1| for plural.
% \begin{macrocode}
-\cs_new:Npn \@@_cuname_parse_input_aux:nn #1#2
+\cs_new:Npn \@@_parse_definename_singular:n #1
{
- \quark_if_recursion_tail_stop:n {#1}
- \quark_if_recursion_tail_stop_do:nn {#2}
+ \quark_if_recursion_tail_stop_do:nn {#1}
{ \msg_error:nn { cooking-units } { missing-argument } }
- \seq_if_in:NnF \g_@@_allowed_special_keys_seq {#1}
- {
- \@@_error_if_unit_not_defined:nT {#1}
- { \use_none_delimit_by_q_recursion_stop:w }
- }
- \@@_deftranslation_to:VxVn
- \l_@@_language_tl {#1}
- \c_@@_postfix_unitname_tl {#2}
+ \prop_put:Nnn \l_@@_tmpa_prop { name } {#1}
\peek_meaning_ignore_spaces:NTF [
- { \@@_cuname_parse_bracket:nw {#1} }
- { \@@_cuname_parse_bracket:nw {#1} [#2] }
+ { \@@_parse_definename_optional_plural:w }
+ { \@@_parse_definename_optional_plural:w [#1] }
}
% \end{macrocode}
+% \end{macro}
%
+% \begin{macro}{ \@@_parse_definename_optional_plural:w }
+% Nothing new here. The next one is the gender. If no gender is found
+% I assume it to be male \enquote{m}.
% \begin{macrocode}
-\cs_new:Npn \@@_cuname_parse_bracket:nw #1 [#2]
+\cs_new:Npn \@@_parse_definename_optional_plural:w [#1]
{
- \seq_if_in:NnF \g_@@_allowed_special_keys_seq {#1}
- {
- \@@_deftranslation_to:VxVn \l_@@_language_tl {#1}
- \c_@@_postfix_unitname_pl_tl {#2}
- }
+ \prop_put:Nnn \l_@@_tmpa_prop { name-pl } {#1}
\peek_meaning_ignore_spaces:NTF <
- { \@@_cuname_parse_gender:nw {#1} }
- { \@@_cuname_parse_gender:nw {#1} <m> }
+ { \@@_parse_definename_optional_gender:w }
+ { \@@_parse_definename_optional_gender:w <m> }
}
% \end{macrocode}
+% \end{macro}
%
+% \begin{macro}{ \@@_parse_definename_optional_plural:w }
+% Check if the gender is correct. Then store it in the property-list
+% and finish the cycle.
% \begin{macrocode}
-\cs_new:Npn \@@_cuname_parse_gender:nw #1 <#2>
+\cs_new:Npn \@@_parse_definename_optional_gender:w <#1>
{
-% \@@_check_if_correct_gender_input:n {#2}
-% \@@_deftranslation_to:VxVn
-% \l_@@_language_tl {#1}
-% \c_@@_postfix_gender_tl {#2}
- \@@_if_gender_error:nTF {#2}
- {
- \@@_deftranslation_to:VxVn
- \l_@@_language_tl {#1}
- \c_@@_postfix_gender_tl { m }
- }{
- \@@_deftranslation_to:VxVn
- \l_@@_language_tl {#1}
- \c_@@_postfix_gender_tl {#2}
- }
- \@@_cuname_parse_input:n
+ \@@_if_gender_error:nT {#1}
+ { \@@_set_state_to:n { error } }
+ \prop_put:Nnn \l_@@_tmpa_prop { gender } {#1}
+ \@@_parse_name_finish_cycle_and_start_new:VV
+ \l_@@_language_tl \l_@@_curr_unit_tl
}
% \end{macrocode}
+% \end{macro}
%
+% \begin{macro}{ \@@_parse_name_finish_cycle_and_start_new:nn }
+% Now it makes sense why we used property list before.
+% Each unit has some basic definitions for each language (see |\newcookingunit| and Co.):
+% \enquote{unit-symbol}, \enquote{name}, \enquote{name\_pl} and \enquote{gender}.
%
+% So going through the property list (where we stored the given values)
+% we set for the given language and unit those definitions (\enquote{unit-symbol} only
+% if found).
%
-% \subsection {cudefinesymbol}
+% Afterwards, start the next cycle.
+% \begin{macrocode}
+\cs_new:Npn \@@_parse_name_finish_cycle_and_start_new:nn #1#2
+ {
+ \@@_if_state_equal:nT { normal }
+ {
+ \prop_map_inline:Nn \l_@@_tmpa_prop
+ { \@@_culang_def_for:nnnn {#1} {##1} {#2} {##2} }
+ }
+ \@@_parse_definename_start_cycle:
+ }
+\cs_generate_variant:Nn \@@_parse_name_finish_cycle_and_start_new:nn { VV }
+% \end{macrocode}
+% \end{macro}
%
+% \subsection {cudefinesymbol}
%
+% \begin{macro}{ \cudefinesymbol }
+% A small and rather straightforward command.
+% No special sanitizing here, just setting the language and parsing.
% \begin{macrocode}
\NewDocumentCommand \cudefinesymbol { m m }
{
@@ -8103,7 +9604,13 @@ and the derived file cooking-units.sty.
\q_recursion_tail \q_recursion_tail \q_recursion_stop
}
% \end{macrocode}
+% \end{macro}
%
+% \begin{macro}{ \@@_cuprint_define_printed_unit:nn }
+% Sets the symbol for given units or \enquote{special keys}.
+% Nothing extraordinary is done here. We we have an unit we
+% set its \enquote{unit-symbol} for given language, for an \enquote{special key}
+% we set its name. Rinse and repeat.
% \begin{macrocode}
\cs_new:Npn \@@_cuprint_define_printed_unit:nn #1#2
{
@@ -8111,167 +9618,264 @@ and the derived file cooking-units.sty.
\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}
+ { \@@_culang_def_for:Vnnn \l_@@_language_tl { name } }
{
- \@@_deftranslation_to:VxVn \l_@@_language_tl {#1}
- \c_@@_postfix_unitname_tl {#2}
- }{
- \@@_error_if_unit_not_defined:nF {#1}
- {
- \@@_deftranslation_to:VxVn
- \l_@@_language_tl {#1}
- \c_@@_postfix_unit_tl {#2}
- }
+ \@@_error_if_unit_not_defined:nTF {#1}
+ { \use_none:nn }
+ { \@@_culang_def_for:Vnnn \l_@@_language_tl { unit-symbol } }
}
+ {#1} {#2}
\@@_cuprint_define_printed_unit:nn
}
% \end{macrocode}
-%
+% \end{macro}
%
%
% \subsection {Phrases}
%
%
-% \begin{macrocode}
-\@@_newtranslation_base:nVn { phrase-prop } \c_@@_postfix_phrase_tl { \q_@@_no_translation }
-% \end{macrocode}
%
+% \begin{macro}{ \@@_cuprint_define_printed_unit:nn }
+% Defining phrases. Phrases (sadly) depend on the language.
+% The idea is going to be: Each language has its own property list
+% which is going to be stored for each language. Later, the property
+% list is recoverd for the language currently used. If no phrase is defined
+% the fallback |\q_@@_no_translation| is returned.
% \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:
- }
- }
+\@@_culang_def_base:nnn { phrase } { phrase-prop } { \q_@@_no_translation }
% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{ \cudefinephrase }
+% Defining some phrases. This command is just a wrapper for the
+% subcommand.
% \begin{macrocode}
\NewDocumentCommand \cudefinephrase { m m }
{
- \@@_cuphrase:nn {#1} {#2}
+ \@@_new_cuphrase_add: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}
+% \end{macro}
+%
+% \begin{macro}{ \@@_new_cuphrase_add:nn }
+% |#1| is the language, |#2| is something to be parsed.
+% I am also not quite happy with this construction, but it works.
+%
+% First, check if we already have existing phrases for the language.
+% If so, recover it, we add the parsed one to them. Else, clear
+% some variables.
+%
+% Next step, sanitize |<| and |>|. I hate this so much.
+%
+% Using |\@@_parse_phrase:V| we parse through the argument |#2|.
+% The results are added to |\l_@@_phrase_prop| and |\l_@@_phrase_numbers_seq|.
+%
+% By our rules, we prefer big numbers over small ones. For example,
+% 120 can be translated into \enquote{2 Schocks} ($2\times60$) or
+% \enquote{10 Dutzend} ($10\times12$). We prefer the bigger number first,
+% so we will always get \enquote{2 Schocks}. Thus we sort the numbers in the
+% sequence from highest to lowest. We also have negative numbers (phrases only
+% used for one specific number). We prefer the negative over the positive ones
+% if possible.
+%
+% Then store the variables and thats it.
% \begin{macrocode}
+\cs_new:Npn \@@_new_cuphrase_add:nn #1#2
+ {
+ \tl_set:Nn \l_@@_language_tl {#1}
+ \@@_culang_if_translation_exists_for:VnnTF \l_@@_language_tl
+ { phrase } { phrase-prop }
+ {
+ \@@_culang_let_for:VnnN \l_@@_language_tl { phrase } { phrase-prop }
+ \l_@@_phrase_prop
+ \prop_get:NnN \l_@@_phrase_prop { seq } \l_@@_phrase_numbers_seq
+ }{
+ \prop_clear:N \l_@@_phrase_prop
+ \seq_clear:N \l_@@_phrase_numbers_seq
+ }
\@@_sanitize_arrows:n {#2}
- \exp_last_unbraced:NV
- \@@_cuphrase_parse:n \l_@@_sanitise_tl
- \q_recursion_tail \q_recursion_tail \q_recursion_stop
+ \@@_parse_phrase:V \l_@@_sanitise_tl
+ \@@_new_cuphrase_sort_sequence:N \l_@@_phrase_numbers_seq
+ \prop_put:NnV \l_@@_phrase_prop { seq } \l_@@_phrase_numbers_seq
+ \@@_culang_def_for:VnnV
+ \l_@@_language_tl { phrase } { phrase-prop } \l_@@_phrase_prop
+ }
% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{ \@@_parse_phrase:n }
+% Wrapper around the parsing cycles. Nothing new.
% \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: }
- }
- }
+\cs_new:Npn \@@_parse_phrase:n #1
+ {
+ \@@_parse_phrase_start_cycle: #1
+ \q_recursion_tail \q_recursion_tail \q_recursion_stop
+ }
+\cs_generate_variant:Nn \@@_parse_phrase:n { V }
% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{ \@@_parse_phrase_start_cycle: }
+% Starts the parsing cycle. Clear some variables, set state to normal.
% \begin{macrocode}
- \@@_deftranslation_to:VxVV
- \l_@@_language_tl { phrase-prop }
- \c_@@_postfix_phrase_tl
- \l_@@_phrase_prop
- \@@_deftranslation_to:VxVV
- \l_@@_language_tl { phrase-clist }
- \c_@@_postfix_phrase_tl \l_@@_phrase_numbers_seq
- }
+\cs_new:Npn \@@_parse_phrase_start_cycle:
+ {
+ \@@_set_state_to:n { normal }
+ \bool_set_false:N \l_@@_tmpa_bool
+ \tl_clear:N \l_@@_curr_unit_tl
+ \prop_clear:N \l_@@_tmpa_prop
+ \@@_parse_stuff_mandatories_plus_star:nn
+ }
% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{ \@@_parse_stuff_mandatories_plus_star:nn }
+% Now. We have two cases: two mandatroy arguments following each other
+% (number plus phrase) \emph{or} number plus star plus phrase (so three arguments).
+% In order to not need explicetly test for the star I do the following:
+% Just grab the first two things. |#1| is always the number. |#2| can either be
+% the star |*| \emph{or} a phrase. If it is a star, set a boolean, and restart the command
+% with |#1| already given.
%
+% Then check if |#2| is a number (with a primitve test). Star-numbers are stored
+% negatively. This makes defining a property list easier for me.
%
+% Note that the key in the first |\l_@@_tmpa_prop| is empty. This is done
+% in order to not screw up the later |\prop_map_inline| loop. We also store
+% if the phrase is only used for one number (aka.\ if there is a star).
+%
+% Then, parse the optionals.
% \begin{macrocode}
-\cs_new:Npn \@@_cuphrase_parse:n #1
+\cs_new:Npn \@@_parse_stuff_mandatories_plus_star:nn #1#2
{
\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 *
+ \quark_if_recursion_tail_stop_do:nn {#2}
+ { \msg_error:nn { cooking-units } { missing-argument } }
+ \str_if_eq:nnTF {#2} { * }
{
- \int_set:Nn \l_@@_tmpa_int {-#1}
- \@@_cuphrase_parse_normal:Vn \l_@@_tmpa_int
+ \bool_set_true:N \l_@@_tmpa_bool
+ \@@_parse_stuff_mandatories_plus_star:nn {#1}
}{
- \int_set:Nn \l_@@_tmpa_int {#1}
- \@@_cuphrase_parse_normal:Vn \l_@@_tmpa_int
+ \@@_if_evaluation_is_integer:nTF {#1}
+ {
+ \int_set:Nn \l_@@_tmpa_int {#1}
+ \tl_set:NV \l_@@_curr_unit_tl \l_@@_tmpa_int
+ \bool_if:NT \l_@@_tmpa_bool
+ { \tl_put_left:Nn \l_@@_curr_unit_tl { - } }
+ }{
+ \@@_set_state_to:n { error }
+ \msg_error:nnn { cooking-units} { phrase-unit-not-an-integer } {#1}
+ }
+ \prop_put:Nnn \l_@@_tmpa_prop { } {#2}
+ \prop_put:NnV \l_@@_tmpa_prop { - singlebool } \l_@@_tmpa_bool
+ \@@_parse_phrase_optionals:n {#2}
}
}
% \end{macrocode}
+% \end{macro}
%
+% \begin{macro}{ \@@_parse_phrase_optionals:n }
+% Get the plural form of the phrase. If the next token is an open bracket,
+% get the plural form, else set the plural form equal to the singular form.
% \begin{macrocode}
-\cs_new:Npn \@@_cuphrase_parse_normal:nn #1#2
+\cs_new:Npn \@@_parse_phrase_optionals:n #1
{
- \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]
- }
+ { \@@_parse_stuff_plural:w }
+ { \@@_parse_stuff_plural:w [#1] }
}
-\cs_generate_variant:Nn \@@_cuphrase_parse_normal:nn { V }
% \end{macrocode}
+% \end{macro}
%
+% \begin{macro}{ \@@_new_cuphrase_add:nn }
+% Store the pluarl form in the property list.
+% Next, parse gender. Pretty much the same as before. By default we use
+% a male gender.
% \begin{macrocode}
-\cs_new:Npn \@@_chuphrase_parse_plural:nw #1 [#2]
+\cs_new:Npn \@@_parse_stuff_plural:w [#1]
{
- \prop_put:Nnn \l_@@_phrase_prop { #1-pl } {#2}
+ \prop_put:Nnn \l_@@_tmpa_prop { -pl } {#1}
\peek_meaning_ignore_spaces:NTF <
+ { \@@_parse_stuff_gender:w }
+ { \@@_parse_stuff_gender:w <m> }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{ \@@_new_cuphrase_add:nn }
+% Check if the gender-input is correct, add it to the property list.
+% Then finish the cycle and start a new one.
+% \begin{macrocode}
+\cs_new:Npn \@@_parse_stuff_gender:w <#1>
+ {
+ \@@_if_gender_error:nTF {#1}
+ { \@@_set_state_to:n { error } }
+ { \prop_put:Nnn \l_@@_tmpa_prop { -gender } {#1} }
+ \@@_parse_phrase_finish_cycle_and_start_anew:V \l_@@_curr_unit_tl
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{ \@@_parse_phrase_finish_cycle_and_start_anew:n }
+% If not errors were found: Add the number to the other numbers (if not already inside).
+% Afterwards map through the property list and set the variations for each number.
+%
+% As an example, if we had \enquote{12}, |\l_@@_phrase_prop| would then contain
+% the keys \enquote{12}, \enquote{12-pl}, \enquote{12-gender}, \enquote{12-singlebool}.
+% \begin{macrocode}
+\cs_new:Npn \@@_parse_phrase_finish_cycle_and_start_anew:n #1
+ {
+ \@@_if_state_equal:nT { normal }
{
- \@@_chuphrase_parse_gender:nw {#1}
- }{
- \@@_chuphrase_parse_gender:nw {#1} < m >
+ \seq_if_in:NnF \l_@@_phrase_numbers_seq {#1}
+ { \seq_put_right:Nn \l_@@_phrase_numbers_seq {#1} }
+ \prop_map_inline:Nn \l_@@_tmpa_prop
+ {
+ \prop_put:Nnn \l_@@_phrase_prop { #1 ##1 } {##2}
+ }
}
+ \@@_parse_phrase_start_cycle:
}
+\cs_generate_variant:Nn \@@_parse_phrase_finish_cycle_and_start_anew:n { V }
% \end{macrocode}
+% \end{macro}
%
+% \begin{macro}{ \@@_new_cuphrase_sort_sequence:N }
+% Sorting the sequence of numbers from highest to lowest (in absolute values).
+% And if two absolute values are equal, negative numbers are preferred over
+% positive ones.
% \begin{macrocode}
-\cs_new:Npn \@@_chuphrase_parse_gender:nw #1 <#2>
+\cs_new:Npn \@@_new_cuphrase_sort_sequence:N #1
{
- \@@_if_gender_error:nTF {#2}
+ \seq_sort:Nn #1
{
- \@@_deftranslation_to:VxVn
- \l_@@_language_tl { #1-phrase-gender }
- \c_@@_postfix_gender_tl { m }
- }{
- \@@_deftranslation_to:VxVn
- \l_@@_language_tl { #1-phrase-gender }
- \c_@@_postfix_gender_tl {#2}
- }
- \@@_cuphrase_parse:n
+ \int_set:Nn \l_@@_tmpa_int { \int_abs:n {##1} }
+ \int_set:Nn \l_@@_tmpb_int { \int_abs:n {##2} }
+ \int_compare:nNnTF { \l_@@_tmpa_int } < { \l_@@_tmpb_int }
+ { \sort_return_swapped: }
+ {
+ \int_compare:nNnTF { \l_@@_tmpa_int } > { \l_@@_tmpb_int }
+ { \sort_return_same: }
+ {
+ \prop_get:NnN \l_@@_phrase_prop { ##1 - singlebool } \l_@@_tmpa_int
+ \int_compare:nNnTF { \l_@@_tmpa_int } = { 1 }
+ { \sort_return_same: }
+ { \sort_return_swapped: }
+ }
+ }
+ }
}
% \end{macrocode}
+% \end{macro}
%
-%
+% \begin{macro}{ \cudefinephrase }
+% \begin{macrocode}
+%\NewDocumentCommand \cudefinephrase { m m }
+% {
+%% \@@_cuphrase:nn {#1} {#2}
+% }
+% \end{macrocode}
+% \end{macro}
%
%
% \subsection{Old stuff}
@@ -8293,7 +9897,7 @@ and the derived file cooking-units.sty.
% \begin{macrocode}
\cs_new:Npn \@@_old_cutext_default:nnn #1#2#3
{
- \bool_if:NTF \l_@@_draft_bool
+ \bool_if:NTF \l_@@_pckopt_draft_bool
{#2}
{
\tl_set:Nn \l_@@_cutext_last_value_tl {#2}
@@ -8313,19 +9917,21 @@ and the derived file cooking-units.sty.
{
\@@_old_cutext_if_numeral_is_int_and_parse_and_smaller_then_print_numerals:NTF #1
{
- \@@_int_if_equal_one:nTF {#1}
+ \int_compare:nNnTF {#1} = { 1 }
{
- \@@_translate_one_and_check_existance:Nx \l_@@_translation_tmpa_tl {#2}
- \bool_if:NTF \l_@@_cutext_uppercase_word_bool
+ \@@_culang_one_let:NnT \l_@@_translation_tmpa_tl {#2}
{
- \exp_args:Nx \tl_upper_case:n { \tl_head:V \l_@@_translation_tmpa_tl }
- \tl_tail:V \l_@@_translation_tmpa_tl
+ \bool_if:NT \l_@@_cutext_uppercase_word_bool
+ {
+ \text_uppercase:x { \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_Numeral:V #1 }
+ { \@@_print_numeral:V #1 }
}
}
{ \@@_print_numerical_input:N #1 }
@@ -8376,7 +9982,7 @@ and the derived file cooking-units.sty.
\char_set_catcode_letter:N \_ %
\char_set_catcode_ignore:N\ %
} {#1}
- \bool_if:NTF \l_@@_draft_bool
+ \bool_if:NTF \l_@@_pckopt_draft_bool
{ \l_@@_tmpa_tl }
{ \@@_cuam_old_parse:V \l_@@_tmpa_tl }
}
@@ -8487,137 +10093,6 @@ and the derived file cooking-units.sty.
% \end{macrocode}
%
%
-%
-%
-% \begin{macrocode}
-\cs_new:Npn \@@_add_forbidden_unit:n #1
- {
- \seq_set_from_clist:Nn \l_@@_tmpa_seq {#1}
- \seq_map_inline:Nn \l_@@_tmpa_seq
- {
- \@@_error_if_unit_not_defined:nF {##1}
- {
- \seq_if_in:NnF \l_@@_curef_do_not_change_seq {##1}
- { \seq_put_right:Nn \l_@@_curef_do_not_change_seq {##1} }
- }
- }
- }
-\cs_new:Npn \@@_remove_forbidden_unit:n #1
- {
- \seq_set_from_clist:Nn \l_@@_tmpa_seq {#1}
- \seq_map_inline:Nn \l_@@_tmpa_seq
- {
- \@@_error_if_unit_not_defined:nF {##1}
- {
- \seq_if_in:NnTF \l_@@_curef_do_not_change_seq {##1}
- { \seq_remove_all:Nn \l_@@_curef_do_not_change_seq {##1} }
- {
- \msg_warning:nnnn { cooking-units } { curef-not-inside-list } {##1}
- { \@@_seq_use_msg:N \l_@@_curef_do_not_change_seq }
- }
- }
- }
- }
-\cs_new:Npn \@@_clear_forbidden_unit:
- { \seq_clear:N \l_@@_curef_do_not_change_seq }
-% \end{macrocode}
-%
-%
-%
-%
-%
-%
-% \begin{macrocode}
-\NewDocumentCommand \cudeclareunitgroup { m m }
- {
- \@@_define_clear_unit_group:nn {#1} {#2}
- \@@_add_to_unit_group:nn {#1} {#2}
- }
-\NewDocumentCommand \cuaddtounitgroup { m m }
- {
- \@@_add_to_unit_group:nn {#1} {#2}
- }
-\NewDocumentCommand \cuclearunitgroup { m }
- {
- \@@_error_if_group_not_defined:nF {#1}
- { \@@_define_clear_unit_group:nn {#1} { } }
- }
-% \end{macrocode}
-%
-%
-%
-%
-%
-%
-%
-%
-%
-%
-%
-% Works better now.
-% \begin{macrocode}
-\NewDocumentCommand \cusetoptionfor { m m }
- {
- \@@_map_trough_valid_unit_options:nnn {#1} {#2}
- { \clist_set:cn { l_@@_unit_option_ ##1 _clist } {##2} }
- }
-\NewDocumentCommand \cuaddoptionfor { m m }
- {
- \@@_map_trough_valid_unit_options:nnn {#1} {#2}
- { \clist_put_right:cn { l_@@_unit_option_ ##1 _clist } {##2} }
- }
-\NewDocumentCommand \cuclearoptionfor { m }
- {
- \@@_map_trough_valid_unit_options:nnn {#1} { }
- { \clist_clear:c { l_@@_unit_option_ ##1 _clist } }
- }
-% \end{macrocode}
-% The reason I map trough the units twice is simply: I think it makes more
-% sense if an \enquote{unknown unit} error is shown before an
-% \enquote{unknown option} error (at least for me).
-% It is kinda stupid, but this is not really a heavily used function, so \dots\ yeah.
-%
-% Note: I cannot check if |\l_@@_tmpa_clist| is empty because one could
-% use |\cusetoptionfor{F,C,Re,K}{}| to clear the options of the given units.
-% \begin{macrocode}
-\cs_new:Npn \@@_tmp:w { }
-\cs_new:Npn \@@_map_trough_valid_unit_options:nnn #1#2 #3
- {
- \seq_clear:N \l_@@_tmpa_seq
- \clist_clear:N \l_@@_tmpa_clist
- \cs_set:Npn \@@_tmp:w ##1##2 {#3}
- \clist_map_inline:nn {#1}
- {
- \@@_error_if_unit_not_defined:nF {##1}
- { \seq_put_right:Nn \l_@@_tmpa_seq {##1} }
- }
- \tl_if_empty:nF {#2}
- { \@@_unit_options_check_validity:n {#2} }
- \seq_map_inline:Nn \l_@@_tmpa_seq
- { \exp_args:NnV \@@_tmp:w {##1} \l_@@_tmpa_clist }
- }
-\cs_new:Npn \@@_unit_options_check_validity:n #1
- {
- \keyval_parse:NNn
- \@@_unit_options_check_validity_aux_i:n
- \@@_unit_options_check_validity_aux_ii:nn
- {#1}
- }
-\cs_new:Npn \@@_unit_options_check_validity_aux_i:n #1
- {
- \keys_if_exist:nnTF { cooking-units } {#1}
- { \clist_put_right:Nn \l_@@_tmpa_clist {#1} }
- { \msg_error:nnn { cooking-units } { unknown-option } {#1} }
- }
-\cs_new:Npn \@@_unit_options_check_validity_aux_ii:nn #1#2
- {
- \keys_if_exist:nnTF { cooking-units } {#1}
- { \clist_put_right:Nn \l_@@_tmpa_clist { #1={#2} } }
- { \msg_error:nnn { cooking-units } { unknown-option } {#1} }
- }
-% \end{macrocode}
-%
-%
%
%
%
@@ -8646,7 +10121,10 @@ and the derived file cooking-units.sty.
\newcookingunit { oz }
\newcookingunit { lb }
\newcookingunit { stick }
-\newcookingunit [ \ensuremath{ \@@_frac:nn { eV } { c^2 } } ] { eVc-2 }
+\newcookingunit [
+ symbol={\ensuremath{ \@@_frac:nn { eV } { c^2 } } } ,
+ natural-unit
+ ] { eVc-2 }
% \end{macrocode}
%
% \begin{macrocode}
@@ -8661,7 +10139,10 @@ and the derived file cooking-units.sty.
\newcookingunit { h }
\newcookingunit { min }
\newcookingunit { s }
-\newcookingunit [ \ensuremath{ \@@_frac:nn { \hbar } { eV } } ] { hbareV-1 }
+\newcookingunit [
+ symbol={\ensuremath{ \@@_frac:nn { \hbar } { eV } } },
+ natural-unit
+ ] { hbareV-1 }
% \end{macrocode}
%
% \begin{macrocode}
@@ -8670,7 +10151,9 @@ and the derived file cooking-units.sty.
\newcookingunit { dm }
\newcookingunit { mm }
\newcookingunit { in }
-\newcookingunit [ \ensuremath{ \@@_frac:nn { c\hbar } { eV } } ] { chbareV-1 }
+\newcookingunit [
+ symbol={ \ensuremath{ \@@_frac:nn { c\hbar } { eV } } } , natural-unit
+ ] { chbareV-1 }
% \end{macrocode}
%
% \begin{macrocode}
@@ -8678,7 +10161,9 @@ and the derived file cooking-units.sty.
\newcookingunit { dl }
\newcookingunit { cl }
\newcookingunit { ml }
-\newcookingunit [ \ensuremath { \@@_frac:nn { c^3 \hbar^3 } { eV^3 } } ] { (chbareV-1)3 }
+\newcookingunit [
+ symbol={ \ensuremath { \@@_frac:nn { c^3 \hbar^3 } { eV^3 } } }, natural-unit
+ ] { (chbareV-1)3 }
% \end{macrocode}
%
% \begin{macrocode}
@@ -8686,7 +10171,7 @@ and the derived file cooking-units.sty.
\newcookingunit { kcal }
\newcookingunit { J }
\newcookingunit { kJ }
-\newcookingunit { eV }
+\newcookingunit [ natural-unit ] { eV }
% \end{macrocode}
%
% \begin{macrocode}
@@ -8905,15 +10390,25 @@ and the derived file cooking-units.sty.
%
%
% \begin{macrocode}
-\cudefinekeys { kg }
+\cudefinekeychain
{
+ { kg } { 1 }
{ dag }{ 100 }
{ g } { 1000 }
{ lb } { 1/0.45359237 }
{ oz } { 16/0.45359237 }
{ stick } { 4/0.45359237 }
- { eVc-2 } { 560958865.0e+27 } %% 560958865.0 +- 3.5 e+27
+ { eVc-2 } { 560958865.0e+27 } %% (560958865.0 +- 3.5) e+27
}
+%\cudefinekeys { kg }
+% {
+% { dag }{ 100 }
+% { g } { 1000 }
+% { lb } { 1/0.45359237 }
+% { oz } { 16/0.45359237 }
+% { stick } { 4/0.45359237 }
+% { eVc-2 } { 560958865.0e+27 } %% (560958865.0 +- 3.5) e+27
+% }
% \end{macrocode}
% \begin{macrocode}
\cudefinekeys { d }
@@ -8921,7 +10416,7 @@ and the derived file cooking-units.sty.
{ h } { 24 }
{ min }{ 1440 }
{ s } { 86400 }
- { hbareV-1 } { 151926746.1e+7 * 86400 } %% 151926746.1 +- 2.1 e+7
+ { hbareV-1 } { 151926746.1e+7 * 86400 } %% (151926746.1 +- 2.1) e+7
}
%\cuaddtokeys { s } { hbareV-1 } { 6.582119514e-16 }
% \end{macrocode}
@@ -8951,7 +10446,7 @@ and the derived file cooking-units.sty.
{ kJ }{ 1e-3 }
{ cal }{ 0.2388459 }
{ kcal }{ 0.2388459e-3 }
- { eV }{ 624150912.6e+10 } %% 624150912.6 +- 3.9 e+10
+ { eV }{ 624150912.6e+10 } %% (624150912.6 +- 3.9) e+10
}
%\cuaddtokeys { J } { eV } { 1.6021766208e-19 }
% \end{macrocode}
@@ -8992,7 +10487,7 @@ and the derived file cooking-units.sty.
\cudefinephrase { German }
{
% { 6 } * { halbes \ Dutzend } < n >
-% { 6 } { efkjwefjkl \ Dutzend } < n >
+% { 6 } { halbe \ Dutzend } < n >
{ 12 } { Dutzend } < n >
% { 60 } { Schock } < n >
% { 1728 } { Gro{\ss}gros } < n >
@@ -9023,6 +10518,20 @@ and the derived file cooking-units.sty.
} ,
round-precision = 2 ,
}
+
+
+% \NewDocumentCommand \cudefinekeys { } { \cudefinekeys }
+
+
+
+%\AtBeginDocument{
+%\keys_define:nn { cooking-units }
+% {
+% unknown .code:n = { \tl_show:N {\l_keys_key_str} }
+% }
+% \keys_set:nn { cooking-units } {#2}
+%
+%}
% \end{macrocode}
%
%
@@ -9064,8 +10573,8 @@ and the derived file cooking-units.sty.
% \bibitem{StickSource} \url{https://cooking.stackexchange.com/questions/784/translating-cooking-terms-between-us-uk-au-ca-nz}
%
% \end{thebibliography}
-%
-%
+%
+%
%
% \endinput
%
diff --git a/macros/latex/contrib/cooking-units/cooking-units.ins b/macros/latex/contrib/cooking-units/cooking-units.ins
index e20b719ad6..7298eb0e53 100644
--- a/macros/latex/contrib/cooking-units/cooking-units.ins
+++ b/macros/latex/contrib/cooking-units/cooking-units.ins
@@ -5,7 +5,7 @@
%% The original source files were:
%%
%% cooking-units.dtx (with options: `install')
-%% Copyright (C) 2016--2020 by Ben Vitecek (current Maintainer)
+%% Copyright (C) 2016--2021 by Ben Vitecek (current Maintainer)
%%
%% This file may be distributed and/or modified under the
%% conditions of the LaTeX Project Public License, either
@@ -25,7 +25,7 @@
\input l3docstrip.tex
\askforoverwritefalse
\preamble
-Copyright (C) 2016--2020 by Ben Vitecek (current Maintainer)
+Copyright (C) 2016--2021 by Ben Vitecek (current Maintainer)
This file may be distributed and/or modified under the
conditions of the LaTeX Project Public License, either
diff --git a/macros/latex/contrib/cooking-units/cooking-units.pdf b/macros/latex/contrib/cooking-units/cooking-units.pdf
index ef512cc946..e65da308d7 100644
--- a/macros/latex/contrib/cooking-units/cooking-units.pdf
+++ b/macros/latex/contrib/cooking-units/cooking-units.pdf
Binary files differ