7

Problem

I use the siunitx-package to typeset numbers and units with correct spacing etc. There is a command

\SI{<number>}{<unit>}

for that. However, it would be much easier to write something like

\xSI{<number and unit>}

and let LaTeX automatically split the number and the unit and call \SI{}{} internally.

\xSI{9.81m/s^2}  →  \SI{9.81}{m/s^2}
\xSI{1e-3m}      →  \SI{1e-3}{m}

I know that expl3 provides some regex-functionality, but as I am only familiar with "regular" LaTeX I do not know where to start.

Question

How can I write a wrapper function for SI{}{} (using expl3?) so that the number and the unit parts get automatically split?

4
  • 1
    So all the trouble to save }{ keystrokes ?
    – percusse
    Apr 7 '13 at 21:17
  • I was thinking the same as percusse. Is this really your final intention? Apr 7 '13 at 21:20
  • @percusse Why not use a proper editor with Auto-Completion? \SI followed by Ctrl + <Space> gives me \SI{<cursor>}{} where I can easily “over-tab” the }{. Apr 7 '13 at 21:21
  • No, I'm not that lazy – I had to convert a pdf back to LaTeX, with lots of units in it. I wrote a script that fixes umlauts, unicode characters and line breaks, so I could copy-paste most of the document. However, it was a pain to fix the units, because pasting gave me something like 9, 81 m/s2 (not the spaces). I thought of a command in which I could wrap everything unit-related and LaTeX would do the rest. Also, this could be a good way to show what is possible in LaTeX3 and a good starting point for me to get more familiar with the expl3-syntax. Apr 10 '13 at 21:16
7

You find a regular expression for numbers in scientific format here

\documentclass{article}
\usepackage{siunitx,l3regex}
\ExplSyntaxOn
\NewDocumentCommand{\xSI}{ O{} m }
 {
  \ralfix_split:n { #2 }
  \ralfix_si:n { #1 }
 }

\seq_new:N \l__ralfix_pieces_seq
\cs_new_protected:Npn \ralfix_split:n #1
 {
  \regex_split:nnN
   {
    ( [ - + ]? [0-9]* [\.\,]? [0-9]+ ( [eE] [-+]? [0-9]+ )? )
    (.*)
   }
   { #1 }
   \l__ralfix_pieces_seq
 }
\cs_new_protected:Npn \ralfix_si:n #1
 {
  \use:x
   {
    \exp_not:n {\SI[#1]}
    {\seq_item:Nn \l__ralfix_pieces_seq {2}}
    {\seq_item:Nn \l__ralfix_pieces_seq {4}}
   }
 }
\ExplSyntaxOff
\begin{document}
\xSI{9.81m/s^2}

\xSI{1e-3m}

\xSI[output-decimal-marker={,}]{1,2e-33kV}
\end{document}

The function could be refined by first examining item number 1 in the resulting sequence, that will be non empty if no match has been found.

This said, I would recommend you using \SI{...}{...} which is not much more difficult to type and clearly separates different things from each other.

enter image description here

1
  • I had to add unit-formatting afterwards, so autocomplete was not a big help. Your solution is just perfect, thank you very much! Apr 10 '13 at 21:20

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.