From 5cb65e963600d41f6c7dfb5161fa72448479d048 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Wed, 3 Feb 2016 22:58:23 +0000 Subject: smartunits (3feb16) git-svn-id: svn://tug.org/texlive/trunk@39556 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/doc/latex/smartunits/README.md | 53 +++ .../texmf-dist/doc/latex/smartunits/smartunits.pdf | Bin 0 -> 331493 bytes .../texmf-dist/doc/latex/smartunits/smartunits.tex | 415 +++++++++++++++++++++ 3 files changed, 468 insertions(+) create mode 100644 Master/texmf-dist/doc/latex/smartunits/README.md create mode 100644 Master/texmf-dist/doc/latex/smartunits/smartunits.pdf create mode 100644 Master/texmf-dist/doc/latex/smartunits/smartunits.tex (limited to 'Master/texmf-dist/doc/latex/smartunits') diff --git a/Master/texmf-dist/doc/latex/smartunits/README.md b/Master/texmf-dist/doc/latex/smartunits/README.md new file mode 100644 index 00000000000..1942639f661 --- /dev/null +++ b/Master/texmf-dist/doc/latex/smartunits/README.md @@ -0,0 +1,53 @@ +smartunits +========== + +A [LaTeX](http://en.wikipedia.org/wiki/LaTeX) package that implements +automatic conversions between (some) metric and Imperial units. + +Example +------- + +```tex +\documentclass{article} +\usepackage{smartunits} +\begin{document} + \SmartUnitSettings{metric imperial, places=1} + \SmartUnit{cm=10} % 10 cm (4') + \SmartUnit{celsius=20} % 20 C (43 F) + \SmartUnit{miles=5} % 8 km (5 mi) + \SmartUnit{miles=5, precision=1} % 8.0 km (5 mi) + \SmartUnit{miles=5, km=7} % 7 km (5 mi) +\end{document} +``` + +Units supported +--------------- + +Currently smartunits converts between the following five classes of units: + + ============ ============== + Metric Imperial + ------------ -------------- ------------- + kilometers miles (distance) + centimeters feet and inches (length) + Celsius Fahrenheit (temperature) + 24-hour time 12-hour time (time) + litres USA/UK gallons (volume) + kilograms pounds (weight) + ============ ============== ============= + +It is quite easy to extend the code to other units. I am happy to consider new requests. + +Requirements +------------ + +The package requires +[pgfkeys](https://www.ctan.org/pkg/pgfkeys) and +[siunitx](https://www.ctan.org/pkg/siunitx). + +### Author + +Copyright (c) 2016 [Andrew Mathas](mailto:andrew.mathas@gmail.com) + +Released under the [LaTeX Project Public +License](http://www.latex-project.org/lppl.txt) v1.3c or later diff --git a/Master/texmf-dist/doc/latex/smartunits/smartunits.pdf b/Master/texmf-dist/doc/latex/smartunits/smartunits.pdf new file mode 100644 index 00000000000..eb81116ba63 Binary files /dev/null and b/Master/texmf-dist/doc/latex/smartunits/smartunits.pdf differ diff --git a/Master/texmf-dist/doc/latex/smartunits/smartunits.tex b/Master/texmf-dist/doc/latex/smartunits/smartunits.tex new file mode 100644 index 00000000000..78c23ee12a0 --- /dev/null +++ b/Master/texmf-dist/doc/latex/smartunits/smartunits.tex @@ -0,0 +1,415 @@ +\documentclass[svgnames]{report} +\usepackage{smartunits} +\usepackage{manfnt} +\usepackage{enumitem} +\setlist[description]{font=\sffamily\bfseries\color{DodgerBlue},labelwidth=\textwidth} +\usepackage{booktabs} +\usepackage[a4paper,margin=18mm]{geometry} +\synctex=1 + +\usepackage{fixltx2e} % LaTeX patches, \textsubscript +\usepackage{cmap} % fix search and cut-and-paste in Acrobat +\usepackage[T1]{fontenc} +\usepackage[utf8]{inputenc} +\setcounter{secnumdepth}{0} + +\usepackage{listings}\lstset{language=[LaTeX]TeX,framerule=2pt} +\lstset{language=[LaTeX]TeX, + texcsstyle=*\bfseries\color{Blue}, + backgroundcolor=\color{Ivory}, + numbers=none, + breaklines=true, + keywordstyle=\color{Blue}, + commentstyle=\color{Brown}, + tabsize=2, + morekeywords={SmartUnit,SmartUnitSettings,sisetup}, + resetmargins=true, +} +% hyperref links to ctan +\newcommand\ctan[1]{\href{https://www.ctan.org/pkg/#1}{\texttt{#1}}} + +\usepackage{xparse} +\NewDocumentCommand{\Verb}{v}{{\color{blue}#1}} + +\newcommand\Section[1]{\subsection{\textcolor{blue}{#1}}} + +\makeatletter +\author{Andrew Mathas} +\usepackage{tikz} +\usetikzlibrary{shadows.blur} +\tikzset{shadowed/.style={blur shadow={shadow blur steps=5}, + bottom color=LightSkyBlue!30, + draw=MidnightBlue!70,shade, + font=\normalfont\Huge\bfseries\scshape, + rounded corners=8pt, + top color=SkyBlue, + }, + boxes/.style={draw=MidnightBlue, + fill=Cornsilk, + font=\sffamily\small, + inner sep=5pt, + rectangle, + rounded corners=8pt, + text=RoyalBlue, + } +} +\def\SmartTitle{ + \begin{tikzpicture}[remember picture,overlay] + \node[yshift=-3cm] at (current page.north west) + {\begin{tikzpicture}[remember picture, overlay] + \draw[shadowed](30mm,0) rectangle node[white]{Smart Units} (\paperwidth-30mm,16mm); + \node[anchor=west,boxes] at (4cm,0cm) {\@author}; + \node[anchor=east,boxes] at (\paperwidth-4cm,0) {\smart@version}; + \end{tikzpicture} + }; + \end{tikzpicture} + \vspace*{20mm} +} + + +\def\@oddfoot{\textsc{Smart Units} -- \smart@version\hfill\thepage} + +\usepackage[colorlinks=true,linkcolor=blue,urlcolor=blue]{hyperref} +\hypersetup{pdfcreator={ Generated by pdfLaTeX }, + pdfinfo={Author ={ Andrew Mathas }, + Keywords={ units, metric, Imperial }, + License ={ LaTeX Project Public License v1.3c or later }, + Subject ={ Convert between metric and Imperial units }, + Title ={ smartunits - \smart@version } + }, +} +\makeatother + +\begin{document} + + \SmartTitle + + %\Section{Smart units} + This package implements a \Verb|\SmartUnit| macro for + converting between the following metric and Imperial units: + + \begin{center} + \begin{tabular}{@{\color{Grey!50}}ll@{\quad$\longleftrightarrow$\quad}l}\toprule + & Metric & Imperial \\\midrule + \color{LightSkyBlue}distance & kilometers & miles \\ + \color{LightSkyBlue}length & centimeters & feet and inches \\ + \color{LightSkyBlue}temperature & Celsius & Fahrenheit \\ + \color{LightSkyBlue}time & 24-hour time& 12-hour time \\ + \color{LightSkyBlue}volume & litres & USA/UK gallons \\ + \color{LightSkyBlue}weight & kilograms & pounds \\ + \bottomrule + \end{tabular} + \end{center} + Of course, the underlying unit for length and distance is the same + but it makes sense to convert between units of similar ``scale''. + The \Verb|\SmartUnit| macro is designed to print only one unit at a + time, where the quantity is given in terms of either metric or + Imperial units (there is no error checking, however). Depending on + the (global) settings the unit will be printed either as a metric + unit, or as an Imperial unit, or both. If the required unit is not + given as an argument to \Verb|\SmartUnit| then it is computed. The + units are printed using \ctan{siunitx}, so the formatting of the + units can be controlled using \Verb|\sisetup| together with + formatting parameters from \ctan{siunitx}. Some aspects of the + formatting can be controlled ``locally'' using \Verb|\SmartUnit| and + ``globally'' using \Verb|\SmartUnitSettings|. + + The \Verb|\SmartUnit| macro can print units in the following + four different formats: + + \begin{lstlisting} + \SmartUnit{metric} % --> metric + \SmartUnit{imperial} % --> Imperial + \SmartUnit{metric imperial} % --> metric (Imperial) + \SmartUnit{imperial metric} % --> Imperial (metric) + \end{lstlisting} + + For the impatient, here are some examples: + + \bgroup + \sisetup{round-mode=places,round-precision=2} + \small + \begin{lstlisting}[escapeinside=<>] + \documentclass{article} + \usepackage{smartunits} + \begin{document} + \SmartUnitSettings{places=2} % Some global settings < \SmartUnitSettings{places=2} > + \SmartUnit{metric imperial} % Output format: metric (Imperial) < \SmartUnit{metric imperial} > + \SmartUnit{cm=10} % < \SmartUnit{cm=10} > + \SmartUnit{feet=4,inches=3} % < \SmartUnit{feet=4,inches=3} > + \SmartUnit{celsius=20} % < \SmartUnit{celsius=20} > + \SmartUnit{metric} % Output format: metric < \SmartUnit{metric} > + \SmartUnit{miles=5, places=1} % < \SmartUnit{miles=5,places=1} > + \SmartUnit{imperial} % Output format: Imperial < \SmartUnit{imperial} > + \SmartUnit{hours=12, minutes=1} % < \SmartUnit{hours=12, minutes=1} > + \SmartUnit{km=5,places=3} % < \SmartUnit{km=5,places=3} > + \SmartUnit{imperial metric} % Output format: Imperial (metric) < \SmartUnit{imperial metric} > + \SmartUnit{miles=5, km=7} % < \SmartUnit{miles=5,km=7} > + \SmartUnit{l=1.0, places=1} % < \SmartUnit{l=1.0, places=1} > + \SmartUnit{L=1.0, places=1} % < \SmartUnit{L=1.0, places=1} > + \SmartUnit{gal=25.0,uk,places=2} % < \SmartUnit{gal=25.0, places=2,uk} > + \SmartUnit{gal=25.0,usa,places=2} % < \SmartUnit{gal=25.0, places=2,usa} > + \end{document} + \end{lstlisting} + \egroup + + The calculations done by \Verb|\SmartUnit| are reasonably accurate + but LaTeX is not a calculator so rounding and other errors can and + do happen (indeed, see the displayed example below). In addition, even assuming + that the calculations done by \Verb|\SmartUnit| are accurate this + may not be what you want. For example, if the metric unit is given + as \SI{100}{km} then many people will want the Imperial unit to be + written as \SI{60}{\text{mi}}, rather than the more accurate + \SI{62.137119}{\text{mi}}. In fact, \Verb|\SmartUnit| can cater for + these considerations because all units are printed using the + \ctan{siunitx} package, which is really clever. The precision of the + printed units can be controlled using \Verb|\sisetup|, from the + \ctan{siunitx} package or by using the short-hands, \textsf{figures} + and \textsf{places}, provided by \Verb|\SmartUnit|: + \begin{lstlisting}[texcl] + \SmartUnit{km=100.0, figures=1} % \SmartUnit{km=100.0,figures=1} + \SmartUnit{km=100.0, places=5} % \SmartUnit{km=100.0,places=5} + \end{lstlisting} + \noindent (Comparing with the paragraph above, the last calculation + is only accurate to three decimal places!) The values of the + computed units can be overridden, during proof-reading for example, + by specifying both the metric and Imperial units: + \begin{lstlisting}[texcl] + \SmartUnit{km=100,miles=70} % \SmartUnit{km=100,miles=70} + \end{lstlisting} + \noindent \raisebox{3.9mm}{\dbend}\quad Of course, if you specify + units incorrectly like this then incorrect values will be printed. + + Behind the scenes all units are printed using \ctan{siunitx}. Therefore, + the precision and formatting of the units can be changed using the + options to \Verb|\sisetup| described in the \ctan{siunitx}\ manual. In + particular, when the rounding capabilities of~\ctan{siunitx}\ are enabled + any units calculated by \Verb|\SmartUnit| will be rounded. + In this case there is a shorthand for overriding the global + \ctan{siunitx}\ settings for the rounding precision on an individual + ``smart unit'': + + \begin{lstlisting}[escapeinside=<>] + % Locally=\sisetup{round-precision=3, round-mode=places} + \SmartUnit{cm=2, places=3} % < \SmartUnit{cm=2, places=3} > + \end{lstlisting} + + Section~5.5 of the \ctan{siunitx}\ manual should be consulted for all of the + options for controlling ``post-processing'' of numbers. In particular, + units that are given as integers will always be printed as integers. + For example, the metric version of \Verb|\SmartUnit{cm=2, places=3}| + is printed as \SmartUnit{cm=2, places=3, metric} whereas the Imperial version is + \num{0.787}$'$. If, instead, we use + \Verb|\SmartUnit{cm=2.0, places=3}| then the metric unit is + printed as \SmartUnit{cm=2.0, places=3, metric}. + + + \Section{Unit conversions} + For all of these examples we use the following global settings: + \begin{lstlisting}[texcl] + \SmartUnitSettings{places=2, metric imperial} % Global settings + \end{lstlisting} + \SmartUnitSettings{places=2, metric imperial} + \noindent Of course, as in some of the example below, this can always be overridden locally. + + \begin{description} + \item[Distance -- km, miles, mi] + Conversions between kilometers and miles. Miles can be specified + using either \textbf{miles} or \textbf{mi}. + \begin{lstlisting}[texcl] + \SmartUnit{km=100,miles=60} % \SmartUnit{km=100,miles=60} + \SmartUnit{km=100.0,figures=1} % \SmartUnit{km=100,figures=1} + \SmartUnit{miles=62.15,places=1} % \SmartUnit{miles=62.15,places=1} + \end{lstlisting} + + \item[Length -- cm, inches, feet] + \begin{lstlisting}[texcl] + \SmartUnit{feet=7, inches=1} % \SmartUnit{feet=7, inches=1} + \SmartUnit{cm=189, feet=7, inches=1} % \SmartUnit{cm=189, feet=7, inches=1} + \SmartUnit{cm=191, places=1} % \SmartUnit{cm=191, places=1} + \end{lstlisting} + + \item[Temperature -- celsius, fahrenheit] + \begin{lstlisting}[texcl] + \SmartUnit{celsius=32,places=3} % \SmartUnit{celsius=32,places=3} + \SmartUnit{celsius=0} % \SmartUnit{celsius=0} + \SmartUnit{fahrenheit=0} % \SmartUnit{fahrenheit=0,places=2} + \end{lstlisting} + + \item[Time -- hours, minutes, seconds, am, pm] + \begin{lstlisting}[texcl] + \SmartUnit{hours=0, minutes=59} % \SmartUnit{hours=0, minutes=59} + \SmartUnit{hours=12, minutes=12} % \SmartUnit{hours=12, minutes=12} + \SmartUnit{hours=13, minutes=9} % \SmartUnit{hours=13, minutes=9} + \SmartUnit{hours=8, minutes=31, pm} % \SmartUnit{hours=8, minutes=31, pm} + \SmartUnit{hours=9, minutes=3, am} % \SmartUnit{hours=9, minutes=3, am} + \SmartUnit{hours=0, minutes=0,seconds=1} % \SmartUnit{hours=0, minutes=0,seconds=1} + \SmartUnit{hours=12, minutes=0,seconds=1} % \SmartUnit{hours=12, minutes=0,seconds=1} + \end{lstlisting} + + \item[Volume -- L, l, gal, gallons] + Converting between litres and gallons. Liters can be specified + using \textbf{L} or \textbf{l} and gallons can be given with + \textbf{gallons} or \textbf{gal}. Both UK gallons and USA + gallons are supported, with USA gallons being the default. + \begin{lstlisting}[texcl] + \SmartUnit{l=10.0, places=1} % \SmartUnit{l=10.0, places=1} + \SmartUnit{L=10.0, places=1,uk} % \SmartUnit{L=10.0, places=1,uk} + \SmartUnit{gal=10.0, places=2} % \SmartUnit{gal=10.0, places=2} + \end{lstlisting} + + \item[Weight -- kg, pounds, lbs] + \begin{lstlisting}[texcl] + \SmartUnit{kg=10.0, places=1} % \SmartUnit{kg=10.0, places=1} + \SmartUnit{pound=10.0, places=1} % \SmartUnit{pound=10.0, places=1} + \SmartUnit{pound=10.0,figures=1} % \SmartUnit{pound=10.0,figures=1} + \end{lstlisting} + \end{description} + + \Section{Formatting options} + + The following options can either be used inside \Verb|\SmartUnit| to + control the formatting \textit{locally} for just the unit being + printed. They can also be used as arguments to + \Verb|\SmartUnitSettings| to change the formatting of all subsequent + smart units (unless these settings are overridden locally). More + control over the formatting of the units is given by the + \Verb|\sisetup| macro from the \ctan{siunitx} package. + + \begin{description} + \item[figures] This is equivalent to \Verb|\sisetup{round-mode=figures, precision=#1}|. All units are printed + with \#1 significant figures. + \begin{lstlisting}[texcl] + \SmartUnit{miles=60, metric, figures=0} % \SmartUnit{miles=60, metric, figures=0} + \SmartUnit{miles=60, metric, figures=1} % \SmartUnit{miles=60, metric, figures=1} + \SmartUnit{miles=60, metric, figures=2} % \SmartUnit{miles=60, metric, figures=2} + \SmartUnit{miles=60, metric, figures=3} % \SmartUnit{miles=60, metric, figures=3} + \SmartUnit{miles=60, metric, figures=4} % \SmartUnit{miles=60, metric, figures=4} + \end{lstlisting} + + \item[places] + This is equivalent to \Verb|\sisetup{round-mode=figures, precision=#1}|. All units are printed + with \#1 significant figures. + \begin{lstlisting}[texcl] + \SmartUnit{miles=60, metric, places=0} % \SmartUnit{miles=60, metric, places=0} + \SmartUnit{miles=60, metric, places=1} % \SmartUnit{miles=60, metric, places=1} + \SmartUnit{miles=60, metric, places=2} % \SmartUnit{miles=60, metric, places=2} + \SmartUnit{miles=60, metric, places=3} % \SmartUnit{miles=60, metric, places=3} + \SmartUnit{miles=60, metric, places=4} % \SmartUnit{miles=60, metric, places=4} + \end{lstlisting} + + + \item[imperial] + Print only Imperial units. + \begin{lstlisting}[texcl] + \SmartUnit{km=1.0, imperial} % \SmartUnit{km=1.0, imperial, figures=2} + \SmartUnit{miles=1.0, imperial} % \SmartUnit{miles=1.0, imperial, figures=2} + \end{lstlisting} + \item[imperial metric] + Print Imperial units with metric units enclosed in brackets. + \begin{lstlisting}[texcl] + \SmartUnit{km=1.0, imperial metric} % \SmartUnit{km=1.0, imperial metric, figures=2} + \SmartUnit{miles=1.0, imperial metric} % \SmartUnit{miles=1.0, imperial metric, figures=2} + \end{lstlisting} + \item[metric (default)] + Print only metric units. + \begin{lstlisting}[texcl] + \SmartUnit{km=1.0, metric} % \SmartUnit{km=1.0, metric, figures=2} + \SmartUnit{miles=1.0, metric} % \SmartUnit{miles=1.0, metric, figures=2} + \end{lstlisting} + \item[metric imperial] + Print metric units with Imperial units enclosed in brackets. + \begin{lstlisting}[texcl] + \SmartUnit{km=1.0, metric imperial} % \SmartUnit{km=1.0, metric imperial, figures=2} + \SmartUnit{miles=1.0, metric imperial} % \SmartUnit{miles=1.0, metric imperial, figures=2} + \end{lstlisting} + \item[uk] + Selects the UK variants of the Imperial units (currently this + only affects gallons): + \begin{lstlisting}[texcl] + \SmartUnit{l=1.0, imperial metric, figures=2,uk} % \SmartUnit{l=1.0, imperial metric, figures=2,uk} + \SmartUnit{gal=1.0, imperial metric, figures=2,uk} % \SmartUnit{gal=1.0, imperial metric, figures=2,uk} + \end{lstlisting} + \item[usa (default)] + Selects the USA variants of the Imperial units (currently this + only affects gallons): + \begin{lstlisting}[texcl] + \SmartUnit{l=1.0, imperial metric, figures=2,usa} % \SmartUnit{l=1.0, imperial metric, figures=2,usa} + \SmartUnit{gal=1.0, imperial metric, figures=2,usa} % \SmartUnit{gal=1.0, imperial metric, figures=2,usa} + \end{lstlisting} + By default \Verb|\SmartUnit| uses the American Imperial units. + This is a purely democratic choice dictated by the populations + of the two countries. + \end{description} + + \Section{The code} + Behind the scenes, the \Verb|\SmartUnit| macro uses \ctan{pgfkeys} and + \ctan{pgfmath} to convert between the different units. The interface is + surprisingly simple and easy to extend. For example, the following + code takes care of the conversion between kilometers and miles: + \bgroup\footnotesize + \begin{lstlisting} + %%%% convert=distance: km <-> miles %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + km/.style={convert=distance, unit km=#1},% + mi/.style={convert=distance, unit miles=#1},% + miles/.style={convert=distance, unit miles=#1},% + distance/metric/.style={/SmartUnit/conversion={km}{miles}{0}{1.609344}{0}{km}},% + distance/imperial/.style={/SmartUnit/conversion={miles}{km}{0}{0.62137119}{0}{\text{mi}}},% + \end{lstlisting} + \egroup + \noindent + Most of the conversions are done in this way --- the exceptions are + ``length'' and ``time'', which are more complicated. The key + \Verb|/SmartUnit/conversion| is a macro that takes six arguments and + then implements the generic conversion formula: + \[ + \text{New unit}(\Verb|#1|) = \Big(\text{Old unit}(\Verb|#2)|+\text{Pre-offset}(\Verb|#3|)\Big)*\text{Multiplier}(\Verb|#4|) + \text{Post-offset}(\Verb|#5|), + \] + where \Verb|#6| is the metric or Imperial symbol for the unit being + printed. + + \textit{Adding additional conversions is quite straightforward and I am + happy to incorporate suggestions.} + + There is, of course, some trickery driving how the units are printed. + Here is the definition of \Verb|\SmartUnit|: + \begin{lstlisting} + \newcommand\SmartUnit[1]{% + \bgroup%=> changes are local to \SmartUnit => no need to reset + \pgfkeys{/SmartUnit,#1}% Pass the keys to /SmartUnit + \pgfkeys{/SmartUnit,printunit}% Calculate units and print + \egroup% + } + \end{lstlisting} + So \Verb|\SmartUnit| calls \ctan{pgfkeys} twice: the first time to + set the keys and the second time to print them using + \Verb|/SmartUnit/printunit|. In turn, this uses + \Verb|/SmartUnit/convert| to identify the unit being printed, + after which the pgf key + \Verb|/SmartUnit/output| is called. This has subkeys for the four + different \textit{output formats}: + \begin{center} + \texttt{metric}, \texttt{imperial}, + \texttt{metric imperial} and \texttt{imperial metric}. + \end{center} + Finally, \Verb|/SmartUnit/output/| uses + \Verb|/SmartUnit/convert| to perform the required conversion. + This multi-step printing process is necessary for converting between + inputs like time or centimeters, feet and inches, where the + output units depend on more than one input value. It is also used to + print the four different output formats discussed above. + + + \Section{Acknowledgement} + The package was written in response to a + \href{http://tex.stackexchange.com/questions/241169/}{TeX.SX question}, + partly as a proof-of-concept and partly as an exercise to learn how + to use \ctan{pgfkeys}. I thank Mark Adams for asking the question. + + \Section{Author} + \href{mailto:Andrew.Mathas@gmail.com?smartunits}{Andrew Mathas}, \copyright\space February 2016. + + \Section{Licence} + Released under the \href{http://www.latex-project.org/lppl.txt}{LaTeX Project Public License}, v1.3c or later. + +\end{document} -- cgit v1.2.3