% \iffalse meta-comment
%<*internal>
\iffalse
%</internal>
%<*readme>
----------------------------------------------------------------
The lengthconvert package --- Convert a length to an other unit.
E-mail: marco.daniel@mada-nada.de
Released under the LaTeX Project Public License v1.3c or later
See http://www.latex-project.org/lppl.txt
----------------------------------------------------------------

Requires expl3
%</readme>
%<*internal>
\fi
\def\nameofplainTeX{plain}
\ifx\fmtname\nameofplainTeX\else
  \expandafter\begingroup
\fi
%</internal>
%<*install>
\input l3docstrip.tex
\keepsilent
\askforoverwritefalse
\preamble
----------------------------------------------------------------
The lengthconvert package --- Convert a length to an other unit.
E-mail: marco.daniel@mada-nada.de
Released under the LaTeX Project Public License v1.3c or later
See http://www.latex-project.org/lppl.txt
----------------------------------------------------------------

\endpreamble
\postamble
Copyright (C) 2013 by
  Marco Daniel marco.daniel@mada-nada.de

It may be distributed and/or modified under the conditions of
the LaTeX Project Public License (LPPL), either version 1.3c of
this license or (at your option) any later version.  The latest
version of this license is in the file:
   http://www.latex-project.org/lppl.txt

This work is "maintained" (as per LPPL maintenance status) by
  Marco Daniel.

\endpostamble
\usedir{tex/latex/lengthconvert}
\generate{\file{\jobname.sty}{\from{\jobname.dtx}{package}}}
%</install>
%<install>\endbatchfile
%<*internal>
\usedir{source/latex/lengthconvert}
\generate{
  \file{\jobname.ins}{\from{\jobname.dtx}{install}}
}
\nopreamble\nopostamble
\usedir{doc/latex/lengthconvert}
\generate{
  \file{README.txt}{\from{\jobname.dtx}{readme}}
}
\ifx\fmtname\nameofplainTeX
  \expandafter\endbatchfile
\else
  \expandafter\endgroup
\fi
%</internal>
%<*driver|package>
\RequirePackage{expl3,xparse}
%</driver|package>
%<*driver>
\setcounter{errorcontextlines}{999}
\documentclass[full]{l3doc}
\usepackage{amsmath,array,booktabs}
\usepackage{siunitx}
\usepackage{lengthconvert}
\usepackage{parskip}
\usepackage{setspace}\onehalfspacing
\begin{document}
  \DocInput{\jobname.dtx}
\end{document}
%</driver>
% \fi
%
% \title{^^A
%   The \textsf{lengthconvert} package
% }
%
% \author{^^A
%  Marco Daniel
%    {^^A
%      E-mail:
%        \href{mailto:marco.daniel@mada-nada.de}
%          {marco.daniel@mada-nada.de}^^A
%    }^^A
% }
%
% \date{Released 2013/06/13}
%
% \changes{v1.0}{2013/06/13}{First official release}
% \changes{v1.0a}{2013/06/15}{fixed typo in package name}
% \maketitle
%
% \begin{documentation}
%
% Sometimes it's useful for some explanation to provide lengths in
% standardizations units instead of the default unit of \TeX. 
% This package can do this for your.
% 
%
% \tableofcontents
%
% \section{Basics}
%
% The package needs the newest version of \pkg{l3kernel} available at CTAN. 
% Internally it uses the modul \pkg{l3fp} to convert the length. 
%
% All allowed units in \TeX\ are listed in the table below.
%
% \begin{table}[!ht]
% \centering
% \caption{Allowed \TeX\ units}
% \vspace*{1em}
% \begin{tabular}{cl}
%  \toprule
%    \textbf{Unit} & \textbf{Measurement}                 \\
%  \midrule
%    pt            &  point                               \\
%    pc            &  pica(1pc=12pt)                      \\
%    in            &  inch (1 in = 72.27 pt)              \\
%    bp            &  bigpoint(72bp=1in)                  \\
%    cm            &  centimeter (2.54 cm = 1 in)         \\
%    mm            &  millimeter (10 mm = 1 cm)           \\
%    dd            &  didot point (1157 dd = 1238 pt)     \\
%    cc            &  cicero (1 cc = 12 dd)               \\
%    sp            &  scaled point (65536 sp = 1 pt)      \\
%  \bottomrule
% \end{tabular}
% \end{table}
%
%
% \section{Usage}
% 
% The usage is really simple. Pass the length to the command \cs{Convert}
% and get the result.
%
% \begin{function}{\Convert}
%   \begin{syntax}
%     \cs{Convert}\oarg{options} \Arg{length}
%   \end{syntax}
% \end{function}
% The command converts the given length to the unit specified by an option. The
% default unit is cm.
% After the conversion the result will be printed.
%
% \begin{function}{\Convertsetup}
%   \begin{syntax}
%     \cs{Convertsetup} \Arg{options}
%   \end{syntax}
% \end{function}
% Allows the specification of options.
%
% \section{Options}
%
% The package is simple and the options too. 
%
%\DescribeOption{unit}
% The option accepts only the abbrevation unit. Allowed units are described in
% the table above. 

