\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{cm=66}                 % < \SmartUnit{cm=66} >
          \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]
        Feet are always printed as integers. Significant figures/places
        are applied only to the printing of inches.
        \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]
        Convesions between Celsius and Fehrenheit can be speficied using
        \textsf{celsius}, \textsf{C}, \textsf{fahrenheit} or \textsf{F}.

        \begin{lstlisting}[texcl]
          \SmartUnit{celsius=32,places=3}           % \SmartUnit{celsius=32,places=3}
          \SmartUnit{celsius=0}                     % \SmartUnit{celsius=0}
          \SmartUnit{C=37}                          % \SmartUnit{C=37}
          \SmartUnit{fahrenheit=0}                  % \SmartUnit{fahrenheit=0,places=2}
          \SmartUnit{F=22,figures=4}                % \SmartUnit{F=212,figures=4}
        \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}|.
      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=places, precision=#1}|.
      Units are printed with \#1 decimal places.
           \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/<format>| 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}. Thanks to Mark Adams for asking the question.

    \Section{Author}
    \href{mailto:Andrew.Mathas@gmail.com?smartunits}{Andrew Mathas},
    \copyright\space 2015, 2016.

    \Section{Licence}
    Released under the
    \href{http://www.latex-project.org/lppl.txt}%
         {LaTeX Project Public License}, v1.3c or later.

\end{document}
