1

In my document, I need to use a large number of different SI units. To ease my typing, I usually define new commands as \newcommand{\unitmass}{\si{\kilogram}} or \newcommand{\unitmomentum}{\si{\kilogram\meter\per\second}}. Then I can use something like 2.5\unitmassor 3.4\unitmementum and be done. It saves me a lot of typing effort.

Not much of a problem till I need \si[2.5d-15]{\kilogram\meter\per\second} (notice the scientific notation of the number), which still requires me to type the full shebang. One alternative is to use math notation only for the number as in $2.5\times 10^{-17}$\unitmomentum$ which is not a terrific option. Ideally I would want something like \unitmomentum[2.5d-15] to get by.

Which means, I have to define my commands way more complicated and there are dozens (rapidly reaching hundred) of it. Hence I must define a template of optional argument accepting commands.

My first approach was to

\newcommand{\SimpleSIunit}[2]{%
    \expandafter\newcommand\csname #1\endcsname{\si{#2}}%
}

It works if I remain content with no optional arguments. I can issue dozens of directives like \SimpleSIunit{unittorque}{\newton\meter} and my basic need is met.

However, what I really want is to say

\newcommand{\SimpleSIunit}[2]{%
    \expandafter\newcommand[1][]\csname #1\endcsname{\si[##1]{#2}}%
}

Which obviously does no good. Any ideas how do I rectify it?

After I pronounce \SimpleSIunit{unittorque}{\newton\meter}, I want these four lines to produce the same output -

2.5\unittorque
\unittorque[2.5]
2.5\si{\newton\meter}
\si[2.5]{\newton\meter}

** PS:: EDIT after comment by @daleif **

The spacings are taken care of by the following directives before I do anything else. It uses the savesym package. I don't pretend that the code below is my original work. Call it Cargo-cult programming, but I am no student in need of a homework. This is my professional work and I use LaTeX as a tool.

% spacing of siunits
\newlength{\siunitspace}
\sisetup{number-unit-product = \hspace{\siunitspace}}

% new units -- to act as supplement to SI units package \si{unit}
\input{unitdef-v01-2018} % a seperate file maintains this

\savesymbol{si}
\newcommand{\si}[2][?]{%
    \if\relax#1\relax%
    \hspace{\siunitspace}\origsi{#2}\xspace%
    \else%
    \if?#1\hspace{\siunitspace}\origsi{#2}\xspace\else\SI{#1}{#2}\xspace\fi%
    \fi%
}
3
  • 1
    You do realize that 2.5\si... is wrong? The inner value spacing is missing. You do not really gain anything by doing this compared to just using \SI
    – daleif
    Mar 14, 2019 at 6:24
  • I am sorry, I had already changed those spacings. I am editing my question, though it doesn't change anything as far as the original problem is i.e, defining templatized commands to accept optional arguments.
    – magguu
    Mar 14, 2019 at 7:19
  • 1
    Why not use \num{2.5d-15}\unitmomentum? Mar 14, 2019 at 14:12

1 Answer 1

2

There is functionality built in to siunitx for this type of input

\documentclass{article}
\usepackage{siunitx}
\sisetup{free-standing-units, ,unit-optional-argument, space-before-unit}
\DeclareSIUnit{\unitmomentum}{\kilogram\meter\per\second}
\begin{document}
Some text $3.5\unitmomentum$ and $\unitmomentum[2.5e-3]$.
\end{document}

Note that this units-like syntax is not the default setting as I believe that it is sub-optimal.

1
  • 1
    hmmm ... it works. thanks a lot. I found that using use-xspace solves the problem of lack of space after the units.
    – magguu
    Mar 14, 2019 at 14:11

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .