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%
}
  • 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 '19 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 '19 at 7:19
  • 1
    Why not use \num{2.5d-15}\unitmomentum? – John Kormylo Mar 14 '19 at 14:12
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.

| improve this answer | |
  • 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 '19 at 14:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.