% You can also use only the abbrevation or a complete word. The following table
% lists all allowed inputs.
%
%
% \begin{center}
% \def\arraystretch{1.4}
% \begin{tabular}{*{6}{c}}
%  \toprule
% pt        & pc         & in         & bp          & cm     & mm           \\
% dd        & cc         & sp         & point       & pica   & inch         \\
% big-point & centimeter & millimeter & didot-point & cicero & scaled-point \\
%  \bottomrule
% \end{tabular}
%
% \end{center}
%
%
%
%\DescribeOption{use-siunitx}
% It's a bool flag which can be either \texttt{true} or \texttt{false}.
% If it is true, the output of the new length is done by the package 
% \pkg{siunitx} using the command \cs{SI}.
%
%\DescribeOption{precision}
% This option accepts an integer and specifies the precision of the output.
%
%\DescribeOption{number-only}
% It's a bool flag which can be either \texttt{true} or \texttt{false}.
% If it's true, only the number is printed.
%
% \section{Examples}
%  Some examples are shown in the following table. In the left column
%  you see the input and in the right the output.
%
% \begin{center}
% \def\arraystretch{1.4}
% \begin{tabular}{ll}
%  \toprule
%   \verb+\Convert{36pt}+                     &  \Convert{36pt}               \\
%   \verb+\Convert[precision=2]{36pt}+        &  \Convert[precision=2]{36pt}  \\
%   \verb+\Convert[use-siunitx]{36pt}+        &  \Convert[use-siunitx]{36pt}  \\
%   \verb+\Convert[unit=pt]{2cm}+             &  \Convert[unit=pt]{2cm}       \\
%   \verb+\Convert[unit=dd,number-only]{2cm}+ & 
%                                          \Convert[unit=dd,number-only]{2cm} \\
%   \verb+\Convert[pt]{2cm}+                  &  \Convert[pt]{2cm}            \\
%   \verb+\Convert[scaled-point]{2cm}+        &  \Convert[scaled-point]{2cm}  \\
%  \bottomrule
% \end{tabular}
%
% \end{center}
%
%
%\end{documentation}
%
% \clearpage
%
%\begin{implementation}
%
%\section{\pkg{lengthconvert} Implementation}
%
%    \begin{macrocode}
%<*package>
%    \end{macrocode}
%    
%    \begin{macrocode}
%<@@=lconv>
%    \end{macrocode}
%
%    \begin{macrocode}
\ProvidesExplPackage
  {lengthconvert}{2013/05/13}{1.0}{Convert length to another unit}
