diff options
-rw-r--r-- | Master/texmf-dist/doc/latex/cooking-units/README.md | 50 | ||||
-rw-r--r-- | Master/texmf-dist/doc/latex/cooking-units/cooking-units.pdf | bin | 0 -> 495535 bytes | |||
-rw-r--r-- | Master/texmf-dist/source/latex/cooking-units/cooking-units.dtx | 3825 | ||||
-rw-r--r-- | Master/texmf-dist/source/latex/cooking-units/cooking-units.ins | 55 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/cooking-units/cooking-units.sty | 1373 | ||||
-rwxr-xr-x | Master/tlpkg/bin/tlpkg-ctan-check | 3 | ||||
-rw-r--r-- | Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc | 1 | ||||
-rw-r--r-- | Master/tlpkg/tlpsrc/cooking-units.tlpsrc | 0 |
8 files changed, 5306 insertions, 1 deletions
diff --git a/Master/texmf-dist/doc/latex/cooking-units/README.md b/Master/texmf-dist/doc/latex/cooking-units/README.md new file mode 100644 index 00000000000..9660bdd6c02 --- /dev/null +++ b/Master/texmf-dist/doc/latex/cooking-units/README.md @@ -0,0 +1,50 @@ + +cooking-units +============= + +Overview +-------- + +While writing a cookery book, units and their format can be quite +troublesome. This contains not only the question of how to print those +units, but also the question of the conversion of units. A cookery book +doesn't contain only SI units, it contains a much more colorful range +of units (kg, dag, g, oz, ... for example) and this may cause some +confusion if too many different units are used, but if you just write a +cookery book for fun you don't think about this case ... until someone +(my mother in my case) tells you that it's too confusing. + +This package solves both problems: It formats your input and +you have the option to convert the units globally or locally using a key-value +system. + +Please note that this package is not intended to be used to +print units (and numbers) physically correct. It should be used for +more light-hearted stuff (like a cookery book for example). + +Requirements +------------ + + * expl3 & xparse + * translator + * xfrac + * l3keys2e + * fmtcount (optional) + + This file contains +------------------ + + * README + * cooking-units.pdf + * cooking-units.dtx + * cooking-units.ins + + License +------- +This material is subject to the LaTeX Project Public License. See + + http://www.ctan.org/tex-archive/help/Catalogue/licenses.lppl.html + +for the details of that license. + + diff --git a/Master/texmf-dist/doc/latex/cooking-units/cooking-units.pdf b/Master/texmf-dist/doc/latex/cooking-units/cooking-units.pdf Binary files differnew file mode 100644 index 00000000000..2a9027ef4a5 --- /dev/null +++ b/Master/texmf-dist/doc/latex/cooking-units/cooking-units.pdf diff --git a/Master/texmf-dist/source/latex/cooking-units/cooking-units.dtx b/Master/texmf-dist/source/latex/cooking-units/cooking-units.dtx new file mode 100644 index 00000000000..7977c41cc57 --- /dev/null +++ b/Master/texmf-dist/source/latex/cooking-units/cooking-units.dtx @@ -0,0 +1,3825 @@ +% \iffalse meta-comment +% !TEX encoding = UTF-8 Unicode +% !TEX program = pdfLaTeX +% +% +% +% +%<*internal> +\iffalse +%</internal> +%<*readme> + +cooking-units +============= + +Overview +-------- + +While writing a cookery book, units and their format can be quite +troublesome. This contains not only the question of how to print those +units, but also the question of the conversion of units. A cookery book +doesn't contain only SI units, it contains a much more colorful range +of units (kg, dag, g, oz, ... for example) and this may cause some +confusion if too many different units are used, but if you just write a +cookery book for fun you don't think about this case ... until someone +(my mother in my case) tells you that it's too confusing. + +This package solves both problems: It formats your input and +you have the option to convert the units globally or locally using a key-value +system. + +Please note that this package is not intended to be used to +print units (and numbers) physically correct. It should be used for +more light-hearted stuff (like a cookery book for example). + +Requirements +------------ + + * expl3 & xparse + * translator + * xfrac + * l3keys2e + * fmtcount (optional) + + + This file contains +------------------ + + * README + * cooking-units.pdf + * cooking-units.dtx + * cooking-units.ins + + License +------- +This material is subject to the LaTeX Project Public License. See + + http://www.ctan.org/tex-archive/help/Catalogue/licenses.lppl.html + +for the details of that license. + +%</readme> +%<*internal> +\fi +\def\nameofplainTeX{plain} +\ifx\fmtname\nameofplainTeX\else + \expandafter\begingroup +\fi +%</internal> +%<*install> +\input l3docstrip.tex +%\keepsilent +\askforoverwritefalse +\preamble +Copyright (C) 2016 by Ben Vitecek (current Maintainer) + +This file may be distributed and/or modified under the +conditions of the LaTeX Project Public License, either +version 1.3 of this license or (at your option) any later +version. The latest version of this license is in: + + http://www.latex-project.org/lppl.txt + +and version 1.3c or later is part of all distributions of +LaTeX version 2008-05-04 or later. + +This work has the LPPL maintenance status `maintained'. + +This work consists of the files README, cooking-units.dtx and cooking-units.ins +and the derived file cooking-units.sty. + +\endpreamble +%\postamble + + +%\endpostamble +\usedir{tex/latex/cooking-units} +\generate{ + \file{\jobname.sty}{\from{\jobname.dtx}{package}} +} +%</install> +%<install>\endbatchfile +%<*internal> +\usedir{source/latex/cooking-units} +\generate{ + \file{\jobname.ins}{\from{\jobname.dtx}{install}} +} +\nopreamble\nopostamble +\usedir{doc/latex/cooking-units} +\generate{ + \file{README.md}{\from{\jobname.dtx}{readme}} +} +\ifx\fmtname\nameofplainTeX + \expandafter\endbatchfile +\else + \expandafter\endgroup +\fi +%</internal> +%<*driver> +\documentclass [ + english, %french, naustrian + onlydoc, +% check-declarations, +]{l3doc} +\usepackage[utf8]{inputenc} +\usepackage{babel} +\usepackage[use-numerals=true]{cooking-units} +\usepackage{tikzsymbols} +\usepackage{listings} +\usepackage{environ} +\usepackage{nicefrac} +\usepackage{varioref} +\usepackage{siunitx} + +\DeclareSIUnit{\ounce}{oz} +\DeclareSIUnit{\oz}{\ounce} +\DeclareSIUnit{\pound}{lb} +\DeclareSIUnit{\lb}{\pound} +\DeclareSIUnit{\stone}{st} +\DeclareSIUnit{\st}{\stone} +\cusetup{use-numerals-below=0} + +%\EnableCrossrefs + +\labelformat{table}{table~#1} + +\newcommand\mycs[1]{\cs{\textcolor{blue}{#1}}} +\newcommand\opt{\texttt} +\newcommand\true{\opt{true}} +\newcommand\false{\opt{false}} + +\ExplSyntaxOn + +\NewDocumentCommand \PrintUnit { m } + { + \translate{ #1 (cu-unitname) } & #1 & \translate{ #1 ( cu-unit ) } + } + +\NewDocumentCommand \PrintUnitSymbol { m } + { + #1 & \translate{ #1 ( cu-unit ) } + } + + + +\NewDocumentCommand \dothewhitespace { O{ All your spaces are belong to us } } + { + \textcolor{white} {#1} \\ + } + +\NewEnviron { cuexamplecode } + { + \begin{center} + \begin{minipage}{0.4\linewidth} + \tl_replace_all:Nnn \BODY { @ } { \dothewhitespace } + \tl_replace_all:Nnn \BODY { ! } { } + \BODY + \end{minipage} + + \int_zero:N \l_tmpa_int + \begin{minipage}{0.5\linewidth} + \ttfamily + \tl_set_rescan:Nno \l_tmpa_tl + { + \char_set_catcode_other:N \{ % + \char_set_catcode_other:N \} % +% \char_set_catcode_other:N \# % + } + { \BODY } + \tl_map_inline:Nn \l_tmpa_tl + { + \token_if_cs:NTF ##1 + { + \cs_if_eq:NNTF ##1 \\ + { \textbackslash\textbackslash \\ } + { + \tl_set_rescan:Nnn \l_tmpb_tl + { + \char_set_catcode_ignore:N \\ % + \char_set_catcode_ignore:N \ % + } + {##1} + \textbackslash \textcolor{blue}{\l_tmpb_tl} + } + } + { + \bool_if:nTF + { + \tl_if_eq_p:NN ##1 @ || + \tl_if_eq_p:NN ##1 ! + } + { \\ } + { + \token_if_active:NTF ##1 + { \string ##1 } + { + \token_if_parameter:NTF ##1 + { + \int_compare:nTF { \l_tmpa_int == 0 } + { + \c_hash_str + \int_incr:N \l_tmpa_int + } + { \int_zero:N \l_tmpa_int } + } + { ##1 {} } + } + } + } + } + \end{minipage} + \end{center} + } + + + +\NewDocumentEnvironment { cuexample } { } + { \paragraph{Example:} } + { } + +\ExplSyntaxOff + +\lstset + { + basicstyle = \ttfamily, + basewidth = 0.51em, + gobble = 3, + keywordstyle = \color{blue}, + language = [LaTeX]{TeX}, + commentstyle=\color{red!80!black}, + moretexcs = + { + cunum, + cutext, + Cutext, + cufrac, + newcookingunit, + cudefinename, + cudefinesymbol, + cusetup, + cudefinekeys, + cudefinesinglekey, + cuaddkeys, + cuaddsinglekeys, + cuaddtokeys, + } + } + +\newcookingunit {st} + +\cuaddkeys {lb} %% adding t to g (could also add to kg, dag and oz) + { + {st} { 1/14 } %% 1 lb are 1/14 st + } + +\newcookingunit [\ensuremath{ {} ^ { \circ } }\kern-\scriptspace R{\o}] {Ro} +\cuaddsinglekeys {C} + { + {Ro} { #1*21/40 + 7.5} + } +\cusetup + { + set-option-for-Ro = { round-to-int = true } + } + + +%: \cusetup +\cusetup + { +% convert-to-eV=true , +% erase-all-options, +% set-option-for-K= {}, +% set-unknown-message = error , +% check-temperature = true, +% round-precision = 30 , + } + + +\EnableCrossrefs +\CodelineIndex +\RecordChanges +\AtEndDocument { \PrintChanges \PrintIndex } + + +\begin{document} +\DocInput{\jobname.dtx} +\end{document} +%</driver> +% \fi +% +% +% +% +% \CharacterTable +% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z +% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z +% Digits \0\1\2\3\4\5\6\7\8\9 +% Exclamation \! Double quote \" Hash (number) \# +% Dollar \$ Percent \% Ampersand \& +% Acute accent \' Left paren \( Right paren \) +% Asterisk \* Plus \+ Comma \, +% Minus \- Point \. Solidus \/ +% Colon \: Semicolon \; Less than \< +% Equals \= Greater than \> Question mark \? +% Commercial at \@ Left bracket \[ Backslash \\ +% Right bracket \] Circumflex \^ Underscore \_ +% Grave accent \` Left brace \{ Vertical bar \| +% Right brace \} Tilde \~} +% +% +% \GetFileInfo{\jobname.sty} +% +%\title{The \pkg{\jobname} package^^A +%\thanks{This document corresponds to \textsf{Benedikt Vitecek}~\fileversion, dated~\filedate.}} +%\author{Ben Vitecek \\ b.vitecek@gmx.at}% +% +% +% \maketitle +% +% +% \begin{documentation} +% +% \begin{abstract} +% This package enables user to globally format units and to switch +% between them. It should be used for light-hearted things like +% cookery books (and not e.g. scientific texts).\footnote{I did hide some +% grammatical and spelling errors for easter egg hunters \Winkey.} +% \end{abstract} +% +% \tableofcontents +% +% +% \section{Introduction} +% +% +% While writing on a cookery book I used -- for reasons whatsoever -- +% three different units for weight: kilogram (kg), gram (g) and +% decagram (dag). Later my mother told me that she doesn't like it if a +% cookery book uses more than two different units (for weight in this case). Happily +% I hardly used Decagram and therefore didn't have many problems +% changing the units. But, well \dots\ I am using \LaTeX\ and changing +% those units by hand seemed not very \LaTeX\-like, so I started +% writing some code to convert units. I expanded the code, rewrote it +% in \LaTeX3 (which is much more pleasant than \LaTeXe) and here it +% is. +% +% \section{Important note} +% +% This package uses the \pkg{translator} package to be able to switch +% between different languages (german, english and french by now). +% To do that \pkg{translator} has to know +% which languages are used. The (I think) easiest way is to specify +% used languages using the optional argument of the documentclass (you +% can do this for both \pkg{babel} and \pkg{polyglossia}\footnote{I +% know that \pkg{polyglossia} doesn't support the \pkg{babel}-way of +% setting the language by optional argument, but it doesn't harm.}): +% +% \begin{lstlisting} +% \documentclass[english,french,ngerman]{class} +% \usepackage[main=english]{babel} +% \usepackage{cooking-units} +% ... +% \end{lstlisting} +% +% or if you are using \pkg{polyglossia} +% +% \begin{lstlisting} +% \documentclass[french,ngerman,english]{class} +% +% \usepackage{polyglossia} +% \setmainlanguage{english} +% \setotherlanguages{german,french} +% +% \usepackage{cooking-units} +% ... +% \end{lstlisting} +% +% At least I hope that this works, dealing with languages is a pain in +% the ass\footnote{If you excuse me being blunt about this}. +% +% \section {The Commands} +% +% This package offers the following commands for unit printing (and converting): +% +% \begin{itemize} +% \item \mycs{cunum} \oarg{options}\marg{amount}\oarg{space}\marg{unit-key} +% \item \mycs{cutext}\oarg{options}\marg{amount}\marg{unit-key} +% \item \mycs{Cutext}\oarg{options}\marg{amount}\marg{unit-key} +% \item \mycs{cufrac}\marg{input} +% \end{itemize} +% +% Numbers and units are printed using \mycs{cunum}. The numerical part +% can interpret \verb|_| and \texttt{/} as (mixed) fractions and +% \verb|--| as a separator for ranges; to convert units use the option +% \texttt{\meta{old-unit}=\meta{new-unit}}\footnote{New keys can be +% added and defined, see \vref{sec:pred-units} and +% \vref{sec:def-units} for further information.}. It furthermore allows the +% sign \texttt{?} to be used as a placeholder for not known amounts +% and raises a warning +% to remind that this amount needs a checkup\footnote{You can +% customize this behavior, see \vref{sec:options}}. \oarg{space} adds +% a space between the number and the unit using \lstinline|\phantom|. +% +% For a list of predefined units have a look at \vref{tab:def-units}. +% +% +% \begin{cuexamplecode} +% \cunum{1}{kg} \\ +% \cunum{2.3}{kg} \\ +% \cunum{2,3}{kg} \\ +% \cunum{2--3}{kg} \\ +% \cunum{2.5--3.5}{kg} \\ +% \cunum[kg=g]{2.5--3.5}{kg} \\ +% \cunum[C=F]{200}{C} \\ +% \cunum[C=F]{180--200}{C} \\ +% \cunum{1/2}{m} \\ +% \cunum{1_1/2}{m} \\ +% \cunum[m=cm]{1_1/2}{m} \\ +% \cunum{?}{l} \\ +% \cunum{50}{dag} \\ +% \cunum{5}[0]{dag} \\ +% \cunum{1.1234}{m} +% \end{cuexamplecode} +% +% Decimal numbers are automatically rounded to 2 digits after the +% colon, temperatures (\texttt{C}, \texttt{F}, \texttt{K} and +% \texttt{Re}) are automatically rounded to integers.\footnote{You can +% -- of course -- change this behavior, see \vref{sec:options}.} +% +% \lstinline|\cutext| and \lstinline|\Cutext| print the number and the +% written name of the unit. Furthermore, if the package option +% \opt{use-numerals} is used, integers below a specific integer (by +% default 13; see \opt{use-numerals-below}) are also written out with +% \lstinline|\Cutext| capitalizing the first letter (using package \pkg{fmtcount}). +% Conversion between +% units is not supported. Without \opt{use-numerals}: +% +% \begin{cuexamplecode} +% \cutext{1}{l} \\ +% \Cutext{1}{l} \\ +% \cutext{12}{l} \\ +% \Cutext{13}{l} +% \end{cuexamplecode} +% and using package option \opt{use-numerals=true} +% \cusetup{use-numerals-below=13} +% \begin{cuexamplecode} +% \cutext{1}{l} \\ +% \Cutext{1}{l} \\ +% \cutext{12}{l} \\ +% \Cutext{13}{l} +%^^A \cutext{23}{kg} \\ +%^^A \Cutext{23}{kg}\\ +%^^A \cutext{1}{l}\\ +%^^A \Cutext{2}{l}\\ +%^^A \cutext{1}{C} \\ +%^^A \cutext{180}{C} \\ +%^^A \Cutext{1}{C} \\ +%^^A \Cutext{180}{C} \\ +%^^A \Cutext{1.4}{C} \\ +% \end{cuexamplecode} +% \cusetup{use-numerals-below=0} +% +% +% \lstinline|\cufrac| can be used to print fractions. Like in \lstinline|\cunum| +% \texttt{\_} and \texttt{/} are used to imply a (mixed) fraction: +% +% \begin{cuexamplecode} +% \cufrac{3} \\ +% \cufrac{2/3} \\ +% \cufrac{1_2/3} +% \end{cuexamplecode} +% +% +% \section{Predefined units \& some notes} +% \label{sec:pred-units} +% +% In \vref{tab:def-units} you can find all predefined units. +% +% I did not include a separate key for \enquote{Prise} (pinch), but you can use +% \texttt{Msp} (Messerspitze) and modify it to fit your +% purpose\footnote{See \vref{sec:language}.}. +% In other languages the nearest equivalent of \enquote{Messerspitze} is +% \enquote{pinch} which I used. +% +%^^A Please note that this package uses \texttt{translator} for defining translations, +%^^A so you may put +% +% \begin{table}[htbp] +% \centering +% \begin{tabular}{ lll } +% \toprule +% unit name & unit-key & symbol \\ \midrule +% \PrintUnit {kg} \\ +% \PrintUnit {dag} \\ +% \PrintUnit {g} \\ +% \PrintUnit {oz} \\ +% \PrintUnit {lb} \\ \addlinespace +% +% \PrintUnit {C} \\ +% \PrintUnit {F} \\ +% \PrintUnit {Re} \\ +% \PrintUnit {K} \\ \addlinespace +% +% \PrintUnit {d} \\ +% \PrintUnit {h} \\ +% \PrintUnit {min} \\ +% \PrintUnit {s} \\ \addlinespace +% +% \PrintUnit {m} \\ +% \PrintUnit {dm} \\ +% \PrintUnit {cm} \\ +% \PrintUnit {mm} \\ +% \PrintUnit {in} \\ \addlinespace +% +% \PrintUnit {l} \\ +% \PrintUnit {dl} \\ +% \PrintUnit {cl} \\ +% \PrintUnit {ml} \\ \addlinespace +% +% \PrintUnit {cal} \\ +% \PrintUnit {kcal} \\ +% \PrintUnit {J} \\ +% \PrintUnit {kJ} \\ +% \PrintUnit {eV} \\ \addlinespace +% +% \PrintUnit {Msp} \\ +% \PrintUnit {EL} \\ +% \PrintUnit {TL} \\ +% \bottomrule +% \end{tabular} +% \caption{List of predefined unit-keys. Note that \enquote{electron +% volt} exists just for fun.} +% \label{tab:def-units} +% \end{table} +% +% \begin{table}[htbp] +% \centering +% \begin{tabular}{ ll } +% \toprule +% unit-key & symbol \\ \midrule +% \PrintUnitSymbol {eVc-2} \\ +% \PrintUnitSymbol {hbareV-1} \\ +% \PrintUnitSymbol {chbareV-1} \\ +% \PrintUnitSymbol {(chbareV-1)3} \\ +% \bottomrule +% \end{tabular} +% \caption{List of nonsense units (exist just for fun, there will +% be no support for those units). } +% \label{tab:def-units} +% \end{table} +% +% +% +% \section{Defining units} +% \label{sec:def-units} +% +% New units can be defined using \lstinline|\newcookingunit|: +% +% \begin{function}{\newcookingunit} +% \begin{syntax} +% \lstinline|\newcookingunit|\oarg{symbol}\marg{new-unit-key} +% \end{syntax} +% This command defines the new unit \meta{new-unit-key}. If the +% key is not the same as the printed symbol use \oarg{symbol}. +% +% Some examples (note: the definition of the printed degree Celsius is +% directly copied \& pasted from [a maybe older version of] \pkg{siunitx}): +% +% \begin{center} +% \begin{tabular}{ll} +% \lstinline|\newcookingunit{kg}| \\ +% \lstinline|\newcookingunit{g}| \\ +% \lstinline|\newcookingunit[Msp.] {Msp}| \\ +% \lstinline|\newcookingunit[\ensuremath{{}^{\circ}}\kern-\scriptspace C] {C} | +% \end{tabular} +% \end{center} +% +% \end{function} +% +% +% \section{Defining options} +% \label{sec:defining-opt} +% +% Options (to change units) can be newly defined or added to already existing keys +% using +% \begin{itemize} +% \item \lstinline|\cudefinekeys| +% \item \lstinline|\cudefinesinglekey| +% \item \lstinline|\cuaddkeys| +% \item \lstinline|\cuaddsinglekeys| +% \item \lstinline|\cuaddtokeys| +% \end{itemize} +% +% +% +% \begin{function}{\cudefinekeys,\cudefinesinglekey} +% \begin{syntax} +% \mycs{cudefinekeys}\marg{unit-key-1} +% \ \ \{ +% \ \ \ \ \marg{unit-key-2} \marg{1 unit-key-1 are \dots\ unit-key-2} +% \ \ \ \ \marg{unit-key-3} \marg{1 unit-key-1 are \dots\ unit-key-3} +% \ \ \ \ \marg{unit-key-4} \marg{1 unit-key-1 are \dots\ unit-key-4} +% \ \ \ \ \dots +% \ \ \} +% +% \mycs{cudefinesinglekey}\marg{unit-key-1} +% \ \ \{ +% \ \ \ \ \marg{unit-key-2} \marg{1 unit-key-2 are \dots\ unit-key-1} +% \ \ \ \ \marg{unit-key-3} \marg{1 unit-key-3 are \dots\ unit-key-1} +% \ \ \ \ \dots +% \ \ \} +% \end{syntax} +% +% If you define new units (see \vref{sec:def-units}) and cannot add +% them to already existing keys you can use \lstinline|\cudefinekeys| bzw. +% \lstinline|\cudefinesinglekey| to define new keys. +% +% \lstinline|\cudefinekeys| takes the \marg{unit-key-1} as a \enquote{basis}, +% defines a key with the name \meta{unit-key-1} and adds the values +% \meta{unit-key-1}, \meta{unit-key-2}, \meta{unit-key-3}, etc. Furthermore +% this command also defines the keys \meta{unit-key-2}, \meta{unit-key-3}, etc. +% with the same values as \meta{unit-key-1}. Please note that \meta{\dots} has to +% be a number. ^^A Those keys are linked to each other. +% +% Sometimes it is not that easy and the conversion of one unit into another +% needs are more complicated formula (see for example temperatures). +% If that is the case use \lstinline|\cudefinesinglekey|. As the name says it +% defines \emph{only} the key \meta{unit-key-1} with the values \meta{unit-key-1}, +% \meta{unit-key-2}, etc. The advantage of this command is that now +% \meta{\dots} can be a formula and the numerical input can be placed explicitly +% using \texttt{\#1}. +% +% +% \end{function} +% +% \begin{cuexample} +% +% This example defines following keys with their respective value: +% \begin{itemize} +% \item the key \texttt{kg} with the values \texttt{kg}, \texttt{dag}, \texttt{g} and \texttt{oz} +% \item the key \texttt{dag} with the values \texttt{kg}, \texttt{dag}, \texttt{g} and \texttt{oz} +% \item the key \texttt{g} with the values \texttt{kg}, \texttt{dag}, \texttt{g} and \texttt{oz} +% \item the key \texttt{oz} with the values \texttt{kg}, \texttt{dag}, \texttt{g} and \texttt{oz} +% \item the key \texttt{d} with the values \texttt{d}, \texttt{h}, \texttt{min} and \texttt{s} +% \item \dots +% \end{itemize} +% +% +% \begin{align*} +% \SI{1}{\kg}&= \SI{1}{\kg} & +% \SI{1}{\kg}&= \SI{100}{\deka\g} & +% \SI{1}{\kg}&= \SI{1000}{\g} \\ +% \SI{1}{\kg}&= \SI{35.27399}{\ounce} & +% \SI{1}{\kg}&= \SI{2.204 622 6}{\pound} +% \end{align*} +% +% \begin{lstlisting} +% \cudefinekeys {kg} +% { +% {dag}{ 100 } %% 1 kg are 100 dag +% {g} { 1000 } %% 1 kg are 1000 g +% {oz} { 35.27399 } %% 1 kg are 35.27399 oz +% {lb} { 2.204 622 6 } %% 1 kg are 2.204 622 6 lb +% } +% \cudefinekeys {d} +% { +% {h} { 24 } %% 1 day are 24 hours +% {min}{ 1440 } %% 1 day are 1440 minutes +% {s} { 86400 } %% 1 day are 86400 seconds +% } +% \end{lstlisting} +% +% To convert degree Fahrenheit to degree Celsius, kelvin and degree R\'eamur one +% needs the formulas +% \begin{align*} +% T_C &= ( T_F - 32 ) \cdot \frac{5}{9} \\ +% T_K &= ( T_F - 459.67 ) \cdot \frac{5}{9} \\ +% T_{Re} &= ( T_F - 32 ) \cdot \frac{4}{9} +% \end{align*} +% +% with $T_F$ being the input temperature in degree Fahrenheit and +% $T_C$ being the same temperature in degree Celsius, etc. Using +% \lstinline|\cudefinesinglekey| the key \texttt{F} and the values \texttt{C}, \texttt{K} and \texttt{Re} +% are defined: +% +% \begin{lstlisting} +% \cudefinesinglekey {F} +% { +% {C} { ( #1 - 32 ) * 5/9 } %% see formulas above +% {K} { ( #1 + 459.67 ) * 5/9 } +% {Re} { ( #1 - 32 ) * 4/9 } +% } +% \end{lstlisting} +% +% This defines the key \texttt{F} with the values \texttt{F}, \texttt{C}, +% \texttt{K} and \texttt{Re}. +% +% \end{cuexample} +% +% +% +% \begin{function}{\cuaddkeys,\cuaddsinglekeys} +% +% \begin{syntax} +% \mycs{cuaddkeys}\marg{unit-key-1} +% \ \ \{ +% \ \ \ \ \marg{unit-key-2} \marg{1 unit-key-1 are \dots\ unit-key-2} +% \ \ \ \ \marg{unit-key-3} \marg{1 unit-key-1 are \dots\ unit-key-3} +% \ \ \ \ \marg{unit-key-4} \marg{1 unit-key-1 are \dots\ unit-key-4} +% \ \ \ \ \dots +% \ \ \} +% +% \mycs{cuaddsinglekeys}\marg{unit-key-1} +% \ \ \{ +% \ \ \ \ \marg{unit-key-2} \marg{1 unit-key-2 are \dots\ unit-key-1} +% \ \ \ \ \marg{unit-key-3} \marg{1 unit-key-3 are \dots\ unit-key-1} +% \ \ \ \ \dots +% \ \ \} +% \end{syntax} +% +% These commands add \meta{unit-key-2}, etc. to the already defined +% key \meta{unit-key-1}. +% +% \lstinline|\cuaddkeys| takes the already defined key +% \marg{unit-key-1} as a \enquote{basis}, and adds +% \meta{unit-key-2}, \meta{unit-key-3}, etc. to its +% values. Furthermore it adds those new values to other keys linked +% to \meta{unit-key-1} and defines the new keys \meta{unit-key-2}, +% etc. with the same values as \meta{unit-key-1}. +% +% +% If the conversion is more complicated use +% \lstinline|\cuaddsinglekeys|. It adds \meta{unit-key-2}, etc. as +% values to \meta{unit-key-1}. The numerical input can be placed +% using \texttt{\#1} (see \lstinline|\cudefinesinglekey|). This +% command neither defines new keys nor does it add values to other +% keys than \meta{unit-key-1}. +% +% +% \end{function} +% +% +% \begin{cuexample} +% Suppose you are british (I am sorry, I can't think of another +% reason to use those units) and you want to implement 'stone' (yes, I +% was surprised myself that such a unit exists, but it even appears in +% a Sherlock-Holmes story). You exactly know that \SI{1}{\st} equals +% \SI{14}{\lb}, well \dots\ now you have two +% choices. \lstinline|\cuaddkeys| or \lstinline|\cuaddtokeys| (use the +% one best fitting). This example uses the first, the next the latter one. +% \begin{lstlisting} +% \newcookingunit {st} %% defining new unit 'stone' +% \cuaddkeys {lb} %% adding st to lb (could also add to kg, dag and oz) +% { +% {st} { 1/14 } %% 1 lb are 1/14 st as 14 lb are 1 st +% } +% \end{lstlisting} +% \begin{cuexamplecode} +% \cunum[lb=st]{1}{lb} \\ +% \cunum[st=lb]{1}{st} \\ +% \cunum[st=g]{1}{st} \\ +% \cunum[st=kg]{1}{st} \\ +% \cunum[kg=st]{1}{kg} \\ +% \end{cuexamplecode} +% \end{cuexample} +% +% +% \begin{cuexample} +% Now you want to add degree R{\o}mer and convert +% Celsius to degree R{\o}mer: +% \begin{equation*} +% T_{R\o} = T_C * \frac{21}{40} + 7.5 +% \end{equation*} +% +% \begin{lstlisting} +% %% defining new unit 'degree R{\o}mer' +% \newcookingunit [\ensuremath{ {} ^ { \circ } }\kern-\scriptspace R{\o}] {Ro} +% \cuaddsinglekeys {C} %% adds value 'Ro' to 'C'. +% { +% {Ro} { #1 * 21/40 + 7.5 } +% } +% \cusetup %% round to integer automatically +% { +% set-option-for-Ro = { round-to-int = true } +% } +% \end{lstlisting} +% \begin{cuexamplecode} +% \cunum{10}{C} \\ +% \cunum[C=Ro]{10}{C} \\ +% \end{cuexamplecode} +% \end{cuexample} +% +% +% +% +% +% +% +% +% +% +% +% \begin{function}{\cuaddtokeys} +% \begin{syntax} +% \mycs{cuaddtokeys} \marg{unit-key-1} \marg{unit-key-2} \marg{1 unit-key-2 are \dots\ unit-key-1} +% \end{syntax} +% Works similar to \mycs{cuaddkeys} regarding the definition of keys. +% \end{function} +% +% \begin{cuexample} +% Continuing the example from before, this time with \lstinline|\cuaddtokeys|: +% \begin{lstlisting} +% \newcookingunit {st} %% defining (again) new unit 'stone' +% \cuaddtokeys {lb} {st} { 14 } %% 1 st are 14 lb +% \end{lstlisting} +% \begin{cuexamplecode} +% \cunum[lb=st]{1}{lb} \\ +% \cunum[st=lb]{1}{st} \\ +% \cunum[st=g]{1}{st} \\ +% \cunum[st=kg]{1}{st} \\ +% \cunum[kg=st]{1}{kg} \\ +% \end{cuexamplecode} +% \end{cuexample} +% +% +% +% \section{Language support} +% \label{sec:language} +% +% The unit names and symbols depend on the language. To change the +% name depending on the language you can use \lstinline|\cudefinename| +% and to only change symbols use \lstinline|\cudefinesymbol|. +% +% \begin{function}{decimal-mark, one(m),one(f),one(n)} +% Those are special keys (as they cannot be used as units). Not only +% are printed units language depending, but as is the decimal +% mark (\enquote{.} or \enquote{,}). To set the decimal mark use +% \opt{decimal-mark} (see examples below). +% +% Furthermore if you are using the package-option \opt{use-numerals} you may +% also use the keys \opt{one(m)}, \opt{one(f)} and \opt{one(n)}. If +% you use this option, integers below a certain value (see option +% \opt{use-numerals-below}) are written-out. The only problem is +% the written-out \enquote{1} mostly depends on the gender of the +% following word (e.g. \enquote{ein Baum} (m), +% \enquote{eine Pflanze} (f) and \enquote{ein Auto} (n)). To set the +% written-out 1 to be correct with the gender of the used unit, use +% this key (see also examples below) +% \end{function} +% +% \begin{function}{\cudefinename} +% \begin{syntax} +% \mycs{cudefinename}\marg{Language} +% \ \ \{ +% \ \ \ \ \marg{unit-key-1} \oarg{symbol-1} \marg{singular-1} \oarg{plural-1} \meta{gender} +% \ \ \ \ \marg{unit-key-2} \oarg{symbol-2} \marg{singular-2} \oarg{plural-2} \meta{gender} +% \ \ \ \ \dots +% \ \ \} +% \end{syntax} +% +% This command defines the names (and optionally the symbol) of the +% commands printed in \lstinline|\cutext| and \lstinline|\Cutext| +% (and \lstinline|\cunum| regarding the symbol) for the specific +% \meta{Language}. For details regarding \meta{language} see the +% \pkg{translator}-documentation. +% +% If the plural form of the name differs from the singular form use +% \oarg{plural} to specify the plural form, if no \oarg{plural} is +% given the plural will be set equal to its singular. The singular +% is only used if the number in \lstinline|\cutext| and +% \lstinline|\Cutext| is equal to 1. +% +% \meta{gender} can be \texttt{m} (maskulin), \texttt{f} (feminin) or +% \texttt{n} (neutrum). If not given \texttt{m} is used as default. +% \end{function} +% +% \begin{lstlisting} +% \cudefinename {English} +% { +% {kg} {kilogramme} +% {oz} {ounce} +% {h} {hour} [hours] +% {C} {degree \space Celsius} [degrees \space Celsius] +% {decimal-marker} {.} +% {one(m)} {one} +% {one(f)} {one} +% {one(n)} {one} +% } +% \end{lstlisting} +% \begin{lstlisting} +% \cudefinename {German} +% { +% {kg} {Kilogramm} <n> +% {oz} {Unze} <f> +% {d} {Tag} [Tage] +% {h} {Stunde} [Stunden] <f> +% {C} {Grad\space Celsius} +% {decimal-marker} {,} +% {one(m)} {ein} +% {one(f)} {eine} +% {one(n)} {ein} +% } +% \end{lstlisting} +% +% +% \begin{function}{\cudefinesymbol} +% +% \begin{syntax} +% \mycs{cudefinesymbol}\marg{Language} +% \ \ \{ +% \ \ \ \ \marg{unit-key-1} \marg{symbol-1} +% \ \ \ \ \marg{unit-key-2} \marg{symbol-2} +% \ \ \ \ \dots +% \ \ \} +% \end{syntax} +% +% This command defines the symbols of the units printed in +% \lstinline|\cunum| for the specific \meta{language}. It works +% similar as \lstinline|\cudefinename|, but only the symbols (and no +% names) can be set. For details regarding \meta{language} see +% the \pkg{translator}-documentation. +% +%^^A A special key is the \texttt{decimal-mark}. It defines the symbol +%^^A printed for the decimal-marker. +% \end{function} +% +% +% \begin{lstlisting} +% \cudefinesymbol {English} +% { +% {decimal-mark} {.} +% {one(m)} {one} +% {one(f)} {one} +% {one(n)} {one} +% } +% \cudefinesymbol {German} +% { +% {decimal-mark} {,} +% {one(m)} {ein} +% {one(f)} {eine} +% {one(n)} {ein} +% } +% \cudefinesymbol {French} +% { +% {l} {L} +% {dl} {dL} +% {cl} {cL} +% {ml} {mL} +% {decimal-mark} {.} +% {one(m)} {un} +% {one(f)} {une} +% {one(n)} {un} +% } +% \end{lstlisting} +% +% +% \section{Options} +% \label{sec:options} +% +% Options in \pkg{cooking-units} can mostly be set globally using +% \lstinline|\cusetup| or locally using the optional argument of the +% respective command (but \emph{not} as a package option). The only +% exception is the option given in \vref{sec:load-time-options} which +% needs to be used as a package option. +% +% \subsection{Load time options} +% \label{sec:load-time-options} +% +% \begin{function}{use-numerals} +% \begin{syntax} +% \cs{usepackage}[use-numerals=\meta{true/false}]\{cooking-units\} +% \end{syntax} +% If set to \true\ loads package \pkg{fmtcount} and uses +% \mycs{numberstringnum} for \mycs{cutext} +% and \mycs{Numberstringnum} for \mycs{Cutext} to write-out numbers below +% \opt{use-numerals-below} (13 by default), integers above are +% printed as numbers. Please note the keys \opt{one(m)}, \opt{one(f)} +% and \opt{one(n)} to change the printed \enquote{one} (as +% \enquote{one} is in many languages dependent on the gender of the +% following word. E.g in German: Maskulin: ein Baum, +% Feminin: eine Pflanze, Neutrum: ein Auto). +% \end{function} +% +% \cusetup{use-numerals-below=13} +% \begin{cuexamplecode} +% \cutext{1}{kg} \\ +% \Cutext{1}{kg} \\ +% \cutext{2}{kg} \\ +% \Cutext{2}{kg} \\ +% \cutext{13}{kg} \\ +% \Cutext{14}{kg} +% \end{cuexamplecode} +% \cusetup{use-numerals-below=0} +% +% \subsection{Normal options} +% +% This option can only be set as local options or using +% \lstinline|\cusetup|, but \emph{not} as load time options. +% +% \begin{function}{\cusetup} +% Options can be set globally using \lstinline|\cusetup|. +% \end{function} +% +% +% \begin{function}{unit} +% \begin{syntax} +% \meta{unit-key-1} = \meta{unit-key-2} +% \end{syntax} +% Convert units from \meta{unit-key-1} to \meta{unit-key-2} (see +% \vref{sec:defining-opt} to define new options). +% \end{function} +% +% \begin{function}{set-option-for-<unit-key>,add-option-for-<unit-key>,erase-all-options} +% \begin{syntax} +% set-option-for-\meta{unit-key} = \meta{key1=value1,\dots} +% add-option-for-\meta{unit-key} = \meta{key1=value1,\dots} +% erase-all-options +% \end{syntax} +% Sets and adds \meta{key1=value1,\dots}, for a specific +% \meta{unit-key} +% ^^A with +% ^^A options being a comma-separated list of \texttt{key=value}. +% \texttt{erase-all-options} is used to erase all options for all +% \meta{unit-key}s. +% +% You may want to attach some options to a special +% \meta{unit-key}. Those options are automatically activated if (and +% only if) the specific \meta{unit-key} is used (or changed into this +% unit). Setting options overwrites old options. Adding options, well +% \dots\ adds the options to the old ones. +% +% The following rounds the values to integers for \texttt{F}, \texttt{C}, +% \texttt{K} and \texttt{Re}. +% +% \end{function} +% +% \begin{lstlisting} +% \cusetup +% { +% set-option-for-F = { round-to-int = true } , +% set-option-for-C = { round-to-int = true } , +% set-option-for-K = { round-to-int = true } , +% set-option-for-Re = { round-to-int = true } +% } +% \end{lstlisting} +% +% You can \enquote{delete} the options by setting +% an empty value for a specific \meta{unit-key} (or use +% \opt{erase-all-options} to erase all options for all \meta{unit-key}s) +% +% +% \begin{function}{eval-fraction} +% \begin{syntax} +% eval-fraction = \meta{true/false} +% \end{syntax} +% This option takes \texttt{true} or \texttt{false} as values. +% If set to \texttt{true} fractions are evaluated. Please note that divisions +% through zero are not allowed. +% \end{function} +% +% \begin{cuexamplecode} +% \cusetup{eval-fraction=true} @ +% \cunum{1/3}{kg} \\ +% \cunum{1/2}{kg} \\ +% \cunum[kg=g]{1/2}{kg} \\ +% \cunum{1_1/2}{kg} \\ +% \cunum[kg=g]{1_1/2}{kg} +% \end{cuexamplecode} +% +% +% \begin{function}{round-precision} +% \begin{syntax} +% round-precision = \meta{integer} +% \end{syntax} +% Rounds the amount automatically to \meta{integer} digits after the colon. +% Note that units like \texttt{C}, \texttt{F}, \texttt{K} and \texttt{Re} are still rounded +% to integers due to \texttt{set-option-for-<unit-key>}. +% \end{function} +% +% +% \begin{cuexamplecode} +% \cusetup{round-precision= 5} @ +% \cunum{1.23456789}{kg} \\ +% \cunum[g=kg]{12.587}{g} \\ +% \cunum{194}{kg} \\ +% \cunum[C=F]{200--210}{C} \\ +% \cunum[K=C]{0.0012}{K} \\ +% \cusetup{round-precision= 1} @ +% \cunum{1.23456789}{kg} \\ +% \cunum{12.58}{kg} \\ +% \cunum[g=kg]{194}{g} \\ +% \cunum[C=F]{200--210}{C} \\ +% \cunum[K=C]{0.0012}{K} +% \end{cuexamplecode} +% +% +% +% \begin{function}{round-to-int} +% \begin{syntax} +% round-to-int = \meta{true/false} +% \end{syntax} +% Rounds the amount to an integer if set \texttt{true}. +% \end{function} +% +% +% \begin{cuexamplecode} +% \cusetup{round-to-int=true} @ +% \cunum{1.23456789}{kg} \\ +% \cunum{12.58}{kg} \\ +% \cunum[g=kg]{194--294}{g} \\ +% \cunum[kg=g]{1.23456789}{kg} \\ +% \end{cuexamplecode} +% +% +% \begin{function}{range-sign} +% \begin{syntax} +% range-sign = \meta{string} +% cunum-range-sign = \meta{string} +% cutext-range-sign = \meta{string} +% \end{syntax} +%^^A Sets the \emph{printed} range-sign equal to \meta{string}. +% The second sets the \emph{printed} range-sign used in \mycs{cunum} to +% \meta{string}, the third sets the printed range-sign used in +% \mycs{cutext}/\mycs{Cutext} to \meta{string}. +% +%^^A If you want to change to the same range-sign for all commands +%^^A use the first option. +% Use the \opt{range-sign} to set the printed range-signs for both +% \mycs{cunum} and \mycs{cutext}/\mycs{Cutext} to \meta{string}. +% +% The default for \meta{string} is \texttt{-{}-} (for both). +% \end{function} +% +% \begin{cuexamplecode} +% \cusetup{cunum-range-sign={~to~}} @ +% \cunum{1--2}{kg} \\ +% \cutext{1--2}{kg} \\ +% \Cutext{1--2}{kg} \\ +% \end{cuexamplecode} +% \begin{cuexamplecode} +% \cusetup{cutext-range-sign={~to~}} @ +% \cunum{1--2}{kg} \\ +% \cutext{1--2}{kg} \\ +% \Cutext{1--2}{kg} \\ +% \end{cuexamplecode} +% \begin{cuexamplecode} +% \cusetup{range-sign={~to~}} @ +% \cunum{1--2}{kg} \\ +% \cutext{1--2}{kg} \\ +% \Cutext{1--2}{kg} \\ +% \end{cuexamplecode} +% +% +% +% \begin{function}{fraction-command} +% \begin{syntax} +% fraction-command = \meta{\cs{command}} +% \end{syntax} +% Sets the command used for printing fractions equal to \meta{\cs{command}}. +% \meta{\cs{command}} has to take two arguments. By default +% it is equal to \lstinline!\sfrac! from \pkg{xfrac}. +% +% Please note that the amount is \emph{not} printed inside a math +% environment by default. +% \end{function} +% +% \begin{cuexamplecode} +% \newcommand\myfrac[2]{#1/#2} @ +% \cusetup{fraction-command=\myfrac} @ +% \cunum{1/2}{kg} \\ +% \cunum{4/5}{C} \\ +% \cunum{1_2/3}{kg} \\ +% \cusetup{fraction-command=\nicefrac} @ +% \cunum{1/2}{kg} \\ +% \cunum{4/5}{C} \\ +% \cunum{1_2/3}{kg} +% \end{cuexamplecode} +% +% \begin{function}{fraction-inline} +% \begin{syntax} +% fraction-inline = \meta{input containing \#1 and \#2} +% \end{syntax} +% Similar to \texttt{fraction-command} only that you don't have to +% define a command to alter the output of the fraction. +% \end{function} +% +% \begin{cuexamplecode} +% \cusetup{fraction-inline={#1/#2} } @ +% \cunum{1/2}{kg} \\ +% \cunum{4/5}{C} \\ +% \cunum{1_2/3}{kg} \\ +% \cusetup{fraction-inline={\nicefrac{#2}{#1}} } @ +% \cunum{1/2}{kg} \\ +% \cunum{4/5}{C} \\ +% \cunum{1_2/3}{kg} +% \end{cuexamplecode} +% +% +% \begin{function}{mixed-fraction-space} +% \begin{syntax} +% mixed-fraction-space = \meta{length} +% \end{syntax} +% Sets the length between the fraction and the number in a mixed-fraction, +% default is \texttt{0.1em}. +% \end{function} +% +% \begin{cuexamplecode} +% \cunum{1_2/3}{kg} \\ +% \cunum{10_2/3}{kg} \\ +% \cusetup{mixed-fraction-space=1em } @ +% \cunum{1_2/3}{kg} \\ +% \cunum{10_2/3}{kg} \\ +% \cusetup{mixed-fraction-space=0em } @ +% \cunum{1_2/3}{kg} \\ +% \cunum{10_2/3}{kg} \\ +% \end{cuexamplecode} +% +% +% \begin{function}{set-special-sign,add-special-sign} +% \begin{syntax} +% set-special-sign = \meta{character(s)} +% add-special-sign = \meta{character(s)} +% \end{syntax} +% Allows \meta{character(s)} to be used in the first mandatory argument of +% \lstinline!\cunum! without raising an error (you can customize this +% behavior, see \opt{set-unknown-message}). By default it is set to \texttt{?}. +% \end{function} +% +% \begin{cuexamplecode} +% \cunum{?}{kg} \\ +% \cunum[g=kg]{10?--20?}{kg} \\ +% \cusetup{add-special-sign={xX} } @ +% \cunum{x}{kg} \\ +% \cunum{X--?}{kg} \\ +% \cusetup{set-special-sign={} } @ +% \cunum{1}{kg} \\ +% \cunum{1--2}{kg} \\ +% \end{cuexamplecode} +% +% +% +% +% +% \begin{function}{parse-number} +% \begin{syntax} +% parse-number = \meta{true/false} +% \end{syntax} +% If set to \texttt{false} prints the number of \lstinline!\cunum!, +% \lstinline!\cutext! and \lstinline!\Cutext! +% as they are (after some \dots\ well \dots\ parsing due to \enquote{\lstinline|_|}). It is \texttt{true} by default. +% \end{function} +% +% +% \begin{cuexamplecode} +% \cusetup{ parse-number=false } @ +% \cunum[kg=g]{1}{kg} \\ +% \cunum{1--2}{kg} \\ +% \cunum{1----------2}{kg} \\ +% \cunum{1.2}{kg} \\ +% \cunum[kg=g]{1,2}{kg} \\ +% \cunum{1/2}{kg} \\ +% \cunum{1_2/3}{kg} \\ +% \cunum{1/2_3}{kg} \\ +% \cunum{qwertzuiop}{kg} \\ +% \cutext{1}{kg} \\ +% \cutext{100}{kg} \\ +% \cutext{gjfak}{kg} \\ +% \end{cuexamplecode} +% +% +% +% +% +% \begin{function}{use-numerals-below} +% \begin{syntax} +% use-numerals-below = \meta{integer} +% \end{syntax} +% Only usable if the package option \opt{use-numerals} is active. Prints the name of +% the numbers for integers used in \mycs{cutext} and \mycs{Cutext} +% smaller than \meta{integer}. \meta{integer} it is by default +% 13. +% \end{function} +% +% \cusetup{ use-numerals-below=13 } +% \begin{cuexamplecode} +% \cutext{1}{kg} \\ +% \cutext{2}{kg} \\ +% \cutext{12}{kg} \\ +% \cutext{13}{kg} \\ +% \cusetup{ use-numerals-below=10 } @ +% \cutext{1}{kg} \\ +% \cutext{2}{kg} \\ +% \cutext{12}{kg} \\ +% \cutext{13}{kg} \\ +% \cusetup{ use-numerals-below=0 } @ +% \cutext{1}{kg} \\ +% \cutext{2}{kg} \\ +% \cutext{12}{kg} \\ +% \cutext{13}{kg} \\ +% \end{cuexamplecode} +% \cusetup{ use-numerals-below=0 } +% +% \begin{function}{set-unknown-message} +% \begin{syntax} +% set-unknown-message = \meta{error/warning/none} +% \end{syntax} +% Using a special sign (\texttt{?} by default) causes a warning to +% be raised. Set this option to \opt{error} if you want an error +% (as an extra emphasis), \opt{warning} if you want a warning +% (default) and \opt{none} if you don't want to know anything about it. +% \end{function} +% +% +% +% \subsection{Weird options} +% +% \begin{function}{check-temperature} +% \begin{syntax} +% check-temperature = \meta{true/false} +% \end{syntax} +% Checks if the used temperature is below the absolute zero point. +% Currently \texttt{C}, \texttt{F}, \texttt{K} and \texttt{Re} are supported. +% While \lstinline|\cunum{0}{K}| is ok, \lstinline!\cunum{-1}{K}! raises an error, +% same for the others. Is set to \texttt{false} by default. +% \end{function} +% +% ^^A \begin{cuexamplecode} +% ^^A \cusetup{check-temperature=true} @ +% ^^A \cunum{0}{K} \\ +% ^^A \cunum[K=C]{0--1}{K} \\ +% ^^A \end{cuexamplecode} +% +% +% +% \begin{function}{convert-to-eV} +% \begin{syntax} +% convert-to-eV = \meta{true/false} +% \end{syntax} +% Converts (nearly) every unit in \vref{tab:def-units} +% to electron volt or the respective derivative. Note that this +% option is: +% a) experimental and probably will forever be and b) just a joke, you are not +% supposed to use this units in a cookery book. +% +% \end{function} +% +% \begin{cuexamplecode} +% \cusetup{ convert-to-eV=true } @ +% \cunum{1}{kg} \\ +% \cunum{1}{l} \\ +% \cunum{1}{J} \\ +% \cunum{1}{m} \\ +% \cunum{1}{C} \\ +% \cunum{1}{s} \\ +% \end{cuexamplecode} +% +% +% +% +% \section{Bugs \& Feedback} +% +% Bug reports are always welcome. If you are sending a bug report +% please include a minimal working example showing the bug and a short +% description. Furthermore please add \enquote{cooking-units} +% to the e-mail header. GMX has the habit of putting e-mails into the +% spam account and adding \enquote{cooking-units} to the header makes +% it easier to recognize those e-mails. +% +% Feedback and requests are most welcome. Please also add (if possible) an example of the +% desired output into the minimal example (and also add \enquote{cooking-units} +% to the header). +% +% Furthermore, as you can see I am not able to speak too many languages (german and +% english to be precise; I managed to add french with the help of the internet, +% which is not optimal) so if you are able to speak a language not yet implemented +% and would like to help you can send me a list of the translations of the units given in +% \vref{tab:def-units}. I would need +% \begin{itemize} +% \item their singular (and plural) form, +% \item the gender, +% \item the printed symbol (if different), +% \item \texttt{decimal-mark} and \texttt{one(m)}, \texttt{one(f)}, \texttt{one(n)} +% \end{itemize} +% +% Oh yeah, if someone has a better idea of how to deal with languages I am happy to know. +% +% \end{documentation} +% +% \begin{implementation} +% +% \section{Implementation} +% +% \subsection{Beginning} +% +% \begin{macrocode} +%<@@=cooking_units> +% \end{macrocode} +% +% \begin{macrocode} +%<*package> +% \end{macrocode} +% +% +% +% Na dann, auf gehts! +% \begin{macrocode} +\@ifpackageloaded {xparse} + { } + { \RequirePackage {xparse} } +\@ifpackageloaded {expl3} + { } + { \RequirePackage {expl3} } +% \end{macrocode} +% \changes {2016/08/31} {1.00} {Initial version} +% \begin{macrocode} +\ProvidesExplPackage + {cooking-units} + {2016/08/31} + {1.00} + {Ein Paket fuer Kocheinheiten} +% \end{macrocode} +% Chekcing if \pkg{expl3} is uptodate, otherwise abort the loading of the package. +% \begin{macrocode} +\@ifpackagelater { expl3 } { 2016/05/18 } + { } + { + \PackageError { cooking-units } { Support~package~expl3~too~old } + { + You~need~to~update~your~installation~of~the~bundles~'l3kernel'~and~ + 'l3packages'.\MessageBreak + Loading~cooking-units~will~abort! + } + \tex_endinput:D + } +% \end{macrocode} +% Loading the packages needed. +% \begin{macrocode} +\@ifpackageloaded { translator } { } { \RequirePackage { translator } } +\@ifpackageloaded { xfrac } { } { \RequirePackage { xfrac } } +\@ifpackageloaded { l3keys2e } { } { \RequirePackage { l3keys2e } } +% \end{macrocode} +% +% \changes {2016/06/11} {0.99} {Added the package option to load +% 'fmtcount'.} +% Define the only load-time option for this package. If it is set, +% load package \pkg{fmtcount} and redefine the option so that it +% displays an error message if used. +% \begin{macrocode} +\bool_new:N \g_@@_load_if_opt_numeral_bool +\keys_define:nn { cooking-units } + { + use-numerals .bool_gset:N = \g_@@_load_if_opt_numeral_bool , + use-numerals .default:n = { false }, + } +\ProcessKeysOptions { cooking-units } +\bool_if:NT \g_@@_load_if_opt_numeral_bool + { + \@ifpackageloaded { fmtcount } { } { \RequirePackage { fmtcount } } + } +\keys_define:nn { cooking-units } + { + use-numerals .code:n = \msg_error:nnn { cooking-units } { load-time-option } { fmtcount } , + } +% \end{macrocode} +% +% +% +% \subsection {Defining Variables} +% +% \begin{macro} +% { +% \tl_replace_all:NVn, +% \tl_replace_once:NnV , +% \tl_replace_once:NVn , +% \tl_if_in:nVT , +% \tl_if_in:NVT , +% \fp_compare:cNnT , +% \fp_eval:c, +% } +% Some commands we will need later. +% \begin{macrocode} +\cs_generate_variant:Nn \tl_replace_all:Nnn { NVn } +\cs_generate_variant:Nn \tl_replace_once:Nnn { NnV, NVn } +\cs_generate_variant:Nn \tl_if_in:nnT { nVT } +\cs_generate_variant:Nn \tl_if_in:NnT { NVT } +\cs_generate_variant:Nn \fp_compare:nNnT { cNnT } +\cs_generate_variant:Nn \fp_eval:n { c } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_frac:nn} +% This command is used to print the fractions and can be changed +% accordingly. +% \begin{macrocode} +\cs_new_eq:NN \@@_frac:nn \sfrac +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{ \l_@@_change_unit_prop } +% Conversions of units are stored within this property list. +% If someone requests that \texttt{kg} should be changed into \texttt{g}, +% \texttt{kg} is stored as a key with the value \texttt{g}. If someone +% then uses the unit \texttt{kg} the value \texttt{g} is restored and the unit +% is changed accordingly. +% \begin{macrocode} +\prop_new:N \l_@@_change_unit_prop +% \end{macrocode} +% \end{macro} +% +% +%\begin{macro} +% { +% \l_@@_tmpa_tl , +% \l_@@_tmpb_tl , +% \l_@@_mixed_fraction_tl , +% \l_@@_tmp_unit_tl , +% \l_@@_option_unit_tl , +% \l_@@_language_tl , +% \l_@@_cunum_range_sign_tl , +% \l_@@_cutext_range_sign_tl , +% \l_@@_value_unit_space_tl , +% \l_@@_input_digits_tl , +% \l_@@_decimal_mark_tl, +% \l_@@_value_signs_tl, +% \c_@@_str_hash_one_tl , +% \l_@@_allowed_special_signs_tl , +% } +% Some token lists needed later. The first two are just basic +% temporary safe tokens which are used everywhere. The third +% is used to store the numerical input of the mixed-fraction part. +% +% \verb|tmp_unit_tl| stores the unit-key given in \lstinline|\cunum|, etc, +% whereas \verb|option_unit_tl| stores the unit which the former unit +% is converted into. +% +% The others are needed for printing and checking. +% \begin{macrocode} +\tl_new:N \l_@@_tmpa_tl +\tl_new:N \l_@@_tmpb_tl +\tl_new:N \l_@@_mixed_fraction_tl +\tl_new:N \l_@@_tmp_unit_tl +\tl_new:N \l_@@_option_unit_tl +\tl_new:N \l_@@_language_tl +\tl_new:N \l_@@_cunum_range_sign_tl +\tl_new:N \l_@@_cutext_range_sign_tl +\tl_new:N \l_@@_value_unit_space_tl +\tl_new:N \l_@@_input_digits_tl +\tl_new:N \l_@@_decimal_mark_tl +\tl_new:N \l_@@_value_signs_tl +\tl_new:N \l_@@_allowed_special_signs_tl +\tl_new:N \c_@@_str_hash_one_tl +\tl_new:N \l_@@_input_range_sign_tl +% \end{macrocode} +% \end{macro} +% +% +% Setting some token lists to their default value. +% \lstinline|str_hash_one_tl| is used for defining single keys. +% (You will see, I didn't have a better idea) +% \begin{macrocode} +\tl_set:Nn \l_@@_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_@@_input_digits_tl { 0123456789 } +\tl_set:Nn \l_@@_decimal_mark_tl { . , } +\tl_set:Nn \l_@@_value_signs_tl { + - } +\tl_set:Nn \l_@@_input_range_sign_tl { -- } +\tl_set:Nn \l_@@_allowed_special_signs_tl { ? } +\tl_set_rescan:Nnn \c_@@_str_hash_one_tl + { \char_set_catcode_letter:N \# } {#1} +% \end{macrocode} +% +% Flat out stolen from \pkg{siunitx} +% \begin{macrocode} +\AtBeginDocument { + \cs_if_free:cT { T@TS1 } + { + \DeclareFontEncoding { TS1 } { } { } + \DeclareFontSubstitution { TS1 } { cmr } { m } { n } + } +} +% \end{macrocode} +% \begin{macrocode} +\DeclareTextSymbolDefault \c_@@_minus_tl { TS1 } +\DeclareTextSymbol \c_@@_minus_tl { TS1 } { 61 } +\AtBeginDocument { + \@ifpackageloaded { fontspec } + { + \@ifpackageloaded { eulervm } + { } + { + \int_const:Nn \c_@@_minus_int { 8722 } + \tl_set:Nn \c_@@_minus_tl + { \tex_char:D \c_@@_minus_int } + } + } + { } +} +% \end{macrocode} +% +% \begin{macro}{ \l_@@_mixed_frac_dim } +% The dimension between the fraction and the mixed fraction part is +% stored within this macro. There is no real reason why I have +% chosen this distance to be 0.1em, I just thought that it looks +% best. But if someone has some ideas of how large this distance +% should be I am happy to listen. +% \begin{macrocode} +\dim_new:N \l_@@_mixed_frac_dim +\dim_set:Nn \l_@@_mixed_frac_dim { 0.1 em } +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{ \l_@@_significant_figures_plus_one_int } +% Stores the round-precision inside. Not sure if 'significant +% figures' is the correct therm for this. Also computes the number +% plus 1, later I will count the tokens after the colon in a number +% (sorry, can't explain. If you have 123.4567, it gets +% \enquote{4567}, 4 tokens, larger then the number plus 1, needs to +% be rounded). +% \begin{macrocode} +\int_new:N \l_@@_significant_figures_int +\int_new:N \l_@@_significant_figures_plus_one_int +\int_set:Nn \l_@@_significant_figures_int { 2 } +\int_set:Nn \l_@@_significant_figures_plus_one_int { 2 + 1 } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{ \l_@@_print_numerals_below_int } +% Used if option 'use-numerals' is active. Uses numerals for +% integers smaller than this number. +% \begin{macrocode} +\int_new:N \l_@@_print_numerals_below_int +\int_set:Nn \l_@@_print_numerals_below_int { 13 } +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{ \l_@@_list_of_defined_keys_clist , \g_@@_list_of_defined_units_clist } +% List of defined units and keys. +% \begin{macrocode} +\clist_new:N \l_@@_list_of_defined_keys_clist +\clist_new:N \g_@@_list_of_defined_units_clist +% \end{macrocode} +%\end{macro} +% +% +% \begin{macro} { \g_@@_allowed_unit_phrases_tl } +% \changes {2016/06/12} {New: \cs{g_@@_allowed_unit_phrases_tl}} +% Used for the keys 'one(m)', 'one(f)', etc. Those are special keys +% which cannot be used as units, but are processed by the commands in +% the language section as such. +% \begin{macrocode} +\clist_new:N \g_@@_allowed_unit_phrases_clist +% \end{macrocode} +% \end{macro} +% +% \begin{macro} +% { +% \l_@@_error_bool , +% \l_@@_eval_fractions_bool, +% \l_@@_parse_input_bool, +% \l_@@_round_to_int_bool, +% \l_@@_special_sign_bool, +% \l_@@_decimal_in_input_bool, +% \l_@@_single_key_bool, +% \l_@@_fraction_in_input_bool, +% \l_@@_check_temperature_bool, +% \l_@@_convert_to_eV_bool, +% \l_@@_cutext_uppercase_word_bool, +% \l_@@_error_for_unknown_value_bool, +% \l_@@_parse_range_bool +% } +% Some booleans we need later. +% \begin{macrocode} +\bool_new:N \l_@@_error_bool +\bool_new:N \l_@@_eval_fractions_bool +\bool_new:N \l_@@_parse_input_bool +\bool_new:N \l_@@_round_to_int_bool +\bool_new:N \l_@@_special_sign_bool +\bool_new:N \l_@@_decimal_in_input_bool +\bool_new:N \l_@@_single_key_bool +\bool_new:N \l_@@_fraction_in_input_bool +\bool_new:N \l_@@_check_temperature_bool +\bool_new:N \l_@@_convert_to_eV_bool +\bool_new:N \l_@@_cutext_uppercase_word_bool +\bool_new:N \l_@@_error_for_unknown_value_bool +\bool_new:N \l_@@_parse_range_bool +% \end{macrocode} +% \end{macro} +% +% Setting some of them to \texttt{true}. +% \begin{macrocode} +\bool_set_true:N \l_@@_parse_input_bool +% \end{macrocode} +% +% +% \begin{macro}{ \q_@@_range } +% Replacing the sign \enquote{-{}-} with \lstinline|\q_@@_range| for testing. +% \begin{macrocode} +\quark_new:N \q_@@_range +% \end{macrocode} +%\end{macro} +% +% +% +% \begin{macro}{ decimal-mark, one(m), one(f), one(n) } +% Defining the translation for the decimal-mark. Note that those +% 'phrases' are stored inside +% \verb|\g_@@_allowed_unit_phrases_clist|. +% Furthermore some translations are defined. +% \begin{macrocode} +\clist_gset:Nn \g_@@_allowed_unit_phrases_clist + { + decimal-mark , + one (m) , + one (f) , + one (n) + } +\newtranslation { decimal-mark (cu-unitname) } { . } +\newtranslation [ to=German ] { decimal-mark (cu-unitname) } { , } +\newtranslation { one (m) (cu-unitname) } { one } +\newtranslation { one (f) (cu-unitname) } { one } +\newtranslation { one (n) (cu-unitname) } { one } +\newtranslation [ to=German ] { one (m) (cu-unitname) } { ein } +\newtranslation [ to=German ] { one (f) (cu-unitname) } { eine } +\newtranslation [ to=German ] { one (n) (cu-unitname) } { ein } +% \end{macrocode} +% \end{macro} +% +% +% +% +% +% \subsection {Keys} +% +% Let's define some keys. +% \begin{macrocode} +\keys_define:nn { cooking - units } + { +% \end{macrocode} +% +%\begin{macro}{ eval-fraction } +% If set to true the fractions are evaluated. +% \begin{macrocode} + eval-fraction .bool_set:N = \l_@@_eval_fractions_bool , + eval-fraction .default:n = { false } , +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{ round-precision } +% Setting the round-precision. Setting those two at once to +% not calculate it every time. +% \begin{macrocode} + round-precision .code:n = + { + \int_set:Nn \l_@@_significant_figures_int {#1} + \int_set:Nn \l_@@_significant_figures_plus_one_int { #1 + \c_one } + } , + round-precision .default:n = { 2 } , +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{ round-to-int } +% Rounding the results to an integer. +% \begin{macrocode} + round-to-int .bool_set:N = \l_@@_round_to_int_bool , + round-to-int .default:n = { false } , +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{ range-sign } +% Setting the printed range sign and make a difference between cunum +% and c(C)utext. +% \begin{macrocode} + range-sign .meta:n = + { + cunum-range-sign = {#1} , + cutext-range-sign = {#1} + } , + range-sign .default:n = { -- } , + cunum-range-sign .tl_set:N = \l_@@_cunum_range_sign_tl , + cunum-range-sign .default:n = { -- } , + cutext-range-sign .tl_set:N = \l_@@_cutext_range_sign_tl , + cutext-range-sign .default:n = { -- } , +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{ value-unit-space } +% Setting the space between the value and the printed unit. +% \begin{macrocode} + value-unit-space .tl_set:N = \l_@@_value_unit_space_tl , + value-unit-space .default:n = { \thinspace } , +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{ fraction-command } +% Setting the fraction command +% \begin{macrocode} + fraction-command .code:n = { \cs_set_eq:NN \@@_frac:nn #1 } , + fraction-command .default:n = { \sfrac } , +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{ fraction-inline } +% Setting the code inline. +% \begin{macrocode} + fraction-inline .code:n = { \cs_set:Npn \@@_frac:nn ##1##2 {#1} } , + fraction-inline .default:n = { \sfrac {#1}{#2} } , +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{ mixed-fraction-space } +% Setting the space between the mixed fraction part and the fraction. +% \begin{macrocode} + mixed-fraction-space .dim_set:N = \l_@@_mixed_frac_dim , + mixed-fraction-space .default:n = { 0.1 em } , +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{ parse-number } +% Parse the numbers? If no the input is printed as is (after some safetyparsing). +% \begin{macrocode} + parse-number .bool_set:N = \l_@@_parse_input_bool , + parse-number .default:n= { true } , +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{ add-special-sign } +% Adding a (some) special sign(s) which is (are) allowed in the input. +% \begin{macrocode} + add-special-sign .code:n = { \tl_put_right:Nn \l_@@_allowed_special_signs_tl {#1} } , + add-special-sign .default:n = { } , +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{ set-special-sign } +% Doing the same as above but also overrides the old signs. +% \begin{macrocode} + set-special-sign .tl_set:N = \l_@@_allowed_special_signs_tl , +% \end{macrocode} +%\end{macro} +% +% +% \begin{macro}{ input-range-sign } +% Don't wanna use \verb|--| as a range sperator in \mycs{cunum}? Set +% Use this option. +% \begin{macrocode} + input-range-sign .tl_set:N = \l_@@_input_range_sign_tl , + input-range-sign .default:n = { -- } , +% \end{macrocode} +%\end{macro} +% +% +%\begin{macro}{ check-temperature } +% Weird option. Checking the temperature, if the temperature is below the absolute zero temperature +% it raises an error. +% \begin{macrocode} + check-temperature .bool_set:N = \l_@@_check_temperature_bool , + check-temperature .default:n = { true } , +% \end{macrocode} +% +%\begin{macro}{ convert-to-eV } +% Another weird option, converts pretty much any unit defined by this +% package to electron volt or the respective derivative. +% \begin{macrocode} + convert-to-eV .bool_set:N = \l_@@_convert_to_eV_bool , + convert-to-eV .default:n = { true } , +% \end{macrocode} +%\end{macro} +% +% \begin{macro}{ use-numerals-below } +% Use numerals if the intger is below the integer set by this option. +% \begin{macrocode} + use-numerals-below .int_set:N = \l_@@_print_numerals_below_int , + use-numerals-below .default:n = { 13 } , +% \end{macrocode} +%\end{macro} +% +% +% \begin{macro}{ set-unknown-message } +% Sets the message for a special-sign to error, warning or none. +% \begin{macrocode} + set-unknown-message .choices:nn = + { error , warning , none } + { + \msg_redirect_name:nnn { cooking-units } { amount-not-known } + { \l_keys_choice_tl } + } , + set-unknown-message .default:n = { warning } , +% \end{macrocode} +%\end{macro} +% +% +%\begin{macro}{ erase-all-options } +% Erasing all preset options. +% \begin{macrocode} + erase-all-options .code:n = + { + \clist_map_inline:Nn \g_@@_list_of_defined_units_clist + { + \clist_clear:c { l_@@_predefined_option_##1_clist } + } + }, +% \end{macrocode} +% Ending the definiton of keys. +% \end{macro} + } +% \begin{macrocode} +% \end{macrocode} +% +% +% +% \subsection {Messages} +% +% Defining messages. +% +% \begin{macro} {Messages} +% I do not allow fractions and ranges in the same input. Maybe I will +% change this. +% \begin{macrocode} +\msg_new:nnnn { cooking-units } { fraction-not-allowed-with-range } + { + 'You' \ cannot \ use \ '/' \ ( and \ '_' )\ in \ combination \ + with \ '\l_@@_input_range_sign_tl' \ in \ '#1'. + }{ + You \ cannot \ use \ fractions \ with \ a \ range. + \msg_see_documentation_text:n { cooking-units } + } +% \end{macrocode} +% +% Do not allow a \_ without a /. +% \begin{macrocode} +\msg_new:nnnn { cooking-units } { missing-slash } + { + You \ cannot \ use \ '_' \ without \ + '/' in '#1'. + }{ + You \ cannot \ have \ a \ mixed \ fraction \ ('_') \ without \ + a \ normal \ fraction \ ('/'). + \msg_see_documentation_text:n { cooking-units } + } +% \end{macrocode} +% Error message if unit is not known to this package. +% \begin{macrocode} +\msg_new:nnnn { cooking-units } { unknown - unit } + { + The \ unit \ '#1' \ is \ not \ defined. \ Use \ + \newcookingunit \ to \ define \ new \ units. + }{ + Define \ units \ before \ using \ or \ check \ if \ the \ + unit-key \ is \ written \ correctly. + \msg_see_documentation_text:n { cooking-units } + } +% \end{macrocode} +% Error if unit is already defined. +% \begin{macrocode} +\msg_new:nnnn { cooking - units } { unit-already-defined } + { The\ unit \ '#1' \ is \ already \ defined. } + { + The \ unit-key \ is \ already \ defined. \ Please \ use \ a \ different \ + key \ for \ a \ new \ unit. + \msg_see_documentation_text:n {cooking-units} + } +% \end{macrocode} +% +% Missing argument in \lstinline|\cudefinesymbols| (et all). +% \begin{macrocode} +\msg_new:nnnn { cooking - units } { missing-argument } + { There \ is \ an \ missing \ argument. } + { + You \ probably \ have \ forgotten \ a \ curly-brace \ pair. + \msg_see_documentation_text:n {cooking-units} + } +% \end{macrocode} +% If fractions are evaluated division by zero is not allowed. +% \begin{macrocode} +\msg_new:nnnn { cooking - units } { Division-by-zero } + { Division\ by \ zero \ is \ not \ allowed. } + { See \ a \ math \ book \ of \ your \ choice \ or \ for \ example \ Wikipedia. } +% \end{macrocode} +% Showing the not allowed token in the input. Hope this helps. +% \begin{macrocode} +\msg_new:nnnn { cooking - units } { Token-not-allowed } + { The \ token \ '#1' \ is \ not \ allowed. } + { + The \ command \ accepts \ only \ a \ fixed \ number \ of \ tokens. + \msg_see_documentation_text:n {cooking-units} + } +% \end{macrocode} +% A second decimal sign is not allowed (No na net). +% \begin{macrocode} +\msg_new:nnnn { cooking - units } { Second - decimal -sign - not - allowed } + { A \ second \ decimal \ sign \ is \ not \ allowed. } + { + Perhaps \ you \ didn't \ type \ it \ correctly. + \msg_see_documentation_text:n {cooking-units} + } +% \end{macrocode} +% Error message for an undefined key. +% \begin{macrocode} +\msg_new:nnnn { cooking - units } { Key - not -defined } + { + The \ key \ '#1' \ is \ not \ defined. \ Use \ \cudefinekeys or \ + \cudefinesinglekey to \ define \ keys. + } + { + This \ key \ is \ not \ defined, \ perhaps \ you \ misspelled \ it. + \msg_see_documentation_text:n {cooking-units} + } +% \end{macrocode} +% If the temperature is too low print this error message. +% \begin{macrocode} +\msg_new:nnnn { cooking - units } { Temperature-to-low } + { + The \ temperature \ '#1' \ is \ to \ low.\ It \ cannot \ be \ + below \ the \ absolute \ zero - point \ of \ '#2'. \ Note \ that \ + by \ default \ the \ temperatures \ 'C', \ 'F' , \ 'K' \ and \ 'Re' \ + are \ rounded \ to \ integers. + \\\\ + You \ can \ disable \ the \ option \ 'check-temperature' \ to \ + disable \ this \ error. + } + { See \ for \ example \ Wikipedia. } +% \end{macrocode} +% If for an unit-key the value is wrong the following error message is shown. +% \begin{macrocode} +\msg_new:nnnn { cooking - units } { key-choice-unknown } + { + The \ key \ '#1' \ only \ accepts \ only \ + '#3' \ as \ a \ set \ of \ choices \ and \ '#2' \ is \ non \ of \ these. + } + { + The \ key \ accepts \ accepts\ only \ a \ fixed \ set \ of \ choices. \ + You \ can \ add \ new \ choices \ via \ \cuaddkeys, \ \cuaddsinglekeys \ + and \ \cuaddtokeys. + \msg_see_documentation_text:n {cooking-units} + } +% \end{macrocode} +% +%\changes {v0.98a} {2016/06/11} {New option: 'value-not-known'.} +%\changes {v0.99} {2016/06/12} {Renamed option: 'amount-not-known'.} +% An info message that there are unknown values. +% \begin{macrocode} +\msg_new:nnnn { cooking - units } { amount-not-known } + { + The \ amount \ of \ #1 \ is \ not \ known \ at \ line \ + \msg_line_number: . + } + { + You \ used\ a\ special\ sign\ indicating\ that\ the\ true\ amount\ of\ the\ + specific\ ingredient\ is\ (was) not\ known\ to\ you. This\ message\ + reminds\ you\ about\ that\ fact. + \msg_see_documentation_text:n {cooking-units} + } +% \end{macrocode} +% +% If a load time option not used as a package option, but later, this +% message is shown. +% \begin{macrocode} +\msg_new:nnnn { cooking - units } { load-time-option } + { + The \ option \ '#1' \ is \ only \ avaiable \ as \ a \ load-time-option. \ + Please \ set \ it \ as \ a \ package \ option. + } + { + You \ cannot \ set \ this \ option \ using \ \cusetup \ + but \ only \ as \ a \ package \ option. + \msg_see_documentation_text:n { cooking-units } + } +% \end{macrocode} +% \end{macro} +% +% \section {Helper Macros} +% +% The name says it all. +% +%\begin{macro} +% { +% \@@_error_if_unit_not_defined:n, +% \@@_error_if_unit_not_defined:V, +% } +% A little helper macro. Checks if the unit is defined, if not raise an error. +% \begin{macrocode} +\cs_new:Npn \@@_error_if_unit_not_defined:n #1 + { + \clist_if_in:NnF \g_@@_list_of_defined_units_clist {#1} + { \msg_error:nnn { cooking-units } { unknown-unit } {#1} } + } +\cs_generate_variant:Nn \@@_error_if_unit_not_defined:n { V } +% \end{macrocode} +%\end{macro} +% +% +% +% +% +% +% \begin{macro}{\@@_if_integer_and_parse:n} +% Checking if the input consists only of numbers. Furthermore tests if +% the input should be parsed at all. +% +% \begin{macrocode} +%\cs_new:Npn \@@_if_number_and_parse_aux: { } +\prg_new_protected_conditional:Npnn \@@_if_integer_and_parse:n #1 { TF } + { + \bool_if:NTF \l_@@_parse_input_bool + { +% \cs_set_eq:NN \@@_if_number_and_parse_aux: \prg_return_true: + \tl_map_inline:nn {#1} + { + \tl_if_in:NnF \l_@@_input_digits_tl {##1} + { +% \cs_set_eq:NN \@@_if_number_and_parse_aux: \prg_return_false: + \tl_map_break:n { \use_iii:nnn } + } + } + \use_i:nn \prg_return_true: \prg_return_false: +% \@@_if_number_and_parse_aux: + } + { \prg_return_false: } + } +\cs_generate_variant:Nn \@@_if_integer_and_parse:nTF { V } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_convert_to_eV:} +% Still work in progress. Will probably forever be. Changes all +% predefined units into natural units (except for those who cannot +% be changed, like Msp. for example). Is the same construct I use +% later in \mycs{cunum}. +% \begin{macrocode} +\cs_new:Npn \@@_convert_to_eV: + { + \keys_set:nn { cooking-units } + { + m= chbareV-1, + cm= chbareV-1, + dm= chbareV-1, + mm= chbareV-1, + in= chbareV-1, + kg= eVc-2, + dag= eVc-2, + g= eVc-2, + oz= eVc-2, + lb= eVc-2, + d= hbareV-1, + h= hbareV-1, + min= hbareV-1, + s= hbareV-1, + cal= eV, + kcal= eV, + J= eV, + kJ= eV, + F= eV, + K= eV, + C= eV, + Re= eV, + l= (chbareV-1)3 , + dl= (chbareV-1)3 , + cl= (chbareV-1)3 , + ml= (chbareV-1)3 , + } + \prop_get:NVN \l_@@_change_unit_prop \l_@@_tmp_unit_tl \l_@@_option_unit_tl + \quark_if_no_value:NT \l_@@_option_unit_tl + { + \tl_set_eq:NN \l_@@_option_unit_tl \l_@@_tmp_unit_tl + } + \keys_set_filter:nnv + { cooking-units } + { change-unit } + { l_@@_predefined_option_ \l_@@_option_unit_tl _clist } + } +% \end{macrocode} +%\end{macro} +% +% \subsection {Parsing and cheking numbers} +% +% This section contains macros helping an checking the input. +% +% \begin{macro}{ \@@_cunum_parse_input:N, \@@_cunum_parse_input:V } +% Splits the input into fractions or ranges (\lstinline|q_@@_range|). +% Depending on the input on of the four macros are used. +% \begin{macrocode} +\cs_new:Npn \@@_cunum_parse_input:N #1 + { + \tl_if_in:nnTF {#1} { \q_@@_range } + { \@@_parse_range_in_input:ww #1 \q_stop } + { + \tl_if_in:nnTF {#1} { / } + { + \tl_if_in:nnTF {#1} { _ } + { \@@_parse_fraction_in_input:www #1 \q_stop } + { \@@_parse_fraction_in_input:ww #1 \q_stop } + } + { \@@_parse_number_in_input:n {#1} } + } + } +\cs_generate_variant:Nn \@@_cunum_parse_input:N { V } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_parse_number_in_input:n} +% If no fractions and ranges are used this macro activated. +% It just checks the input, stores the checked (and a bit +% changed) input into a macro. This macro is given to another +% function to calculate the input and print it. +% \begin{macrocode} +\cs_new:Npn \@@_parse_number_in_input:n #1 + { + \@@_parse_input_and_safe_in:nN {#1} \l_@@_tmpa_tl + \@@_calculate_and_print_input:N \l_@@_tmpa_tl + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{ \@@_parse_range_in_input:ww } +% Is used if a \lstinline|\q_@@_range| is found inside the input. +% Seperates the input, checks it and prints it (after calculating +% it). Furthermore a boolean is set to true, is used to check for +% errors (ergo if fractions are used). +% \begin{macrocode} +\cs_new:Npn \@@_parse_range_in_input:ww #1 \q_@@_range #2 \q_stop + { + \bool_set_true:N \l_@@_parse_range_bool + \@@_parse_input_and_safe_in:nN {#1} \l_@@_tmpa_tl + \@@_parse_input_and_safe_in:nN {#2} \l_@@_tmpb_tl + \@@_calculate_and_print_input:N \l_@@_tmpa_tl + \tl_use:N \l_@@_cunum_range_sign_tl + \@@_calculate_and_print_input:N \l_@@_tmpb_tl + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{ \@@_parse_fraction_in_input:ww } +% If a \lstinline|/| (but no \lstinline|_|) is found inside the input. +% Well \dots\ does the same as the functions before. +% If fractions should be evaluated the input is \dots\ well, +% evaluated and printed. Otherwise the input is given to +% another function which prints the fractions. Note that the empty +% argument in \lstinline|\@@_formatiere_fractions:nnn| indicates a +% \enquote{normal} fraction. +% \begin{macrocode} +\cs_new:Npn \@@_parse_fraction_in_input:ww #1/#2 \q_stop + { + \@@_parse_input_and_safe_in:nN {#1} \l_@@_tmpa_tl + \@@_parse_input_and_safe_in:nN {#2} \l_@@_tmpb_tl + \bool_if:NTF \l_@@_eval_fractions_bool + { + \@@_calculate_and_print_input:n + { \l_@@_tmpa_tl / \l_@@_tmpb_tl } + }{ + \@@_formatiere_fractions:nnn + { } + { \l_@@_tmpa_tl } + { \l_@@_tmpb_tl } + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{ \@@_parse_fraction_in_input:www } +% The same procedure as last function? The same procedure as every +% function! +% +% If it should be evaluated it is important to check if the mixed-fraction +% part is positive or negative. +% +% \begin{align} +% \cufrac{1_2/3} &= 1 + 2/3 \\ +% \cufrac{-1_2/3} &= -1 - 2/3 +% \end{align} +% +% \begin{macrocode} +\cs_new:Npn \@@_parse_fraction_in_input:www #1_#2/#3 \q_stop + { + \@@_parse_input_and_safe_in:nN {#1} \l_@@_mixed_fraction_tl + \@@_parse_input_and_safe_in:nN {#2} \l_@@_tmpa_tl + \@@_parse_input_and_safe_in:nN {#3} \l_@@_tmpb_tl + \bool_if:NTF \l_@@_eval_fractions_bool + { + \@@_calculate_and_print_input:n + { + \l_@@_mixed_fraction_tl + \fp_compare:nNnTF + { \l_@@_mixed_fraction_tl } < { \c_zero_fp } + { - } + { + } + \l_@@_tmpa_tl / \l_@@_tmpb_tl + } + }{ + \@@_formatiere_fractions:nnn + { \l_@@_mixed_fraction_tl } + { \l_@@_tmpa_tl } + { \l_@@_tmpb_tl } + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{ \@@_parse_input_and_safe_in:nN } +% Used to check the input. \lstinline|\l_tmpa_tl| is cleared +% at the beginning. At first it checks if the first token +% is a sign or not. The parsed input is stored into \lstinline|\l_tmpa_tl|. +% \begin{macrocode} +\cs_new:Npn \@@_parse_input_and_safe_in:nN #1 #2 + { + \tl_clear:N \l_tmpa_tl + \bool_set_false:N \l_@@_decimal_in_input_bool + \@@_parse_vorzeichen_and_rest:Nw #1 \q_stop + \bool_if:NTF \l_@@_error_bool + { \tl_set:Nn #2 {#1} } + { \tl_set_eq:NN #2 \l_tmpa_tl } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{ \@@_parse_vorzeichen_and_rest:Nw } +% This function seperates the input into two parts with the first +% part being the first token. This token is checked whetever or not +% it is a sign. If it is a sign it is put into +% \lstinline|\l_tmpa_tl|, if not it is checked normally by +% \lstinline|\@@_parse_input_for_safety_aux:N|. \#2 (the other +% tokens) is then given to \lstinline|\tl_map_function:nN|. This +% also works if the input only conists of one token with \#2 being +% empty (hopefully). +% \begin{macrocode} +\cs_new:Npn \@@_parse_vorzeichen_and_rest:Nw #1#2 \q_stop + { + \tl_if_in:NnTF \l_@@_value_signs_tl {#1} + { \tl_put_right:Nn \l_tmpa_tl {#1} } + { + \tl_map_function:nN {#1} \@@_parse_input_for_safety_aux:N + } + \bool_if:NF \l_@@_error_bool + { \tl_map_function:nN {#2} \@@_parse_input_for_safety_aux:N } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{ \@@_parse_input_for_safety_aux:N } +% Parses the input. It also is more or less copied from +% \texttt{siunitx}. Checks if the input consists only of numbers, +% one decimal-sign and the allowed special input. If an allowed +% token is found the boolean \lstinline|\l_@@_special_sign_bool| is +% set to true. +% \begin{macrocode} +\cs_new:Npn \@@_parse_input_for_safety_aux:N #1 + { + \tl_if_in:NnTF \l_@@_input_digits_tl {#1} + { \tl_put_right:Nn \l_tmpa_tl {#1} } + { + \tl_if_in:NnTF \l_@@_decimal_mark_tl {#1} + { + \bool_if:NT \l_@@_decimal_in_input_bool + { + \msg_error:nn { cooking-units } + { Second - decimal -sign - not - allowed } + } + \bool_set_true:N \l_@@_decimal_in_input_bool + \tl_put_right:Nn \l_tmpa_tl { . } + }{ + \tl_if_in:NnTF \l_@@_allowed_special_signs_tl {#1} + { + \bool_set_true:N \l_@@_special_sign_bool + \tl_put_right:Nn \l_tmpa_tl {#1} + }{ + \bool_if:NTF \l_@@_parse_range_bool + { + \tl_if_in:nnTF { / _ } {#1} + { \msg_error:nnn { cooking-units } { fraction-not-allowed-with-range } {#1} } + { \msg_error:nnn { cooking-units } { Token-not-allowed } {#1} } + } + { + \tl_if_in:nnTF { _ } {#1} + { \msg_error:nnn { cooking-units } { missing-slash } {#1} } + { \msg_error:nnn { cooking-units } { Token-not-allowed } {#1} } + } + \bool_set_true:N \l_@@_error_bool + \tl_map_break: + } + } + } + } +% \end{macrocode} +% \end{macro} +% +% \subsection {Formatiere \& Calculiere} +% +% \begin{macro}{ \@@_calculate_and_print_input:n , \@@_calculate_and_print_input:n } +% +% \changes {v0.98a} {2016/06/11} {Added warning to show if an unknown value is used.} +% +% After parsing the input, it is given to this function. If a not +% allowed token is found (and \lstinline|\l_@@_error_bool| is set to +% true) it just prints the input. Otherwise it checks if a allowed sign was +% found. If so it is just stored inside \lstinline|\l_tmpa_tl|, +% otherwise it is calulcated and stored in \lstinline|\l_tmpa_tl|. The input +% \#1 can be either a token or a number. +% \begin{macrocode} +\cs_new:Npn \@@_calculate_and_print_input:n #1 + { + \bool_if:NTF \l_@@_error_bool + {#1} + { + \bool_if:NTF \l_@@_special_sign_bool + { + \tl_set:Nf \l_tmpa_tl {#1} + \msg_warning:nnx { cooking-units } { amount-not-known } \l_tmpa_tl + } + { + \@@_calculate_input_and_store_in:nN {#1} \l_tmpa_tl + \@@_check_temperature_limit:N \l_tmpa_tl + } + \@@_print_nummerical_output:N \l_tmpa_tl + } + } +\cs_generate_variant:Nn \@@_calculate_and_print_input:n { N } +% \end{macrocode} +% \end{macro} +% +% \begin{macro} +% { +% \@@_calculate_input_and_store_in:nN , +% \@@_calculate_input_and_store_in:VN +% } +% Well \dots\ this function calculates the input. First checks if the +% wanted conversion contains a \lstinline|\l_tmpa_fp| (ergo a \#1 in +% the key definition). If true the conversion token (which already has +% \lstinline|\l_tmpa_fp| in its input) is executed, else the input +% number is multiplicated with the conversion token. +% \begin{macrocode} +\cs_new:Npn \@@_calculate_input_and_store_in:nN #1#2 + { + \fp_set:Nn \l_tmpa_fp {#1} + \tl_if_in:cnTF { l_@@_tmpa_ \l_@@_tmp_unit_tl _ tl } { \l_tmpa_fp } + { + \tl_set:Nf #2 + { + \fp_eval:c { l_@@_tmpa_ \l_@@_tmp_unit_tl _ tl } + } + }{ + \tl_set:Nf #2 + { + \fp_eval:n + { + \l_tmpa_fp * + \tl_use:c { l_@@_tmpa_ \l_@@_tmp_unit_tl _ tl } + } + } + } + \@@_round_calculated_input:NV #2 #2 + } +\cs_generate_variant:Nn \@@_calculate_input_and_store_in:nN { V } +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\@@_get_number_after_dot:n,\@@_get_number_after_dot_aux:w} +% Getting the number after the decimal point. If it doesn't exist +% the boolean is set to false, otherwise it checks how many tokens +% are within the number after the decimal point. If the number of +% tokens is greater than significant\_figures\_plus\_one the bool is +% set to true (which tells the package later that the number should +% be rounded). +% \begin{macrocode} +\cs_new:Npn \@@_get_number_after_dot:n #1 + { + \@@_get_number_after_dot_aux:w #1 . \q_recursion_tail . + \q_recursion_stop + } +\cs_new:Npn \@@_get_number_after_dot_aux:w #1. #2 . + { + \quark_if_recursion_tail_stop_do:nn {#2} + { \bool_set_false:N \l_tmpa_bool } + \int_compare:nNnTF { \tl_count:n {#2} } < {\l_@@_significant_figures_plus_one_int } + { \bool_set_false:N \l_tmpa_bool } + { \bool_set_true:N \l_tmpa_bool } + \use_none_delimit_by_q_recursion_stop:w + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{ \@@_round_calculated_input:NN,\@@_round_calculated_input:NV } +% After calculating the numbers are rounded (if needed). We test at first if +% the input needs to be rounded by comparing the number of tokens after the +% decimal with the number of significant figures plus one. Afterwards the +% input is expanded and stored in \#1. If rounding needs to be done it happens now. +% \begin{macrocode} +\cs_new:Npn \@@_round_calculated_input:NN #1#2 + { + \@@_get_number_after_dot:n {#2} + \tl_set:Nf #1 + { + \bool_if:nTF { \l_tmpa_bool || \l_@@_round_to_int_bool } + { + \fp_eval:n + { + \bool_if:NTF \l_@@_round_to_int_bool + { round (#2) } + { + round( #2 , \l_@@_significant_figures_int ) + } + } + } + {#2} + } + } +\cs_generate_variant:Nn \@@_round_calculated_input:NN { NV } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{ \@@_formatiere_fractions:nnn } +% The name of this function is the name of the game: It prints fractions. +% Furthermore it sets the boolean \lstinline|fraction_in_input_bool| to true +% so that the correct unit is printed. Instead of \lstinline|\kern| I used the +% \lstinline|\hbox_to_wd:nn| command (I don't have a better idea). +% \begin{macrocode} +\cs_new:Npn \@@_formatiere_fractions:nnn #1#2#3 + { + \bool_set_true:N \l_@@_fraction_in_input_bool + \tl_if_blank:nF {#1} + { + #1 + \hbox_to_wd:nn { \l_@@_mixed_frac_dim } { } + } + \@@_frac:nn {#2} {#3} + } +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\@@_check_temperature_limit:n} +% If \lstinline|check_temperature_bool| is set to true it now checks +% if the value is below the absolute temperature. \lstinline|\clist_if_in:nVT| +% is needed due to \texttt{Re}, a \lstinline|\tl_if_in:nVT| would also check for \texttt{R} +% and \texttt{e} instead of only \texttt{Re}. +% \begin{macrocode} +\cs_new:Npn \@@_check_temperature_limit:N #1 + { + \bool_if:NT \l_@@_check_temperature_bool + { + \clist_if_in:nVT { C , F , K , Re } \l_@@_option_unit_tl + { + \fp_compare:cNnT + { c_@@_ \l_@@_option_unit_tl _min_fp } > {#1} + { + \msg_error:nnxx { cooking-units } + { Temperature-to-low } + { #1 \space \l_@@_option_unit_tl } + { + \fp_use:c { c_@@_ \l_@@_option_unit_tl _min_fp } + \space \l_@@_option_unit_tl + } + } + } + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{ \@@_print_nummerical_output:N } +% Prints the nummerical ouput (if it is not a fraction). +% +% \lstinline|\l_@@_tmpa_tl| can be very dangerous because values are also stored +% within \lstinline|\l_@@_tmpa_tl|, but as long as the value stored inside +% this function is processed first all is fine. +% \begin{macrocode} +\cs_new_protected:Npn \@@_print_nummerical_output:N #1 + { +%% \l_@@_tmpa_tl is sehr gefaehrlich hier. + \translatelet \l_@@_tmpa_tl { decimal-mark ( cu-unit name ) } + \tl_replace_once:NnV #1 { . } \l_@@_tmpa_tl + \tl_replace_once:NnV #1 { - } \c_@@_minus_tl + #1 + } +% \end{macrocode} +% \end{macro} +% +% +% +% \subsection {\mycs{cunum}} +% +% +% \begin{macro}{ \cunum } +% The main command of this package. +% \begin{macrocode} +\NewDocumentCommand \cunum { O{} m O{} m } + { + \group_begin: + \@@_cunum_initialise:nnnn {#1} {#2} {#3} {#4} + \bool_if:NTF \l_@@_parse_input_bool + { \@@_cunum:nnVV {#2} {#3} \l_@@_option_unit_tl \l_@@_tmp_unit_tl } + { \@@_cunum_do_not_parse:nnn {#2} {#3} {#4} } + \group_end: + } +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{ \@@_cunum_initialise:nnnn } +% Lots of things to do in this function. It checks if the unit is defined or not, +% sets the keys for converting the unit and sets the optional unit (the unit +% our input is converted to) accordingly, sets the options again (to get the +% option-specific options) and \dots\ yeah. +% +% First parses the change of unit ('set groups'), afterwards set +% the predefined options for the new unit. Afterwards +% set the 'normal' options given by the optional argument. +% +% \begin{macrocode} +\cs_new_protected:Npn \@@_cunum_initialise:nnnn #1#2#3#4 + { + \tl_set:Nn \l_@@_tmp_unit_tl {#4} + \@@_error_if_unit_not_defined:V \l_@@_tmp_unit_tl + \bool_if:NTF \l_@@_convert_to_eV_bool + { \@@_convert_to_eV: } + { + \keys_set_groups:nnn { cooking-units } { change-unit } {#1} + \prop_get:NVN \l_@@_change_unit_prop \l_@@_tmp_unit_tl \l_@@_option_unit_tl + \quark_if_no_value:NT \l_@@_option_unit_tl + { + \tl_set_eq:NN \l_@@_option_unit_tl \l_@@_tmp_unit_tl + } + \keys_set_filter:nnv + { cooking-units } + { change-unit } + { l_@@_predefined_option_ \l_@@_option_unit_tl _clist } + \keys_set_filter:nnn { cooking-units } { change-unit } {#1} + } + \bool_set_false:N \l_@@_special_sign_bool + \bool_set_false:N \l_@@_error_bool + \bool_set_false:N \l_@@_parse_range_bool + } +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{ \@@_cunum_do_not_parse:nnn } +% If the input shoudn't be parsed this function is used to print the +% input without error messages (mostly concerning the \_). Spaces are still ignored. +% \begin{macrocode} +\cs_new:Npn \@@_cunum_do_not_parse:nnn #1#2#3 + { + \tl_set_rescan:Nnn \l_tmpa_tl + { + \char_set_catcode_letter:N \_ % + \char_set_catcode_ignore:N \ % + } {#1} + \l_tmpa_tl + \@@_cunum_print_correct_unit:nnn {#2} {#3} {#3} + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{ \@@_cunum:nnNN, \@@_cunum:nnVV } +% Rescans the input to get rid of spaces and to make \_ and ? inactive +% (french with babel makes ? active and changes the definition of it). +% \lstinline|--| is replaced by \lstinline|\q_@@_range| and the input is parsed +% (if not empty). Afterwards the units are printed. +% \begin{macrocode} +\cs_new:Npn \@@_cunum:nnNN #1#2#3#4 + { + \tl_set_rescan:Nnn \l_tmpa_tl + { + \char_set_catcode_letter:N \_ % + \char_set_catcode_ignore:N \ % + \char_set_catcode_other:N ? % + } {#1} + \tl_if_empty:VF \l_tmpa_tl + { + \tl_if_in:NVT \l_tmpa_tl \l_@@_input_range_sign_tl + { \tl_replace_once:NVn \l_tmpa_tl \l_@@_input_range_sign_tl { \q_@@_range } } + \@@_cunum_parse_input:V \l_tmpa_tl + } + \@@_cunum_print_correct_unit:nnn {#2} {#3} {#4} + } +\cs_generate_variant:Nn \@@_cunum:nnNN { nnVV } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{ \@@_cunum_print_correct_unit:nnn } +% The invisible space is added by a \lstinline|\phantom|, afterwards +% \lstinline|value_unit_space_tl| is used (which is set to +% \lstinline|\thinspace| by default) and if either special signs or +% fractions are parsed the input-unit is printed else the converted +% unit is. +% \begin{macrocode} +\cs_new:Npn \@@_cunum_print_correct_unit:nnn #1#2#3 + { + \phantom {#1} + \tl_use:N \l_@@_value_unit_space_tl + \bool_if:nTF + { + \l_@@_fraction_in_input_bool || + \l_@@_special_sign_bool + } + { \translate { #3 ( cu-unit ) } } + { \translate { #2 ( cu-unit ) } } + } +% \end{macrocode} +% \end{macro} +% +% +% +% +% +% \section {cukeys} +% +% \subsection {Define Keys} +% +% \begin{macro}{ \cudefinekeys } +% Defining keys. +% \begin{macrocode} +\NewDocumentCommand \cudefinekeys { m m } + { + \bool_set_false:N \l_@@_single_key_bool + \cukeys_define_keys_and_single_keys:nn {#1} {#2} + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{ \cudefinesinglekey } +% Again, but with the boolean set to true. +% \begin{macrocode} +\NewDocumentCommand \cudefinesinglekey { m m } + { + \bool_set_true:N \l_@@_single_key_bool + \cukeys_define_keys_and_single_keys:nn {#1} {#2} + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{ \cukeys_define_keys_and_single_keys:nn } +% First checks whetever the unit is defined or not, then clears some macros +% which are needed later. Further procession depends on the boolean. +% If more than one key is created, the value \lstinline|\l_tmpa_fp| is set to one. +% This is important for adding keys where \lstinline|\l_tmpa_fp| is changed accordingly. +% \begin{macrocode} +\cs_new:Npn \cukeys_define_keys_and_single_keys:nn #1#2 + { + \@@_error_if_unit_not_defined:n {#1} + \tl_if_blank:nF {#2} + { + \clist_clear:N \l_tmpa_clist + \prop_clear:N \l_tmpa_prop + \bool_if:NTF \l_@@_single_key_bool + { + \@@_cukeys_parse_and_create_single_key:nn {#1} {#2} + }{ +% \fp_set:Nn \l_tmpa_fp { \c_one_fp } + \fp_set_eq:NN \l_tmpa_fp \c_one_fp + \tl_set:Nn \l_@@_tmp_unit_tl {#1} + \@@_cukeys_parse_and_create_keys:nn {#1} + { + {#1} { \c_one_fp } #2 + } + } + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{ \@@_cukeys_parse_and_create_keys:nn } +% A simple parsing function using quarks (which are pretty handy). +% At first parses the input, then creates the property lists for each key +% (containing all the values) and at last defines the keys. +% \begin{macrocode} +\cs_new:Npn \@@_cukeys_parse_and_create_keys:nn #1#2 + { + \@@_cukeys_parse_input:nn #2 + \q_recursion_tail \q_recursion_tail \q_recursion_stop + \@@_cukeys_create_key_prop:n {#1} + \@@_cukeys_define_keys:V \l_tmpa_clist + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{ \@@_cukeys_parse_input:nn } +% Yeah \dots\ \lstinline|\l_tmpa_clist| stores all the used unit-keys, while +% the property list saves the relation to each other. This cycle is repeated until an +% recursion tail is found. If you define a new key, \verb|\l_tmpa_fp| is set to +% 1 and changed later if a new key is added. +% \begin{macrocode} +\cs_new:Npn \@@_cukeys_parse_input:nn #1#2 + { + \quark_if_recursion_tail_stop:n {#1} + \quark_if_recursion_tail_stop_do:nn {#2} + { \msg_error:nn { cooking-units } { missing-argument } } + \@@_error_if_unit_not_defined:n {#1} + \clist_put_right:Nn \l_tmpa_clist {#1} + \prop_put:Nnx \l_tmpa_prop {#1} { \fp_eval:n { #2 / \l_tmpa_fp } } + \@@_cukeys_parse_input:nn + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{ \@@_cukeys_create_key_prop:n } +% All linked unit-keys are stored within \lstinline|\l_tmpa_clist| and are mapped +% one after another. At first a property list is created (or cleared), this property list +% stores the units linked to this unit, saves the created property list which contains the +% numerical relation of each unit. \lstinline|Erstes Ding| (firsth thing) stores +% the first unit used for defining the keys, it is needed later for adding keys. +% +% For each unit the other units are added in the cleared or newly created property list +% as keys with their value being the correct numerical relation. For example: +% +% \begin{align*} +% \SI{1}{\kg}&= \SI{1}{\kg} \\ +% \SI{1}{\kg}&= \SI{100}{\deka\gram} \\ +% \SI{1}{\kg}&= \SI{1000}{\g} \\ +% \SI{1}{\kg}&= \SI{35.27399}{oz} \\ +% \end{align*} +% +% Therefore the property list for \lstinline|kg| contains the keys and values: +% \texttt{kg}=\texttt{1} +% \texttt{dag}=\texttt{100}, \texttt{g}=\texttt{1000} and \texttt{oz}= \texttt{35.27399}. +% +% For the next unit (\texttt{dag} in this case) a new property list is created, relation above +% stored inside etc. The condition now is that \texttt{dag}=\texttt{1}, therefore every number +% is divided the the number \texttt{100}: +% +% \begin{align*} +% \SI{1}{\deka\gram}&= \SI{0.01}{\kg} \\ +% \SI{1}{\deka\gram}&= \SI{1}{\deka\gram} \\ +% \SI{1}{\deka\gram}&= \SI{10}{\g} \\ +% \SI{1}{\deka\gram}&= \SI{0.3527399}{\oz} \\ +% \end{align*} +% +% Same for \texttt{g}: +% +% \begin{align*} +% \SI{1}{\g}&= \SI{0.001}{\kg} \\ +% \SI{1}{\g}&= \SI{0.1}{\deka\gram} \\ +% \SI{1}{\g}&= \SI{1}{\g} \\ +% \SI{1}{\g}&= \SI{0.03527399}{oz} \\ +% \end{align*} +% +% and \texttt{oz} +% +% \begin{align*} +% \SI{1}{oz}&= \SI{0.0283495}{\kg} \\ +% \SI{1}{oz}&= \SI{2.83495}{\deka\gram} \\ +% \SI{1}{oz}&= \SI{28.3495}{\g} \\ +% \SI{1}{oz}&= \SI{1}{oz} \\ +% \end{align*} +% +% \begin{macrocode} +\cs_new:Npn \@@_cukeys_create_key_prop:n #1 + { + \clist_map_inline:Nn \l_tmpa_clist + { + \prop_clear_new:c { l_@@_cukeys_ ##1 _prop } + \tl_clear_new:c { l_@@_tmpa_ ##1 _tl } +% \tl_set:cn { l_@@_tmpa_ ##1 _tl } { 1 } +% \tl_set:cn { l_@@_tmpa_ ##1 _tl } { \c_one_fp } + \tl_set_eq:cN { l_@@_tmpa_ ##1 _tl } \c_one_fp + \prop_put:cnV { l_@@_cukeys_ ##1 _prop } { Liste } \l_tmpa_clist + \prop_put:cnV { l_@@_cukeys_ ##1 _prop } { prop } \l_tmpa_prop + \prop_put:cnV { l_@@_cukeys_ ##1 _prop } { Erstes Ding } \l_@@_tmp_unit_tl + \clist_map_inline:Nn \l_tmpa_clist + { + \prop_put:cnx { l_@@_cukeys_ ##1 _prop } + {####1} + { + \fp_eval:n + { \prop_item:Nn \l_tmpa_prop {####1} / \prop_item:Nn \l_tmpa_prop {##1} } + } + } + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{ \@@_cukeys_define_keys:N , \@@_cukeys_define_keys:V } +% Defining the keys: It maps through the list of unit-keys and creates a +% unit key respectively. +% \begin{macrocode} +\cs_new:Npn \@@_cukeys_define_keys:N #1 + { + \clist_map_inline:Nn \l_tmpa_clist + { + \clist_put_right:Nn \l_@@_list_of_defined_keys_clist {##1} + \keys_define:nn { cooking-units } + { + ##1 .choices:Vn = + \l_tmpa_clist + { + \@@_cukeys_define_keys_and_single_key_aux:n {##1} + } , + ##1 / unknown .code:n= + { + \seq_set_split:Nnn \l_tmpa_seq { , } {#1} + \msg_error:nnxxx + { cooking-units } + { key-choice-unknown } + {##1} + {####1} + { \seq_use:Nnnn \l_tmpa_seq { ',' } { ',' } { ' ~ and ~ ' } } + } , + ##1 .default:n = {##1} , + ##1 .groups:n = { change-unit } + } + } + \clist_remove_duplicates:N \l_@@_list_of_defined_keys_clist + } +\cs_generate_variant:Nn \@@_cukeys_define_keys:N { V } +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +\cs_new:Npn \@@_cukeys_define_keys_and_single_key_aux:n #1 + { + \prop_get:cVN + { l_@@_cukeys_#1_prop } + \l_keys_choice_tl + \l_tmpa_tl + \tl_set:cV { l_@@_tmpa_ #1_tl } \l_tmpa_tl + \prop_put:NnV \l_@@_change_unit_prop {#1} \l_keys_choice_tl + } +% \end{macrocode} +% +% +% \begin{macrocode} +\cs_new:Npn \@@_cukeys_parse_and_create_single_key:nn #1#2 + { + \tl_set_rescan:Nnn \l_tmpa_tl + { + \char_set_catcode_letter:N \# % + \char_set_catcode_ignore:N\ % + } { {#1} { \c_one_fp } #2 } + \@@_cusinglekeys_parse_input:V \l_tmpa_tl + \@@_cusinglekeys_create_key_prop:n {#1} + \@@_cukeys_define_singlekey:nV {#1} \l_tmpa_clist + } +% \end{macrocode} +% +% \begin{macrocode} +\cs_new:Npn \@@_cusinglekeys_parse_input:n #1 + { + \@@_cusinglekeys_parse_input_aux:nn #1 + \q_recursion_tail \q_recursion_tail \q_recursion_stop + } +\cs_generate_variant:Nn \@@_cusinglekeys_parse_input:n { V } +% +\cs_new:Npn \@@_cusinglekeys_parse_input_aux:nn #1#2 + { + \quark_if_recursion_tail_stop:n {#1} + \quark_if_recursion_tail_stop_do:nn {#2} + { \msg_error:nn { cooking-units } { missing-argument } } + \clist_put_right:Nn \l_tmpa_clist {#1} + \tl_set:Nn \l_tmpa_tl {#2} + \tl_replace_all:NVn \l_tmpa_tl \c_@@_str_hash_one_tl { \l_tmpa_fp } + \prop_put:NnV \l_tmpa_prop {#1} \l_tmpa_tl + \@@_cusinglekeys_parse_input_aux:nn + } +% \end{macrocode} +% +% \begin{macrocode} +\cs_new:Npn \@@_cusinglekeys_create_key_prop:n #1 + { + \prop_clear_new:c { l_@@_cukeys_ #1 _prop } + \tl_set_eq:cN { l_@@_tmpa_ #1 _tl } \c_one_fp +% \tl_set:cn { l_@@_tmpa_ #1 _tl } { \c_one_fp } + \prop_put:cnV { l_@@_cukeys_ #1 _prop } { Liste } \l_tmpa_clist + \prop_put:cnV { l_@@_cukeys_ #1 _prop } { prop } \l_tmpa_prop + \prop_put:cnn { l_@@_cukeys_ #1 _prop } { Erstes Ding } {#1} + \prop_map_inline:Nn \l_tmpa_prop + { + \prop_put:cnn { l_@@_cukeys_ #1 _prop } + {##1} + {##2} + } + } +% \end{macrocode} +% +% \begin{macrocode} +\cs_new:Npn \@@_cukeys_define_singlekey:nN #1#2 + { + \clist_put_right:Nn \l_@@_list_of_defined_keys_clist {#1} + \keys_define:nn { cooking-units } + { + #1 .choices:Vn = + \l_tmpa_clist + { + \@@_cukeys_define_keys_and_single_key_aux:n {#1} + } , + #1 / unknown .code:n= + { + \seq_set_split:Nnn \l_tmpa_seq { , } {#2} + \msg_error:nnxxx + { cooking-units } + { key-choice-unknown } + {#1} + {##1} + { \seq_use:Nnnn \l_tmpa_seq { ',' } { ',' } { ' ~ and ~ ' } } + } , + #1 .default:n = {#1} , + #1 .groups:n = { change-unit } , + } + \clist_remove_duplicates:N \l_@@_list_of_defined_keys_clist + } +\cs_generate_variant:Nn \@@_cukeys_define_singlekey:nN { nV } +% \end{macrocode} +% +% +% \section {Adding Keys} +% +% +% \begin{macrocode} +\NewDocumentCommand \cuaddkeys { m m } + { + \bool_set_false:N \l_@@_single_key_bool + \tl_set:Nn \l_tmpa_tl {#1} + \tl_set:Nn \l_tmpb_tl {#2} + \@@_cukeys_add_keys_or_single_keys:VV \l_tmpa_tl \l_tmpb_tl + } +% \end{macrocode} +% +% \begin{macrocode} +\NewDocumentCommand \cuaddsinglekeys { m m } + { + \bool_set_true:N \l_@@_single_key_bool + \tl_set:Nn \l_tmpa_tl {#1} + \tl_set:Nn \l_tmpb_tl {#2} + \@@_cukeys_add_keys_or_single_keys:VV \l_tmpa_tl \l_tmpb_tl + } +% \end{macrocode} +% +% \begin{macrocode} +\NewDocumentCommand \cuaddtokeys { m m m } + { + \bool_set_false:N \l_@@_single_key_bool + \tl_set:Nn \l_tmpa_tl {#1} + \tl_set:Nn \l_tmpb_tl { {#2} { \fp_eval:n { \c_one_fp / #3 } } } + \@@_cukeys_add_keys_or_single_keys:VV \l_tmpa_tl \l_tmpb_tl + } +% \end{macrocode} +% +% +% +% \begin{macrocode} +\cs_new:Npn \@@_cukeys_add_keys_or_single_keys:nn #1#2 + { + \@@_error_if_unit_not_defined:n {#1} + \clist_if_in:NnF \l_@@_list_of_defined_keys_clist {#1} + { \msg_error:nnn { cooking-units } { Key - not - defined } {#1} } + \tl_if_blank:nF {#2} + { + \@@_cukeys_add_keys_and_single_key_aux:n {#1} + \bool_if:NTF \l_@@_single_key_bool + { \@@_cukeys_parse_and_create_single_key:nn {#1} {#2} } + { \@@_cukeys_parse_and_create_keys:nn {#1} {#2} } + } + } +\cs_generate_variant:Nn \@@_cukeys_add_keys_or_single_keys:nn { VV } +% \end{macrocode} +% +% +% \begin{macrocode} +\cs_new:Npn \@@_cukeys_add_keys_and_single_key_aux:n #1 + { + \prop_get:cnN { l_@@_cukeys_ #1 _prop } { Liste } \l_tmpa_clist + \prop_get:cnN { l_@@_cukeys_ #1 _prop } { prop } \l_tmpa_prop + \prop_get:cnN { l_@@_cukeys_ #1 _prop } { Erstes Ding } \l_@@_tmp_unit_tl + \prop_get:cVN { l_@@_cukeys_ #1 _prop } \l_@@_tmp_unit_tl \l_tmpa_fp + } +% \end{macrocode} +% +% +% \section {Creating New Units} +% +% +%\begin{macro}{ \newcookingunit } +% \begin{macrocode} +\NewDocumentCommand \newcookingunit { o m } + { + \@@_new_cooking_unit:nn {#1} {#2} + } +% \end{macrocode} +%\end{macro} +% +% \begin{macrocode} +\cs_new:Npn \@@_new_cooking_unit:nn #1#2 + { + \clist_if_in:NnTF \g_@@_list_of_defined_units_clist {#2} + { \msg_error:nnn { cooking-units } { unit-already-defined } {#2} } + { + \tl_new:c { l_@@_tmpa_ #2 _tl } +% \tl_set:cn { l_@@_tmpa_ #2 _tl } { \c_one_fp } + \tl_set_eq:cN { l_@@_tmpa_ #2 _tl } \c_one_fp + \clist_put_right:Nn \g_@@_list_of_defined_units_clist {#2} + \clist_new:c { l_@@_predefined_option_#2_clist } + \keys_define:nn { cooking - units } + { + set-option-for-#2 .clist_set:c = { l_@@_predefined_option_#2_clist } , + add-option-for-#2 .code:n = + { \clist_put_right:cn { l_@@_predefined_option_#2_clist } {##1} }, + } + \prop_new:c { l_@@_cukeys_ #2 _prop } + \IfNoValueTF {#1} + { + \newtranslation { #2 ( cu-unit ) } {#2} + }{ + \newtranslation { #2 ( cu-unit ) } {#1} + } + } + } +% \end{macrocode} +% +% +% +% \section { cutext \& Cutext } +% +% \end{macro} +% +% \begin{macrocode} +\NewDocumentCommand \cutext { O{} m m } + { + \group_begin: + \@@_cutext_default:nnn {#1} {#2} {#3} + \@@_cutext_print_correct_unitname:nn {#2} {#3} + \group_end: + } +% \end{macrocode} +% +% \begin{macrocode} +\NewDocumentCommand \Cutext { O{} m m } + { + \group_begin: + \bool_set_true:N \l_@@_cutext_uppercase_word_bool + \@@_cutext_default:nnn {#1} {#2} {#3} + \@@_cutext_print_correct_unitname:nn {#2} {#3} + \group_end: + } +% \end{macrocode} +% +% \begin{macro} { \@@_cutext_default:nnn } +% \changes {2016/06/11} {0.98a} { New command } +% \begin{macrocode} +\cs_new:Npn \@@_cutext_default:nnn #1#2#3 + { + \@@_error_if_unit_not_defined:n {#3} + \keys_set:nn { cooking-units } {#1} + \bool_if:NT \l_@@_convert_to_eV_bool + { \@@_convert_to_eV: } + \bool_if:NTF \l_@@_parse_input_bool + { + \tl_set:Nn \l_tmpb_tl {#2} + \tl_replace_once:Nnn \l_tmpb_tl { -- } { \q_@@_range } + \tl_if_in:NnTF \l_tmpb_tl \q_@@_range + { \@@_cunum_parse_range:Vn \l_tmpb_tl {#3} } + { \@@_cutext_print_nummerical_output:Nn \l_tmpb_tl {#3} } + } + {#2} + } +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +\cs_new:Npn \@@_cunum_parse_range:Nn #1 #2 + { + \@@_cunum_parse_range_aux:nww {#2} #1 \q_stop + } +\cs_generate_variant:Nn \@@_cunum_parse_range:Nn { V } +\cs_new:Npn \@@_cunum_parse_range_aux:nww #1 #2 \q_@@_range #3 \q_stop + { + \tl_set:Nn \l_@@_tmpa_tl {#2} + \tl_set:Nn \l_@@_tmpb_tl {#3} + \@@_cutext_print_nummerical_output:Nn \l_@@_tmpa_tl {#1} + \tl_use:N \l_@@_cutext_range_sign_tl + \@@_cutext_print_nummerical_output:Nn \l_@@_tmpb_tl {#1} + } +% \end{macrocode} +% +% \begin{macrocode} +\cs_new:Npn \@@_cutext_just_print_number_correctly:N #1 + { + \translatelet \l_tmpa_tl { decimal-mark ( cu-unit name ) } + \tl_replace_once:NnV #1 { . } \l_tmpa_tl + \tl_replace_once:NnV #1 { - } \c_@@_minus_tl + #1 + } +% \end{macrocode} +% +% \begin{macro} {\@@_cutext_print_nummerical_output:N} +% \changes {2016/06/11} {0.99} {New.} +% \begin{macrocode} +\cs_new_protected:Npn \@@_cutext_print_nummerical_output:Nn #1#2 + { + \bool_if:NTF \g_@@_load_if_opt_numeral_bool + { + \@@_if_integer_and_parse:VTF #1 + { + \fp_compare:nNnTF {#1} < { \l_@@_print_numerals_below_int } + { + \fp_compare:nNnTF {#1} = { \c_one_fp } + { + \translatelet \l_tmpa_tl { #2 (cu-unitgender) } + \translatelet \l_tmpa_tl { one (\l_tmpa_tl) (cu-unitname) } + \bool_if:NTF \l_@@_cutext_uppercase_word_bool + { + \exp_args:Nf \tl_to_uppercase:n { \tl_head:V \l_tmpa_tl } + \tl_tail:V \l_tmpa_tl + } + { \l_tmpa_tl } + }{ + \bool_if:NTF \l_@@_cutext_uppercase_word_bool + { \Numberstringnum {#1} } + { \numberstringnum {#1} } + } + }{ \@@_cutext_just_print_number_correctly:N #1 } + }{ \@@_cutext_just_print_number_correctly:N #1 } + } + { \@@_cutext_just_print_number_correctly:N #1 } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +\cs_new:Npn \@@_cutext_print_correct_unitname:nn #1#2 + { + \space + \@@_if_integer_and_parse:nTF {#1} + { + \fp_compare:nNnTF {#1} = { \c_one_fp } + { \translate { #2 (cu-unitname) } } + { \translate { #2 (cu-unitname pl) } } + }{ + \translate { #2 (cu-unitname pl) } + } + } +% \end{macrocode} +% +% +% +% \section {cufrac} +% +% \begin{macrocode} +\NewDocumentCommand \cufrac { O{} m } + { + \group_begin: + \keys_set:nn { cooking-units } {#1} + \@@_cufrac:n {#2} + \group_end: + } +% \end{macrocode} +% +% \begin{macrocode} +\cs_new:Npn \@@_cufrac:n #1 + { + \tl_set_rescan:Nnn \l_tmpa_tl + { + \char_set_catcode_letter:N \_ % + \char_set_catcode_ignore:N\ % + } {#1} + \@@_cufrac_parse:V \l_tmpa_tl + } +% \end{macrocode} +% +% \begin{macrocode} +\cs_new:Npn \@@_cufrac_parse:n #1 + { + \tl_if_in:nnTF {#1} { / } + { + \tl_if_in:nnTF {#1} { _ } + { \@@_cufrac_parse_mixed_frac:www #1 \q_stop } + { \@@_cufrac_parse_frac:ww #1 \q_stop } + }{ + \tl_if_in:nnTF {#1} { _ } + { \msg_error:nnn { cooking-units } { missing-slash } {#1} } + { \@@_cufrac_parse_scale:n {#1} } + } + } +\cs_generate_variant:Nn \@@_cufrac_parse:n { V } +% \end{macrocode} +% +% \begin{macrocode} +\cs_new:Npn \@@_cufrac_parse_scale:n #1 {#1} +% \end{macrocode} +% +% \begin{macrocode} +\cs_new:Npn \@@_cufrac_parse_frac:ww #1/#2 \q_stop + { \@@_frac:nn {#1} {#2} } +% \end{macrocode} +% +% \begin{macrocode} +\cs_new:Npn \@@_cufrac_parse_mixed_frac:www #1_#2/#3 \q_stop + { + #1 + \hbox_to_wd:nn { \l_@@_mixed_frac_dim } { } + \@@_frac:nn {#2} {#3} + } +% \end{macrocode} +% +% +% \section {Names} +% +% +% \begin{macrocode} +\NewDocumentCommand \cudefinename { m m } + { + \tl_set:Nn \l_@@_language_tl {#1} + \@@_cuname_parse_input:n #2 + \q_recursion_tail \q_recursion_tail \q_recursion_stop + } +% \end{macrocode} +% +% +% \begin{macrocode} +\cs_new:Npn \@@_cuname_parse_input:n #1 + { + \peek_meaning_ignore_spaces:NTF [ + { \@@_cuname_parse_unit_symbol:nw {#1} } + { \@@_cuname_parse_input_aux:nn {#1} } + } +% \end{macrocode} +% +% \begin{macrocode} +\cs_new:Npn \@@_cuname_parse_unit_symbol:nw #1 [#2] + { + \quark_if_recursion_tail_stop:n {#1} + \quark_if_recursion_tail_stop_do:nn {#2} + { \msg_error:nn { cooking-units } { missing-argument } } + \@@_error_if_unit_not_defined:n {#1} + \deftranslation [ to=\l_@@_language_tl ] { #1 ( cu-unit ) } {#2} + \@@_cuname_parse_input_aux:nn {#1} + } +% \end{macrocode} +% +% +% \begin{macrocode} +\cs_new:Npn \@@_cuname_parse_input_aux:nn #1#2 + { + \quark_if_recursion_tail_stop:n {#1} + \quark_if_recursion_tail_stop_do:nn {#2} + { \msg_error:nn { cooking-units } { missing-argument } } + \clist_if_in:NnF \g_@@_allowed_unit_phrases_clist {#1} + { \@@_error_if_unit_not_defined:n {#1} } + \deftranslation [ to=\l_@@_language_tl ] { #1 (cu-unitname) } {#2} + \peek_meaning_ignore_spaces:NTF [ + { \@@_cuname_parse_bracket:nw {#1} } + { \@@_cuname_parse_bracket:nw {#1} [#2] } + } +% \end{macrocode} +% +% \begin{macrocode} +\cs_new:Npn \@@_cuname_parse_bracket:nw #1 [#2] + { + \deftranslation [ to=\l_@@_language_tl ] { #1 ( cu-unitname pl ) } {#2} + \peek_meaning_ignore_spaces:NTF < + { \@@_cuname_parse_arrows:nw {#1} } + { \@@_cuname_parse_arrows:nw {#1} <m> } + } +% \end{macrocode} +% +% \begin{macrocode} +\cs_new:Npn \@@_cuname_parse_arrows:nw #1 <#2> + { + \deftranslation [ to=\l_@@_language_tl ] { #1 ( cu-unitgender ) } {#2} + \@@_cuname_parse_input:n + } +% \end{macrocode} +% +% +% +% \subsection {cudefinesymbol} +% +% +% \begin{macrocode} +\NewDocumentCommand \cudefinesymbol { m m } + { + \tl_set:Nn \l_@@_language_tl {#1} + \@@_cuprint_define_printed_unit:nn #2 + \q_recursion_tail \q_recursion_tail \q_recursion_stop + } +% \end{macrocode} +% +% \begin{macrocode} +\cs_new:Npn \@@_cuprint_define_printed_unit:nn #1#2 + { + \quark_if_recursion_tail_stop:n {#1} + \quark_if_recursion_tail_stop_do:nn {#2} + { \msg_error:nn { cooking-units } { missing-argument } } + \clist_if_in:NnF \g_@@_allowed_unit_phrases_clist {#1} + { \@@_error_if_unit_not_defined:n {#1} } + \deftranslation [ to=\l_@@_language_tl ] { #1 ( cu-unit ) } {#2} + \@@_cuprint_define_printed_unit:nn + } +% \end{macrocode} +% +% +% +% +% +% \subsection {cusetup} +% +% \begin{macrocode} +\NewDocumentCommand \cusetup { m } + { + \keys_set:nn { cooking-units } {#1} + } +% \end{macrocode} +% +% +% \begin{macrocode} +\newcookingunit { kg } +\newcookingunit { dag } +\newcookingunit { g } +\newcookingunit { oz } +\newcookingunit { lb } +\newcookingunit [ \ensuremath{ \@@_frac:nn { eV } { c^2 } } ] { eVc-2 } +% \end{macrocode} +% +% \begin{macrocode} +\newcookingunit [ \ensuremath{ {} ^ { \circ } } \kern-\scriptspace C ] { C } +\newcookingunit { K } +\newcookingunit [ \ensuremath{ {} ^ { \circ } } \kern-\scriptspace F ] { F } +\newcookingunit [ \ensuremath{ {} ^ { \circ } } \kern-\scriptspace R\'{e} ] { Re } +% \end{macrocode} +% +% \begin{macrocode} +\newcookingunit { d } +\newcookingunit { h } +\newcookingunit { min } +\newcookingunit { s } +\newcookingunit [ \ensuremath{ \@@_frac:nn { \hbar } { eV } } ] { hbareV-1 } +% \end{macrocode} +% +% \begin{macrocode} +\newcookingunit { m } +\newcookingunit { cm } +\newcookingunit { dm } +\newcookingunit { mm } +\newcookingunit { in } +\newcookingunit [ \ensuremath{ \@@_frac:nn { c\hbar } { eV } } ] { chbareV-1 } +% \end{macrocode} +% +% \begin{macrocode} +\newcookingunit { l } +\newcookingunit { dl } +\newcookingunit { cl } +\newcookingunit { ml } +\newcookingunit [ \ensuremath { \@@_frac:nn { c^3 \hbar^3 } { eV^3 } } ] { (chbareV-1)3 } +% \end{macrocode} +% +% \begin{macrocode} +\newcookingunit { cal } +\newcookingunit { kcal } +\newcookingunit { J } +\newcookingunit { kJ } +\newcookingunit { eV } +% \end{macrocode} +% +% \begin{macrocode} +\newcookingunit [ Msp. ] { Msp } +\newcookingunit { EL } +\newcookingunit { TL } +% \end{macrocode} +% +% +% +% \begin{macrocode} +\cudefinename { German } + { + { kg } { Kilogramm } < n > + { dag } { Dekagramm } < n > + { g } { Gramm } < n > + { oz } { Unze } < f > + { lb } { Pfund } < n > +% \end{macrocode} +% \begin{macrocode} + { d } { Tag } [ Tage ] + { h } { Stunde } [ Stunden ] < f > + { min } { Minute } [ Minuten ] < f > + { s } { Sekunde } [ Sekunden ] < f > +% \end{macrocode} +% \begin{macrocode} + { C } { Grad \space Celsius } + { K } { Kelvin } < n > + { F } { Grad \space Fahrenheit } + { Re } { Grad \space R\'{e}amur } +% \end{macrocode} +% \begin{macrocode} + { m } { Meter } < n > + { dm } { Dezimeter } < n > + { cm } { Centimeter } < n > + { mm } { Millimeter } < n > + { in } { Zoll } +% \end{macrocode} +% \begin{macrocode} + { l } { Liter } + { dl } { Deziliter } + { cl } { Centiliter } + { ml } { Milliliter } +% \end{macrocode} +% \begin{macrocode} + { cal } { Kalorie } [ Kalorien ] < f > + { kcal } { Kilokalorie } [ Kilokalorien ] < f > + { J } { Joule } + { kJ } { Kilojoule } + { eV } { ELektronenvolt } < n > +% \end{macrocode} +% \begin{macrocode} + { Msp } [ Msp. ] { Messerspitze } [ Messerspitzen ] < f > + { EL } [ EL ] { Essl{\"o}ffel } + { TL } [ TL ] { Teel{\"o}ffel } +% \end{macrocode} +% \begin{macrocode} + { decimal-mark } { , } + { one (m) } { ein } + { one (f) } { eine } + { one (n) } { ein } + } +% \end{macrocode} +% +% +% \begin{macrocode} +\cudefinename { English } + { + { kg } { kilogramme } + { dag } { decagramme } + { g } { gramme } + { oz } { ounce } + { lb } { pound } [ pounds ] +% \end{macrocode} +% \begin{macrocode} + { d } { day } [ days ] + { h } { hour } [ hours ] + { min } { minute } [ minutes ] + { s } { second } [ seconds ] +% \end{macrocode} +% \begin{macrocode} + { C } { degree \space Celsius } [ degrees \space Celsius ] + { F } { degree \space Fahrenheit } [ degrees \space Fahrenheit ] + { K } { kelvin } + { Re } { degree \space R\'{e}aumur } [ degrees \space R\'{e}aumur ] +% \end{macrocode} +% \begin{macrocode} + { m } { metre } [ metres ] + { dm } { decimetre } [ decimetres ] + { cm } { centimetre } [ centimetres ] + { mm } { millimitre } [ millimitres ] + { in } { inch } [ inches ] +% \end{macrocode} +% \begin{macrocode} + { l } { litre } [ litres ] + { dl } { decilitre } [ decilitres ] + { cl } { centilitre } [ centilitres ] + { ml } { millilitre } [ millilitres ] +% \end{macrocode} +% \begin{macrocode} + { cal } { calorie } [ calories ] + { kcal } { kilocalorie } [ kilocalories ] + { J } { joule } [ joules ] + { kJ } { kilojoule } [ kilojoules ] + { eV } { electron \space volt } +% \end{macrocode} +% \begin{macrocode} + { Msp } [ pn ] { pinch } [ pinches ] + { EL } [ tsp. ] { tablespoon } [ tablespoons ] + { TL } [ tbsp. ] { teaspoon } [ teaspoons ] +% \end{macrocode} +% \begin{macrocode} + { decimal-mark } { . } + { one (m) } { one } + { one (f) } { one } + { one (n) } { one } + } +% \end{macrocode} +% +% \begin{macrocode} +\cudefinename { AmericanEnglish } + { + { kg } { kilogram } + { dag } { decagram } + { g } { gram } + { oz } { ounce } +% \end{macrocode} +% \begin{macrocode} + { m } { meter } [ meters ] + { dm } { decimeter } [ decimeters ] + { cm } { centimeter } [ centimeters ] + { mm } { millimiter } [ millimiters ] + { in } { inch } [ inches ] +% \end{macrocode} +% \begin{macrocode} + { l } { liter } [ liters ] + { dl } { deciliter } [ deciliters ] + { cl } { centiliter } [ centiliters ] + { ml } { milliliter } [ milliliters ] + } +% \end{macrocode} +% +% +% \begin{macrocode} +\cudefinename { French } + { + { kg } { kilogramme } [ kilogrammes ] + { dag } { d\'{e}cagramme } [ d\'{e}cagrammes] + { g } { gramme } [ gramme ] + { oz } { once } < f > + { lb } { livre } [ livres ] < f > +% \end{macrocode} +% \begin{macrocode} + { d } { jour } [ jours ] + { h } { heure } [ heures ] < f > + { min } { minute } [ minutes ] < f > + { s } { seconde } [ secondes ] < f > +% \end{macrocode} +% \begin{macrocode} + { C } { degr\'{e} \space Celsius } [ degr\'{e}s \space Celsius ] + { K } { degr\'{e} \space Fahrenheit } [ degr\'{e}s \space Fahrenheit ] + { F } { kelvin } [ kelvins ] + { Re } { \'{e}chelle \space R\'{e}aumur } [ degr\'{e}s \space R\'{e}aumur ] +% \end{macrocode} +% \begin{macrocode} + { m } { m\`{e}tre } [ m\`{e}tres ] + { dm } { d\'{e}cim\`{e}tre } [ d\'{e}cim\`{e}tres ] + { cm } { centim\`{e}tre } [ centim\`{e}tres ] + { mm } { millim\`{e}tre } [ millim\`{e}tre ] +% \end{macrocode} +% \begin{macrocode} + { l } [ L ] { litre } [ litres ] + { dl } [ dL ] { d\'{e}cilitre } [ d\'{e}cilitres ] + { cl } [ cL ] { centilitre } [ centilitres ] + { ml } [ mL ] { millilitre } [ millilitres ] +% \end{macrocode} +% \begin{macrocode} + { cal } { calorie } [ calorie ] + { kcal } { kilocalorie } [ kilocalories ] + { J } { joule } [ joules ] + { kJ } { kilojoule } [ kilojoules ] + { eV } { \'{e}lectron-volt } [ \'{e}lectron-volts ] +% \end{macrocode} +% \begin{macrocode} + { Msp } { pinc\'{e}e } < f > + { EL } { cuill\'{e}re \space \`{a} \space soupe } < f > + { TL } { cuill\'{e}re \space \`{a} \space caf\'{e} } < f > +% \end{macrocode} +% \begin{macrocode} + { decimal-mark } { . } + { one (m) } { un } + { one (f) } { une } + { one (n) } { un } + } +% \end{macrocode} +% +% +% +% \begin{macrocode} +\cudefinekeys { kg } + { + { dag }{ 100 } + { g } { 1000 } + { oz } { 35.27399 } + { lb } { 2.204 622 6 } %% 2.204 622 6 + } +\cuaddtokeys { kg } { eVc-2 } { 1.78266173e-16 } +% \end{macrocode} +% \begin{macrocode} +\cudefinekeys { d } + { + { h } { 24 } + { min }{ 1440 } + { s } { 86400 } + } +\cuaddtokeys { s } { hbareV-1 } { 6.582119514e-16 } +% \end{macrocode} +% \begin{macrocode} +\cudefinekeys { m } + { + { dm } { 10 } + { cm } { 100 } + { mm } { 1000 } + { in } { 39.370079 } + } +\cuaddtokeys { m } { chbareV-1 } { 1.97326972e-7 } +% \end{macrocode} +% \begin{macrocode} +\cudefinekeys { l } + { + { dl } { 10 } + { cl } { 100 } + { ml }{ 1000 } + { (chbareV-1)3 } { 1.30148943e+17 } + } +% \end{macrocode} +% \begin{macrocode} +\cudefinekeys { J } + { + { kJ }{ 1e-3 } + { cal }{ 0.2388459 } + { kcal }{ 0.2388459e-3 } + } +\cuaddtokeys { J } { eV } { 1.6021766208e-19 } +% \end{macrocode} +% \begin{macrocode} +\fp_const:Nn \c_@@_kb_eV_fp { 8.617 330 3 e-5 } +\cudefinesinglekey { C } + { + { F } { #1 * 1.8 + 32 } + { K } { #1 + 273.15 } + { Re } { #1 * 0.8 } + { eV } { ( #1 + 273.15 ) * \c_@@_kb_eV_fp } + } +\cudefinesinglekey { F } + { + { C } { ( #1 - 32 ) * 5/9 } + { K } { ( #1 + 459.67 ) * 5/9 } + { Re } { ( #1 - 32 ) * 4/9 } + { eV } {( #1 + 459.67 ) * 5/9 * \c_@@_kb_eV_fp } + } +\cudefinesinglekey { K } + { + { C } { #1 - 273.15 } + { F } { #1 * 1.8 - 459.67 } + { Re } { ( #1 - 273.15 ) * 0.8 } + { eV } { #1 * \c_@@_kb_eV_fp } + } +\cudefinesinglekey { Re } + { + { K } { #1 * 1.25 + 273.15 } + { C } { #1 * 1.25 } + { F } { #1 * 2.25 + 32 } + { eV } { ( #1 - 273.15 ) * 1.25 * \c_@@_kb_eV_fp } + } +% \end{macrocode} +% +% +% \begin{macrocode} +\fp_const:Nn \c_@@_K_min_fp { 0 } +\fp_const:Nn \c_@@_C_min_fp { -273.15 } +\fp_const:Nn \c_@@_F_min_fp { -459.67 } +\fp_const:Nn \c_@@_Re_min_fp { -218.52 } +% \end{macrocode} +% +% +% +% \subsection{Finish} +% +% \begin{macrocode} +\cusetup + { + set-option-for-F = { round-to-int = true } , + set-option-for-C = { round-to-int = true } , + set-option-for-K = { round-to-int = true } , + set-option-for-Re = { round-to-int = true } , + } +% \end{macrocode} +% +% \begin{macrocode} +%</package> +% \end{macrocode} +% +% \end{implementation} +% +% \endinput +% +% +% +% +% Local Variables: +% mode: doctex +% TeX-master: t +% End: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Master/texmf-dist/source/latex/cooking-units/cooking-units.ins b/Master/texmf-dist/source/latex/cooking-units/cooking-units.ins new file mode 100644 index 00000000000..0084204cbee --- /dev/null +++ b/Master/texmf-dist/source/latex/cooking-units/cooking-units.ins @@ -0,0 +1,55 @@ +%% +%% This is file `cooking-units.ins', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% cooking-units.dtx (with options: `install') +%% Copyright (C) 2016 by Ben Vitecek (current Maintainer) +%% +%% This file may be distributed and/or modified under the +%% conditions of the LaTeX Project Public License, either +%% version 1.3 of this license or (at your option) any later +%% version. The latest version of this license is in: +%% +%% http://www.latex-project.org/lppl.txt +%% +%% and version 1.3c or later is part of all distributions of +%% LaTeX version 2008-05-04 or later. +%% +%% This work has the LPPL maintenance status `maintained'. +%% +%% This work consists of the files README, cooking-units.dtx and cooking-units.ins +%% and the derived file cooking-units.sty. +%% +\input l3docstrip.tex +\askforoverwritefalse +\preamble +Copyright (C) 2016 by Ben Vitecek (current Maintainer) + +This file may be distributed and/or modified under the +conditions of the LaTeX Project Public License, either +version 1.3 of this license or (at your option) any later +version. The latest version of this license is in: + +http://www.latex-project.org/lppl.txt + +and version 1.3c or later is part of all distributions of +LaTeX version 2008-05-04 or later. + +This work has the LPPL maintenance status `maintained'. + +This work consists of the files README, cooking-units.dtx and cooking-units.ins +and the derived file cooking-units.sty. + +\endpreamble + +\usedir{tex/latex/cooking-units} +\generate{ + \file{\jobname.sty}{\from{\jobname.dtx}{package}} +} +\endbatchfile + +\endinput +%% +%% End of file `cooking-units.ins'. diff --git a/Master/texmf-dist/tex/latex/cooking-units/cooking-units.sty b/Master/texmf-dist/tex/latex/cooking-units/cooking-units.sty new file mode 100644 index 00000000000..af9dbde6fbf --- /dev/null +++ b/Master/texmf-dist/tex/latex/cooking-units/cooking-units.sty @@ -0,0 +1,1373 @@ +%% +%% This is file `cooking-units.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% cooking-units.dtx (with options: `package') +%% Copyright (C) 2016 by Ben Vitecek (current Maintainer) +%% +%% This file may be distributed and/or modified under the +%% conditions of the LaTeX Project Public License, either +%% version 1.3 of this license or (at your option) any later +%% version. The latest version of this license is in: +%% +%% http://www.latex-project.org/lppl.txt +%% +%% and version 1.3c or later is part of all distributions of +%% LaTeX version 2008-05-04 or later. +%% +%% This work has the LPPL maintenance status `maintained'. +%% +%% This work consists of the files README, cooking-units.dtx and cooking-units.ins +%% and the derived file cooking-units.sty. +%% +\@ifpackageloaded {xparse} + { } + { \RequirePackage {xparse} } +\@ifpackageloaded {expl3} + { } + { \RequirePackage {expl3} } +\ProvidesExplPackage + {cooking-units} + {2016/08/31} + {1.00} + {Ein Paket fuer Kocheinheiten} +\@ifpackagelater { expl3 } { 2016/05/18 } + { } + { + \PackageError { cooking-units } { Support~package~expl3~too~old } + { + You~need~to~update~your~installation~of~the~bundles~'l3kernel'~and~ + 'l3packages'.\MessageBreak + Loading~cooking-units~will~abort! + } + \tex_endinput:D + } +\@ifpackageloaded { translator } { } { \RequirePackage { translator } } +\@ifpackageloaded { xfrac } { } { \RequirePackage { xfrac } } +\@ifpackageloaded { l3keys2e } { } { \RequirePackage { l3keys2e } } +\bool_new:N \g__cooking_units_load_if_opt_numeral_bool +\keys_define:nn { cooking-units } + { + use-numerals .bool_gset:N = \g__cooking_units_load_if_opt_numeral_bool , + use-numerals .default:n = { false }, + } +\ProcessKeysOptions { cooking-units } +\bool_if:NT \g__cooking_units_load_if_opt_numeral_bool + { + \@ifpackageloaded { fmtcount } { } { \RequirePackage { fmtcount } } + } +\keys_define:nn { cooking-units } + { + use-numerals .code:n = \msg_error:nnn { cooking-units } { load-time-option } { fmtcount } , + } +\cs_generate_variant:Nn \tl_replace_all:Nnn { NVn } +\cs_generate_variant:Nn \tl_replace_once:Nnn { NnV, NVn } +\cs_generate_variant:Nn \tl_if_in:nnT { nVT } +\cs_generate_variant:Nn \tl_if_in:NnT { NVT } +\cs_generate_variant:Nn \fp_compare:nNnT { cNnT } +\cs_generate_variant:Nn \fp_eval:n { c } +\cs_new_eq:NN \__cooking_units_frac:nn \sfrac +\prop_new:N \l__cooking_units_change_unit_prop +\tl_new:N \l__cooking_units_tmpa_tl +\tl_new:N \l__cooking_units_tmpb_tl +\tl_new:N \l__cooking_units_mixed_fraction_tl +\tl_new:N \l__cooking_units_tmp_unit_tl +\tl_new:N \l__cooking_units_option_unit_tl +\tl_new:N \l__cooking_units_language_tl +\tl_new:N \l__cooking_units_cunum_range_sign_tl +\tl_new:N \l__cooking_units_cutext_range_sign_tl +\tl_new:N \l__cooking_units_value_unit_space_tl +\tl_new:N \l__cooking_units_input_digits_tl +\tl_new:N \l__cooking_units_decimal_mark_tl +\tl_new:N \l__cooking_units_value_signs_tl +\tl_new:N \l__cooking_units_allowed_special_signs_tl +\tl_new:N \c__cooking_units_str_hash_one_tl +\tl_new:N \l__cooking_units_input_range_sign_tl +\tl_set:Nn \l__cooking_units_cunum_range_sign_tl { -- } +\tl_set:Nn \l__cooking_units_cutext_range_sign_tl { -- } +\tl_set:Nn \l__cooking_units_value_unit_space_tl { \thinspace } +\tl_set:Nn \l__cooking_units_input_digits_tl { 0123456789 } +\tl_set:Nn \l__cooking_units_decimal_mark_tl { . , } +\tl_set:Nn \l__cooking_units_value_signs_tl { + - } +\tl_set:Nn \l__cooking_units_input_range_sign_tl { -- } +\tl_set:Nn \l__cooking_units_allowed_special_signs_tl { ? } +\tl_set_rescan:Nnn \c__cooking_units_str_hash_one_tl + { \char_set_catcode_letter:N \# } {#1} +\AtBeginDocument { + \cs_if_free:cT { T@TS1 } + { + \DeclareFontEncoding { TS1 } { } { } + \DeclareFontSubstitution { TS1 } { cmr } { m } { n } + } +} +\DeclareTextSymbolDefault \c__cooking_units_minus_tl { TS1 } +\DeclareTextSymbol \c__cooking_units_minus_tl { TS1 } { 61 } +\AtBeginDocument { + \@ifpackageloaded { fontspec } + { + \@ifpackageloaded { eulervm } + { } + { + \int_const:Nn \c__cooking_units_minus_int { 8722 } + \tl_set:Nn \c__cooking_units_minus_tl + { \tex_char:D \c__cooking_units_minus_int } + } + } + { } +} +\dim_new:N \l__cooking_units_mixed_frac_dim +\dim_set:Nn \l__cooking_units_mixed_frac_dim { 0.1 em } +\int_new:N \l__cooking_units_significant_figures_int +\int_new:N \l__cooking_units_significant_figures_plus_one_int +\int_set:Nn \l__cooking_units_significant_figures_int { 2 } +\int_set:Nn \l__cooking_units_significant_figures_plus_one_int { 2 + 1 } +\int_new:N \l__cooking_units_print_numerals_below_int +\int_set:Nn \l__cooking_units_print_numerals_below_int { 13 } +\clist_new:N \l__cooking_units_list_of_defined_keys_clist +\clist_new:N \g__cooking_units_list_of_defined_units_clist +\clist_new:N \g__cooking_units_allowed_unit_phrases_clist +\bool_new:N \l__cooking_units_error_bool +\bool_new:N \l__cooking_units_eval_fractions_bool +\bool_new:N \l__cooking_units_parse_input_bool +\bool_new:N \l__cooking_units_round_to_int_bool +\bool_new:N \l__cooking_units_special_sign_bool +\bool_new:N \l__cooking_units_decimal_in_input_bool +\bool_new:N \l__cooking_units_single_key_bool +\bool_new:N \l__cooking_units_fraction_in_input_bool +\bool_new:N \l__cooking_units_check_temperature_bool +\bool_new:N \l__cooking_units_convert_to_eV_bool +\bool_new:N \l__cooking_units_cutext_uppercase_word_bool +\bool_new:N \l__cooking_units_error_for_unknown_value_bool +\bool_new:N \l__cooking_units_parse_range_bool +\bool_set_true:N \l__cooking_units_parse_input_bool +\quark_new:N \q__cooking_units_range +\clist_gset:Nn \g__cooking_units_allowed_unit_phrases_clist + { + decimal-mark , + one (m) , + one (f) , + one (n) + } +\newtranslation { decimal-mark (cu-unitname) } { . } +\newtranslation [ to=German ] { decimal-mark (cu-unitname) } { , } +\newtranslation { one (m) (cu-unitname) } { one } +\newtranslation { one (f) (cu-unitname) } { one } +\newtranslation { one (n) (cu-unitname) } { one } +\newtranslation [ to=German ] { one (m) (cu-unitname) } { ein } +\newtranslation [ to=German ] { one (f) (cu-unitname) } { eine } +\newtranslation [ to=German ] { one (n) (cu-unitname) } { ein } +\keys_define:nn { cooking - units } + { + eval-fraction .bool_set:N = \l__cooking_units_eval_fractions_bool , + eval-fraction .default:n = { false } , + round-precision .code:n = + { + \int_set:Nn \l__cooking_units_significant_figures_int {#1} + \int_set:Nn \l__cooking_units_significant_figures_plus_one_int { #1 + \c_one } + } , + round-precision .default:n = { 2 } , + round-to-int .bool_set:N = \l__cooking_units_round_to_int_bool , + round-to-int .default:n = { false } , + range-sign .meta:n = + { + cunum-range-sign = {#1} , + cutext-range-sign = {#1} + } , + range-sign .default:n = { -- } , + cunum-range-sign .tl_set:N = \l__cooking_units_cunum_range_sign_tl , + cunum-range-sign .default:n = { -- } , + cutext-range-sign .tl_set:N = \l__cooking_units_cutext_range_sign_tl , + cutext-range-sign .default:n = { -- } , + value-unit-space .tl_set:N = \l__cooking_units_value_unit_space_tl , + value-unit-space .default:n = { \thinspace } , + fraction-command .code:n = { \cs_set_eq:NN \__cooking_units_frac:nn #1 } , + fraction-command .default:n = { \sfrac } , + fraction-inline .code:n = { \cs_set:Npn \__cooking_units_frac:nn ##1##2 {#1} } , + fraction-inline .default:n = { \sfrac {#1}{#2} } , + mixed-fraction-space .dim_set:N = \l__cooking_units_mixed_frac_dim , + mixed-fraction-space .default:n = { 0.1 em } , + parse-number .bool_set:N = \l__cooking_units_parse_input_bool , + parse-number .default:n= { true } , + add-special-sign .code:n = { \tl_put_right:Nn \l__cooking_units_allowed_special_signs_tl {#1} } , + add-special-sign .default:n = { } , + set-special-sign .tl_set:N = \l__cooking_units_allowed_special_signs_tl , + input-range-sign .tl_set:N = \l__cooking_units_input_range_sign_tl , + input-range-sign .default:n = { -- } , + check-temperature .bool_set:N = \l__cooking_units_check_temperature_bool , + check-temperature .default:n = { true } , + convert-to-eV .bool_set:N = \l__cooking_units_convert_to_eV_bool , + convert-to-eV .default:n = { true } , + use-numerals-below .int_set:N = \l__cooking_units_print_numerals_below_int , + use-numerals-below .default:n = { 13 } , + set-unknown-message .choices:nn = + { error , warning , none } + { + \msg_redirect_name:nnn { cooking-units } { amount-not-known } + { \l_keys_choice_tl } + } , + set-unknown-message .default:n = { warning } , + erase-all-options .code:n = + { + \clist_map_inline:Nn \g__cooking_units_list_of_defined_units_clist + { + \clist_clear:c { l__cooking_units_predefined_option_##1_clist } + } + }, + } +\msg_new:nnnn { cooking-units } { fraction-not-allowed-with-range } + { + 'You' \ cannot \ use \ '/' \ ( and \ '_' )\ in \ combination \ + with \ '\l__cooking_units_input_range_sign_tl' \ in \ '#1'. + }{ + You \ cannot \ use \ fractions \ with \ a \ range. + \msg_see_documentation_text:n { cooking-units } + } +\msg_new:nnnn { cooking-units } { missing-slash } + { + You \ cannot \ use \ '_' \ without \ + '/' in '#1'. + }{ + You \ cannot \ have \ a \ mixed \ fraction \ ('_') \ without \ + a \ normal \ fraction \ ('/'). + \msg_see_documentation_text:n { cooking-units } + } +\msg_new:nnnn { cooking-units } { unknown - unit } + { + The \ unit \ '#1' \ is \ not \ defined. \ Use \ + \newcookingunit \ to \ define \ new \ units. + }{ + Define \ units \ before \ using \ or \ check \ if \ the \ + unit-key \ is \ written \ correctly. + \msg_see_documentation_text:n { cooking-units } + } +\msg_new:nnnn { cooking - units } { unit-already-defined } + { The\ unit \ '#1' \ is \ already \ defined. } + { + The \ unit-key \ is \ already \ defined. \ Please \ use \ a \ different \ + key \ for \ a \ new \ unit. + \msg_see_documentation_text:n {cooking-units} + } +\msg_new:nnnn { cooking - units } { missing-argument } + { There \ is \ an \ missing \ argument. } + { + You \ probably \ have \ forgotten \ a \ curly-brace \ pair. + \msg_see_documentation_text:n {cooking-units} + } +\msg_new:nnnn { cooking - units } { Division-by-zero } + { Division\ by \ zero \ is \ not \ allowed. } + { See \ a \ math \ book \ of \ your \ choice \ or \ for \ example \ Wikipedia. } +\msg_new:nnnn { cooking - units } { Token-not-allowed } + { The \ token \ '#1' \ is \ not \ allowed. } + { + The \ command \ accepts \ only \ a \ fixed \ number \ of \ tokens. + \msg_see_documentation_text:n {cooking-units} + } +\msg_new:nnnn { cooking - units } { Second - decimal -sign - not - allowed } + { A \ second \ decimal \ sign \ is \ not \ allowed. } + { + Perhaps \ you \ didn't \ type \ it \ correctly. + \msg_see_documentation_text:n {cooking-units} + } +\msg_new:nnnn { cooking - units } { Key - not -defined } + { + The \ key \ '#1' \ is \ not \ defined. \ Use \ \cudefinekeys or \ + \cudefinesinglekey to \ define \ keys. + } + { + This \ key \ is \ not \ defined, \ perhaps \ you \ misspelled \ it. + \msg_see_documentation_text:n {cooking-units} + } +\msg_new:nnnn { cooking - units } { Temperature-to-low } + { + The \ temperature \ '#1' \ is \ to \ low.\ It \ cannot \ be \ + below \ the \ absolute \ zero - point \ of \ '#2'. \ Note \ that \ + by \ default \ the \ temperatures \ 'C', \ 'F' , \ 'K' \ and \ 'Re' \ + are \ rounded \ to \ integers. + \\\\ + You \ can \ disable \ the \ option \ 'check-temperature' \ to \ + disable \ this \ error. + } + { See \ for \ example \ Wikipedia. } +\msg_new:nnnn { cooking - units } { key-choice-unknown } + { + The \ key \ '#1' \ only \ accepts \ only \ + '#3' \ as \ a \ set \ of \ choices \ and \ '#2' \ is \ non \ of \ these. + } + { + The \ key \ accepts \ accepts\ only \ a \ fixed \ set \ of \ choices. \ + You \ can \ add \ new \ choices \ via \ \cuaddkeys, \ \cuaddsinglekeys \ + and \ \cuaddtokeys. + \msg_see_documentation_text:n {cooking-units} + } +\msg_new:nnnn { cooking - units } { amount-not-known } + { + The \ amount \ of \ #1 \ is \ not \ known \ at \ line \ + \msg_line_number: . + } + { + You \ used\ a\ special\ sign\ indicating\ that\ the\ true\ amount\ of\ the\ + specific\ ingredient\ is\ (was) not\ known\ to\ you. This\ message\ + reminds\ you\ about\ that\ fact. + \msg_see_documentation_text:n {cooking-units} + } +\msg_new:nnnn { cooking - units } { load-time-option } + { + The \ option \ '#1' \ is \ only \ avaiable \ as \ a \ load-time-option. \ + Please \ set \ it \ as \ a \ package \ option. + } + { + You \ cannot \ set \ this \ option \ using \ \cusetup \ + but \ only \ as \ a \ package \ option. + \msg_see_documentation_text:n { cooking-units } + } +\cs_new:Npn \__cooking_units_error_if_unit_not_defined:n #1 + { + \clist_if_in:NnF \g__cooking_units_list_of_defined_units_clist {#1} + { \msg_error:nnn { cooking-units } { unknown-unit } {#1} } + } +\cs_generate_variant:Nn \__cooking_units_error_if_unit_not_defined:n { V } +\prg_new_protected_conditional:Npnn \__cooking_units_if_integer_and_parse:n #1 { TF } + { + \bool_if:NTF \l__cooking_units_parse_input_bool + { + \tl_map_inline:nn {#1} + { + \tl_if_in:NnF \l__cooking_units_input_digits_tl {##1} + { + \tl_map_break:n { \use_iii:nnn } + } + } + \use_i:nn \prg_return_true: \prg_return_false: + } + { \prg_return_false: } + } +\cs_generate_variant:Nn \__cooking_units_if_integer_and_parse:nTF { V } +\cs_new:Npn \__cooking_units_convert_to_eV: + { + \keys_set:nn { cooking-units } + { + m= chbareV-1, + cm= chbareV-1, + dm= chbareV-1, + mm= chbareV-1, + in= chbareV-1, + kg= eVc-2, + dag= eVc-2, + g= eVc-2, + oz= eVc-2, + lb= eVc-2, + d= hbareV-1, + h= hbareV-1, + min= hbareV-1, + s= hbareV-1, + cal= eV, + kcal= eV, + J= eV, + kJ= eV, + F= eV, + K= eV, + C= eV, + Re= eV, + l= (chbareV-1)3 , + dl= (chbareV-1)3 , + cl= (chbareV-1)3 , + ml= (chbareV-1)3 , + } + \prop_get:NVN \l__cooking_units_change_unit_prop \l__cooking_units_tmp_unit_tl \l__cooking_units_option_unit_tl + \quark_if_no_value:NT \l__cooking_units_option_unit_tl + { + \tl_set_eq:NN \l__cooking_units_option_unit_tl \l__cooking_units_tmp_unit_tl + } + \keys_set_filter:nnv + { cooking-units } + { change-unit } + { l__cooking_units_predefined_option_ \l__cooking_units_option_unit_tl _clist } + } +\cs_new:Npn \__cooking_units_cunum_parse_input:N #1 + { + \tl_if_in:nnTF {#1} { \q__cooking_units_range } + { \__cooking_units_parse_range_in_input:ww #1 \q_stop } + { + \tl_if_in:nnTF {#1} { / } + { + \tl_if_in:nnTF {#1} { _ } + { \__cooking_units_parse_fraction_in_input:www #1 \q_stop } + { \__cooking_units_parse_fraction_in_input:ww #1 \q_stop } + } + { \__cooking_units_parse_number_in_input:n {#1} } + } + } +\cs_generate_variant:Nn \__cooking_units_cunum_parse_input:N { V } +\cs_new:Npn \__cooking_units_parse_number_in_input:n #1 + { + \__cooking_units_parse_input_and_safe_in:nN {#1} \l__cooking_units_tmpa_tl + \__cooking_units_calculate_and_print_input:N \l__cooking_units_tmpa_tl + } +\cs_new:Npn \__cooking_units_parse_range_in_input:ww #1 \q__cooking_units_range #2 \q_stop + { + \bool_set_true:N \l__cooking_units_parse_range_bool + \__cooking_units_parse_input_and_safe_in:nN {#1} \l__cooking_units_tmpa_tl + \__cooking_units_parse_input_and_safe_in:nN {#2} \l__cooking_units_tmpb_tl + \__cooking_units_calculate_and_print_input:N \l__cooking_units_tmpa_tl + \tl_use:N \l__cooking_units_cunum_range_sign_tl + \__cooking_units_calculate_and_print_input:N \l__cooking_units_tmpb_tl + } +\cs_new:Npn \__cooking_units_parse_fraction_in_input:ww #1/#2 \q_stop + { + \__cooking_units_parse_input_and_safe_in:nN {#1} \l__cooking_units_tmpa_tl + \__cooking_units_parse_input_and_safe_in:nN {#2} \l__cooking_units_tmpb_tl + \bool_if:NTF \l__cooking_units_eval_fractions_bool + { + \__cooking_units_calculate_and_print_input:n + { \l__cooking_units_tmpa_tl / \l__cooking_units_tmpb_tl } + }{ + \__cooking_units_formatiere_fractions:nnn + { } + { \l__cooking_units_tmpa_tl } + { \l__cooking_units_tmpb_tl } + } + } +\cs_new:Npn \__cooking_units_parse_fraction_in_input:www #1_#2/#3 \q_stop + { + \__cooking_units_parse_input_and_safe_in:nN {#1} \l__cooking_units_mixed_fraction_tl + \__cooking_units_parse_input_and_safe_in:nN {#2} \l__cooking_units_tmpa_tl + \__cooking_units_parse_input_and_safe_in:nN {#3} \l__cooking_units_tmpb_tl + \bool_if:NTF \l__cooking_units_eval_fractions_bool + { + \__cooking_units_calculate_and_print_input:n + { + \l__cooking_units_mixed_fraction_tl + \fp_compare:nNnTF + { \l__cooking_units_mixed_fraction_tl } < { \c_zero_fp } + { - } + { + } + \l__cooking_units_tmpa_tl / \l__cooking_units_tmpb_tl + } + }{ + \__cooking_units_formatiere_fractions:nnn + { \l__cooking_units_mixed_fraction_tl } + { \l__cooking_units_tmpa_tl } + { \l__cooking_units_tmpb_tl } + } + } +\cs_new:Npn \__cooking_units_parse_input_and_safe_in:nN #1 #2 + { + \tl_clear:N \l_tmpa_tl + \bool_set_false:N \l__cooking_units_decimal_in_input_bool + \__cooking_units_parse_vorzeichen_and_rest:Nw #1 \q_stop + \bool_if:NTF \l__cooking_units_error_bool + { \tl_set:Nn #2 {#1} } + { \tl_set_eq:NN #2 \l_tmpa_tl } + } +\cs_new:Npn \__cooking_units_parse_vorzeichen_and_rest:Nw #1#2 \q_stop + { + \tl_if_in:NnTF \l__cooking_units_value_signs_tl {#1} + { \tl_put_right:Nn \l_tmpa_tl {#1} } + { + \tl_map_function:nN {#1} \__cooking_units_parse_input_for_safety_aux:N + } + \bool_if:NF \l__cooking_units_error_bool + { \tl_map_function:nN {#2} \__cooking_units_parse_input_for_safety_aux:N } + } +\cs_new:Npn \__cooking_units_parse_input_for_safety_aux:N #1 + { + \tl_if_in:NnTF \l__cooking_units_input_digits_tl {#1} + { \tl_put_right:Nn \l_tmpa_tl {#1} } + { + \tl_if_in:NnTF \l__cooking_units_decimal_mark_tl {#1} + { + \bool_if:NT \l__cooking_units_decimal_in_input_bool + { + \msg_error:nn { cooking-units } + { Second - decimal -sign - not - allowed } + } + \bool_set_true:N \l__cooking_units_decimal_in_input_bool + \tl_put_right:Nn \l_tmpa_tl { . } + }{ + \tl_if_in:NnTF \l__cooking_units_allowed_special_signs_tl {#1} + { + \bool_set_true:N \l__cooking_units_special_sign_bool + \tl_put_right:Nn \l_tmpa_tl {#1} + }{ + \bool_if:NTF \l__cooking_units_parse_range_bool + { + \tl_if_in:nnTF { / _ } {#1} + { \msg_error:nnn { cooking-units } { fraction-not-allowed-with-range } {#1} } + { \msg_error:nnn { cooking-units } { Token-not-allowed } {#1} } + } + { + \tl_if_in:nnTF { _ } {#1} + { \msg_error:nnn { cooking-units } { missing-slash } {#1} } + { \msg_error:nnn { cooking-units } { Token-not-allowed } {#1} } + } + \bool_set_true:N \l__cooking_units_error_bool + \tl_map_break: + } + } + } + } +\cs_new:Npn \__cooking_units_calculate_and_print_input:n #1 + { + \bool_if:NTF \l__cooking_units_error_bool + {#1} + { + \bool_if:NTF \l__cooking_units_special_sign_bool + { + \tl_set:Nf \l_tmpa_tl {#1} + \msg_warning:nnx { cooking-units } { amount-not-known } \l_tmpa_tl + } + { + \__cooking_units_calculate_input_and_store_in:nN {#1} \l_tmpa_tl + \__cooking_units_check_temperature_limit:N \l_tmpa_tl + } + \__cooking_units_print_nummerical_output:N \l_tmpa_tl + } + } +\cs_generate_variant:Nn \__cooking_units_calculate_and_print_input:n { N } +\cs_new:Npn \__cooking_units_calculate_input_and_store_in:nN #1#2 + { + \fp_set:Nn \l_tmpa_fp {#1} + \tl_if_in:cnTF { l__cooking_units_tmpa_ \l__cooking_units_tmp_unit_tl _ tl } { \l_tmpa_fp } + { + \tl_set:Nf #2 + { + \fp_eval:c { l__cooking_units_tmpa_ \l__cooking_units_tmp_unit_tl _ tl } + } + }{ + \tl_set:Nf #2 + { + \fp_eval:n + { + \l_tmpa_fp * + \tl_use:c { l__cooking_units_tmpa_ \l__cooking_units_tmp_unit_tl _ tl } + } + } + } + \__cooking_units_round_calculated_input:NV #2 #2 + } +\cs_generate_variant:Nn \__cooking_units_calculate_input_and_store_in:nN { V } +\cs_new:Npn \__cooking_units_get_number_after_dot:n #1 + { + \__cooking_units_get_number_after_dot_aux:w #1 . \q_recursion_tail . + \q_recursion_stop + } +\cs_new:Npn \__cooking_units_get_number_after_dot_aux:w #1. #2 . + { + \quark_if_recursion_tail_stop_do:nn {#2} + { \bool_set_false:N \l_tmpa_bool } + \int_compare:nNnTF { \tl_count:n {#2} } < {\l__cooking_units_significant_figures_plus_one_int } + { \bool_set_false:N \l_tmpa_bool } + { \bool_set_true:N \l_tmpa_bool } + \use_none_delimit_by_q_recursion_stop:w + } +\cs_new:Npn \__cooking_units_round_calculated_input:NN #1#2 + { + \__cooking_units_get_number_after_dot:n {#2} + \tl_set:Nf #1 + { + \bool_if:nTF { \l_tmpa_bool || \l__cooking_units_round_to_int_bool } + { + \fp_eval:n + { + \bool_if:NTF \l__cooking_units_round_to_int_bool + { round (#2) } + { + round( #2 , \l__cooking_units_significant_figures_int ) + } + } + } + {#2} + } + } +\cs_generate_variant:Nn \__cooking_units_round_calculated_input:NN { NV } +\cs_new:Npn \__cooking_units_formatiere_fractions:nnn #1#2#3 + { + \bool_set_true:N \l__cooking_units_fraction_in_input_bool + \tl_if_blank:nF {#1} + { + #1 + \hbox_to_wd:nn { \l__cooking_units_mixed_frac_dim } { } + } + \__cooking_units_frac:nn {#2} {#3} + } +\cs_new:Npn \__cooking_units_check_temperature_limit:N #1 + { + \bool_if:NT \l__cooking_units_check_temperature_bool + { + \clist_if_in:nVT { C , F , K , Re } \l__cooking_units_option_unit_tl + { + \fp_compare:cNnT + { c__cooking_units_ \l__cooking_units_option_unit_tl _min_fp } > {#1} + { + \msg_error:nnxx { cooking-units } + { Temperature-to-low } + { #1 \space \l__cooking_units_option_unit_tl } + { + \fp_use:c { c__cooking_units_ \l__cooking_units_option_unit_tl _min_fp } + \space \l__cooking_units_option_unit_tl + } + } + } + } + } +\cs_new_protected:Npn \__cooking_units_print_nummerical_output:N #1 + { +%% \l_@@_tmpa_tl is sehr gefaehrlich hier. + \translatelet \l__cooking_units_tmpa_tl { decimal-mark ( cu-unit name ) } + \tl_replace_once:NnV #1 { . } \l__cooking_units_tmpa_tl + \tl_replace_once:NnV #1 { - } \c__cooking_units_minus_tl + #1 + } +\NewDocumentCommand \cunum { O{} m O{} m } + { + \group_begin: + \__cooking_units_cunum_initialise:nnnn {#1} {#2} {#3} {#4} + \bool_if:NTF \l__cooking_units_parse_input_bool + { \__cooking_units_cunum:nnVV {#2} {#3} \l__cooking_units_option_unit_tl \l__cooking_units_tmp_unit_tl } + { \__cooking_units_cunum_do_not_parse:nnn {#2} {#3} {#4} } + \group_end: + } +\cs_new_protected:Npn \__cooking_units_cunum_initialise:nnnn #1#2#3#4 + { + \tl_set:Nn \l__cooking_units_tmp_unit_tl {#4} + \__cooking_units_error_if_unit_not_defined:V \l__cooking_units_tmp_unit_tl + \bool_if:NTF \l__cooking_units_convert_to_eV_bool + { \__cooking_units_convert_to_eV: } + { + \keys_set_groups:nnn { cooking-units } { change-unit } {#1} + \prop_get:NVN \l__cooking_units_change_unit_prop \l__cooking_units_tmp_unit_tl \l__cooking_units_option_unit_tl + \quark_if_no_value:NT \l__cooking_units_option_unit_tl + { + \tl_set_eq:NN \l__cooking_units_option_unit_tl \l__cooking_units_tmp_unit_tl + } + \keys_set_filter:nnv + { cooking-units } + { change-unit } + { l__cooking_units_predefined_option_ \l__cooking_units_option_unit_tl _clist } + \keys_set_filter:nnn { cooking-units } { change-unit } {#1} + } + \bool_set_false:N \l__cooking_units_special_sign_bool + \bool_set_false:N \l__cooking_units_error_bool + \bool_set_false:N \l__cooking_units_parse_range_bool + } +\cs_new:Npn \__cooking_units_cunum_do_not_parse:nnn #1#2#3 + { + \tl_set_rescan:Nnn \l_tmpa_tl + { + \char_set_catcode_letter:N \_ % + \char_set_catcode_ignore:N \ % + } {#1} + \l_tmpa_tl + \__cooking_units_cunum_print_correct_unit:nnn {#2} {#3} {#3} + } +\cs_new:Npn \__cooking_units_cunum:nnNN #1#2#3#4 + { + \tl_set_rescan:Nnn \l_tmpa_tl + { + \char_set_catcode_letter:N \_ % + \char_set_catcode_ignore:N \ % + \char_set_catcode_other:N ? % + } {#1} + \tl_if_empty:VF \l_tmpa_tl + { + \tl_if_in:NVT \l_tmpa_tl \l__cooking_units_input_range_sign_tl + { \tl_replace_once:NVn \l_tmpa_tl \l__cooking_units_input_range_sign_tl { \q__cooking_units_range } } + \__cooking_units_cunum_parse_input:V \l_tmpa_tl + } + \__cooking_units_cunum_print_correct_unit:nnn {#2} {#3} {#4} + } +\cs_generate_variant:Nn \__cooking_units_cunum:nnNN { nnVV } +\cs_new:Npn \__cooking_units_cunum_print_correct_unit:nnn #1#2#3 + { + \phantom {#1} + \tl_use:N \l__cooking_units_value_unit_space_tl + \bool_if:nTF + { + \l__cooking_units_fraction_in_input_bool || + \l__cooking_units_special_sign_bool + } + { \translate { #3 ( cu-unit ) } } + { \translate { #2 ( cu-unit ) } } + } +\NewDocumentCommand \cudefinekeys { m m } + { + \bool_set_false:N \l__cooking_units_single_key_bool + \cukeys_define_keys_and_single_keys:nn {#1} {#2} + } +\NewDocumentCommand \cudefinesinglekey { m m } + { + \bool_set_true:N \l__cooking_units_single_key_bool + \cukeys_define_keys_and_single_keys:nn {#1} {#2} + } +\cs_new:Npn \cukeys_define_keys_and_single_keys:nn #1#2 + { + \__cooking_units_error_if_unit_not_defined:n {#1} + \tl_if_blank:nF {#2} + { + \clist_clear:N \l_tmpa_clist + \prop_clear:N \l_tmpa_prop + \bool_if:NTF \l__cooking_units_single_key_bool + { + \__cooking_units_cukeys_parse_and_create_single_key:nn {#1} {#2} + }{ + \fp_set_eq:NN \l_tmpa_fp \c_one_fp + \tl_set:Nn \l__cooking_units_tmp_unit_tl {#1} + \__cooking_units_cukeys_parse_and_create_keys:nn {#1} + { + {#1} { \c_one_fp } #2 + } + } + } + } +\cs_new:Npn \__cooking_units_cukeys_parse_and_create_keys:nn #1#2 + { + \__cooking_units_cukeys_parse_input:nn #2 + \q_recursion_tail \q_recursion_tail \q_recursion_stop + \__cooking_units_cukeys_create_key_prop:n {#1} + \__cooking_units_cukeys_define_keys:V \l_tmpa_clist + } +\cs_new:Npn \__cooking_units_cukeys_parse_input:nn #1#2 + { + \quark_if_recursion_tail_stop:n {#1} + \quark_if_recursion_tail_stop_do:nn {#2} + { \msg_error:nn { cooking-units } { missing-argument } } + \__cooking_units_error_if_unit_not_defined:n {#1} + \clist_put_right:Nn \l_tmpa_clist {#1} + \prop_put:Nnx \l_tmpa_prop {#1} { \fp_eval:n { #2 / \l_tmpa_fp } } + \__cooking_units_cukeys_parse_input:nn + } +\cs_new:Npn \__cooking_units_cukeys_create_key_prop:n #1 + { + \clist_map_inline:Nn \l_tmpa_clist + { + \prop_clear_new:c { l__cooking_units_cukeys_ ##1 _prop } + \tl_clear_new:c { l__cooking_units_tmpa_ ##1 _tl } + \tl_set_eq:cN { l__cooking_units_tmpa_ ##1 _tl } \c_one_fp + \prop_put:cnV { l__cooking_units_cukeys_ ##1 _prop } { Liste } \l_tmpa_clist + \prop_put:cnV { l__cooking_units_cukeys_ ##1 _prop } { prop } \l_tmpa_prop + \prop_put:cnV { l__cooking_units_cukeys_ ##1 _prop } { Erstes Ding } \l__cooking_units_tmp_unit_tl + \clist_map_inline:Nn \l_tmpa_clist + { + \prop_put:cnx { l__cooking_units_cukeys_ ##1 _prop } + {####1} + { + \fp_eval:n + { \prop_item:Nn \l_tmpa_prop {####1} / \prop_item:Nn \l_tmpa_prop {##1} } + } + } + } + } +\cs_new:Npn \__cooking_units_cukeys_define_keys:N #1 + { + \clist_map_inline:Nn \l_tmpa_clist + { + \clist_put_right:Nn \l__cooking_units_list_of_defined_keys_clist {##1} + \keys_define:nn { cooking-units } + { + ##1 .choices:Vn = + \l_tmpa_clist + { + \__cooking_units_cukeys_define_keys_and_single_key_aux:n {##1} + } , + ##1 / unknown .code:n= + { + \seq_set_split:Nnn \l_tmpa_seq { , } {#1} + \msg_error:nnxxx + { cooking-units } + { key-choice-unknown } + {##1} + {####1} + { \seq_use:Nnnn \l_tmpa_seq { ',' } { ',' } { ' ~ and ~ ' } } + } , + ##1 .default:n = {##1} , + ##1 .groups:n = { change-unit } + } + } + \clist_remove_duplicates:N \l__cooking_units_list_of_defined_keys_clist + } +\cs_generate_variant:Nn \__cooking_units_cukeys_define_keys:N { V } +\cs_new:Npn \__cooking_units_cukeys_define_keys_and_single_key_aux:n #1 + { + \prop_get:cVN + { l__cooking_units_cukeys_#1_prop } + \l_keys_choice_tl + \l_tmpa_tl + \tl_set:cV { l__cooking_units_tmpa_ #1_tl } \l_tmpa_tl + \prop_put:NnV \l__cooking_units_change_unit_prop {#1} \l_keys_choice_tl + } +\cs_new:Npn \__cooking_units_cukeys_parse_and_create_single_key:nn #1#2 + { + \tl_set_rescan:Nnn \l_tmpa_tl + { + \char_set_catcode_letter:N \# % + \char_set_catcode_ignore:N\ % + } { {#1} { \c_one_fp } #2 } + \__cooking_units_cusinglekeys_parse_input:V \l_tmpa_tl + \__cooking_units_cusinglekeys_create_key_prop:n {#1} + \__cooking_units_cukeys_define_singlekey:nV {#1} \l_tmpa_clist + } +\cs_new:Npn \__cooking_units_cusinglekeys_parse_input:n #1 + { + \__cooking_units_cusinglekeys_parse_input_aux:nn #1 + \q_recursion_tail \q_recursion_tail \q_recursion_stop + } +\cs_generate_variant:Nn \__cooking_units_cusinglekeys_parse_input:n { V } +\cs_new:Npn \__cooking_units_cusinglekeys_parse_input_aux:nn #1#2 + { + \quark_if_recursion_tail_stop:n {#1} + \quark_if_recursion_tail_stop_do:nn {#2} + { \msg_error:nn { cooking-units } { missing-argument } } + \clist_put_right:Nn \l_tmpa_clist {#1} + \tl_set:Nn \l_tmpa_tl {#2} + \tl_replace_all:NVn \l_tmpa_tl \c__cooking_units_str_hash_one_tl { \l_tmpa_fp } + \prop_put:NnV \l_tmpa_prop {#1} \l_tmpa_tl + \__cooking_units_cusinglekeys_parse_input_aux:nn + } +\cs_new:Npn \__cooking_units_cusinglekeys_create_key_prop:n #1 + { + \prop_clear_new:c { l__cooking_units_cukeys_ #1 _prop } + \tl_set_eq:cN { l__cooking_units_tmpa_ #1 _tl } \c_one_fp + \prop_put:cnV { l__cooking_units_cukeys_ #1 _prop } { Liste } \l_tmpa_clist + \prop_put:cnV { l__cooking_units_cukeys_ #1 _prop } { prop } \l_tmpa_prop + \prop_put:cnn { l__cooking_units_cukeys_ #1 _prop } { Erstes Ding } {#1} + \prop_map_inline:Nn \l_tmpa_prop + { + \prop_put:cnn { l__cooking_units_cukeys_ #1 _prop } + {##1} + {##2} + } + } +\cs_new:Npn \__cooking_units_cukeys_define_singlekey:nN #1#2 + { + \clist_put_right:Nn \l__cooking_units_list_of_defined_keys_clist {#1} + \keys_define:nn { cooking-units } + { + #1 .choices:Vn = + \l_tmpa_clist + { + \__cooking_units_cukeys_define_keys_and_single_key_aux:n {#1} + } , + #1 / unknown .code:n= + { + \seq_set_split:Nnn \l_tmpa_seq { , } {#2} + \msg_error:nnxxx + { cooking-units } + { key-choice-unknown } + {#1} + {##1} + { \seq_use:Nnnn \l_tmpa_seq { ',' } { ',' } { ' ~ and ~ ' } } + } , + #1 .default:n = {#1} , + #1 .groups:n = { change-unit } , + } + \clist_remove_duplicates:N \l__cooking_units_list_of_defined_keys_clist + } +\cs_generate_variant:Nn \__cooking_units_cukeys_define_singlekey:nN { nV } +\NewDocumentCommand \cuaddkeys { m m } + { + \bool_set_false:N \l__cooking_units_single_key_bool + \tl_set:Nn \l_tmpa_tl {#1} + \tl_set:Nn \l_tmpb_tl {#2} + \__cooking_units_cukeys_add_keys_or_single_keys:VV \l_tmpa_tl \l_tmpb_tl + } +\NewDocumentCommand \cuaddsinglekeys { m m } + { + \bool_set_true:N \l__cooking_units_single_key_bool + \tl_set:Nn \l_tmpa_tl {#1} + \tl_set:Nn \l_tmpb_tl {#2} + \__cooking_units_cukeys_add_keys_or_single_keys:VV \l_tmpa_tl \l_tmpb_tl + } +\NewDocumentCommand \cuaddtokeys { m m m } + { + \bool_set_false:N \l__cooking_units_single_key_bool + \tl_set:Nn \l_tmpa_tl {#1} + \tl_set:Nn \l_tmpb_tl { {#2} { \fp_eval:n { \c_one_fp / #3 } } } + \__cooking_units_cukeys_add_keys_or_single_keys:VV \l_tmpa_tl \l_tmpb_tl + } +\cs_new:Npn \__cooking_units_cukeys_add_keys_or_single_keys:nn #1#2 + { + \__cooking_units_error_if_unit_not_defined:n {#1} + \clist_if_in:NnF \l__cooking_units_list_of_defined_keys_clist {#1} + { \msg_error:nnn { cooking-units } { Key - not - defined } {#1} } + \tl_if_blank:nF {#2} + { + \__cooking_units_cukeys_add_keys_and_single_key_aux:n {#1} + \bool_if:NTF \l__cooking_units_single_key_bool + { \__cooking_units_cukeys_parse_and_create_single_key:nn {#1} {#2} } + { \__cooking_units_cukeys_parse_and_create_keys:nn {#1} {#2} } + } + } +\cs_generate_variant:Nn \__cooking_units_cukeys_add_keys_or_single_keys:nn { VV } +\cs_new:Npn \__cooking_units_cukeys_add_keys_and_single_key_aux:n #1 + { + \prop_get:cnN { l__cooking_units_cukeys_ #1 _prop } { Liste } \l_tmpa_clist + \prop_get:cnN { l__cooking_units_cukeys_ #1 _prop } { prop } \l_tmpa_prop + \prop_get:cnN { l__cooking_units_cukeys_ #1 _prop } { Erstes Ding } \l__cooking_units_tmp_unit_tl + \prop_get:cVN { l__cooking_units_cukeys_ #1 _prop } \l__cooking_units_tmp_unit_tl \l_tmpa_fp + } +\NewDocumentCommand \newcookingunit { o m } + { + \__cooking_units_new_cooking_unit:nn {#1} {#2} + } +\cs_new:Npn \__cooking_units_new_cooking_unit:nn #1#2 + { + \clist_if_in:NnTF \g__cooking_units_list_of_defined_units_clist {#2} + { \msg_error:nnn { cooking-units } { unit-already-defined } {#2} } + { + \tl_new:c { l__cooking_units_tmpa_ #2 _tl } + \tl_set_eq:cN { l__cooking_units_tmpa_ #2 _tl } \c_one_fp + \clist_put_right:Nn \g__cooking_units_list_of_defined_units_clist {#2} + \clist_new:c { l__cooking_units_predefined_option_#2_clist } + \keys_define:nn { cooking - units } + { + set-option-for-#2 .clist_set:c = { l__cooking_units_predefined_option_#2_clist } , + add-option-for-#2 .code:n = + { \clist_put_right:cn { l__cooking_units_predefined_option_#2_clist } {##1} }, + } + \prop_new:c { l__cooking_units_cukeys_ #2 _prop } + \IfNoValueTF {#1} + { + \newtranslation { #2 ( cu-unit ) } {#2} + }{ + \newtranslation { #2 ( cu-unit ) } {#1} + } + } + } +\NewDocumentCommand \cutext { O{} m m } + { + \group_begin: + \__cooking_units_cutext_default:nnn {#1} {#2} {#3} + \__cooking_units_cutext_print_correct_unitname:nn {#2} {#3} + \group_end: + } +\NewDocumentCommand \Cutext { O{} m m } + { + \group_begin: + \bool_set_true:N \l__cooking_units_cutext_uppercase_word_bool + \__cooking_units_cutext_default:nnn {#1} {#2} {#3} + \__cooking_units_cutext_print_correct_unitname:nn {#2} {#3} + \group_end: + } +\cs_new:Npn \__cooking_units_cutext_default:nnn #1#2#3 + { + \__cooking_units_error_if_unit_not_defined:n {#3} + \keys_set:nn { cooking-units } {#1} + \bool_if:NT \l__cooking_units_convert_to_eV_bool + { \__cooking_units_convert_to_eV: } + \bool_if:NTF \l__cooking_units_parse_input_bool + { + \tl_set:Nn \l_tmpb_tl {#2} + \tl_replace_once:Nnn \l_tmpb_tl { -- } { \q__cooking_units_range } + \tl_if_in:NnTF \l_tmpb_tl \q__cooking_units_range + { \__cooking_units_cunum_parse_range:Vn \l_tmpb_tl {#3} } + { \__cooking_units_cutext_print_nummerical_output:Nn \l_tmpb_tl {#3} } + } + {#2} + } +\cs_new:Npn \__cooking_units_cunum_parse_range:Nn #1 #2 + { + \__cooking_units_cunum_parse_range_aux:nww {#2} #1 \q_stop + } +\cs_generate_variant:Nn \__cooking_units_cunum_parse_range:Nn { V } +\cs_new:Npn \__cooking_units_cunum_parse_range_aux:nww #1 #2 \q__cooking_units_range #3 \q_stop + { + \tl_set:Nn \l__cooking_units_tmpa_tl {#2} + \tl_set:Nn \l__cooking_units_tmpb_tl {#3} + \__cooking_units_cutext_print_nummerical_output:Nn \l__cooking_units_tmpa_tl {#1} + \tl_use:N \l__cooking_units_cutext_range_sign_tl + \__cooking_units_cutext_print_nummerical_output:Nn \l__cooking_units_tmpb_tl {#1} + } +\cs_new:Npn \__cooking_units_cutext_just_print_number_correctly:N #1 + { + \translatelet \l_tmpa_tl { decimal-mark ( cu-unit name ) } + \tl_replace_once:NnV #1 { . } \l_tmpa_tl + \tl_replace_once:NnV #1 { - } \c__cooking_units_minus_tl + #1 + } +\cs_new_protected:Npn \__cooking_units_cutext_print_nummerical_output:Nn #1#2 + { + \bool_if:NTF \g__cooking_units_load_if_opt_numeral_bool + { + \__cooking_units_if_integer_and_parse:VTF #1 + { + \fp_compare:nNnTF {#1} < { \l__cooking_units_print_numerals_below_int } + { + \fp_compare:nNnTF {#1} = { \c_one_fp } + { + \translatelet \l_tmpa_tl { #2 (cu-unitgender) } + \translatelet \l_tmpa_tl { one (\l_tmpa_tl) (cu-unitname) } + \bool_if:NTF \l__cooking_units_cutext_uppercase_word_bool + { + \exp_args:Nf \tl_to_uppercase:n { \tl_head:V \l_tmpa_tl } + \tl_tail:V \l_tmpa_tl + } + { \l_tmpa_tl } + }{ + \bool_if:NTF \l__cooking_units_cutext_uppercase_word_bool + { \Numberstringnum {#1} } + { \numberstringnum {#1} } + } + }{ \__cooking_units_cutext_just_print_number_correctly:N #1 } + }{ \__cooking_units_cutext_just_print_number_correctly:N #1 } + } + { \__cooking_units_cutext_just_print_number_correctly:N #1 } + } +\cs_new:Npn \__cooking_units_cutext_print_correct_unitname:nn #1#2 + { + \space + \__cooking_units_if_integer_and_parse:nTF {#1} + { + \fp_compare:nNnTF {#1} = { \c_one_fp } + { \translate { #2 (cu-unitname) } } + { \translate { #2 (cu-unitname pl) } } + }{ + \translate { #2 (cu-unitname pl) } + } + } +\NewDocumentCommand \cufrac { O{} m } + { + \group_begin: + \keys_set:nn { cooking-units } {#1} + \__cooking_units_cufrac:n {#2} + \group_end: + } +\cs_new:Npn \__cooking_units_cufrac:n #1 + { + \tl_set_rescan:Nnn \l_tmpa_tl + { + \char_set_catcode_letter:N \_ % + \char_set_catcode_ignore:N\ % + } {#1} + \__cooking_units_cufrac_parse:V \l_tmpa_tl + } +\cs_new:Npn \__cooking_units_cufrac_parse:n #1 + { + \tl_if_in:nnTF {#1} { / } + { + \tl_if_in:nnTF {#1} { _ } + { \__cooking_units_cufrac_parse_mixed_frac:www #1 \q_stop } + { \__cooking_units_cufrac_parse_frac:ww #1 \q_stop } + }{ + \tl_if_in:nnTF {#1} { _ } + { \msg_error:nnn { cooking-units } { missing-slash } {#1} } + { \__cooking_units_cufrac_parse_scale:n {#1} } + } + } +\cs_generate_variant:Nn \__cooking_units_cufrac_parse:n { V } +\cs_new:Npn \__cooking_units_cufrac_parse_scale:n #1 {#1} +\cs_new:Npn \__cooking_units_cufrac_parse_frac:ww #1/#2 \q_stop + { \__cooking_units_frac:nn {#1} {#2} } +\cs_new:Npn \__cooking_units_cufrac_parse_mixed_frac:www #1_#2/#3 \q_stop + { + #1 + \hbox_to_wd:nn { \l__cooking_units_mixed_frac_dim } { } + \__cooking_units_frac:nn {#2} {#3} + } +\NewDocumentCommand \cudefinename { m m } + { + \tl_set:Nn \l__cooking_units_language_tl {#1} + \__cooking_units_cuname_parse_input:n #2 + \q_recursion_tail \q_recursion_tail \q_recursion_stop + } +\cs_new:Npn \__cooking_units_cuname_parse_input:n #1 + { + \peek_meaning_ignore_spaces:NTF [ + { \__cooking_units_cuname_parse_unit_symbol:nw {#1} } + { \__cooking_units_cuname_parse_input_aux:nn {#1} } + } +\cs_new:Npn \__cooking_units_cuname_parse_unit_symbol:nw #1 [#2] + { + \quark_if_recursion_tail_stop:n {#1} + \quark_if_recursion_tail_stop_do:nn {#2} + { \msg_error:nn { cooking-units } { missing-argument } } + \__cooking_units_error_if_unit_not_defined:n {#1} + \deftranslation [ to=\l__cooking_units_language_tl ] { #1 ( cu-unit ) } {#2} + \__cooking_units_cuname_parse_input_aux:nn {#1} + } +\cs_new:Npn \__cooking_units_cuname_parse_input_aux:nn #1#2 + { + \quark_if_recursion_tail_stop:n {#1} + \quark_if_recursion_tail_stop_do:nn {#2} + { \msg_error:nn { cooking-units } { missing-argument } } + \clist_if_in:NnF \g__cooking_units_allowed_unit_phrases_clist {#1} + { \__cooking_units_error_if_unit_not_defined:n {#1} } + \deftranslation [ to=\l__cooking_units_language_tl ] { #1 (cu-unitname) } {#2} + \peek_meaning_ignore_spaces:NTF [ + { \__cooking_units_cuname_parse_bracket:nw {#1} } + { \__cooking_units_cuname_parse_bracket:nw {#1} [#2] } + } +\cs_new:Npn \__cooking_units_cuname_parse_bracket:nw #1 [#2] + { + \deftranslation [ to=\l__cooking_units_language_tl ] { #1 ( cu-unitname pl ) } {#2} + \peek_meaning_ignore_spaces:NTF < + { \__cooking_units_cuname_parse_arrows:nw {#1} } + { \__cooking_units_cuname_parse_arrows:nw {#1} <m> } + } +\cs_new:Npn \__cooking_units_cuname_parse_arrows:nw #1 <#2> + { + \deftranslation [ to=\l__cooking_units_language_tl ] { #1 ( cu-unitgender ) } {#2} + \__cooking_units_cuname_parse_input:n + } +\NewDocumentCommand \cudefinesymbol { m m } + { + \tl_set:Nn \l__cooking_units_language_tl {#1} + \__cooking_units_cuprint_define_printed_unit:nn #2 + \q_recursion_tail \q_recursion_tail \q_recursion_stop + } +\cs_new:Npn \__cooking_units_cuprint_define_printed_unit:nn #1#2 + { + \quark_if_recursion_tail_stop:n {#1} + \quark_if_recursion_tail_stop_do:nn {#2} + { \msg_error:nn { cooking-units } { missing-argument } } + \clist_if_in:NnF \g__cooking_units_allowed_unit_phrases_clist {#1} + { \__cooking_units_error_if_unit_not_defined:n {#1} } + \deftranslation [ to=\l__cooking_units_language_tl ] { #1 ( cu-unit ) } {#2} + \__cooking_units_cuprint_define_printed_unit:nn + } +\NewDocumentCommand \cusetup { m } + { + \keys_set:nn { cooking-units } {#1} + } +\newcookingunit { kg } +\newcookingunit { dag } +\newcookingunit { g } +\newcookingunit { oz } +\newcookingunit { lb } +\newcookingunit [ \ensuremath{ \__cooking_units_frac:nn { eV } { c^2 } } ] { eVc-2 } +\newcookingunit [ \ensuremath{ {} ^ { \circ } } \kern-\scriptspace C ] { C } +\newcookingunit { K } +\newcookingunit [ \ensuremath{ {} ^ { \circ } } \kern-\scriptspace F ] { F } +\newcookingunit [ \ensuremath{ {} ^ { \circ } } \kern-\scriptspace R\'{e} ] { Re } +\newcookingunit { d } +\newcookingunit { h } +\newcookingunit { min } +\newcookingunit { s } +\newcookingunit [ \ensuremath{ \__cooking_units_frac:nn { \hbar } { eV } } ] { hbareV-1 } +\newcookingunit { m } +\newcookingunit { cm } +\newcookingunit { dm } +\newcookingunit { mm } +\newcookingunit { in } +\newcookingunit [ \ensuremath{ \__cooking_units_frac:nn { c\hbar } { eV } } ] { chbareV-1 } +\newcookingunit { l } +\newcookingunit { dl } +\newcookingunit { cl } +\newcookingunit { ml } +\newcookingunit [ \ensuremath { \__cooking_units_frac:nn { c^3 \hbar^3 } { eV^3 } } ] { (chbareV-1)3 } +\newcookingunit { cal } +\newcookingunit { kcal } +\newcookingunit { J } +\newcookingunit { kJ } +\newcookingunit { eV } +\newcookingunit [ Msp. ] { Msp } +\newcookingunit { EL } +\newcookingunit { TL } +\cudefinename { German } + { + { kg } { Kilogramm } < n > + { dag } { Dekagramm } < n > + { g } { Gramm } < n > + { oz } { Unze } < f > + { lb } { Pfund } < n > + { d } { Tag } [ Tage ] + { h } { Stunde } [ Stunden ] < f > + { min } { Minute } [ Minuten ] < f > + { s } { Sekunde } [ Sekunden ] < f > + { C } { Grad \space Celsius } + { K } { Kelvin } < n > + { F } { Grad \space Fahrenheit } + { Re } { Grad \space R\'{e}amur } + { m } { Meter } < n > + { dm } { Dezimeter } < n > + { cm } { Centimeter } < n > + { mm } { Millimeter } < n > + { in } { Zoll } + { l } { Liter } + { dl } { Deziliter } + { cl } { Centiliter } + { ml } { Milliliter } + { cal } { Kalorie } [ Kalorien ] < f > + { kcal } { Kilokalorie } [ Kilokalorien ] < f > + { J } { Joule } + { kJ } { Kilojoule } + { eV } { ELektronenvolt } < n > + { Msp } [ Msp. ] { Messerspitze } [ Messerspitzen ] < f > + { EL } [ EL ] { Essl{\"o}ffel } + { TL } [ TL ] { Teel{\"o}ffel } + { decimal-mark } { , } + { one (m) } { ein } + { one (f) } { eine } + { one (n) } { ein } + } +\cudefinename { English } + { + { kg } { kilogramme } + { dag } { decagramme } + { g } { gramme } + { oz } { ounce } + { lb } { pound } [ pounds ] + { d } { day } [ days ] + { h } { hour } [ hours ] + { min } { minute } [ minutes ] + { s } { second } [ seconds ] + { C } { degree \space Celsius } [ degrees \space Celsius ] + { F } { degree \space Fahrenheit } [ degrees \space Fahrenheit ] + { K } { kelvin } + { Re } { degree \space R\'{e}aumur } [ degrees \space R\'{e}aumur ] + { m } { metre } [ metres ] + { dm } { decimetre } [ decimetres ] + { cm } { centimetre } [ centimetres ] + { mm } { millimitre } [ millimitres ] + { in } { inch } [ inches ] + { l } { litre } [ litres ] + { dl } { decilitre } [ decilitres ] + { cl } { centilitre } [ centilitres ] + { ml } { millilitre } [ millilitres ] + { cal } { calorie } [ calories ] + { kcal } { kilocalorie } [ kilocalories ] + { J } { joule } [ joules ] + { kJ } { kilojoule } [ kilojoules ] + { eV } { electron \space volt } + { Msp } [ pn ] { pinch } [ pinches ] + { EL } [ tsp. ] { tablespoon } [ tablespoons ] + { TL } [ tbsp. ] { teaspoon } [ teaspoons ] + { decimal-mark } { . } + { one (m) } { one } + { one (f) } { one } + { one (n) } { one } + } +\cudefinename { AmericanEnglish } + { + { kg } { kilogram } + { dag } { decagram } + { g } { gram } + { oz } { ounce } + { m } { meter } [ meters ] + { dm } { decimeter } [ decimeters ] + { cm } { centimeter } [ centimeters ] + { mm } { millimiter } [ millimiters ] + { in } { inch } [ inches ] + { l } { liter } [ liters ] + { dl } { deciliter } [ deciliters ] + { cl } { centiliter } [ centiliters ] + { ml } { milliliter } [ milliliters ] + } +\cudefinename { French } + { + { kg } { kilogramme } [ kilogrammes ] + { dag } { d\'{e}cagramme } [ d\'{e}cagrammes] + { g } { gramme } [ gramme ] + { oz } { once } < f > + { lb } { livre } [ livres ] < f > + { d } { jour } [ jours ] + { h } { heure } [ heures ] < f > + { min } { minute } [ minutes ] < f > + { s } { seconde } [ secondes ] < f > + { C } { degr\'{e} \space Celsius } [ degr\'{e}s \space Celsius ] + { K } { degr\'{e} \space Fahrenheit } [ degr\'{e}s \space Fahrenheit ] + { F } { kelvin } [ kelvins ] + { Re } { \'{e}chelle \space R\'{e}aumur } [ degr\'{e}s \space R\'{e}aumur ] + { m } { m\`{e}tre } [ m\`{e}tres ] + { dm } { d\'{e}cim\`{e}tre } [ d\'{e}cim\`{e}tres ] + { cm } { centim\`{e}tre } [ centim\`{e}tres ] + { mm } { millim\`{e}tre } [ millim\`{e}tre ] + { l } [ L ] { litre } [ litres ] + { dl } [ dL ] { d\'{e}cilitre } [ d\'{e}cilitres ] + { cl } [ cL ] { centilitre } [ centilitres ] + { ml } [ mL ] { millilitre } [ millilitres ] + { cal } { calorie } [ calorie ] + { kcal } { kilocalorie } [ kilocalories ] + { J } { joule } [ joules ] + { kJ } { kilojoule } [ kilojoules ] + { eV } { \'{e}lectron-volt } [ \'{e}lectron-volts ] + { Msp } { pinc\'{e}e } < f > + { EL } { cuill\'{e}re \space \`{a} \space soupe } < f > + { TL } { cuill\'{e}re \space \`{a} \space caf\'{e} } < f > + { decimal-mark } { . } + { one (m) } { un } + { one (f) } { une } + { one (n) } { un } + } +\cudefinekeys { kg } + { + { dag }{ 100 } + { g } { 1000 } + { oz } { 35.27399 } + { lb } { 2.204 622 6 } %% 2.204 622 6 + } +\cuaddtokeys { kg } { eVc-2 } { 1.78266173e-16 } +\cudefinekeys { d } + { + { h } { 24 } + { min }{ 1440 } + { s } { 86400 } + } +\cuaddtokeys { s } { hbareV-1 } { 6.582119514e-16 } +\cudefinekeys { m } + { + { dm } { 10 } + { cm } { 100 } + { mm } { 1000 } + { in } { 39.370079 } + } +\cuaddtokeys { m } { chbareV-1 } { 1.97326972e-7 } +\cudefinekeys { l } + { + { dl } { 10 } + { cl } { 100 } + { ml }{ 1000 } + { (chbareV-1)3 } { 1.30148943e+17 } + } +\cudefinekeys { J } + { + { kJ }{ 1e-3 } + { cal }{ 0.2388459 } + { kcal }{ 0.2388459e-3 } + } +\cuaddtokeys { J } { eV } { 1.6021766208e-19 } +\fp_const:Nn \c__cooking_units_kb_eV_fp { 8.617 330 3 e-5 } +\cudefinesinglekey { C } + { + { F } { #1 * 1.8 + 32 } + { K } { #1 + 273.15 } + { Re } { #1 * 0.8 } + { eV } { ( #1 + 273.15 ) * \c__cooking_units_kb_eV_fp } + } +\cudefinesinglekey { F } + { + { C } { ( #1 - 32 ) * 5/9 } + { K } { ( #1 + 459.67 ) * 5/9 } + { Re } { ( #1 - 32 ) * 4/9 } + { eV } {( #1 + 459.67 ) * 5/9 * \c__cooking_units_kb_eV_fp } + } +\cudefinesinglekey { K } + { + { C } { #1 - 273.15 } + { F } { #1 * 1.8 - 459.67 } + { Re } { ( #1 - 273.15 ) * 0.8 } + { eV } { #1 * \c__cooking_units_kb_eV_fp } + } +\cudefinesinglekey { Re } + { + { K } { #1 * 1.25 + 273.15 } + { C } { #1 * 1.25 } + { F } { #1 * 2.25 + 32 } + { eV } { ( #1 - 273.15 ) * 1.25 * \c__cooking_units_kb_eV_fp } + } +\fp_const:Nn \c__cooking_units_K_min_fp { 0 } +\fp_const:Nn \c__cooking_units_C_min_fp { -273.15 } +\fp_const:Nn \c__cooking_units_F_min_fp { -459.67 } +\fp_const:Nn \c__cooking_units_Re_min_fp { -218.52 } +\cusetup + { + set-option-for-F = { round-to-int = true } , + set-option-for-C = { round-to-int = true } , + set-option-for-K = { round-to-int = true } , + set-option-for-Re = { round-to-int = true } , + } + +\endinput +%% +%% End of file `cooking-units.sty'. diff --git a/Master/tlpkg/bin/tlpkg-ctan-check b/Master/tlpkg/bin/tlpkg-ctan-check index 8ed24810098..69daf0d9afb 100755 --- a/Master/tlpkg/bin/tlpkg-ctan-check +++ b/Master/tlpkg/bin/tlpkg-ctan-check @@ -166,7 +166,8 @@ my @TLP_working = qw( context-transliterator context-typearea context-typescripts context-vim context-visualcounter continue contour contracard convbkmk - cooking cookingsymbols cool coollist coolstr coolthms cooltooltips + cooking cooking-units cookingsymbols + cool coollist coolstr coolthms cooltooltips coordsys copyedit copyrightbox cormorantgaramond coseoul countriesofeurope counttexruns courier-scaled courseoutline coursepaper coverpage covington diff --git a/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc b/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc index 2f254de6596..5485e312150 100644 --- a/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc +++ b/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc @@ -179,6 +179,7 @@ depend continue depend contour depend contracard depend cooking +depend cooking-units depend cool depend coollist depend coolstr diff --git a/Master/tlpkg/tlpsrc/cooking-units.tlpsrc b/Master/tlpkg/tlpsrc/cooking-units.tlpsrc new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/Master/tlpkg/tlpsrc/cooking-units.tlpsrc |