summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/cooking-units/cooking-units.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'macros/latex/contrib/cooking-units/cooking-units.dtx')
-rw-r--r--macros/latex/contrib/cooking-units/cooking-units.dtx2304
1 files changed, 1477 insertions, 827 deletions
diff --git a/macros/latex/contrib/cooking-units/cooking-units.dtx b/macros/latex/contrib/cooking-units/cooking-units.dtx
index b953801209..ad55c18e70 100644
--- a/macros/latex/contrib/cooking-units/cooking-units.dtx
+++ b/macros/latex/contrib/cooking-units/cooking-units.dtx
@@ -817,6 +817,9 @@ and the derived file cooking-units.sty.
% \changes {2022/06/06} {2.01} {Implement a way to define the plural-finding algorithm.}
% \changes {2022/06/06} {2.01} {Add two public commands \cs{cookingunits_print_fraction:nnn} and \cs{cookingunits_print_range:nn}.}
%
+% \changes {2022/11/27} {3.00} {Allow ranges and fractions to be combined!}
+% \changes {2022/11/27} {3.00} {New input type: products!}
+% \changes {2022/11/27} {3.00} {Change |cutext-range-unit| to |cutext-range-phrase|.}
%
%
%
@@ -829,7 +832,7 @@ and the derived file cooking-units.sty.
%
%
% \maketitle
-%
+%^^A \TODO{Test für Phrases schreiben!}
%
% \begin{documentation}
% \begin{abstract}
@@ -875,6 +878,10 @@ and the derived file cooking-units.sty.
% See \cref{sec:bug-feed} for more details. Wanna just check the
% existing translations? See \cref{sec:Translations}.
%
+% \subsection{What's new?}
+% Since v3.00 fraction and ranges can now be combined!
+% Furthermore, products are introduced! Check the next section for more info.
+%
% \section {The Commands}
% \label{sec:commands}
%
@@ -891,8 +898,9 @@ and the derived file cooking-units.sty.
% \end{itemize}
%
% Numbers and units are printed using \mycs{cunum}. The numerical part
-% can interpret \verb|_| and \texttt{/} as (mixed) fractions and
-% \verb|--| as a separator for ranges; to convert units use the option
+% can interpret \verb|_| and \texttt{/} as (mixed) fractions,
+% \verb|--| as a separator for ranges and |x| or |\times| for products;
+% to convert units use the option
% \texttt{\meta{old-unit}=\meta{new-unit}}\footnote{New keys can be
% added and defined, see \cref{sec:pred-units} and
% \cref{sec:def-units} for further information.}. It furthermore
@@ -913,12 +921,19 @@ and the derived file cooking-units.sty.
% \cunum{2,3}{kg} \\
% \cunum{2--3}{kg} \\
% \cunum{2.5--3.5}{kg} \\
+% \cunum{2.5 x 3.5}{kg} \\
+% \cunum{2.5 \times 3.5}{kg} \\
+% \cunum{2.5 x 3 \times 4,5}{kg} \\
% \cunum[kg=g]{2.5--3,5}{kg} \\
+% \cunum[kg=g]{2.5 x 3,5}{kg} \\
% \cunum[C=F]{200}{C} \\
% \cunum[C=F]{180--200}{C} \\
% \cunum{1/2}{m} \\
% \cunum{1_1/2}{m} \\
% \cunum[m=cm]{1_1/2}{m} \\
+% \cunum{1_1/2--2}{m} \\
+% \cunum[m=cm]{1--1_1/2}{m} \\
+% \cunum[m=cm]{1 x 1_1/2 x 2}{m} \\
% \cunum{?}{l} \\
% \cunum{50}{dag} \\
% \cunum{5}[0]{dag} \\
@@ -935,7 +950,8 @@ and the derived file cooking-units.sty.
% v1.10 it works similar\footnote{One could also say \enquote{exactly
% like}.} to \mycs{cunum}: it allows the conversion between units and
% interprets the numerical part (again |_| and |/| are used for
-% (mixed) fractions and |--| for ranges). Furthermore, \cCutext\ allow
+% (mixed) fractions, |--| for ranges and |x| or |\times| for products).
+% Furthermore, \cCutext\ allow
% the usages of numerals (see \cref{sec:load-time-options} for more information).
%^^A if the package
%^^A option \opt{use-fmtcount-numerals} (see \cref{sec:load-time-options})
@@ -948,6 +964,7 @@ and the derived file cooking-units.sty.
% \cutext{1}{l} \\
% \Cutext{1}{l} \\
% \Cutext{1--2}{l} \\
+% \Cutext{1 x 2}{l} \\
% \cutext{12}{l} \\
% \Cutext{13}{l}
% \end{cuexamplecode}
@@ -958,6 +975,7 @@ and the derived file cooking-units.sty.
% \Cutext{1}{l} \\
% \cutext{1--2}{l} \\
% \Cutext{1--2}{l} \\
+% \Cutext{1 x 2}{l} \\
% \cutext{12}{l} \\
% \Cutext{13}{l}
% \end{cuexamplecode}
@@ -973,6 +991,7 @@ and the derived file cooking-units.sty.
% \cutext{1}{l} \\
% \Cutext{1}{l} \\
% \cutext{1--2}{l} \\
+% \cutext{1 x 2}{l} \\
% \cutext{12}{l} \\
% \Cutext{13}{l} \\
% \Cutext{?}{l} \\
@@ -981,14 +1000,16 @@ and the derived file cooking-units.sty.
%
%
% \lstinline|\cuam| works like \mycs{cunum}, but without a unit, so
-% changing units doesn't affect it. Like \mycs{cunum} \texttt{\_} and
-% \texttt{/} are used to imply a (mixed) fraction and |--| is used for ranges.
+% changing units doesn't affect it. It has the same syntax as \mycs{cunum}.
%
% \begin{cuexamplecode}
% \cuam{3} \\
% \cuam{2--3} \\
+% \cuam{2 x 3 x 4} \\
% \cuam{2/3} \\
-% \cuam{1_2/3}
+% \cuam{1_2/3} \\
+% \cuam{2/3--1_2/3} \\
+% \cuam{2/3 x 1 x 1_2/3}
% \end{cuexamplecode}
%
% Furthermore it allows the concept of \enquote{phrases} (replacing a positive integer
@@ -1005,6 +1026,7 @@ and the derived file cooking-units.sty.
% \cuam{24} \\
% \cuam{12--24} \\
% \cuam{12--13}\\
+% \cuam{12x24x36} \\
% \cuam{18} \\
% \cuam{60}
% \end{cuexamplecode}
@@ -1103,20 +1125,19 @@ and the derived file cooking-units.sty.
% While using \cCutext\ one may wonder which rules are used in order to determine
% if the printed unit is singular or plural. If rules for a specific language are not found
% the default ruleset is used. There are currently two rule sets: One default
-% and one if you are using french.
+% and one for the french language.
%
-% Each set has three seperate rules: one for \enquote{normal} numbers, one for
+% Each set has three separate rules: one for \enquote{normal} numbers, one for
% ranges and one for fractions.
%
% \subsubsection*{French}
%
% Use singular if:
% \begin{description}
-% \item[normal] The absolute value of the number is smaller $2$
+% \item[number] The absolute value of the number is smaller $2$
% \item[fraction] The absolute value of the evaluated fraction is smaller $2$.
% (e.g.\ $1\,\sfrac{1}{2} = 1.5$ uses singular, $2\,\sfrac{3}{4} = 2.75$ uses plural).
-% \item[range] The absolute value of the second number is smaller $2$.
-% (e.g.\ \cuam{1--2}: Take $2$.)
+% \item[range/product] Take the last item and use one of the rules above.
% \end{description}
%
% For sources see \cite{Plural-French-Academia}, \cite{Plural-French-absolute-1} \&
@@ -1127,9 +1148,9 @@ and the derived file cooking-units.sty.
%
% Use singular if:
% \begin{description}
-% \item[normal] The number is equal to $1$.
-% \item[fraction] There is no mixed fraction part and the nominator is equal to $1$.
-% \item[range] The second number is equal to $1$. (e.g.\ \cuam{1--2}: Take $2$.)
+% \item[number] The number is equal to $1$.
+% \item[fraction] There is no mixed fraction part and the numerator is equal to $1$.
+% \item[range/product] Take the last item and use one of the rules above.
% \end{description}
%
% \section{Predefined units \& some notes}
@@ -1682,15 +1703,15 @@ and the derived file cooking-units.sty.
% name and symbol for given language you can use \lstinline|\cudefinename|;
% to only change symbols use \lstinline|\cudefinesymbol|.
%
-% \begin{function}{decimal-mark,cutext-range-sign, one(m),one(f),one(n)}
+% \begin{function}{decimal-mark,cutext-range-phrase, one(m),one(f),one(n)}
% Those are special keys (as they cannot be used as units). Not only
% are printed units language depending, but as is the decimal mark
% (|.| or |,|) and the text which substitutes the range-sign.
% To set the decimal mark use
% \opt{decimal-mark} (see examples below), to set the range-sign for \cCutext\
-% use \opt{cutext-range-sign}.
+% use \opt{cutext-range-phrase}.
%
-% Note that \opt{cutext-range-sign} is \enquote{overwritten} by the \emph{option}
+% Note that \opt{cutext-range-phrase} is \enquote{overwritten} by the \emph{option}
% \opt{cutext-range-sign}. If the \emph{option} is set, then the language symbol
% will be ignored.
%
@@ -1738,7 +1759,7 @@ and the derived file cooking-units.sty.
% {h} {hour} [hours]
% {C} {degree\space Celsius} [degrees\space Celsius]
% {decimal-marker} {.}
-% {cutext-range-sign} {~to~}
+% {cutext-range-phrase} {~to~}
% {one(m)} {one}
% {one(f)} {one}
% {one(n)} {one}
@@ -1753,7 +1774,7 @@ and the derived file cooking-units.sty.
% {h} {Stunde} [Stunden] <f>
% {C} {Grad\space Celsius}
% {decimal-marker} {,}
-% {cutext-range-sign} {~bis~}
+% {cutext-range-phrase} {~bis~}
% {one(m)} {ein}
% {one(f)} {eine}
% {one(n)} {ein}
@@ -1785,7 +1806,7 @@ and the derived file cooking-units.sty.
% \cudefinesymbol {English}
% {
% {decimal-mark} {.}
-% {cutext-range-sign} {~to~}
+% {cutext-range-phrase} {~to~}
% {one(m)} {one}
% {one(f)} {one}
% {one(n)} {one}
@@ -1793,7 +1814,7 @@ and the derived file cooking-units.sty.
% \cudefinesymbol {German}
% {
% {decimal-mark} {,}
-% {cutext-range-sign} {~bis~}
+% {cutext-range-phrase} {~bis~}
% {one(m)} {ein}
% {one(f)} {eine}
% {one(n)} {ein}
@@ -1804,7 +1825,7 @@ and the derived file cooking-units.sty.
% {dl} {dL}
% {cl} {cL}
% {ml} {mL}
-% {cutext-range-sign} {~\`{a}~}
+% {cutext-range-phrase} {~\`{a}~}
% {decimal-mark} {,}
% {one(m)} {un}
% {one(f)} {une}
@@ -2410,7 +2431,7 @@ and the derived file cooking-units.sty.
% Allows \meta{character(s)} to be used in the first mandatory argument of
% \mycs{cunum}, \mycs{cuam}, \cCutext{} without raising an error (you can customize this
% behavior, see \opt{set-unknown-message}). By default it is set to |?|.
-% Please note that the sign |<| is not allowed as a special sign.
+% Please note that the sign |<| is not allowed as a special sign.
% \end{function}
%
% \begin{cuexamplecode}
@@ -3197,7 +3218,6 @@ and the derived file cooking-units.sty.
%
%
%
-%
% \begin{function}{42}
% \begin{syntax}
% 42 = \meta{true/false}
@@ -3213,6 +3233,7 @@ and the derived file cooking-units.sty.
% \cunum{180}{C} \\
% \cunum{15/4}{s} \\
% \cunum{1--2}{min} \\
+% \cunum{1x2x3}{min} \\
% \cunum{?}{l}
% \end{cuexamplecode}
%
@@ -3693,14 +3714,14 @@ and the derived file cooking-units.sty.
% \begin{macrocode}
\ProvidesExplPackage
{cooking-units}
- {2022/06/06}
- {2.01}
+ {2022/12/10}
+ {3.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 } { 2022/02/24 }
+\@ifpackagelater { expl3 } { 2022-09-28 }
{ }
{
\PackageError { cooking-units } { Support~package~expl3~too~old }
@@ -3853,9 +3874,9 @@ and the derived file cooking-units.sty.
% Commands to print numerals. Either use default or set yourself.
% \begin{macrocode}
\cs_new:Npn \@@_print_numeral:n #1
- { \msg_error:nnn {cooking-units} { define-numeral-function } }
+ { \msg_error:nn {cooking-units} { define-numeral-function } #1 }
\cs_new:Npn \@@_print_Numeral:n #1
- { \msg_error:nnn {cooking-units} { define-Numeral-function } }
+ { \msg_error:nn {cooking-units} { define-Numeral-function } #1 }
\bool_if:NT \g_@@_opt_numeral_bool
{
\cs_set_eq:NN \@@_print_numeral:n \numberstringnum
@@ -3921,6 +3942,7 @@ and the derived file cooking-units.sty.
% , \l_@@_input_allowed_special_signs_tl
% , \g_@@_input_str_hash_one_tl
% , \l_@@_input_range_sign_tl
+% , \l_@@_input_times_sign_tl
% , \l_@@_cutext_space_tl
% , \l_@@_cutext_numeral_space_tl
% , \l_@@_cuphrase_space_tl
@@ -3965,6 +3987,7 @@ and the derived file cooking-units.sty.
\tl_new:N \l_@@_input_allowed_special_signs_tl
\tl_new:N \g_@@_input_str_hash_one_tl
\tl_new:N \l_@@_input_range_sign_tl
+\tl_new:N \l_@@_input_times_sign_tl
\tl_new:N \l_@@_cutext_space_tl
\tl_new:N \l_@@_cutext_numeral_space_tl
\tl_new:N \l_@@_cuphrase_space_tl
@@ -3985,8 +4008,8 @@ and the derived file cooking-units.sty.
\tl_new:N \l_@@_stored_units_tl
\tl_new:N \l_@@_stored_formula_tl
\tl_new:N \l_@@_base_tl
-\tl_new:N \l_cookingunits_raw_amount_a_tl
-\tl_new:N \l_cookingunits_raw_amount_b_tl
+\tl_new:N \l_@@_times_space_tl
+\tl_new:N \l_@@_times_sign_tl
% \end{macrocode}
% \begin{macrocode}
\tl_new:N \l_@@_cmd_hook_tl
@@ -4004,6 +4027,7 @@ and the derived file cooking-units.sty.
% \begin{macrocode}
\tl_set:Nn \l_@@_input_digits_tl { 0123456789 }
\tl_set:Nn \l_@@_input_range_sign_tl { -- }
+\tl_set:Nn \l_@@_input_times_sign_tl { \times x X }
\tl_set:Nn \l_@@_input_fraction_sign_tl { / }
\tl_set:Nn \l_@@_input_mixed_fraction_sign_tl { _ }
\tl_set:Nn \l_@@_input_decimal_mark_tl { . , }
@@ -4012,11 +4036,13 @@ and the derived file cooking-units.sty.
\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 { +-()*/ }
+\tl_set:Nn \l_@@_times_sign_tl { \ensuremath { \times } }
% \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_@@_times_space_tl { \, } % \:
\tl_set:Nn \l_@@_cutext_space_tl { ~ }
\tl_set:Nn \l_@@_cutext_numeral_space_tl { \space }
\tl_set:Nn \l_@@_cuphrase_space_tl { \space }
@@ -4279,6 +4305,21 @@ and the derived file cooking-units.sty.
\bool_new:N \l_@@_contains_valid_key_bool
\bool_new:N \l_@@_check_decimal_bool
\bool_new:N \l_@@_unit_error_bool
+\bool_new:N \l_@@_rf_contains_fraction_bool
+\bool_new:N \l_@@_rf_contains_range_bool
+\bool_new:N \l_@@_rf_contains_times_bool
+\bool_new:N \l_@@_rf_check_fraction_bool
+\bool_new:N \l_@@_lokal_eval_fractions_bool
+\seq_new:N \l_@@_split_input_seq
+\seq_new:N \l_@@_parsed_seq
+\seq_new:N \l_@@_numbers_to_check_seq
+\int_new:N \l_@@_largest_common_divisor_int
+\seq_new:N \l_@@_reduced_numbers_seq
+\bool_new:N \l_@@_seperator_after_fraction_bool
+\seq_new:N \l_@@_prepared_printing_seq
+\int_new:N \l_@@_nr_of_items
+\seq_new:N \l_@@_processed_seq
+\tl_new:N \l_@@_precompiled_options_tl
% \end{macrocode}
% \end{macro}
%
@@ -4514,13 +4555,27 @@ and the derived file cooking-units.sty.
{
\tl_map_inline:nn {#1}
{
- \str_if_eq:nnT {##1} { < }
+ \str_if_eq:nnTF {##1} { < }
{
\msg_error:nn { cooking-units } { <-not-allowed-as-special-sign }
\tl_map_break:n { \use_none:nn }
}
}
- \use:n { \tl_set:Nn \l_@@_input_allowed_special_signs_tl {#1} }
+ \use:n
+ {
+ \str_if_in:nnTF {#1} { x }
+ {
+ \tl_remove_all:Nn \l_@@_input_times_sign_tl { x }
+ \tl_remove_all:Nn \l_@@_input_times_sign_tl { X }
+ }{
+ \str_if_in:nnT {#1} { X }
+ {
+ \tl_remove_all:Nn \l_@@_input_times_sign_tl { x }
+ \tl_remove_all:Nn \l_@@_input_times_sign_tl { X }
+ }
+ }
+ \tl_set:Nn \l_@@_input_allowed_special_signs_tl {#1}
+ }
} ,
set-special-sign .groups:n = { parse } ,
% \end{macrocode}
@@ -4536,6 +4591,13 @@ and the derived file cooking-units.sty.
{
\msg_error:nn { cooking-units } { <-not-allowed-as-special-sign }
}{
+ \bool_lazy_or:nnT
+ { \str_if_eq_p:nn {##1} { x } }
+ { \str_if_eq_p:nn {##1} { X } }
+ {
+ \tl_remove_all:Nn \l_@@_input_times_sign_tl { x }
+ \tl_remove_all:Nn \l_@@_input_times_sign_tl { X }
+ }
\tl_put_right:Nn \l_@@_input_allowed_special_signs_tl {##1}
}
}
@@ -4578,6 +4640,7 @@ and the derived file cooking-units.sty.
% \begin{macrocode}
print-numerals .bool_set:N = \l_@@_pckopt_print_numeral_bool ,
print-numerals .default:n = { true } ,
+ print-numerals .groups:n = { unit-hook } ,
% \end{macrocode}
% \end{macro}
%
@@ -4586,6 +4649,7 @@ and the derived file cooking-units.sty.
% \begin{macrocode}
use-numerals-below .int_set:N = \l_@@_print_numerals_below_int ,
use-numerals-below .default:n = { 13 } ,
+ use-numerals-below .groups:n = { unit-hook } ,
% \end{macrocode}
%\end{macro}
%
@@ -4612,6 +4676,9 @@ and the derived file cooking-units.sty.
cunum-range-sign .default:n = { -- } ,
cutext-range-sign .tl_set:N = \l_@@_cutext_range_sign_tl ,
cutext-range-sign .default:n = { -- } ,
+ range-sign .groups:n = { unit-hook } ,
+ cunum-range-sign .groups:n = { unit-hook } ,
+ cutext-range-sign .groups:n = { unit-hook } ,
% \end{macrocode}
%\end{macro}
%
@@ -4620,6 +4687,7 @@ and the derived file cooking-units.sty.
% \begin{macrocode}
use-phrases .bool_set:N = \l_@@_pckopt_use_phrases_bool ,
use-phrases .default:n = { true } ,
+ use-phrases .groups:n = { unit-hook } ,
% \end{macrocode}
% \end{macro}
%
@@ -4641,6 +4709,7 @@ and the derived file cooking-units.sty.
\l_@@_pckopt_round_precision_negative_bool
} ,
round-precision .default:n = { 2 } ,
+ round-precision .groups:n = { unit-hook } ,
% \end{macrocode}
%\end{macro}
%
@@ -4651,16 +4720,16 @@ and the derived file cooking-units.sty.
round-to-int .choices:nn =
{ true , false }
{
- \msg_error:nnnn { cooking-units } { Option-deprecated } { round-to-int } { round-precision = 0 }
- \int_compare:nNnTF { \l_keys_choice_int } = { 1 }
+ \msg_error:nnnn { cooking-units }
+ { Option-deprecated } { round-to-int } { round-precision = 0 }
+ \int_compare:nNnT { \l_keys_choice_int } = { 1 }
{
\int_set:Nn \l_@@_round_precision_int { 0 }
- }{
-
}
\use:c { bool_set_ \l_keys_choice_tl :N } \l_@@_pckopt_round_to_int_bool
} ,
round-to-int .default:n = { false } ,
+ round-to-int .groups:n = { unit-hook } ,
% \end{macrocode}
%\end{macro}
%
@@ -4680,6 +4749,7 @@ and the derived file cooking-units.sty.
}
},
round-half .default:n = { default },
+ round-half .groups:n = { unit-hook } ,
% \end{macrocode}
% \end{macro}
%
@@ -4726,6 +4796,7 @@ and the derived file cooking-units.sty.
% \begin{macrocode}
mixed-fraction-space .dim_set:N = \l_@@_mixed_frac_dim ,
mixed-fraction-space .default:n = { 0.1 em } ,
+ mixed-fraction-space .groups:n = { unit-hook } ,
% \end{macrocode}
%\end{macro}
%
@@ -4735,6 +4806,7 @@ and the derived file cooking-units.sty.
% \begin{macrocode}
cutext-space .tl_set:N = \l_@@_cutext_space_tl ,
cutext-space .default:n = { ~ } ,
+ cutext-space .groups:n = { unit-hook } ,
% \end{macrocode}
% \end{macro}
%
@@ -4744,6 +4816,7 @@ and the derived file cooking-units.sty.
% \begin{macrocode}
cutext-numeral-space .tl_set:N = \l_@@_cutext_numeral_space_tl ,
cutext-numeral-space .default:n = { \space } ,
+ cutext-numeral-space .groups:n = { unit-hook } ,
% \end{macrocode}
% \end{macro}
%
@@ -4752,6 +4825,7 @@ and the derived file cooking-units.sty.
% \begin{macrocode}
phrase-space .tl_set:N = \l_@@_cuphrase_space_tl ,
phrase-space .default:n = { ~ } ,
+ phrase-space .groups:n = { unit-hook } ,
% \end{macrocode}
% \end{macro}
%
@@ -4760,9 +4834,18 @@ and the derived file cooking-units.sty.
% \begin{macrocode}
amount-unit-space .tl_set:N = \l_@@_value_unit_space_tl ,
amount-unit-space .default:n = { \thinspace } ,
+ amount-unit-space .groups:n = { unit-hook } ,
% \end{macrocode}
%\end{macro}
%
+%\begin{macro}{ amount-unit-space }
+% Setting the space between the value and the printed unit.
+% \begin{macrocode}
+ times-space .tl_set:N = \l_@@_times_space_tl ,
+ times-space .default:n = { \: } ,
+ times-space .groups:n = { unit-hook } ,
+% \end{macrocode}
+%\end{macro}
%
%
%
@@ -5163,12 +5246,34 @@ and the derived file cooking-units.sty.
% I do not allow fractions and ranges in the same input. Maybe I will
% change this.
% \begin{macrocode}
-\msg_new:nnnn { cooking-units } { fraction-not-allowed-with-range }
+%\msg_new:nnnn { cooking-units } { fraction-not-allowed-with-range }
+% {
+% You \ cannot \ use \ '/' \ ( and \ '_' )\ in \ combination \
+% with \ '\l_@@_input_range_sign_tl' \ in \ '#1'.
+% }{
+% You \ cannot \ use \ fractions \ with \ a \ range.
+% \msg_see_documentation_text:n { cooking-units }
+% }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\msg_new:nnnn { cooking-units } { range-too-many-items }
+ {
+ A \ range \ is \ only \ allowed \ to \ have \ a \ maximum \ of
+ \ two \ items. \ You \ have \ #1 \ items \ in \ '#2'.
+ }{
+ You \ cannot \ use \ more \ than \ two \ '--' .
+ \msg_see_documentation_text:n { cooking-units }
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\msg_new:nnnn { cooking-units } { range-and-times-not-allowed }
{
- You \ cannot \ use \ '/' \ ( and \ '_' )\ in \ combination \
- with \ '\l_@@_input_range_sign_tl' \ in \ '#1'.
+ It \ is \ not \ allowed \ to \ mix \ ranges \ ('--') \ and \
+ times \ in \ '#1'.
}{
- You \ cannot \ use \ fractions \ with \ a \ range.
+ Do \ not \ use \ times \ and \ ranges \ in \ the \ same \ command.
\msg_see_documentation_text:n { cooking-units }
}
% \end{macrocode}
@@ -5892,17 +5997,6 @@ and the derived file cooking-units.sty.
% \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: }
{
@@ -6081,7 +6175,7 @@ and the derived file cooking-units.sty.
\@@_if_unit_has_a_key:VTF #1
{
\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 }
+ \prop_get:cnNT { l_@@_rf_cukeys_ \l_@@_tmp_unit_tl _prop }
{ Liste } \l_@@_tmpa_seq
{
\@@_seq_get_overlap:NNTF \g_@@_natural_units_seq \l_@@_tmpa_seq
@@ -6138,7 +6232,7 @@ and the derived file cooking-units.sty.
\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
+ \prop_get:cnN { l_@@_rf_cukeys_ \l_@@_tmp_unit_tl _prop } { Liste } \l_@@_tmpa_seq
\bool_set_false:N \l_@@_tmpa_bool
\bool_until_do:Nn \l_@@_tmpa_bool
{
@@ -6164,29 +6258,56 @@ and the derived file cooking-units.sty.
%
%
%
-% \begin{macro}{\@@_tl_eval:Nn}
+% \begin{macro}{\@@_tl_set_eval:Nn}
% I am using this construction often enough, so \dots\ yeah.
% \begin{macrocode}
-\cs_new:Npn \@@_tl_eval:Nn #1#2 { \tl_set:Nf #1 { \fp_eval:n {#2} } }
-\cs_generate_variant:Nn \@@_tl_eval:Nn { Nv, cn }
+\cs_new:Npn \@@_tl_set_eval:Nn #1#2 { \tl_set:Nf #1 { \fp_eval:n {#2} } }
+\cs_generate_variant:Nn \@@_tl_set_eval:Nn { Nv, cn }
% \end{macrocode}
% \end{macro}
%
+% \begin{macro}{ \@@_bool_reverse:N }
+% Also used sometimes.
+% \begin{macrocode}
+\cs_new:Npn \@@_bool_reverse:N #1
+ { \bool_if:NTF #1 { \bool_set_false:N } { \bool_set_true:N } #1 }
+% \end{macrocode}
+% \end{macro}
%
+% \begin{macro}{\@@_rf_seq_put_right:Nnnnnn, \@@_rf_seq_put_right:NnVVVV, \@@_rf_seq_put_right:NnnnnV}
+% Nothing special here, just a wrapper used later.
+% \begin{macrocode}
+\cs_new:Npn \@@_rf_seq_put_right:Nnnnnn #1 #2#3#4#5#6
+ { \seq_put_right:Nn #1 { {#2} {#3} {#4} {#5} {#6} } }
+\cs_generate_variant:Nn \@@_rf_seq_put_right:Nnnnnn { NnVVVV, NnnVVV, NnnnnV }
+% \end{macrocode}
+% \end{macro}
%
-% \begin{macro}{ }
+%
+% \begin{macro}{ \@@_change_unit:TF }
% 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 }
{
- \@@_if_print_type_equal:nTF { fraction }
+ \@@_if_state_equal:nTF { special_sign }
{ \prg_return_false: }
- {
- \@@_if_state_equal:nTF { special_sign }
- { \prg_return_false: }
- { \prg_return_true: }
+ {
+ \bool_if:NTF \l_@@_rf_contains_fraction_bool
+ {
+ \bool_if:NTF \l_@@_lokal_eval_fractions_bool
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+ { \prg_return_true: }
}
+% \bool_if:NTF \l_@@_rf_contains_fraction_bool
+% { \prg_return_false: }
+% {
+% \@@_if_state_equal:nTF { special_sign }
+% { \prg_return_false: }
+% { \prg_return_true: }
+% }
}
% \end{macrocode}
% \end{macro}
@@ -6339,7 +6460,7 @@ and the derived file cooking-units.sty.
\tl_if_in:NnT #2 { - }
{
\tl_remove_once:Nn #2 { - }
- \bool_if:NTF #1 { \bool_set_false:N } { \bool_set_true:N } #1
+ \@@_bool_reverse:N #1
}
\@@_check_minus_remove_and_reverse:NN #1
}
@@ -6657,6 +6778,7 @@ and the derived file cooking-units.sty.
\seq_gset_from_clist:Nn \g_@@_allowed_special_keys_seq
{
cutext-range-sign ,
+ cutext-range-phrase ,
decimal-mark ,
one (m) ,
one (f) ,
@@ -6697,11 +6819,16 @@ and the derived file cooking-units.sty.
% \end{macrocode}
%
% \begin{macrocode}
-\@@_culang_def_base:nnn { name } { cutext-range-sign } { -- }
-\@@_culang_def_base:nnn { name-pl } { cutext-range-sign } { \c_@@_no_translation_str }
-\@@_culang_def_for:nnnn { German } { name } { cutext-range-sign } { ~bis~ }
-\@@_culang_def_for:nnnn { English } { name } { cutext-range-sign } { ~to~ }
-\@@_culang_def_for:nnnn { French } { name } { cutext-range-sign } { ~\`{a}~ }
+\@@_culang_def_base:nnn { name } { cutext-range-phrase } { -- }
+%\@@_culang_def_base:nnn { name } { cutext-range-sign } { -- }
+%\@@_culang_def_base:nnn { name-pl } { cutext-range-sign } { \c_@@_no_translation_str }
+\@@_culang_def_base:nnn { name-pl } { cutext-range-phrase } { \c_@@_no_translation_str }
+%\@@_culang_def_for:nnnn { German } { name } { cutext-range-sign } { ~bis~ }
+%\@@_culang_def_for:nnnn { English } { name } { cutext-range-sign } { ~to~ }
+%\@@_culang_def_for:nnnn { French } { name } { cutext-range-sign } { ~\`{a}~ }
+\@@_culang_def_for:nnnn { German } { name } { cutext-range-phrase } { ~bis~ }
+\@@_culang_def_for:nnnn { English } { name } { cutext-range-phrase } { ~to~ }
+\@@_culang_def_for:nnnn { French } { name } { cutext-range-phrase } { ~\`{a}~ }
% \end{macrocode}
%
%
@@ -6765,10 +6892,6 @@ and the derived file cooking-units.sty.
{ 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}
@@ -6798,78 +6921,78 @@ and the derived file cooking-units.sty.
%
%
%
-% \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{macro}{ \@@_rf_main_command:nnnnnnm \@@_rf_main_command:nnnnnV }
% \begin{macrocode}
-\cs_new:Npn \@@_do_the_stuff:nnnnnn #1#2#3#4#5#6
+\cs_new:Npn \@@_rf_main_command: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:
+ \@@_rf_initialice:nnnn {#1} {#2} {#5} {#4}
+ \@@_rf_use_hook_accordingly:
+ \@@_rf_parse_the_amount:n {#3}
+ \@@_rf_general_checkups:
\@@_if_state_equal:nTF { normal }
- { \@@_process_amount_normally:n {#2} }
- { \@@_process_amount_special: }
- \@@_new_print_amount_correctly:
- \@@_new_print_unit_correctly:
+ {
+ \@@_rf_process_amount_normally:n {#2}
+ \@@_rf_post_process_amount:
+ }{
+ \@@_rf_process_amount_special:
+ }
+ \@@_rf_prepare_amount_printing:N \l_@@_processed_seq
+ \@@_rf_print_amount_correctly:
+ \@@_rf_print_unit_correctly:
}
-\cs_generate_variant:Nn \@@_do_the_stuff:nnnnnn { nnnnV }
+\cs_generate_variant:Nn \@@_rf_main_command: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.
+% \subsubsection{Initialization}
+%
+% \begin{macro}{\@@_rf_initialice:nnnn }
+% A hub command for several steps. See the inividual commands for more
+% details. As each command is slightly different in execution, do some setup
+% depending on which command is currently in use.
% \begin{macrocode}
-\cs_new:Npn \@@_initialice_accordingly:nnnn #1#2#3#4
+\cs_new:Npn \@@_rf_initialice:nnnn #1#2#3#4
{
- \@@_initialize_new_default:nnn {#1} {#3} {#4}
- \@@_initialize_new_default_units:
+ \@@_rf_initialice_default:nnn {#1} {#2} {#3}
+ \@@_rf_initialize_units:
+ \@@_rf_setup_bools_for_process_and_prints:
\tl_case:NnF \l_@@_cmd_type_tl
{
- \c_@@_cmd_type_cunum_tl { \tl_set:Nn \l_@@_phantom_tl {#2} }
+ \c_@@_cmd_type_cunum_tl { \tl_set:Nn \l_@@_phantom_tl {#4} }
\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_use_single_bool
- }
-% \end{macrocode}
% \end{macro}
+
+% \begin{macro}{\@@_rf_initialice_default:nnn}
+% Set some variables to their default value, set the options (unit changes, etc.), check if
+% a label
+% is used and make sure the units are defined.
%
-%
-% \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.
+% We set the state to |42| in case of using the \opt{42} option to later proceeed to the
+% special post-processing case.
% \begin{macrocode}
-\cs_new:Npn \@@_initialize_new_default:nnn #1#2#3
+\cs_new:Npn \@@_rf_initialice_default:nnn #1#2#3
{
+ \tl_clear:N \l_@@_phantom_tl
\tl_clear:N \l_@@_option_unit_tl
- \tl_if_empty:nF {#2} { \keys_set:nn { cooking-units } {#2} }
+ \tl_clear:N \l_@@_precompiled_options_tl
+ \bool_set_false:N \l_@@_lokal_recalc_for_people_bool
+ \bool_set_false:N \l_@@_lokal_eval_fractions_bool
+ \tl_if_empty:nF {#2}
+ {
+ \keys_precompile:nnN { cooking-units } {#2} \l_@@_precompiled_options_tl
+ \l_@@_precompiled_options_tl
+ }
\IfNoValueF {#1}
{ \@@_reference_label_and_persons:n {#1} }
\@@_expand_unit_input:Nn \l_@@_original_unit_tl {#3}
@@ -6879,113 +7002,91 @@ and the derived file cooking-units.sty.
\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:
+ \bool_if:NT \l_@@_pckopt_fourty_two_bool
+ { \@@_set_state_to:n { 42 } }
}
% \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|.
+% \end{macro}
+% \begin{macro}{\@@_rf_initialize_units:}
+% Looks more complicated than it is. |\l_@@_option_unit_tl| is the conversion unit (aka.\
+% the unit that should be printed if a unit-change is requested).
+% If |\cuam| is used there is no unit, but
+% a special marker instead: Set the option unit to the original unit as it does not matter.
+%
+% A bonkers unit change overrules a \enquote{eV} unit change; so if both are true,
+% prefer the bonkers one. All currently active unit-conversions are stored in the property
+% list |\l_@@_change_unit_prop|; get the conversion unit (if exists) and store it into
+% |\l_@@_option_unit_tl|.
% \begin{macrocode}
-\cs_new:Npn \@@_initialize_new_default_units:
+\cs_new:Npn \@@_rf_initialize_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_@@_decided_unit_tl _clist }
- \tl_if_empty:nF {#1} { \keys_set:nn { cooking-units } {#1} }
+ {
+ \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 }
}
- \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{macro}{\@@_rf_setup_bools_for_process_and_prints:}
+% Set some booleans for later use (after parsing). Funnily enough, we can already
+% decide some future interactions like a evaluation of fractions or if the amount should
+% be recalculated to fit the references number of persons. We can do this, as for
+% errors or special-signs we skip the process where those booleans would be needed.
% \begin{macrocode}
-\cs_new:Npn \@@_new_setup_bools_for_process_and_prints:
+\cs_new:Npn \@@_rf_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 }
+ { \bool_set_true:N \l_@@_lokal_eval_fractions_bool }
{
- \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 } }
- }
+% "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 }
+ { \bool_set_true:N \l_@@_lokal_eval_fractions_bool }
}
}
% \end{macrocode}
% \end{macro}
+% \begin{macro}{\@@_initialice_addon_cutext:}
+% 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_set_false:N \l_@@_cutext_use_single_bool
+ \bool_if:NT \l_@@_pckopt_cutext_to_cunum_bool
+ { \@@_set_cmd_type_to:n { cunum } }
+ }
+% \end{macrocode}
+% \end{macro}
%
-% \begin{macro}{ \@@_use_hook_accordingly: }
-% Hooks are straightforward. I know which command I used and thus set the
+% \subsubsection{Hooks}
+%
+% \begin{macro}{ \@@_rf_use_hook_accordingly: }
+% Hooks are straightforward. I know the current command and thus use the
% respective hook.
% \begin{macrocode}
-\cs_new:Npn \@@_use_hook_accordingly:
+\cs_new:Npn \@@_rf_use_hook_accordingly:
{
\l_@@_cmd_hook_tl
\tl_case:NnF \l_@@_cmd_type_tl
@@ -7006,600 +7107,1275 @@ and the derived file cooking-units.sty.
%
%
%
-% \begin{macro}{ \@@_general_checkups: }
-% Doing some general stuff and tests which are done before further processing
-% the amount.
+% \subsubsection{Parsing}
+%
+% \begin{macro}{\@@_rf_parse_the_amount:n}
+% We finally set the amount. Afterwards make sure some tokens have the correct
+% catcode (and remove all spaces). Not quite sure if I should also set the catcode for
+% |-| or others.
+%
+% If the amount is empty or the draft mode is active do some preperations to just print
+% the input, else parse the amount.
% \begin{macrocode}
-\cs_new:Npn \@@_general_checkups:
+\cs_new:Npn \@@_rf_parse_the_amount:n #1
{
- \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: }
+ \@@_expand_amount_input:Nn \l_@@_original_amount_tl {#1}
+ \tl_set_rescan:NnV \l_@@_original_amount_tl
+ {
+ \char_set_catcode_letter:N \_ %
+ \char_set_catcode_ignore:N \ %
+ \char_set_catcode_other:N ? %
+ } \l_@@_original_amount_tl
+ \bool_lazy_any:nTF
+ {
+ { \tl_if_empty_p:N \l_@@_original_amount_tl }
+ { \l_@@_pckopt_draft_bool }
+ }
+ { \@@_rf_prepare_just_print_input: }
+ {
+ \@@_rf_split_and_parse_input:N \l_@@_original_amount_tl
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\@@_rf_prepare_just_print_input:}
+% There is no \enquote{real} \enquote{print the input}, instead act as if there
+% was an error (which is the same as just printing the input).
+% \begin{macrocode}
+\cs_new:Npn \@@_rf_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}{ \@@_rf_split_and_parse_input:N }
+% Here we split and parse the amount. First it is split (separating ranges and
+% times into their separate values). Afterwards the split parts are parsed for
+% special signs, if they contain the allowed input-tokens, etc.
%
+% |\use_none_delimit_by_q_nil:w \q_nil| allows me to \enquote{jump} here in case
+% of an error.
%
+% After everything is done everything is stored into |\l_@@_parsed_seq|.
+% \begin{macrocode}
+\cs_new:Npn \@@_rf_split_and_parse_input:N #1
+ {
+ \tl_set_eq:NN \l_@@_tmpa_tl #1
+ \@@_rf_prepare_input_before_split:N \l_@@_tmpa_tl
+ \@@_rf_split_input:V \l_@@_tmpa_tl
+ \@@_rf_parse_input:N \l_@@_split_input_seq
+ \use_none_delimit_by_q_nil:w \q_nil
+ }
+% \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{macro}{\@@_rf_prepare_input_before_split:N }
+% As the name suggests we make some preparations before we split.
+% We could do this (especially checking for a special sign) during the parsing,
+% but I think it is cleaner to do it now. First checks if a special sign is in the amount,
+% second replaces the times (|\times|, |xX|) or range-sign (|--|) with an internal
+% token.
% \begin{macrocode}
-\cs_new:Npn \@@_process_amount_normally:n #1
+\cs_new:Npn \@@_rf_prepare_input_before_split:N #1
{
- \@@_initialise_new_after_parsing:n {#1}
- \tl_case:NnF \l_@@_parse_and_process_type_tl
+ \@@_rf_prepare_input_check_for_special_sign:N #1
+ \@@_rf_prepare_input_check_for_range_or_times_sign:N #1
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_rf_prepare_input_check_for_special_sign:N,
+% \@@_rf_prepare_input_check_for_range_or_times_sign:N}
+% Loops over all user-given (or predefined) special signs and tests the input
+% for their appearances. If we find one (more are not really necessary), set the state
+% to |special_sign|.
+% \begin{macrocode}
+\cs_new:Npn \@@_rf_prepare_input_check_for_special_sign:N #1
+ {
+ \tl_map_inline:Nn \l_@@_input_allowed_special_signs_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:
+ \tl_if_in:NnT #1 {##1}
+ {
+ \@@_if_state_equal:nF { error }
+ { \@@_set_state_to:n { special_sign } }
+ \tl_map_break:
+ }
}
- { \@@_create_internal_error:nN { process_the_input } \l_@@_parse_and_process_type_tl }
}
% \end{macrocode}
-% \end{macro}
+% Here we replace all valid \enquote{times} signs and \enquote{range} signs
+% with |\q_@@_range|. Both use the same marker as a combination between those
+% two is not allowed (cannot use ranges and times).
%
-% \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.
+% Doing the times-loop first (for no real particular reason), all occurrences of a valid
+% times-sign are replaced. No breaking the loop here as a mix of different signs may
+% be used.
+%
+% Afterwards all occurences of the one valid range sign are replaced by |\q_@@_range|.
+% Furthermore, create an error if times signs and ranges are used both at once.
% \begin{macrocode}
-\cs_new:Npn \@@_process_amount_special:
+\cs_new:Npn \@@_rf_prepare_input_check_for_range_or_times_sign:N #1
{
- \@@_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: }
+ \tl_map_inline:Nn \l_@@_input_times_sign_tl
+ {
+ \tl_if_in:NnT #1 {##1}
+ {
+ \tl_replace_all:Nnn #1 {##1} { \q_@@_range }
+ \bool_set_true:N \l_@@_rf_contains_times_bool
+ }
+ }
+ \tl_if_in:NVT #1 \l_@@_input_range_sign_tl
+ {
+ \tl_replace_all:NVn #1 \l_@@_input_range_sign_tl { \q_@@_range }
+ \bool_set_true:N \l_@@_rf_contains_range_bool
+ \bool_if:NT \l_@@_rf_contains_times_bool
+ { \@@_create_error:n { range-and-times-not-allowed } }
+ }
}
% \end{macrocode}
% \end{macro}
%
+% \begin{macro}{\@@_rf_split_input:n, \@@_rf_split_input:V}
+% Here the splitting the amount into a sequence of values is done.
+% Sequences are quite handy here as we can just loop over all split items
+% and we have an arbitrary number of parts (1, 2 or even 20).
%
-% \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}.
+% Not quite sure if keeping the spaces is necessary, but I guess this is a minor
+% optimisation (as |keep_spaces| does not actively remove spaces).
+%
+% After the \enquote{main} splitting we still need to make some furhter splitting
+% for frations. This does not result into additional seq-items.
+%
+% After everything is done, the split parts are stored into the sequence
+% |\l_@@_split_input_seq|.
% \begin{macrocode}
-\cs_new:Npn \@@_prepare_fourty_two_amount:
+\cs_new:Npn \@@_rf_split_input:n #1
{
- \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 { (!) } }
+ \seq_clear:N \l_@@_split_input_seq
+ \seq_set_split_keep_spaces:Nnn \l_@@_tmpa_seq { \q_@@_range } {#1}
+ \int_set:Nn \l_@@_nr_of_items { \seq_count:N \l_@@_tmpa_seq }
+ \bool_if:NT \l_@@_rf_contains_range_bool
+ {
+ \int_compare:nNnT { \l_@@_nr_of_items } > { 2 }
+ {
+ \@@_create_error:nf { range-too-many-items }
+ { \int_use:N \l_@@_nr_of_items }
+ }
}
- }
+ \seq_map_function:NN \l_@@_tmpa_seq \@@_rf_split_inividual_item:n
+ }
+\cs_generate_variant:Nn \@@_rf_split_input:n { V }
% \end{macrocode}
% \end{macro}
%
+% \begin{macro}{\@@_rf_split_inividual_item:n}
+% For a fraction the |/| token is neccessary. Thus, if not |/| is found we have a normal
+% number.
%
+% |\l_@@_split_input_seq| contains 4 brace-pairs. First contains a boolean denoting if
+% we have a fraction or not. 2nd, 3rd and 4th contains the inivdual parts of the fraction
+% (2nd contains the mixed-fraction part; 3rd the numerator and 4th the denominator).
+% If there is no fraction we store the number in the 4th brace-pair.
+% \begin{macrocode}
+\cs_new:Npn \@@_rf_split_inividual_item:n #1
+ {
+ \tl_if_in:nnTF {#1} { / }
+ { \@@_rf_split_fraction:ww #1 \q_stop }
+ {
+ %% normal number
+ \tl_if_empty:nT {#1}
+ { \@@_create_error:n { empty-argument } }
+ \seq_put_right:Nn \l_@@_split_input_seq { { \c_false_bool } {} {} {#1} }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
%
-% \subsubsection{Process the input}
+% \begin{macro}{\@@_rf_split_fraction:ww, \@@_rf_split_mixed_fraction:wwn}
+% Here we split the fractions into numerator |#1| and denominator |#2|.
+% A mixed-fraction sign is only allowed in the numerator part, having it in |#2| throws
+% an error (case: |1/2_3|). If a mixed fraction sign is found in |#1| we do furhter splitting,
+% else we store the values in |\l_@@_split_input_seq|.
%
-% \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.
+% Furthermore we set |\l_@@_rf_contains_fraction_bool| to true. This is done for all
+% sequence parts as it changes unit-chaning behavior.
% \begin{macrocode}
-\cs_new:Npn \@@_new_process_number_in_input:
+\cs_new:Npn \@@_rf_split_fraction:ww #1 / #2 \q_stop
{
- \@@_calculate_and_store_in:N \l_@@_number_tmpa_tl
- \@@_post_process_accordingly:NN \l_@@_number_tmpa_tl \q_no_value
+ \bool_set_true:N \l_@@_rf_contains_fraction_bool
+ \tl_if_in:nnT {#2} { _ }
+ { \@@_create_error:n { fraction-wrong-order } }
+ \tl_if_empty:nT {#2}
+ { \@@_create_error:n { empty-argument } }
+ \tl_if_in:nnTF {#1} { _ }
+ {
+ \@@_rf_split_mixed_fraction:wwn #1 \q_stop {#2}
+ }{
+ \tl_if_empty:nT {#1}
+ { \@@_create_error:n { empty-argument } }
+ \seq_put_right:Nn \l_@@_split_input_seq { { \c_true_bool } {} {#1} {#2} }
+ }
+ }
+% \end{macrocode}
+% Straighforward. |#1| is the mixed-fraction part, |#2| is the numerator and |#3|
+% is the denominator. Make sure they are not empty and store them.
+% \begin{macrocode}
+\cs_new:Npn \@@_rf_split_mixed_fraction:wwn #1 _ #2 \q_stop #3
+ {
+ \tl_if_empty:nT {#1}
+ { \@@_create_error:n { empty-argument } }
+ \tl_if_empty:nT {#2}
+ { \@@_create_error:n { empty-argument } }
+ \seq_put_right:Nn \l_@@_split_input_seq { { \c_true_bool } {#1} {#2} {#3} }
}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{ \@@_new_process_range_in_input: }
-% Same as before, this time with two variables.
+%
+%
+% \begin{macro}{\@@_rf_parse_input:N}
+% Now that splitting is done, we start parsing! Using sequences, we jus loop ober
+% every item. (Which is extremly useful as we can loop over 1 or 100 items).
% \begin{macrocode}
-\cs_new:Npn \@@_new_process_range_in_input:
+\cs_new:Npn \@@_rf_parse_input:N #1
{
- \@@_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
+ \seq_clear:N \l_@@_parsed_seq
+ \seq_map_inline:Nn #1
+ { \@@_rf_parse_input:nnnn ##1 }
}
% \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.
+% \begin{macro}{\@@_rf_parse_input:nnnn}
+% Looks more intimidating than it is. The 4 arguments are the ones from
+% |\l_@@_split_input_seq| and are thus:
+% \begin{itemize}
+% \item |#1|: Contains this item a fraction?
+% \item |#2|: mixed-fraction part (if it exists for this item).
+% \item |#3|: numerator part (if it exists for this item).
+% \item |#4|: number part or (if it is a fraction) or denominator.
+% \end{itemize}
+%
+% If we have a fraction we parse the inividual parts and store them temporarily in
+% tl's. Afterwards we remove all minus signs, but remember if the whole fraction is
+% positive or negative. Store the parsed parts into |\l_@@_parsed_seq| (this time with
+% 5 items!).
%
-% 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.
+% If we just have a single number, parse it and store it in |\l_@@_parsed_seq|.
+%
+% |\l_@@_parsed_seq| contains 5 items. First is, again, if the item contains a fraction.
+% 2nd is new, is only used in combination with fractions (else it is empty) and stores
+% if the fraction is positive or negative (aka.\ if there is a minus sign in front of it
+% during printing).
% \begin{macrocode}
-\cs_new:Npn \@@_new_process_fraction_in_input:
+\cs_new:Npn \@@_rf_parse_input:nnnn #1 #2#3#4
{
- \@@_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:nTF { number }
- {
- \@@_convert_fraction_to_number_in_input:NNN
- \l_@@_mixed_fraction_tl
- \l_@@_number_tmpa_tl
- \l_@@_number_tmpb_tl
- }{
- \@@_post_process_fraction_accordingly:NNN
- \l_@@_mixed_fraction_tl
- \l_@@_number_tmpa_tl
+ \bool_set_eq:NN \l_@@_rf_check_fraction_bool #1
+ \bool_if:NTF #1
+ {
+ \@@_parse_input_and_safe_in:nN {#2} \l_@@_mixed_fraction_tl
+ \@@_parse_input_and_safe_in:nN {#3} \l_@@_number_tmpa_tl
+ \@@_parse_input_and_safe_in:nN {#4} \l_@@_number_tmpb_tl
+ \@@_rf_frac_remove_minus:NNN
+ \l_@@_mixed_fraction_tl
+ \l_@@_number_tmpa_tl
+ \l_@@_number_tmpb_tl
+ \@@_rf_seq_put_right:NnVVVV
+ \l_@@_parsed_seq
+ {#1} \l_@@_minus_bool
+ \l_@@_mixed_fraction_tl
+ \l_@@_number_tmpa_tl
\l_@@_number_tmpb_tl
+ }{
+ \@@_parse_input_and_safe_in:nN {#4} \l_@@_number_tmpb_tl
+ \@@_rf_seq_put_right:NnnnnV \l_@@_parsed_seq
+ {#1} { } { } { } \l_@@_number_tmpb_tl
}
}
% \end{macrocode}
-% This command loops over each variable, removes the minus and reverses the
-% bool if needed.
+% \end{macro}
+%
+%
+% \begin{macro}{\@@_rf_frac_remove_minus:NNN}
+% Removes the minus signs from the inividual fraction parts, but remembers
+% if we have removed an odd or even number of minus signs. This will determine
+% if the whole fraction is negative or not.
% \begin{macrocode}
-\cs_new:Npn \@@_process_and_remove_minus_in_fraction:NNNN #1 #2#3#4
+\cs_new:Npn \@@_rf_frac_remove_minus:NNN #1#2#3
{
- \bool_set_false:N #1
- \@@_check_minus_remove_and_reverse:NN
- #1 #2#3#4
- \q_nil
- }
+ \bool_set_false:N \l_@@_minus_bool
+ \tl_if_empty:NF #1
+ {
+ \exp_last_unbraced:NNV
+ \@@_rf_frac_remove_minus_aux:Nww #1 #1 \q_stop
+ }
+ \exp_last_unbraced:NNV
+ \@@_rf_frac_remove_minus_aux:Nww #2 #2 \q_stop
+ \exp_last_unbraced:NNV
+ \@@_rf_frac_remove_minus_aux:Nww #3 #3 \q_stop
+ }
% \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.
+% Not sure if |\token_if_eq_charcode| is the best choice, but I think I stole it from
+% \pkg{siunitx}, so it should be fine.
% \begin{macrocode}
-\cs_new:Npn \@@_convert_fraction_to_number_in_input:NNN #1#2#3
+\cs_new:Npn \@@_rf_frac_remove_minus_aux:Nww #1 #2#3 \q_stop
{
- \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:
+ \token_if_eq_charcode:NNTF #2 -
+ {
+ \@@_bool_reverse:N \l_@@_minus_bool
+ \tl_set:Nn #1 {#3}
}
+ { \tl_set:Nn #1 {#2#3} }
}
% \end{macrocode}
% \end{macro}
%
%
-% \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.
+% \subsubsection{Processing}
+%
%
-% 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{macro}{\@@_rf_process_amount_special:}
+% In case the current state is not-normal we end up here. No (real) processing is
+% done here, just a warning message is printed. Here we also change the input
+% if \opt{42} is used.
% \begin{macrocode}
-\cs_new:Npn \@@_new_print_amount_correctly:
+\cs_new:Npn \@@_rf_process_amount_special:
{
- \@@_if_state_equal:nTF { error }
- { \l_@@_original_amount_tl }
+ \@@_if_state_equal:nT { special_sign }
+ { \msg_warning:nnV { cooking-units } { amount-not-known } \l_@@_original_amount_tl }
+ \bool_if:NTF \l_@@_pckopt_fourty_two_bool
+ { \@@_rf_prepare_fourty_two_amount: }
+ { \seq_set_eq:NN \l_@@_processed_seq \l_@@_parsed_seq }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_rf_process_amount_normally:n}
+% Now that we know e.g.\ if we have an unit change (no special sign, fractions?, etc.)
+% we do some more initializing. Afterwards, process the input (e.g.\ evaluate fractions
+% if needed, scale the amount depending on the unit, etc.).
+% \begin{macrocode}
+\cs_new:Npn \@@_rf_process_amount_normally:n #1
+ {
+ \@@_rf_initialise_after_parsing:n {#1}
+ \seq_clear:N \l_@@_processed_seq
+ \seq_map_inline:Nn \l_@@_parsed_seq
{
- \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 }
+ \@@_rf_process_amount_normally:nnnnn ##1
}
}
% \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.
+% \begin{macro}{\@@_rf_process_amount_normally:nnnnn}
+% Looks more intimidating (again) as it is. Here are the arguments:
+%
+% \begin{itemize}
+% \item |#1|: Contains this item a fraction? (Boolean)
+% \item |#2|: (Only non-empty for fractions) Is the fraction negative?
+% \item |#2|: mixed-fraction part (if it exists for this item).
+% \item |#3|: numerator part (if it exists for this item).
+% \item |#4|: number part or denominator (if it is a fraction) .
+% \end{itemize}
%
-% Else, parse the unit depending on the command used. For |\cuam| no unit
-% is printed, but a phrase can be required.
+% Two cases here: Do we have a fraction or not.
+%
+% If we have a fraction and no evaluation is done, do nothing essentially.
+% Else an evaluation of the fraction is required and the whole thing is calculated.
+% Do some Division-by-zero checks; make sure the resulting number is negative
+% (|#2| argument) and do some further calculations with the resulting number.
+% Afterwards, store the number in |\l_@@_processed_seq|. (Note that we define the
+% fraction-boolean as |\c_false_bool|).
+%
+% If the current item is simply a number, do some further calculations and store the result
+% in |\l_@@_processed_seq|.
+%
% \begin{macrocode}
-\cs_new:Npn \@@_new_print_unit_correctly:
+\cs_new:Npn \@@_rf_process_amount_normally:nnnnn #1#2#3#4#5
{
- \@@_if_state_equal:nTF { error }
- {
- \tl_case:NnF \l_@@_cmd_type_tl
- { \c_@@_cmd_type_cuam_tl { } }
- { \@@_print_unit_in_case_of_error: }
- }
+ \bool_if:NTF #1
{
- \tl_case:NnF \l_@@_cmd_type_tl
+ \bool_if:NTF \l_@@_lokal_eval_fractions_bool
{
- \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: }
+ \bool_set_false:N \l_@@_rf_contains_fraction_bool
+ \fp_compare:nNnT {#5} = { 0 }
+ { \@@_create_error:n { Division-by-zero } }
+ \@@_tl_set_eval:Nn \l_@@_number_tmpb_tl { #3 + #4/#5 }
+ \int_compare:nNnT {#2} = { \c_one_int }
+ { \tl_put_left:Nn \l_@@_number_tmpb_tl { - } }
+ \@@_calculate_and_store_in:N \l_@@_number_tmpb_tl
+ \@@_rf_seq_put_right:NnnnnV \l_@@_processed_seq
+ { \c_false_bool } { } {} {} \l_@@_number_tmpb_tl
+ }{
+ \@@_rf_seq_put_right:Nnnnnn \l_@@_processed_seq
+ {#1} {#2} {#3} {#4} {#5}
+ }
+ }{
+ \tl_if_empty:nF {#2}
+ { \@@_create_internal_error:nN
+ { non-empty-sign-for-non-fraction } \l_@@_original_amount_tl
}
- { \@@_create_internal_error:nN { print-unit-acc } \l_@@_cmd_type_tl }
+ \tl_set:Nn \l_@@_number_tmpb_tl {#5}
+ \@@_calculate_and_store_in:N \l_@@_number_tmpb_tl
+ \@@_rf_seq_put_right:NnnnnV \l_@@_processed_seq
+ {#1} { } { } { } \l_@@_number_tmpb_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.
+% \end{macro}
+%
+% \begin{macro}{\@@_rf_post_process_amount:}
+% Doing some post-processing. This is dependend on which command was used
+% (\cCutext\ has some other functionalities than |\cuam|).
% \begin{macrocode}
-\cs_new:Npn \@@_print_unit_in_case_of_error:
+\cs_new:Npn \@@_rf_post_process_amount:
{
- \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 }
- }
+ \tl_case:NnF \l_@@_cmd_type_tl
+ {
+ \c_@@_cmd_type_cunum_tl { \@@_rf_cunum_post_process:N \l_@@_processed_seq }
+ \c_@@_cmd_type_cCutext_tl { \@@_rf_cutext_post_process:N \l_@@_processed_seq }
+ \c_@@_cmd_type_cuam_tl { \@@_cuam_post_process:N \l_@@_processed_seq }
+ }{
+ \@@_create_internal_error:nN { post-process } \l_@@_cmd_type_tl
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\@@_rf_cunum_post_process:N}
+% Nothing is done here.
+% \begin{macrocode}
+\cs_new:Npn \@@_rf_cunum_post_process:N #1 { }
% \end{macrocode}
% \end{macro}
%
+% \begin{macro}{\@@_rf_cutext_post_process:N}
+% Ok, first decide if we need the plural or singular version of the unit. We can do it
+% now as we will not \enquote{reduce} the amounts (as |\cuam| is able to do).
%
-% \begin{macro} { \@@_print_number_accordingly:N }
-% Prints the input |#1| according to the used command.
-% This command is
-% also used in ranges.
+% If numerals should be used and we do \emph{not} have a fraction (in all items)
+% we first check if all items only contain integers. If they all are integers, check if numerals
+% can be used.
% \begin{macrocode}
-\cs_new:Npn \@@_print_number_accordingly:N #1
+\cs_new:Npn \@@_rf_cutext_post_process:N #1
{
- \tl_case:NnF \l_@@_cmd_type_tl
+ \@@_rf_check_plural:N #1
+ \bool_lazy_and:nnT
+ { \l_@@_lokal_numeral_bool }
+ { ! \l_@@_rf_contains_fraction_bool }
+ {
+ \@@_rf_check_if_decimal:NNTF #1 \l_@@_numbers_to_check_seq
+ { \bool_set_false:N \l_@@_lokal_numeral_bool }
+ { \@@_rf_check_if_numerals_can_be_used:N \l_@@_numbers_to_check_seq }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{ \@@_rf_check_plural:N }
+% For plural-checking we alawys use the last item (and hope that in no language we would
+% need to e.g.\ use the first item). |\l_@@_tmpa_tl| contains 5 braced pairs; so one
+% expansion allows |\@@_rf_check_plural_aux:nnnnn| to get them.
+% \begin{macrocode}
+\cs_new:Npn \@@_rf_check_plural:N #1
+ {
+ \seq_get_right:NN #1 \l_@@_tmpa_tl
+ \exp_after:wN \@@_rf_check_plural_aux:nnnnn \l_@@_tmpa_tl
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_rf_check_plural_aux:nnnnn}
+% So \dots\ the algorithm used to determine plural or singular is depending on the
+% current language (french has other rules than english or german) and if we have a
+% fraction or not. Call the respective command and hope that the result is correct.
+% \begin{macrocode}
+\cs_new:Npn \@@_rf_check_plural_aux:nnnnn #1#2#3#4#5
+ {
+ \bool_if:NTF #1
{
- \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 }
+ \@@_culang_let:nnN { pluraltest } { fraction } \l_@@_translation_tmpa_tl
+ \use:c { @@_pluraltest_fraction_ \l_@@_translation_tmpa_tl :nnn }
+ {#3} {#4} {#5}
+ }{
+ \@@_culang_let:nnN { pluraltest } { normal } \l_@@_translation_tmpa_tl
+ \use:c { @@_pluraltest_normal_ \l_@@_translation_tmpa_tl :n } {#5}
}
- { \@@_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{macro}{\@@_rf_check_if_decimal:NN, \@@_rf_check_if_decimal_aux:Nnnnnn}
+% Test if all items are integers or not. As the numbers are stored in tl's and not in
+% fp's or int's we can just check for a |.|. If one is found, we have a decimal. To do this
+% efficiently we loop through all items, get the needed number (we have no fractions,
+% we checked that earlier), store it in |#2| for later use and |\tl_put_right:Nn| it into
+% |\l_@@_tmpa_tl|. |\l_@@_tmpa_tl| will then contain all numbers that need to be
+% checked as a single string. |#2| is a sequence we can use in the future (is is more
+% practical as it only contains a single number and not 6 braced pairs; making looping
+% easier it can be placed directly where we need it).
+% \begin{macrocode}
+\prg_new_conditional:Npnn \@@_rf_check_if_decimal:NN #1#2 { TF }
+ {
+ \tl_clear:N \l_@@_tmpa_tl
+ \seq_clear:N #2
+ \seq_map_inline:Nn #1
+ {
+ \@@_rf_check_if_decimal_aux:Nnnnnn #2 ##1
+ }
+ \tl_if_in:NnTF \l_@@_tmpa_tl { . }
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+% \end{macrocode}
+%
% \begin{macrocode}
-\cs_new:Npn \@@_print_range_accordingly:NN #1#2
+\cs_new:Npn \@@_rf_check_if_decimal_aux:Nnnnnn #1#2#3#4#5#6
{
- \@@_print_number_accordingly:N #1
- \@@_print_range_sign:
- \@@_print_number_accordingly:N #2
+ \tl_put_right:Nn \l_@@_tmpa_tl {#6}
+ \seq_put_right:Nn #1 {#6}
}
% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \begin{macro}{\@@_rf_check_if_numerals_can_be_used:N}
+% The items of sequence in |#1| only contains a number and not the 6 braced pairs.
+% This makes this loop a lot more straightforward to write.
% \begin{macrocode}
-\cs_new:Npn \@@_print_range_sign:
+\cs_new:Npn \@@_rf_check_if_numerals_can_be_used:N #1
{
- \@@_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 }
+ \seq_map_inline:Nn #1
+ {
+ \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
+ \seq_map_break:
}
- { \tl_use:N \l_@@_cunum_range_sign_tl }
- }
+ }
}
% \end{macrocode}
% \end{macro}
%
-% \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{macro}{\@@_cuam_post_process:N}
+% Ok, shit gets real at this point. Compared to the other post process stuffs (especially
+% |\cunum|) here we do more complicated things. This is mostly due to |\cuam| allowing
+% phrases (\enquote{12} to \enquote{1 Dutzend}). This needs its own processing algorithm.
+% Furthermore, we still allow numerals (and we need to be careful because both can be used
+% at the same time). Of course, all this is only done if the input conists of only integers (and
+% no fractions)
% \begin{macrocode}
-\cs_new:Npn \@@_post_process_accordingly:NN #1#2
+\cs_new:Npn \@@_cuam_post_process:N #1
{
- \tl_case:NnF \l_@@_cmd_type_tl
+ \bool_if:NF \l_@@_rf_contains_fraction_bool
{
- \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
+ \@@_rf_check_if_decimal:NNTF #1 \l_@@_numbers_to_check_seq
+ { \bool_set_false:N \l_@@_lokal_numeral_bool }
+ {
+ \bool_if:NT \l_@@_pckopt_use_phrases_bool
+ { \@@_rf_cuam_post_process_input_phrases:NN #1 \l_@@_numbers_to_check_seq }
+ \bool_if:NT \l_@@_lokal_numeral_bool
+ { \@@_rf_check_if_numerals_can_be_used:N \l_@@_numbers_to_check_seq }
+ }
}
}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{ \@@_post_process_fraction_accordingly:NNN }
-% Decided to make this into its own command. This post processes fractions
-% which is only needed by \cCutext.
+% \begin{macro}{\@@_rf_cuam_post_process_input_phrases:NN}
+% This algorithm is thankfully much simpler compared to the old one!
+% First, we get the property list for the current language that contains
+% the phrases. If there are none (aka.\ if it is equal to |\c_@@_no_translation_str|)
+% we just skip to the end. Else we get the number-sequence from the property
+% list. |#2| is the list of numbers from the input. |\l_@@_number_tmpa_tl| will contain the
+% largest common divisor $l$ between those numbers (e.g. $2$, $4$ and $6$ have the
+% largest common divisor of $l=2$; $12$ and $16$ have $l=4$). If it is $l=1$ we do
+% nothing (as there is none). Else, take it as a upper cap (there cannot be a common
+% divisor above $l$; thus only check phrase numbers $n \leq l$).
% \begin{macrocode}
-\cs_new:Npn \@@_post_process_fraction_accordingly:NNN #1#2#3
+\cs_new:Npn \@@_rf_cuam_post_process_input_phrases:NN #1#2
{
- \tl_case:NnF \l_@@_cmd_type_tl
+ \@@_culang_get_phrase_prop:N \l_@@_phrase_prop
+ \tl_if_eq:NNT \c_@@_no_translation_str \l_@@_phrase_prop
+ { \use_none_delimit_by_q_stop:w }
+ \prop_get:NnN \l_@@_phrase_prop { seq } \l_@@_phrase_numbers_seq
+ \@@_get_largest_common_divisor:NN #2 \l_@@_largest_common_divisor_int
+ \int_compare:nNnF { \l_@@_largest_common_divisor_int } = { 1 }
{
- \c_@@_cmd_type_cunum_tl { }
- \c_@@_cmd_type_cCutext_tl { \@@_cutext_post_process_fraction_input:NNN #1#2#3 }
- \c_@@_cmd_type_cuam_tl { }
- }{
- \@@_create_internal_error:nN { post-process-frac } \l_@@_cmd_type_tl
+ \@@_find_common_phrase:NNV #1#2 \l_@@_largest_common_divisor_int
}
+ \use_none_delimit_by_q_stop:w
+ \q_stop
}
% \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{macro}{\@@_get_largest_common_divisor:NN, \@@_get_largest_common_divisor_aux:Nn}
+% |#1| is the sequence of numbers we want to check (we need in later; thus no
+% \enquote{pop}); in |#2| we will store the largest common
+% divisor $l$. The \enquote{find the largest common divisor} algorithm is only needed
+% if we have more than $1$ item (so if we have a range or a times).
+%
+% $l$ must be the same for all numbers.
+%
% \begin{macrocode}
-\cs_new_protected:Npn \@@_print_numerical_input:N #1
+\cs_new:Npn \@@_get_largest_common_divisor:NN #1#2
{
- \tl_if_in:NnT #1 { . }
+ \seq_get_left:NN #1 \l_@@_tmpa_tl
+ \int_set:Nn #2 { \l_@@_tmpa_tl }
+ \bool_lazy_or:nnT
+ \l_@@_rf_contains_range_bool
+ \l_@@_rf_contains_times_bool
+ {
+ \seq_map_inline:Nn #1
+ {
+ \@@_get_largest_common_divisor_aux:Nn #2 {##1}
+ \int_compare:nNnT {#2} = { 1 }
+ { \seq_map_break: }
+ }
+ }
+ }
+% \end{macrocode}
+%
+% The source for the algorithm is \url{https://en.wikipedia.org/wiki/Euclidean_algorithm#Implementations}.
+% To make my future life easier, here is the copy-and-pasted code:
+% \begin{verbatim}
+% function gcd(a, b)
+% while b \neq 0
+% t := b
+% b := a mod b
+% a := t
+% return a
+% \end{verbatim}
+% and here is the algorithm with the current variables:
+% \begin{verbatim}
+% function gcd(#1, b)
+% while b \neq 0
+% a := b
+% b := #1 mod b
+% #1 := a
+% return #2
+% \end{verbatim}
+%
+% \begin{macrocode}
+\cs_new:Npn \@@_get_largest_common_divisor_aux:Nn #1#2
+ {
+ \int_set:Nn \l_@@_tmpb_int {#2}
+ \int_until_do:nNnn { \l_@@_tmpb_int } = { 0 }
{
- \@@_culang_let:nnN { name } { decimal-mark } \l_@@_translation_tmpa_tl
- \tl_replace_once:Nnn #1 { . } { \l_@@_translation_tmpa_tl }
+ \int_set_eq:NN \l_@@_tmpa_int \l_@@_tmpb_int
+ \int_set:Nn \l_@@_tmpb_int
+ { \int_mod:nn {#1} { \l_@@_tmpb_int } }
+ \int_set_eq:NN #1 \l_@@_tmpa_int
}
- \tl_replace_once:Nnn #1 { - } \c_@@_minus_tl
- #1
}
% \end{macrocode}
% \end{macro}
%
%
-% \begin{macro}{ \@@_print_fractions:Nnn }
-% The name of this function is the name of the game: It prints fractions.
-% The minus sign is always put in front of the fraction.
%
-% The first argument regards the mixed fraction part. It is either empty
-% or not empty. If empty, do nothing. Else insert and add space.
+% \begin{macro}{\@@_find_common_phrase:NNn}
+% Ok, this one is complicated.
+% |#1| is the original prcoess sequence; |#2| is the sequence of numbers-to-check
+% (which were extracted from |#1| in a previous step to make loops easier);
+% |#3| is the largest common divisor $l$ which requires $l>1|$.
%
-% The 2nd and 3rd argument are the nominator and denominator, they are
-% used in the fraction command directly.
+% As a reminder, |\l_@@_phrase_numbers_seq| contains two braced-pairs:
+% first is the phrase-number, second is a boolean which defines if multiples of the
+% phrase-number should be checked too. The phrase-number is thus gained by
+% |\use_i:nn ##1| which must be smaller or equal to $l$ (I explain why in a previous
+% function). So do nothing if it is larger. |\l_@@_phrase_numbers_seq| is also sorted
+% from largest to smallest, so no |\seq_map_break:| unless we found a number.
%
-% All three arguments are currently tl varables, but only the first is a dedicated
-% \enquote{can only take one token}.
+% If for the current phrase number all values have an integer quotient (|\l_@@_tmpa_bool|
+% remains |true| after |\@@_find_common_phrase_aux:Nnn|) (integer quotients are stored in
+% |\l_@@_reduced_numbers_seq|) we gain the other properties from this phrase-number
+% like the phrase-text (\enquote{Dutzend}) and its gender; break the loop.
%
-% Since v.1.10(alpha) it also prints the minus sign (hopefully correct).
+% If the loop was terminated via a break |\l_@@_tmpa_bool| remains |true| and
+% we continue with updating the values in sequences |#1| and |#2|.
% \begin{macrocode}
-\cs_new:Npn \@@_print_fractions:Nnn #1#2#3
+\cs_new:Npn \@@_find_common_phrase:NNn #1 #2#3
{
- \bool_if:NT \l_@@_minus_bool { \c_@@_minus_tl }
- \tl_if_empty:NF #1
+ \bool_set_false:N \l_@@_lokal_phrase_bool
+ \seq_map_inline:Nn \l_@@_phrase_numbers_seq
+ {
+ \int_compare:nNnF { \use_i:nn ##1 } > {#3}
+ {
+ \bool_set_true:N \l_@@_tmpa_bool
+ \seq_clear:N \l_@@_reduced_numbers_seq
+ \@@_find_common_phrase_aux:Nnn #2 ##1
+ \bool_if:NT \l_@@_tmpa_bool
+ {
+ \int_compare:nNnTF { \l_@@_tmpa_int } = { 1 }
+ { \prop_get:NnN \l_@@_phrase_prop { ##1 } \l_@@_phrase_text_tl }
+ { \prop_get:NnN \l_@@_phrase_prop { ##1 - pl } \l_@@_phrase_text_tl }
+ \prop_get:NnN \l_@@_phrase_prop { ##1 - gender } \l_@@_phrase_gender_tl
+ \seq_map_break:
+ }
+ }
+ }
+ \bool_if:NT \l_@@_tmpa_bool
{
- #1
- \skip_horizontal:N \l_@@_mixed_frac_dim
+ \bool_set_true:N \l_@@_lokal_phrase_bool
+ \seq_set_eq:NN #2 \l_@@_reduced_numbers_seq
+ \@@_update_values:NN #1 \l_@@_reduced_numbers_seq
+ }
+ }
+\cs_generate_variant:Nn \@@_find_common_phrase:NNn { NNV }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_find_common_phrase_aux:Nnn}
+% Thankfully a lot more simplified compared to a previous version.
+% The idea is simple: loop over all numbers in |#1| (the \enquote{numbers-to-check}
+% sequence) and figure out if all its items are a multiple of the phrase-number |#2|.
+% If multiples should not be checked (boolean |#3|) we set the multiple to be
+% $1$. Else we use |\int_div_truncate:nn| to find the closest (checks Wikipedia for
+% terminology) integer quotient. Afterwards we see if the quotient (calculated ot $1$)
+% times the phrase number |#2| is equal to the original value (We check if the modulo is
+% $0$). We do not use the modulo directly as we need the quotient for further uses
+% (if an integer quotient without reminder exists).
+%
+% If integer quotient times phrase number equals the original one, we store the
+% quotient in |\l_@@_reduced_numbers_seq| for later usage. If we have one whiff
+% we break the loop as there are no integer quotients for the current phrase-number.
+%
+% \begin{macrocode}
+\cs_new:Npn \@@_find_common_phrase_aux:Nnn #1 #2#3
+ {
+ \seq_map_inline:Nn #1
+ {
+ \bool_if:NTF #3
+ { \int_set:Nn \l_@@_tmpa_int { 1 } }
+ { \int_set:Nn \l_@@_tmpa_int { \int_div_truncate:nn {##1} {#2} } }
+ \int_compare:nNnTF { \l_@@_tmpa_int * #2 } = {##1}
+ { \seq_put_right:NV \l_@@_reduced_numbers_seq \l_@@_tmpa_int }
+ { \bool_set_false:N \l_@@_tmpa_bool \seq_map_break: }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\@@_update_values:NN, \@@_update_values_aux:Nnnnnn}
+% Here we update the numbers in |\l_@@_processed_seq| (given in |#1|) with
+% the integer quotient numbers in |#2|). Do a copy of |#1| (to loop over it) than clear
+% the process-sequence |#1|. Looping is not necessary as we technically know
+% every information, but this makes it a bit easier in case I change things in the future
+% (I can also add some tests).
+\cs_new:Npn \@@_update_values:NN #1#2
+ {
+ \seq_set_eq:NN \l_@@_tmpa_seq #1
+ \seq_clear:N #1
+ \seq_map_inline:Nn \l_@@_tmpa_seq
+ {
+ \@@_update_values_aux:NNnnnnn #1 #2 ##1
}
- \@@_frac:nn {#2} {#3}
+ }
+\cs_new:Npn \@@_update_values_aux:NNnnnnn #1 #2#3#4#5#6#7
+ {
+ \bool_if:NT #3
+ { \@@_create_internal_error:nn { fraction-wrong-value } {#3} }
+ \tl_if_empty:nF {#4#5#6}
+ { \@@_create_internal_error:nn { update-values-non-empty } {#4;;#5;;#6} }
+ \seq_pop_left:NN #2 \l_@@_tmpa_tl
+ \@@_rf_seq_put_right:NnnnnV #1
+ {#3} {#4} {#5} {#6} \l_@@_tmpa_tl
}
% \end{macrocode}
% \end{macro}
%
%
+% \subsubsection{Printing}
%
+% \begin{macro}{\@@_rf_prepare_amount_printing:N}
+% Printing the amount depends on the commands and the results-to-be-printed
+% are stored into |\l_@@_prepared_printing_seq|. If fractions and ranges are combined,
+% a small space is inserted between the fraction and the range sign, but \emph{only}
+% if it is \emph{not} the last item in the sequence. |\l_@@_nr_of_items| stores the number
+% of items in the sequence. If the last item in the loop is encountered (by checking if
+% the index |##1| is equal to |\l_@@_tmpa_int|) give the auxiliary function |\c_true_bool|
+% and it will figure out the rest.
+% \begin{macrocode}
+\cs_new:Npn \@@_rf_prepare_amount_printing:N #1
+ {
+ \tl_case:NnF \l_@@_cmd_type_tl
+ {
+ \c_@@_cmd_type_cunum_tl
+ { \cs_set_eq:NN \@@_print_number:n \@@_print_number_default:n }
+ \c_@@_cmd_type_cCutext_tl
+ { \cs_set_eq:NN \@@_print_number:n \@@_cutext_print_number:n }
+ \c_@@_cmd_type_cuam_tl
+ { \cs_set_eq:NN \@@_print_number:n \@@_cuam_print_number:n }
+ }
+ { \@@_create_internal_error:nN { post-process } \l_@@_cmd_type_tl }
+ \bool_set_false:N \l_@@_seperator_after_fraction_bool
+ \seq_clear:N \l_@@_prepared_printing_seq
+ \seq_map_indexed_inline:Nn #1
+ {
+ \int_compare:nNnTF { \l_@@_nr_of_items } = {##1}
+ { \@@_rf_prepare_amount_printing_aux:nnnnnn { \c_true_bool } }
+ { \@@_rf_prepare_amount_printing_aux:nnnnnn { \c_false_bool } }
+ ##2
+ }
+ }
+% \end{macrocode}
+% \end{macro}
%
-% \subsection {Parsing and checking numbers}
+% \begin{macro}{\@@_rf_prepare_amount_printing_aux:nnnnnn}
+% |#1| is a boolean which signifies if the last item of the sequence is encountered.
+% |#2| to |#6| are our typical sequence-arguments. All this function acutally does
+% is to store the to-be-printed stuff into |\l_@@_prepared_printing_seq|. Could be
+% optimized a bit more. The booleans are set here so that later on |\seq_use:Nn| can
+% be used.
+% \begin{macrocode}
+\cs_new:Npn \@@_rf_prepare_amount_printing_aux:nnnnnn #1#2#3#4#5#6
+ {
+ \bool_if:NTF #2
+ {
+ \seq_put_right:Nn \l_@@_prepared_printing_seq
+ {
+ \@@_print_fraction:nnnn {#3} {#4} {#5} {#6}
+ \bool_set_false:N \l_@@_cutext_uppercase_word_bool
+ \bool_if:NTF #1
+ { \bool_set_false:N \l_@@_seperator_after_fraction_bool }
+ { \bool_set_true:N \l_@@_seperator_after_fraction_bool }
+ }
+ }{
+ \seq_put_right:Nn \l_@@_prepared_printing_seq
+ {
+ \@@_print_number:n {#6}
+ \bool_set_false:N \l_@@_cutext_uppercase_word_bool
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
%
-% 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{macro}{\@@_print_fraction:nnnn}
+% Printing a fraction is quite easy and straightforward. Use |\@@_print_number_default:n|
+% for correct decimal-printing.
% \begin{macrocode}
-\cs_new:Npn \@@_create_internal_error:nN #1#2
+\cs_new:Npn \@@_print_fraction:nnnn #1#2#3#4
{
- \@@_set_state_to:n { error }
- \msg_error:nnnV { cooking-units } { internal-error } {#1} #2
+ \int_compare:nNnT {#1} = { 1 } { \c_@@_minus_tl }
+ \tl_if_empty:nF {#2}
+ {
+ \@@_print_number_default:n {#2}
+ \skip_horizontal:N \l_@@_mixed_frac_dim
+ }
+ \@@_frac:nn { \@@_print_number_default:n {#3} } { \@@_print_number_default:n {#4} }
}
-\cs_new:Npn \@@_create_error:n #1
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \begin{macro}{\@@_print_number:n}
+% This command will be redefined.
+% \begin{macrocode}
+\cs_new:Npn \@@_print_number:n #1 {}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_print_number_default:n}
+% Do two things: Replace the dot with the correct decimal-sign of the current language
+% and replace the |-| token with the correct minus sign.
+% \begin{macrocode}
+\cs_new:Npn \@@_print_number_default:n #1
{
- \@@_set_state_to:n { error }
- \msg_error:nnV { cooking-units } {#1} \l_@@_original_amount_tl
+ \tl_set:Nn \l_@@_tmpa_tl {#1}
+ \tl_if_in:NnT \l_@@_tmpa_tl { . }
+ {
+ \@@_culang_let:nnN { name } { decimal-mark } \l_@@_translation_tmpa_tl
+ \tl_replace_once:Nnn \l_@@_tmpa_tl { . } { \l_@@_translation_tmpa_tl }
+ }
+ \tl_replace_once:Nnn \l_@@_tmpa_tl { - } \c_@@_minus_tl
+ \l_@@_tmpa_tl
}
-\cs_new:Npn \@@_create_error_and_stop:n #1
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_cutext_print_number:n, \@@_cutext_print_input_aux:nn, \@@_cutext_print_input_aux:nV}
+% For \cCutext\ we pretty much always print the numbers using |\@@_print_number_default:n| (like |\cunum| does). However, \cCutext\ have the
+% ability to print numerals (if the input can be transformed into one).
+%
+% For numerals we captialize in the case of |\Cutext| and print it normally (assuming
+% lowercase) for |\cutext|. If the number is equal to $1$ we use the special
+% |one(m)|, |one(f)| or |one(n)| translation (which also gets captialized if needed).
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_cutext_print_number:n #1
{
- \@@_create_error:n {#1}
- \use_none_delimit_by_q_nil:w
+ \bool_if:NTF \l_@@_lokal_numeral_bool
+ { \@@_cutext_print_input_aux:nV {#1} \l_@@_decided_unit_tl }
+ { \@@_print_number_default:n {#1} }
}
-\cs_new:Npn \@@_create_error:nn #1#2
+\cs_new_protected:Npn \@@_cutext_print_input_aux:nn #1#2
{
- \@@_set_state_to:n { error }
- \msg_error:nnnV { cooking-units } {#1} {#2} \l_@@_original_amount_tl
+ \int_compare:nNnTF {#1} = { 1 }
+ {
+ \@@_culang_one_let:NnT \l_@@_translation_tmpa_tl {#2}
+ {
+ \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
+ }{
+ \bool_if:NTF \l_@@_cutext_uppercase_word_bool
+ { \@@_print_Numeral:n {#1} }
+ { \@@_print_numeral:n {#1} }
+ }
}
+\cs_generate_variant:Nn \@@_cutext_print_input_aux:nn { nV }
% \end{macrocode}
% \end{macro}
%
-% \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{macro}{\@@_cuam_print_number:n, \@@_cuam_print_numerical_input_aux:nn, \@@_cuam_print_numerical_input_aux:nV }
+% If both a phrase and a numeral is requested we do some more complicated stuff,
+% else just print a number.
+%
+% If the numeral is \emph{not} equal to $1$ use the |\@@_print_numeral:n| function.
+% Else get the translation for |one(m)|, |one(f)| or |one(n)| (depends).
% \begin{macrocode}
-\cs_new:Npn \@@_parse_the_amount:n #1
+\cs_new_protected:Npn \@@_cuam_print_number:n #1
{
- \@@_expand_amount_input:Nn \l_@@_original_amount_tl {#1}
- \tl_set_rescan:NnV \l_@@_original_amount_tl
+ \bool_lazy_and:nnTF
+ { \l_@@_lokal_phrase_bool }
+ { \l_@@_lokal_numeral_bool }
{
- \char_set_catcode_letter:N \_ %
- \char_set_catcode_ignore:N \ %
- \char_set_catcode_other:N ? %
- } \l_@@_original_amount_tl
- \bool_lazy_any:nTF
+ \@@_cuam_print_numerical_input_aux:nV {#1} \l_@@_phrase_number_tl
+ }
+ { \@@_print_number_default:n {#1} }
+ }
+\cs_new:Npn \@@_cuam_print_numerical_input_aux:nn #1#2
+ {
+ \int_compare:nNnTF {#1} = { 1 }
{
- { \tl_if_empty_p:N \l_@@_original_amount_tl }
- { \l_@@_pckopt_draft_bool }
+ \@@_culang_one_let_by_gender:NVTF
+ \l_@@_translation_tmpa_tl \l_@@_phrase_gender_tl
+ { \l_@@_translation_tmpa_tl }
+ {
+ \@@_print_numeral:n {#1}
+ \bool_set_false:N \l_@@_lokal_numeral_bool
+ }
}
- { \@@_prepare_just_print_input: }
- { \@@_split_and_parse_input: }
+ { \@@_print_numeral:n {#1} }
}
+\cs_generate_variant:Nn \@@_cuam_print_numerical_input_aux:nn { nV }
% \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{macro}{\@@_rf_print_amount_correctly:}
+% In case of an error just print the original input.
+%
+% Else we check how many items the printing sequence has. If it is $1$
+% print the sequence with an empty argument.
+%
+% Else: Do we print ranges? Do we print times? If neither, there is something wrong.
% \begin{macrocode}
-\cs_new:Npn \@@_split_and_parse_input:
+\cs_new:Npn \@@_rf_print_amount_correctly:
{
- \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
+ \@@_if_state_equal:nTF { error }
+ {
+ \l_@@_original_amount_tl
+ }{
+ \int_compare:nNnTF { \l_@@_nr_of_items } = { 1 }
+ { \seq_use:Nn \l_@@_prepared_printing_seq { } }
+ {
+ \bool_if:NTF \l_@@_rf_contains_range_bool
+ { \seq_use:Nn \l_@@_prepared_printing_seq { \@@_rf_print_range_sign: } }
+ {
+ \bool_if:NTF \l_@@_rf_contains_times_bool
+ { \seq_use:Nn \l_@@_prepared_printing_seq { \@@_print_times_sign: } }
+ {
+ \@@_create_internal_error:nx { neither-range-nor-times }
+ {
+ \fp_eval:n
+ { \l_@@_rf_contains_range_bool + 2*\l_@@_rf_contains_times_bool }
+ }
+ }
+ }
+ }
+ }
}
% \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{macro}{\@@_rf_print_unit_correctly:}
+% Quite straightforward.
% \begin{macrocode}
-\cs_new:Npn \@@_prepare_just_print_input:
+\cs_new:Npn \@@_rf_print_unit_correctly:
{
- \@@_set_state_to:n { error }
- \tl_if_empty:NT \l_@@_original_amount_tl
- { \@@_create_error:nn { cooking-units } { empty-amount } }
+ \@@_if_state_equal:nTF { error }
+ {
+ \tl_if_eq:NNF \l_@@_cmd_type_tl \c_@@_cmd_type_cuam_tl
+ { \@@_rf_print_unit_in_case_of_error: }
+ }
+ { \@@_rf_print_unit_or_phrase: }
}
% \end{macrocode}
% \end{macro}
%
-% \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{macro}{\@@_rf_print_unit_or_phrase:}
+% Printing the unit depends on the unit; nothing more or less.
% \begin{macrocode}
-\cs_new:Npn \@@_prepare_to_split_input:N #1
+\cs_new:Npn \@@_rf_print_unit_or_phrase:
{
- \tl_if_in:NVT #1 \l_@@_input_range_sign_tl
+ \tl_case:NnF \l_@@_cmd_type_tl
{
- \tl_replace_once:NVn #1 \l_@@_input_range_sign_tl { \q_@@_range }
- \@@_set_parse_and_process_type_to:n { range }
- }
- \tl_if_in:NnT #1 { / }
- {
- \@@_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 }
+ \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: }
}
- \@@_split_and_parse:N #1
- \use_none_delimit_by_q_nil:w \q_nil
+ { \@@_create_internal_error:nN { print-unit-acc } \l_@@_cmd_type_tl }
}
% \end{macrocode}
% \end{macro}
%
%
-% \begin{macro}{ \@@_split_and_parse:N}
-% Splits the input into fractions or ranges (or numbers).
+%
+%
+%
+% \begin{macro}{\@@_rf_initialise_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:Npn \@@_split_and_parse:N #1
- {
- \tl_case:NnF \l_@@_parse_and_process_type_tl
+\cs_new_protected:Npn \@@_rf_initialise_after_parsing:n #1
+ {
+ \clist_if_empty:cF { l_@@_unit_option_ \l_@@_decided_unit_tl _clist }
{
- \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
+ \keys_set_groups:nnv
+ { cooking-units }
+ { unit-hook }
+ { l_@@_unit_option_ \l_@@_decided_unit_tl _clist }
+ }
+ \tl_if_empty:nF {#1} { \l_@@_precompiled_options_tl }
+ \@@_if_cmd_type_equal:nTF { cunum }
+ { \bool_set_false:N \l_@@_lokal_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}{ \@@_split_and_parse_number:n }
-% Gets the input , parses it and stores it into |\l_@@_number_tmpa_tl|.
+%
+%
+%
+%
+% \begin{macro}{ \@@_rf_general_checkups: }
+% Doing some general stuff and tests which are done before further processing
+% the amount.
% \begin{macrocode}
-\cs_new:Npn \@@_split_and_parse_number:n #1
+\cs_new:Npn \@@_rf_general_checkups:
{
- \@@_parse_input_and_safe_in:nN {#1} \l_@@_number_tmpa_tl
+ \@@_decide_unit:
+ \@@_if_cmd_type_equal:nT { cCutext }
+ { \@@_rf_cutext_check_if_translation_available: }
}
% \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{macro}{ \@@_rf_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 \@@_split_and_parse_range:n #1
+\cs_new:Npn \@@_rf_prepare_fourty_two_amount:
{
- \@@_split_and_parse_range_aux:ww #1 \q_stop
+ \seq_map_inline:Nn \l_@@_parsed_seq
+ {
+ \@@_rf_prepare_fourty_two_amount_aux:nnnnn
+ ##1
+ }
+ }
+\tl_const:Nn \c_@@_fourty_two_tl { 42 }
+\tl_const:Nn \c_@@_fourty_two_unknown_tl { 42(!) }
+\cs_new:Npn \@@_rf_prepare_fourty_two_amount_aux:nnnnn #1#2#3#4#5
+ {
+ \tl_clear:N \l_@@_mixed_fraction_tl
+ \tl_clear:N \l_@@_number_tmpa_tl
+ \@@_if_state_equal:nTF { special_sign }
+ { \tl_set_eq:NN \l_@@_number_tmpb_tl \c_@@_fourty_two_unknown_tl }
+ { \tl_set_eq:NN \l_@@_number_tmpb_tl \c_@@_fourty_two_tl }
+ \bool_if:NT #1
+ {
+ \tl_if_empty:nF {#3}
+ { \tl_set_eq:NN \l_@@_mixed_fraction_tl \l_@@_number_tmpb_tl }
+ \tl_if_empty:nF {#4}
+ { \tl_set_eq:NN \l_@@_number_tmpa_tl \l_@@_number_tmpb_tl }
+ }
+ \@@_rf_seq_put_right:NnnVVV \l_@@_processed_seq
+ {#1} {#2} \l_@@_mixed_fraction_tl \l_@@_number_tmpa_tl \l_@@_number_tmpb_tl
}
-\cs_new:Npn \@@_split_and_parse_range_aux:ww #1 \q_@@_range #2 \q_stop
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \subsubsection{Process the input}
+%
+%
+% \begin{macro}{ \@@_rf_print_unit_in_case_of_error: }
+% 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 \@@_rf_print_unit_in_case_of_error:
{
- \@@_parse_input_and_safe_in:nN {#1} \l_@@_number_tmpa_tl
- \@@_parse_input_and_safe_in:nN {#2} \l_@@_number_tmpb_tl
- }
+ \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}{ \@@_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{macro} { \@@_rf_print_range_sign: , \@@_print_times_sign: }
+% Prints ranges. It simply prints the numbers twice, inbetween a range sign.
% \begin{macrocode}
-\cs_new:Npn \@@_split_and_parse_fraction:n #1
+\cs_new:Npn \@@_rf_print_range_sign:
+ {
+% \@@_if_cmd_type_equal:nTF { cunum }
+% {
+% \bool_if:NT \l_@@_seperator_after_fraction_bool { \, }
+% \tl_use:N \l_@@_cunum_range_sign_tl
+% }{
+ \bool_lazy_or:nnTF
+ { \@@_if_cmd_type_equal_p:n { cCutext } }
+ { \l_@@_lokal_numeral_bool }
+ {
+ \tl_if_empty:NTF \l_@@_cutext_range_sign_tl
+ {
+ \@@_culang_print:nn { name } { cutext-range-phrase }
+ }
+ { \tl_use:N \l_@@_cutext_range_sign_tl }
+ }{
+ \bool_if:NT \l_@@_seperator_after_fraction_bool { \, }
+ \tl_use:N \l_@@_cunum_range_sign_tl
+ }
+% }
+ }
+\cs_new:Npn \@@_print_times_sign:
{
- \@@_split_and_parse_fraction_mixed:ww
- #1 \q_stop / \q_recursion_tail _ \q_nil \q_stop
- \q_recursion_stop
+ \l_@@_times_space_tl \l_@@_times_sign_tl \l_@@_times_space_tl
}
% \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|.
+% \end{macro}
%
-% 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{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:Npn \@@_split_and_parse_fraction_mixed:ww #1 _ #2 \q_stop
+\cs_new_protected:Npn \@@_print_numerical_input:N #1
{
- \quark_if_nil:nTF {#2}
- {
- \tl_clear:N \l_@@_mixed_fraction_tl
- \@@_split_and_parse_fraction_frac:ww #1 \q_stop
- }{
- \@@_parse_input_and_safe_in:nN {#1} \l_@@_mixed_fraction_tl
- \@@_split_and_parse_fraction_frac:ww #2 \q_stop
+ \tl_if_in:NnT #1 { . }
+ {
+ \@@_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
+ #1
}
% \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.
+% \end{macro}
+%
+%
+%
+%
+%
+% \subsection {Parsing and checking numbers}
+%
+% 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 \@@_split_and_parse_fraction_frac:ww #1 / #2 \q_stop
+\cs_new:Npn \@@_create_internal_error:nN #1#2
{
- \quark_if_recursion_tail_stop_do:nn {#2}
- { \@@_create_error:n { fraction-wrong-order } }
- \@@_parse_input_and_safe_in:nN {#1} \l_@@_number_tmpa_tl
- \@@_parse_input_and_safe_in:nN {#2} \l_@@_number_tmpb_tl
- \use_none_delimit_by_q_recursion_stop:w
+ \@@_set_state_to:n { error }
+ \msg_error:nnnV { cooking-units } { internal-error } {#1} #2
+ }
+\cs_new:Npn \@@_create_internal_error:nn #1#2
+ {
+ \@@_set_state_to:n { error }
+ \msg_error:nnnn { cooking-units } { internal-error } {#1} #2
}
+\cs_generate_variant:Nn \@@_create_internal_error:nn { nx }
+\cs_new:Npn \@@_create_error:n #1
+ {
+ \@@_set_state_to:n { error }
+ \msg_error:nnV { cooking-units } {#1} \l_@@_original_amount_tl
+ }
+\cs_new:Npn \@@_create_error_and_stop:n #1
+ {
+ \@@_create_error:n {#1}
+ \use_none_delimit_by_q_nil:w
+ }
+\cs_new:Npn \@@_create_error:nn #1#2
+ {
+ \@@_set_state_to:n { error }
+ \msg_error:nnnV { cooking-units } {#1} {#2} \l_@@_original_amount_tl
+ }
+\cs_generate_variant:Nn \@@_create_error:nn { nf }
% \end{macrocode}
% \end{macro}
-% \begin{macro}{ \@@_split_and_parse_number:V ,
-% \@@_split_and_parse_range:V , \@@_split_and_parse_fraction:V }
-% Some variants.
+%
+% \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_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 }
+\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}{ \@@_parse_input_and_safe_in:nN }
% 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}
@@ -7609,6 +8385,7 @@ and the derived file cooking-units.sty.
{
\tl_clear:N \l_@@_tmpa_tl
\bool_set_false:N \l_@@_check_decimal_bool
+ \bool_set_false:N \l_@@_minus_bool
\cs_set_eq:NN \@@_parse:N \@@_start_loop:N
\tl_map_function:nN {#1} \@@_parse:N
\@@_if_state_equal:nF { error }
@@ -7618,21 +8395,24 @@ and the derived file cooking-units.sty.
% \end{macro}
%
% \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 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 consists of one token with \#2 being
-% empty (hopefully).
+% First, check for signs ($+$ and $-$ by default). If a sign is found and is $+$, do nothing
+% and repat the sign-checking-process. If the sign is a $-$ reverese the boolean
+% |\l_@@_minus_bool|. Reversing it is necessary to simulate mathematics of e.g. $+-+-1$
+% or $-+-+-1$, etc. If a non-sign is found, check if a minus sign is added and parse
+% the rest. |\token_if_eq_charcode:NNF| is stolen from \pkg{siunitx}.
% \begin{macrocode}
\cs_new:Npn \@@_start_loop:N #1
{
- \cs_set_eq:NN \@@_parse:N \@@_parse_input_loop_aux:N
\tl_if_in:NnTF \l_@@_input_value_signs_tl {#1}
- { \tl_put_right:Nn \l_@@_tmpa_tl {#1} }
- { \tl_map_function:nN {#1} \@@_parse:N }
+ {
+ \token_if_eq_charcode:NNT #1 -
+ { \@@_bool_reverse:N \l_@@_minus_bool }
+ }{
+ \bool_if:NT \l_@@_minus_bool
+ { \tl_put_left:Nn \l_@@_tmpa_tl { - } }
+ \cs_set_eq:NN \@@_parse:N \@@_parse_input_loop_aux:N
+ \tl_map_function:nN {#1} \@@_parse:N
+ }
}
% \end{macrocode}
% \end{macro}
@@ -7680,7 +8460,7 @@ and the derived file cooking-units.sty.
{
\tl_if_in:NnTF \l_@@_input_mixed_fraction_sign_tl {#1}
{
- \@@_if_parse_and_process_type_equal:nTF { fraction }
+ \bool_if:NTF \l_@@_rf_check_fraction_bool
{ \@@_create_error:n { Second-mixed-fraction-sign-not-allowed } }
{ \@@_create_error:n { missing-slash } }
}
@@ -7753,9 +8533,9 @@ and the derived file cooking-units.sty.
\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_set_eval:Nv #1 { l_@@_unit_change_ \l_@@_original_unit_tl _tl }
}{
- \@@_tl_eval:Nn #1
+ \@@_tl_set_eval:Nn #1
{ \l_@@_tmpa_fp * \tl_use:c { l_@@_unit_change_ \l_@@_original_unit_tl _tl } }
}
}
@@ -7769,12 +8549,19 @@ and the derived file cooking-units.sty.
% 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}
+\bool_new:N \l_@@_curef_forbidden_unit_msg_used_bool
\cs_new:Npn \@@_calc_references_and_store_in:N #1
{
\bool_if:NT \l_@@_lokal_recalc_for_people_bool
{
\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 }
+ {
+ \bool_if:NF \l_@@_curef_forbidden_unit_msg_used_bool
+ {
+ \msg_error:nnV { cooking-units } { curef-forbidden-unit } \l_@@_decided_unit_tl
+ \bool_set_true:N \l_@@_curef_forbidden_unit_msg_used_bool
+ }
+ }
{ \@@_calc_references_and_store_in_aux:N #1 }
}
}
@@ -7783,7 +8570,7 @@ and the derived file cooking-units.sty.
% \begin{macrocode}
\cs_new:Npn \@@_calc_references_and_store_in_aux:N #1
{
- \@@_tl_eval:Nn #1
+ \@@_tl_set_eval:Nn #1
{
#1 *
\l_@@_wanted_number_of_persons_int /
@@ -7807,7 +8594,7 @@ and the derived file cooking-units.sty.
{ \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} ) } }
+ { \@@_tl_set_eval:Nn #1 { round ( \@@_rounding_function:n {#1} ) } }
}
% \end{macrocode}
% \end{macro}
@@ -7955,7 +8742,7 @@ and the derived file cooking-units.sty.
\cs_new:Npn \@@_cunum:nnnnn #1#2#3#4#5
{
\@@_set_cmd_type_to:n { cunum }
- \@@_do_the_stuff:nnnnnn {#1} {#2} {#3} {#4} {#5} { }
+ \@@_rf_main_command:nnnnnn {#1} {#2} {#3} {#4} {#5} { }
}
% \end{macrocode}
% \end{macro}
@@ -8025,7 +8812,7 @@ and the derived file cooking-units.sty.
\cs_new:Npn \@@_cutext:nnnn #1#2#3#4
{
\@@_set_cmd_type_to:n { cCutext }
- \@@_do_the_stuff:nnnnnn {#1} {#2} {#3} { } {#4} { }
+ \@@_rf_main_command:nnnnnn {#1} {#2} {#3} { } {#4} { }
}
% \end{macrocode}
% \end{macro}
@@ -8097,13 +8884,13 @@ and the derived file cooking-units.sty.
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{ \@@_cutext_check_if_translation_available: }
+% \begin{macro}{ \@@_rf_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_check_if_translation_available:
+\cs_new:Npn \@@_rf_cutext_check_if_translation_available:
{
\bool_if:NTF \l_@@_pckopt_cutext_keep_unit_bool
{ \tl_set_eq:NN \l_@@_curr_unit_tl \l_@@_original_unit_tl }
@@ -8136,34 +8923,12 @@ and the derived file cooking-units.sty.
% 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
- {
- \@@_if_parse_and_process_type_equal:nTF { range }
- {
- \@@_culang_let:nnN { pluraltest } { range } \l_@@_translation_tmpa_tl
- \use:c { @@_pluraltest_range_ \l_@@_translation_tmpa_tl :NN } #1#2
-% \@@_cutext_check_if_plural_is_needed:N #2
- }{
- \@@_culang_let:nnN { pluraltest } { normal } \l_@@_translation_tmpa_tl
- \use:c { @@_pluraltest_normal_ \l_@@_translation_tmpa_tl :N } #1
-% \@@_cutext_check_if_plural_is_needed: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_post_process_fraction_input:NNN }
% \begin{macrocode}
-\cs_new:Npn \@@_cutext_post_process_fraction_input:NNN #1#2#3
- {
- \@@_culang_let:nnN { pluraltest } { fraction } \l_@@_translation_tmpa_tl
- \use:c { @@_pluraltest_fraction_ \l_@@_translation_tmpa_tl :NNN } #1#2#3
- }
+
% \end{macrocode}
% \end{macro}
% \begin{macro} { \@@_cutext_check_if_plural_is_needed:N }
@@ -8180,32 +8945,6 @@ and the derived file cooking-units.sty.
% \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
- {
- \@@_if_parse_and_process_type_equal:nTF { range }
- {
- \bool_lazy_all:nF
- {
- { \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 }
- }
- }
-% \end{macrocode}
-% \end{macro}
%
%
%
@@ -8225,7 +8964,13 @@ and the derived file cooking-units.sty.
\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: }
+ {
+ \tl_if_eq:NNF \l_@@_cmd_type_tl \c_@@_cmd_type_cuam_tl
+ {
+ \@@_create_internal_error:nN { cmd-type-no-unit-maker } \l_@@_cmd_type_tl
+ }
+ \prg_return_true:
+ }
{ \prg_return_false: }
}
\seq_gput_right:NV \g_@@_list_of_defined_units_seq \c_@@_no_unit_marker_tl
@@ -8257,7 +9002,7 @@ and the derived file cooking-units.sty.
\cs_new:Npn \@@_cuam:nnn #1#2#3
{
\@@_set_cmd_type_to:n { cuam }
- \@@_do_the_stuff:nnnnVn {#1} {#2} {#3} { } \c_@@_no_unit_marker_tl { }
+ \@@_rf_main_command:nnnnVn {#1} {#2} {#3} { } \c_@@_no_unit_marker_tl { }
}
% \end{macrocode}
% \end{macro}
@@ -8271,17 +9016,7 @@ 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_protected:Npn \@@_cuam_post_process_input: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}
@@ -8294,85 +9029,10 @@ and the derived file cooking-units.sty.
% 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
- {
- \@@_culang_get_phrase_prop:N \l_@@_phrase_prop
- \tl_if_eq:NNT \c_@@_no_translation_str \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 }
- {
- \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}
-\cs_new:Npn \@@_cuam_post_process_input_phrases_aux:NNN #1#2#3
- {
- \bool_set_false:N \l_@@_lokal_phrase_bool
- \seq_map_inline:Nn \l_@@_phrase_numbers_seq
- {
- \int_compare:nNnF { \int_abs:n {##1} } > {#1}
- {
- \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_false:N \l_@@_phrase_negative_bool
- \tl_set:Nf \l_tmpa_tl { \int_div_truncate:nn {#1} {##1} }
- }
- \int_compare:nNnT { \int_abs:n {##1} * \l_tmpa_tl } = {#1}
- {
- \tl_set_eq:NN #2 \l_tmpa_tl
- \tl_set:Nn #3 {##1}
- \bool_set_true:N \l_@@_lokal_phrase_bool
- \seq_map_break:
- }
- }
- }
- }
-\cs_new:Npn \@@_cuam_post_process_input_phrases_range:NN #1#2
- {
- \int_set:Nn \l_tmpa_int
- {
- \int_div_truncate:nn {#1} { \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
- }{
- \bool_set_false:N \l_@@_lokal_phrase_bool
- }
- }
-\cs_new:Npn \@@_cuam_get_phrase_name:NnN #1#2#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}
%
@@ -8403,7 +9063,9 @@ and the derived file cooking-units.sty.
{
\@@_culang_one_let_by_gender:NVTF
\l_@@_translation_tmpa_tl \l_@@_phrase_gender_tl
- { \l_@@_translation_tmpa_tl }
+ {
+ \l_@@_translation_tmpa_tl
+ }
{
\@@_print_numeral:V #1
\bool_set_false:N \l_@@_lokal_numeral_bool
@@ -8440,13 +9102,7 @@ and the derived file cooking-units.sty.
\cs_new:Npn \cookingunits_print_fraction:nnn #1#2#3
{
\group_begin:
- \@@_set_amount:Nn \l_@@_mixed_fraction_tl {#1}
- \@@_set_amount:Nn \l_@@_number_tmpa_tl {#2}
- \@@_set_amount:Nn \l_@@_number_tmpb_tl {#3}
- \@@_print_fractions:Nnn
- \l_@@_mixed_fraction_tl
- \l_@@_number_tmpa_tl
- \l_@@_number_tmpb_tl
+ \@@_print_fraction:nnnn { 0 } {#1} {#2} {#3}
\group_end:
}
% \end{macrocode}
@@ -8457,9 +9113,9 @@ and the derived file cooking-units.sty.
{
\group_begin:
\@@_set_cmd_type_to:n { cunum }
- #1
- \@@_print_range_sign:
- #2
+ \@@_print_number_default:n {#1}
+ \@@_rf_print_range_sign:
+ \@@_print_number_default:n {#2}
\group_end:
}
% \end{macrocode}
@@ -8610,7 +9266,7 @@ and the derived file cooking-units.sty.
\@@_if_state_equal:nF { error }
{
\exp_args:NV \@@_initialice_cukeys_define:n \l_@@_curr_unit_tl
- \@@_tl_eval:Nn \l_@@_new_key_base_tl { 1 / (\l_@@_base_tl) }
+ \@@_tl_set_eval:Nn \l_@@_new_key_base_tl { 1 / (\l_@@_base_tl) }
\tl_clear:N \l_@@_curr_unit_tl
}
}
@@ -8708,7 +9364,7 @@ and the derived file cooking-units.sty.
\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_set_eq:Nc \l_@@_tmpa_prop { l_@@_rf_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
@@ -8749,7 +9405,7 @@ and the derived file cooking-units.sty.
\@@_if_state_equal:nF { error }
{
\@@_initialice_cukeys_add:V \l_@@_curr_unit_tl
- \@@_tl_eval:Nn \l_@@_new_key_base_tl { (\l_@@_new_key_base_tl) / (\l_@@_base_tl) }
+ \@@_tl_set_eval:Nn \l_@@_new_key_base_tl { (\l_@@_new_key_base_tl) / (\l_@@_base_tl) }
}
}
% \end{macrocode}
@@ -8826,7 +9482,7 @@ and the derived file cooking-units.sty.
{
\prop_gclear:N \g_@@_master_changer_prop
\@@_cukeys_prepare_lists:N \l_@@_original_unit_tl
- \@@_new_cukeys_create_keys:V \l_@@_original_unit_tl
+ \@@_rf_cukeys_create_keys:V \l_@@_original_unit_tl
}
}
\cs_generate_variant:Nn \@@_cukeys_prepare_parsing_keys:nn { nV }
@@ -8894,7 +9550,7 @@ and the derived file cooking-units.sty.
{
\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) } }
+ { \@@_tl_set_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
@@ -8920,10 +9576,10 @@ and the derived file cooking-units.sty.
% \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
+ \prop_clear_new:c { l_@@_rf_cukeys_ #1 _prop }
+ \prop_set_eq:cN { l_@@_rf_cukeys_ #1 _prop } \l_@@_tmpa_prop
+ \prop_put:cnV { l_@@_rf_cukeys_ #1 _prop } { Liste } \l_@@_tmpa_seq
+ \prop_put:cnV { l_@@_rf_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
@@ -8938,33 +9594,33 @@ and the derived file cooking-units.sty.
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{ \@@_new_cukeys_create_keys:n , \@@_new_cukeys_create_keys:V }
+% \begin{macro}{ \@@_rf_cukeys_create_keys:n , \@@_rf_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 \@@_new_cukeys_create_keys:n #1
+\cs_new:Npn \@@_rf_cukeys_create_keys:n #1
{
% % #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
+ \@@_rf_cukeys_define_key:nVn
{#1} \l_@@_tmpa_clist {#1}
}{
\seq_map_inline:Nn \l_@@_tmpa_seq
{
- \@@_new_cukeys_define_key:nVn
+ \@@_rf_cukeys_define_key:nVn
{##1} \l_@@_tmpa_clist {#1}
}
}
}
-\cs_generate_variant:Nn \@@_new_cukeys_create_keys:n { V }
+\cs_generate_variant:Nn \@@_rf_cukeys_create_keys:n { V }
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{ \@@_new_cukeys_define_key:nnn , \@@_new_cukeys_define_key:nVn }
+% \begin{macro}{ \@@_rf_cukeys_define_key:nnn , \@@_rf_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.
@@ -8980,7 +9636,7 @@ and the derived file cooking-units.sty.
% In order to remind the user which choices each key have, define an error
% message for unknown keys.
% \begin{macrocode}
-\cs_new:Npn \@@_new_cukeys_define_key:nnn #1#2#3
+\cs_new:Npn \@@_rf_cukeys_define_key:nnn #1#2#3
{
\@@_if_unit_has_a_key:nF {#1}
{ \seq_put_right:Nn \l_@@_list_of_defined_keys_seq {#1} }
@@ -9003,7 +9659,7 @@ and the derived file cooking-units.sty.
#1 .groups:n = { change-unit }
}
}
-\cs_generate_variant:Nn \@@_new_cukeys_define_key:nnn { nVn }
+\cs_generate_variant:Nn \@@_rf_cukeys_define_key:nnn { nVn }
% \end{macrocode}
% \end{macro}
%
@@ -9050,7 +9706,7 @@ and the derived file cooking-units.sty.
% 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|.
+% of key-values |l_@@_rf_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|
@@ -9062,10 +9718,10 @@ and the derived file cooking-units.sty.
{
\str_if_eq:nnTF {#1} {#3}
{
- \prop_get:cnc { l_@@_new_cukeys_ #1 _prop } {#2} { l_@@_unit_change_ #1 _tl }
+ \prop_get:cnc { l_@@_rf_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_set_eq:Nc \l_@@_tmpa_prop { l_@@_rf_cukeys_ #3 _prop }
+ \@@_tl_set_eval:cn { l_@@_unit_change_ #1 _tl }
{
( \prop_item:Nn \l_@@_tmpa_prop {#2} ) /
( \prop_item:Nn \l_@@_tmpa_prop {#1} )
@@ -9341,7 +9997,7 @@ and the derived file cooking-units.sty.
\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 }
+ { l_@@_rf_cukeys_ \l_@@_curr_unit_tl _prop }
\prop_get:cnc { l_@@_keys_ ##1 _prop } { Liste } { l_@@_list_ ##1 _seq }
}
}
@@ -9371,7 +10027,7 @@ and the derived file cooking-units.sty.
\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}
+ \exp_not:c { l_@@_rf_cukeys_ \l_@@_original_unit_tl _prop } {#1}
) } }
\int_compare:nNnTF { \l_@@_depth_int } = { \l_@@_nr_of_units_int }
{
@@ -9437,7 +10093,7 @@ and the derived file cooking-units.sty.
\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 }
+ \@@_tl_set_eval:cn { l_@@_unit_change_ #1 _tl }
{
(\l_@@_tmpb_tl) / (\l_@@_tmpa_tl)
}
@@ -9571,7 +10227,9 @@ and the derived file cooking-units.sty.
\quark_if_recursion_tail_stop:n {#1}
\seq_if_in:NnTF \g_@@_allowed_special_keys_seq {#1}
{
- \@@_set_unit:Nn \l_@@_curr_unit_tl {#1}
+ \str_if_eq:nnTF { cutext-range-sign } {#1}
+ { \@@_set_unit:Nn \l_@@_curr_unit_tl { cutext-range-phrase } }
+ { \@@_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
@@ -9691,7 +10349,6 @@ and the derived file cooking-units.sty.
% (just a number), \enquote{range} and \enquote{fraction}.
% \begin{macrocode}
\@@_culang_def_base:nnn { pluraltest } { normal } { \c_@@_no_translation_str }
-\@@_culang_def_base:nnn { pluraltest } { range } { \c_@@_no_translation_str }
\@@_culang_def_base:nnn { pluraltest } { fraction } { \c_@@_no_translation_str }
% \end{macrocode}
% \end{macro}
@@ -9703,22 +10360,16 @@ and the derived file cooking-units.sty.
% For ranges take the last value, for fractions make sure there are no mixed fractions
% and that the nominator is equal to $1$.
% \begin{macrocode}
-\cs_set:cpn { @@_pluraltest_normal_ \c_@@_no_translation_str :N } #1
+\cs_set:cpn { @@_pluraltest_normal_ \c_@@_no_translation_str :n } #1
{
\fp_compare:nNnTF {#1} = { 1.0 }
{ \bool_set_true:N } { \bool_set_false:N }
\l_@@_cutext_use_single_bool
}
-\cs_set:cpn { @@_pluraltest_range_ \c_@@_no_translation_str :NN } #1#2
- {
- \fp_compare:nNnTF {#2} = { 1.0 }
- { \bool_set_true:N } { \bool_set_false:N }
- \l_@@_cutext_use_single_bool
- }
-\cs_set:cpn { @@_pluraltest_fraction_ \c_@@_no_translation_str :NNN } #1#2#3
+\cs_set:cpn { @@_pluraltest_fraction_ \c_@@_no_translation_str :nnn } #1#2#3
{
- \tl_if_empty:NTF #1
- { \fp_compare:nNnTF {#2} = { 1.0 } } { \use_ii:nn }
+ \tl_if_empty:nTF {#1}
+ { \fp_compare:nNnTF {#2} = { \c_one_fp } } { \use_ii:nn }
{ \bool_set_true:N } { \bool_set_false:N }
\l_@@_cutext_use_single_bool
}
@@ -9731,17 +10382,12 @@ and the derived file cooking-units.sty.
\cs_new:Npn \@@_pluraltest_define:nn #1#2
{
\@@_culang_def_for:nnnn {#1} { pluraltest } { normal } {#1}
- \cs_set:cpn { @@_pluraltest_normal_ #1 :N } ##1 {#2}
- }
-\cs_new:Npn \@@_pluraltest_define_range:nn #1#2
- {
- \@@_culang_def_for:nnnn {#1} { pluraltest } { range } {#1}
- \cs_set:cpn { @@_pluraltest_range_ #1 :NN } ##1##2 {#2}
+ \cs_set:cpn { @@_pluraltest_normal_ #1 :n } ##1 {#2}
}
\cs_new:Npn \@@_pluraltest_define_fraction:nn #1#2
{
\@@_culang_def_for:nnnn {#1} { pluraltest } { fraction } {#1}
- \cs_set:cpn { @@_pluraltest_fraction_ #1 :NNN } ##1##2##3 {#2}
+ \cs_set:cpn { @@_pluraltest_fraction_ #1 :nnn } ##1##2##3 {#2}
}
% \end{macrocode}
% \end{macro}
@@ -9760,15 +10406,9 @@ and the derived file cooking-units.sty.
{ \bool_set_true:N } { \bool_set_false:N }
\l_@@_cutext_use_single_bool
}
-\@@_pluraltest_define_range:nn { French }
- {
- \fp_compare:nNnTF { \fp_abs:n {#2} } < { 2.0 }
- { \bool_set_true:N } { \bool_set_false:N }
- \l_@@_cutext_use_single_bool
- }
\@@_pluraltest_define_fraction:nn { French }
{
- \quark_if_nil:NTF #1
+ \tl_if_empty:nTF {#1}
{ \fp_compare:nNnTF { #2/#3 } < { 2.0 } }
{ \fp_compare:nNnTF { #1 + #2/#3 } < { 2.0 } }
{ \bool_set_true:N } { \bool_set_false:N }
@@ -9805,13 +10445,15 @@ 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 } }
- {
+ {
+ \str_if_eq:nnTF { cutext-range-sign } {#1}
+ { \@@_culang_def_for:Vnnn \l_@@_language_tl { name } { cutext-range-phrase } {#2} }
+ { \@@_culang_def_for:Vnnn \l_@@_language_tl { name } {#1} {#2} }
+ }{
\@@_error_if_unit_not_defined:nTF {#1}
- { \use_none:nn }
- { \@@_culang_def_for:Vnnn \l_@@_language_tl { unit-symbol } }
+ { \use_none:nn {#1} {#2} }
+ { \@@_culang_def_for:Vnnn \l_@@_language_tl { unit-symbol } {#1} {#2} }
}
- {#1} {#2}
\@@_cuprint_define_printed_unit:nn
}
% \end{macrocode}
@@ -9822,7 +10464,7 @@ and the derived file cooking-units.sty.
%
%
%
-% \begin{macro}{ }
+% \begin{macro}{ phrase }
% 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
@@ -9834,7 +10476,7 @@ and the derived file cooking-units.sty.
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{ }
+% \begin{macro}{ \@@_culang_get_phrase_prop:N }
% \begin{macrocode}
\cs_new:Npn \@@_culang_get_phrase_prop:N #1
{
@@ -9858,14 +10500,17 @@ and the derived file cooking-units.sty.
% Defining some phrases. This command is just a wrapper for the
% subcommand.
% \begin{macrocode}
+\tl_new:N \l_@@_phrase_tmp_tl
+\tl_new:N \l_@@_phrase_tmpb_tl
+\seq_new:N \l_@@_phrase_full_seq
\NewDocumentCommand \cudefinephrase { m m }
{
- \@@_new_cuphrase_add:nn {#1} {#2}
+ \@@_rf_cuphrase_add:nn {#1} {#2}
}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{ \@@_new_cuphrase_add:nn }
+% \begin{macro}{ \@@_rf_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.
%
@@ -9888,28 +10533,25 @@ and the derived file cooking-units.sty.
%
% Then store the variables and thats it.
% \begin{macrocode}
-\cs_new:Npn \@@_new_cuphrase_add:nn #1#2
+\cs_new:Npn \@@_rf_cuphrase_add:nn #1#2
{
\tl_set:Nn \l_@@_language_tl {#1}
\@@_culang_if_translation_exists_for:VnnTF \l_@@_language_tl
{ phrase } { phrase-lang }
{
-% \@@_culang_let_for:VnnN \l_@@_language_tl { phrase } { phrase-prop }
-% \l_@@_phrase_prop
\prop_set_eq:Nc \l_@@_phrase_prop { l_@@_ \l_@@_language_tl _phrase_prop }
\prop_get:NnN \l_@@_phrase_prop { seq } \l_@@_phrase_numbers_seq
}{
\prop_new:c { l_@@_ \l_@@_language_tl _phrase_prop }
\prop_clear:N \l_@@_phrase_prop
\seq_clear:N \l_@@_phrase_numbers_seq
+ \seq_clear:N \l_@@_phrase_full_seq
}
\@@_sanitize_arrows:n {#2}
\@@_parse_phrase:V \l_@@_sanitise_tl
- \@@_new_cuphrase_sort_sequence:N \l_@@_phrase_numbers_seq
+ \@@_rf_cuphrase_sort_sequence:N \l_@@_phrase_numbers_seq
\prop_put:NnV \l_@@_phrase_prop { seq } \l_@@_phrase_numbers_seq
\prop_set_eq:cN { l_@@_ \l_@@_language_tl _phrase_prop } \l_@@_phrase_prop
-% \@@_culang_def_for:VnnV
-% \l_@@_language_tl { phrase } { phrase-prop } \l_@@_phrase_prop
\@@_culang_def_for:VnnV
\l_@@_language_tl { phrase } { phrase-lang } \l_@@_language_tl
}
@@ -9936,6 +10578,8 @@ and the derived file cooking-units.sty.
\@@_set_state_to:n { normal }
\bool_set_false:N \l_@@_tmpa_bool
\tl_clear:N \l_@@_curr_unit_tl
+ \tl_clear:N \l_@@_phrase_tmp_tl
+ \tl_clear:N \l_@@_phrase_tmpb_tl
\prop_clear:N \l_@@_tmpa_prop
\@@_parse_stuff_mandatories_plus_star:nn
}
@@ -9973,13 +10617,20 @@ and the derived file cooking-units.sty.
{
\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 { - } }
+ \tl_put_right:Nx \l_@@_phrase_tmpb_tl { { \l_@@_curr_unit_tl } }
}{
\@@_set_state_to:n { error }
\msg_error:nnn { cooking-units} { phrase-unit-not-an-integer } {#1}
}
+ \bool_if:NTF \l_@@_tmpa_bool
+ {
+ \tl_put_right:Nn \l_@@_phrase_tmpb_tl { { \c_true_bool } }
+ }{
+ \tl_put_right:Nn \l_@@_phrase_tmpb_tl { { \c_false_bool } }
+ }
+%
\prop_put:Nnn \l_@@_tmpa_prop { } {#2}
+ \tl_put_right:Nn \l_@@_phrase_tmp_tl { {#2} }
\prop_put:NnV \l_@@_tmpa_prop { - singlebool } \l_@@_tmpa_bool
\@@_parse_phrase_optionals:n {#2}
}
@@ -10003,7 +10654,7 @@ and the derived file cooking-units.sty.
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{ \@@_new_cuphrase_add:nn }
+% \begin{macro}{ \@@_parse_stuff_plural:w }
% Store the pluarl form in the property list.
% Next, parse gender. Pretty much the same as before. By default we use
% a male gender.
@@ -10011,6 +10662,7 @@ and the derived file cooking-units.sty.
\cs_new:Npn \@@_parse_stuff_plural:w [#1]
{
\prop_put:Nnn \l_@@_tmpa_prop { -pl } {#1}
+ \tl_put_right:Nn \l_@@_phrase_tmp_tl { {#1} }
\peek_remove_spaces:n
{
\peek_meaning:NTF <
@@ -10021,7 +10673,7 @@ and the derived file cooking-units.sty.
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{ \@@_new_cuphrase_add:nn }
+% \begin{macro}{ \@@_parse_stuff_gender:w }
% Check if the gender-input is correct, add it to the property list.
% Then finish the cycle and start a new one.
% \begin{macrocode}
@@ -10029,8 +10681,12 @@ and the derived file cooking-units.sty.
{
\@@_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
+ {
+ \prop_put:Nnn \l_@@_tmpa_prop { -gender } {#1}
+ \tl_put_right:Nn \l_@@_phrase_tmp_tl { {#1} }
+ }
+ \@@_parse_phrase_finish_cycle_and_start_anew:VVV
+ \l_@@_curr_unit_tl \l_@@_phrase_tmp_tl \l_@@_phrase_tmpb_tl
}
% \end{macrocode}
% \end{macro}
@@ -10042,42 +10698,42 @@ and the derived file cooking-units.sty.
% 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
+\cs_new:Npn \@@_parse_phrase_finish_cycle_and_start_anew:nnn #1#2#3
{
\@@_if_state_equal:nT { normal }
{
- \seq_if_in:NnF \l_@@_phrase_numbers_seq {#1}
- { \seq_put_right:Nn \l_@@_phrase_numbers_seq {#1} }
+ \seq_if_in:NnF \l_@@_phrase_numbers_seq {#3}
+ { \seq_push:Nn \l_@@_phrase_numbers_seq {#3} }
\prop_map_inline:Nn \l_@@_tmpa_prop
{
- \prop_put:Nnn \l_@@_phrase_prop { #1 ##1 } {##2}
+ \prop_put:Nnn \l_@@_phrase_prop { #3 ##1 } {##2}
}
+ \prop_put:Nnn \l_@@_phrase_prop { #3 -all } {#2}
}
\@@_parse_phrase_start_cycle:
}
-\cs_generate_variant:Nn \@@_parse_phrase_finish_cycle_and_start_anew:n { V }
+\cs_generate_variant:Nn \@@_parse_phrase_finish_cycle_and_start_anew:nnn { VVV }
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{ \@@_new_cuphrase_sort_sequence:N }
+% \begin{macro}{ \@@_rf_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 \@@_new_cuphrase_sort_sequence:N #1
+\cs_new:Npn \@@_rf_cuphrase_sort_sequence:N #1
{
\seq_sort:Nn #1
{
- \int_set:Nn \l_@@_tmpa_int { \int_abs:n {##1} }
- \int_set:Nn \l_@@_tmpb_int { \int_abs:n {##2} }
+ \int_set:Nn \l_@@_tmpa_int { \use_i:nn ##1 }
+ \int_set:Nn \l_@@_tmpb_int { \use_i:nn ##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 }
+ \bool_if:nTF { \use_ii:nn ##1 }
{ \sort_return_same: }
{ \sort_return_swapped: }
}
@@ -10099,7 +10755,7 @@ and the derived file cooking-units.sty.
%
% \subsection{Old stuff}
%
-% \begin{macro} { }
+% \begin{macro} { \@@_old_cutext:nnn }
% \begin{macrocode}
\cs_new:Npn \@@_old_cutext:nnn #1#2#3
{
@@ -10737,12 +11393,6 @@ and the derived file cooking-units.sty.
} ,
round-precision = 2 ,
}
-
-
-% \NewDocumentCommand \cudefinekeys { } { \cudefinekeys }
-
-
-
%\AtBeginDocument{
%\keys_define:nn { cooking-units }
% {