%    \end{macrocode}
%
% Make sure that the version of \pkg{l3kernel} in use is sufficiently new.
% This will also trap any problems with \pkg{l3packages} (as the two are now
% tied together, version-wise).
%    \begin{macrocode}
\@ifpackagelater { expl3 } { 2012/11/21 }
  { }
  {
    \PackageError { lengthtconvert } { Support~package~expl3~too~old }
      {
        You~need~to~update~your~installation~of~the~bundles~'l3kernel'~and~
        'l3packages'.\MessageBreak
        Loading~lengthtconvert~will~abort!
      }
    \tex_endinput:D
  }
%    \end{macrocode}
%
% Now load the support packages.
%    \begin{macrocode}
\RequirePackage{ l3keys2e }
%    \end{macrocode}
%
%
% \begin{macro}{\@@_allowed_shortunits_clist}
% \begin{macro}{\@@_allowed_longunits_clist}
% \begin{macro}{\@@_allowed_allunits_clist}
%   Save all allowed units in a clist
%    \begin{macrocode}
\clist_new:N \g__@@_allowed_shortunits_clist
\clist_gset:Nn \g__@@_allowed_shortunits_clist
   { pt , pc , in , bp , cm , mm , dd , cc ,sp }
\clist_new:N \g__@@_allowed_longunits_clist
\clist_gset:Nn \g__@@_allowed_longunits_clist
   { point , pica , inch , big-point , centimeter , millimeter ,
     didot-point , cicero , scaled-point }
\clist_new:N \g__@@_allowed_allunits_clist
\clist_gset:NV \g__@@_allowed_allunits_clist \g__@@_allowed_shortunits_clist
\clist_gput_right:NV \g__@@_allowed_allunits_clist \g__@@_allowed_longunits_clist
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\@@_unit_tl}
% Save the default unit in a token list variable and provide them as option
% 
%    \begin{macrocode}
\tl_new:N \l__@@_unit_tl
\keys_define:nn { lengthconvert } 
 {
   unit  .tl_set:N = \l__@@_unit_tl
 }
\keys_set:nn { lengthconvert } 
 {
  unit  = cm ,
 }
%    \end{macrocode}
%
%
% Provide also abbreviation and word of units 
% 
%    \begin{macrocode}
\tl_new:N \l_@@_default_unit_tl
\keys_define:nn { lengthconvert } 
 {
    pt    .meta:n  = 
            {  unit   =   pt     },
    pc    .meta:n  = 
            {  unit   =   pc     },
    in    .meta:n  = 
            {  unit   =   in     },
    bp    .meta:n  = 
            {  unit   =   bp     },
    cm    .meta:n  = 
            {  unit   =   cm     },
    mm    .meta:n  = 
            {  unit   =   mm     },
    dd    .meta:n  = 
            {  unit   =   dd     },
    cc    .meta:n  = 
            {  unit   =   cc     },
    sp    .meta:n  = 
            {  unit   =   sp     },
    point .meta:n  = 
            {  unit   =   pt     },
    pica  .meta:n  = 
            {  unit   =   pc     },
    inch  .meta:n  = 
            {  unit   =   in     },
    big-point  .meta:n  = 
            {  unit   =   bp     },
    centimeter .meta:n  = 
            {  unit   =   cm     },
    millimeter .meta:n  = 
            {  unit   =   mm     },
    didot-point .meta:n  = 
            {  unit   =   dd     },
    cicero .meta:n  = 
            {  unit   =   cc     },
    scaled-point .meta:n  = 
            {  unit   =   sp     },
 }
%    \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\l__@@_use_siunitx_bool}
% Output should be done by \pkg{sinutix}.
%    \begin{macrocode}
\keys_define:nn { lengthconvert } {
  use-siunitx   .bool_set:N = \l__@@_use_siunitx_bool
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\l_@@_precision_tl}
% Specify the precision
%    \begin{macrocode}
\keys_define:nn { lengthconvert } {
  precision   .int_set:N = \l__@@_precision_int
}
\keys_set:nn { lengthconvert } 
 {
  precision  = 5 ,
 }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\l__@@_only_num_bool}
