# siunitx: combine “\num” and “\SI” and change order of arguments

I'm trying to combine the \num and \SI command of siunitx and change the order of the arguments. In particular, what I want to achieve is a new command \Zahl[siunitx-options]<pre-unit>{number}[measure] where everything but number is optional.

The MWE below achieves my objective by copying siunitx internals, which is a bad idea. In particular, I create a new Npn "jorg" based in \SI that changes the order of the original SI command and define \Zahl accordingly. Is there a more consistent and reliable way to achieve the same?

\documentclass{scrartcl}

\usepackage{siunitx,xparse,expl3}

\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}

\ExplSyntaxOn
% Create \Zahl based on siunitx' \num and \SI
%  The syntax is then \Zahl[siunitx-options]<pre-unit>{number}[measure]
\cs_new_protected:Npn \__siunitx_jorg:nnnn #1#2#3#4 {
\IfNoValueTF {#2}
{ \tl_clear:N \l__siunitx_pre_unit_tl }
{
\group_begin:
\__siunitx_unit_in:nn {#2} {#1}
\cs_set_eq:NN \l__siunitx_pre_unit_tl \l__siunitx_unit_tl
\exp_args:NNNo \group_end:
\tl_set:Nn \l__siunitx_pre_unit_tl { \l__siunitx_unit_tl }
}
\cs_set_eq:NN \l__siunitx_brackets_bool
\l__siunitx_multi_brackets_bool
\__siunitx_combined_unit:nnn {#3} {#4} {#1}
\__siunitx_combined_output:n {#3}
}

\NewDocumentCommand\Zahl{o D<>{} m O{}}%
{
\leavevmode
\group_begin:
\IfNoValueTF {#1}
{ \__siunitx_jorg:nnnn { } {#2} {#3} {#4} }
{
\keys_set:nn { siunitx } {#1}
\__siunitx_jorg:nnnn {#1} {#2} {#3} {#4}
}
\group_end:
}
\ExplSyntaxOff

\DeclareSIUnit\%{\char37}

\begin{document}

\Zahl{200}

\Zahl{200}[\percent]

\Zahl<£>{200}

\Zahl<£>{200}[\percent]

\Zahl[round-mode=figures,round-precision=3]<£>{200.7}[\percent]

\end{document}
-
This seems like a situation where using key values instead of optional arguments might be more user-friendly –  A.Ellett Dec 5 '12 at 16:02
I've wondered about a keyval 'pre-unit' argument, but it's not really correct. I also suspect I should have coded the pre-unit part completely separately from the main unit as it's conceptually entirely different. –  Joseph Wright Dec 5 '12 at 17:47

You don't need to have a relay function here, as part of the point of xparse is that the code-level functions should 'just work' with the correct number of mandatory arguments.

\documentclass{article}
\usepackage{siunitx}
\ExplSyntaxOn
\NewDocumentCommand \Zahl {o D<>{} m O{}}
{
\leavevmode
\group_begin:
\IfNoValueTF {#1}
{ \__siunitx_combined:nnnn { } {#3} {#2} {#4} }
{
\keys_set:nn { siunitx } {#1}
\__siunitx_combined:nnnn {#1} {#3} {#2} {#4}
}
\group_end:
}
\ExplSyntaxOff
\begin{document}

\Zahl{200}

\Zahl{200}[\percent]

\Zahl<\pounds>{200}

\Zahl<\pounds>{200}[\percent]

\Zahl[round-mode=figures,round-precision=3]<\pounds>{200.7}[\percent]

\end{document}

There are a few reasons I don't particularly like this idea, from an interface point of view

• Trailing optional arguments are not very common in LaTeX2e (certain for general use document commands)
• I chose to separate out \num and \SI for a reason :-) (The concepts 'a number' and 'a quantity' are different.)

plus one from a coding point of view

• There is not a proper documented code level interface for siunitx (my fault!)

However, it should work well enough. I'm not about to alter the internal interface at the moment, and if I do it will be to provide a documented code-level one.

-
Thanks, I forgot to ask in the main question: Is there a drawback of \DeclareSIUnit\%{\char37} and using \% instead of \percent for si-numbers? –  Jörg Dec 5 '12 at 17:49
@Jörg No, should be fine: it's just a convention that unit names are words. To be honest, % is an odd one as it's not really a unit, but is in siunitx for reasons of realism :-) –  Joseph Wright Dec 5 '12 at 17:57