% Only the number should be used
%    \begin{macrocode}
\keys_define:nn { lengthconvert } {
  number-only  .bool_set:N = \l__@@_only_num_bool
}
%    \end{macrocode}
% \end{macro}
%
% Unknown options should be raised an error
%    \begin{macrocode}
\keys_define:nn { lengthconvert } {
  unknown .code:n =
    {
      \msg_error:nnx { lengthconvert } { option-unknown }
            { \exp_not:V \l_keys_key_tl }
    }
}
%    \end{macrocode}
%
%
%
% \begin{macro}{\Convertsetup}
% User settings
%    \begin{macrocode}
\NewDocumentCommand \Convertsetup { m }
 {
  \keys_set:nn { lengthconvert } { #1 }
 }
%    \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\Convert}
% Expandable definition of the main command
%    \begin{macrocode}
\DeclareExpandableDocumentCommand \Convert { O{} m }
 {
  \group_begin:
    \keys_set:nn { lengthconvert } { #1 }
    \clist_if_in:NVTF \g_@@_allowed_allunits_clist \l__@@_unit_tl
     {
      \bool_if:NTF \l__@@_use_siunitx_bool
       {
        \@@_using_siunitx:n { #2 }
       }
       {
        \@@_nousing_siunitx:n { #2 }
       }
     }
     {
      \msg_error:nnx { lengthconvert } { unit-unknown }
            { \exp_not:V \l__@@_unit_tl }
     }  
  \group_end:
 }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@@_calc_dim:n}
% Output using \pkg{siunitx}
%    \begin{macrocode}
\cs_new:Npn \@@_calc_dim:n #1
 {
  \fp_eval:n 
     { 
      round( \dim_to_fp:n { #1 } / 1\l__@@_unit_tl , \l__@@_precision_int) 
     } 
 }
%    \end{macrocode}
% \end{macro}

%
% \begin{macro}{\@@_using_siunitx:n}
% Output using \pkg{siunitx}
%    \begin{macrocode}
\cs_new:Npn \@@_using_siunitx:n #1
 {
  \bool_if:NTF \l__@@_only_num_bool
   {
    \num { \@@_calc_dim:n { #1 } }
   }
   {
    \SI { \@@_calc_dim:n { #1 } } { \l__@@_unit_tl }
   }
 }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@@_nousing_siunitx:n}
% Output using \pkg{siunitx}
%    \begin{macrocode}
\cs_new:Npn \@@_nousing_siunitx:n #1
 {
  \bool_if:NTF \l__@@_only_num_bool
   {
    \@@_calc_dim:n { #1 } 
   }
   {
    \@@_calc_dim:n { #1 } \, \l__@@_unit_tl 
   }
 }
%    \end{macrocode}
% \end{macro}
%
%
%    \begin{macrocode}
\msg_new:nnnn { lengthconvert } { option-unknown }
  { Unknown~option~'#1'~for~package~#2. }
  {
    LaTeX~has~been~asked~to~set~an~option~called~'#1'~
    but~the~#2~package~has~not~created~an~option~with~this~name.
  }
%    \end{macrocode}
%
%    \begin{macrocode}
\msg_new:nnnn { lengthconvert } { unit-unknown }
  { Unknown~unit~'#1'~for~package~#2. }
  {
    You~are~setting~an~unit~'#1'~which~
    is~unknonw~for~the~package~#2.
  }
%    \end{macrocode}
%
%
%
% Finally apply the settings given at load time.
%    \begin{macrocode}
\ProcessKeysOptions { lengthconvert }
%    \end{macrocode}
%
%
%    \begin{macrocode}
%</package>
%    \end{macrocode}
%
% \end{implementation}
%
% \begingroup
% \clearpage
% \let\part\section
% \PrintChanges
% \clearpage
% \PrintIndex
% \endgroup
