11

Suppose I am using siunitx with per-mode=fraction, and that I have declared \mile to be a new unit (with abbreviation 'mi').

Is there any automated way to have \si{\mile\per\hour} be recognized as special, and output 'mph' instead of 'mi' on top of 'h'? I'd be fine if there were a way to do this that either did or did not extend to things like \si{\per\hour\mile} or \si{\kilo\gram\mile\per\hour}.

EDIT----

For instance, is there a way to insert a hook macro into \SI{}{} and \si{} that would examine the argument, and in the case it was \mile\per\hour, swap it out for something separately defined like a \mph?

  • 2
    Is there something stopping you from simply writing "mph" to begin with? By the way, isn't one expressly discouraged from using "imperial" units of measurement (miles, gallons, ounces, degrees Fahrenheit, etc) in scientific publications? – Mico Jan 21 '15 at 4:51
  • 1
    @Mico To your first question, I'm not working on a scientific publication. My document projects often require use of non-SI units because of who the audience is. To the second question, is there something stopping anyone from just writing any unit abbreviation directly in the first place? Why use \si{\kilo\meter} instead of just km? Because of global control of unit formatting. That's not only something that SI unit-users want. Suppose I manage to implement this and decide to change how this particular unit should be formatted. It's about separating content from presentation. – alex.jordan Jan 21 '15 at 5:00
  • 1
    Why don't simply define \DeclareSIUnit\mph{mph} and use \mph instead of \mile\per\hour? – karlkoeller Jan 21 '15 at 6:10
  • 1
    @karlkoeller I could; in fact that's what I'm doing for now. But that practice is inconsistent with good separation of content and presentation. Perhaps I should say: I don't expect that siunitx has a built-in way to do this. I've already combed through its documentation. I'm posting a question here in case someone knows of a more base tex macro that could be employed to recognize \mile\per\hour and treat it as an alias for something like \mph. – alex.jordan Jan 21 '15 at 6:49
  • 2
    Also, this project stems from xml source processed via xsltproc into tex. In theory, my xml source indicating something like 60 miles per hour could be processed into kilometers per hour, miles per second, feet per minute, etc. And so I wouldn't care to hard code a compound unit like mph. I'm trying to ask a very specific tex question, not look for workarounds. – alex.jordan Jan 21 '15 at 6:53
13

As already noted, there is no build-in functionality to do this and the 'preferred' way to handle odd units is either to define a unit macro for the special case

\DeclareSIUnit{\mph}{mph}

or to use 'literal' input

\si{mph}

There is no 'hook' available for picking out 'special case' multi-part units but we can pick this up by redefining an internal function (note: I am working on v3 of siunitx and this name therefore may change: there will though be documented interfaces at the code level).

\documentclass{article}
\usepackage{siunitx}
\ExplSyntaxOn
\cs_new_eq:NN \__siunitx_saved_unit_in:nn \__siunitx_unit_in:nn
\cs_set_protected:Npn \__siunitx_unit_in:nn #1
  {
    \str_if_eq:nnTF {#1} { \mile \per \hour }
      { \__siunitx_saved_unit_in:nn { \mph } }
      { \__siunitx_saved_unit_in:nn {#1} }
  }
\ExplSyntaxOff

\sisetup{per-mode=fraction}
\DeclareSIUnit\mile{mi}
\DeclareSIUnit{\mph}{mph}

\begin{document}
\si{\mile}
\si{\kilo\gram\mile\per\hour}
\si{\mile\per\hour}
\SI{10}{\mile\per\hour}
\SI{20}{\kilo\gram\mile\per\hour}
\end{document}

The idea here is to alter the function that does the parsing/formatting of the unit so we test 'up front' for the exact input \mile\per\hour, and if found we replace it with \mph which is then processed as normal. An alternative would be to skip the parser entirely and hard-code mph:

\cs_set_protected:Npn \__siunitx_unit_in:nn #1
  {
    \str_if_eq:nnTF {#1} { \mile \per \hour }
      { \tl_set:Nn \l__siunitx_unit_tl { mph } }
      { \__siunitx_saved_unit_in:nn {#1} }
  }
  • This is what I was hoping for, thank you. I may implement this for kph and fps as well. I'm trying to maintain the logical connections between things like \mile, \hour, and 'mph', and just making \mph as a new odd unit doesn't exactly do that. – alex.jordan Jan 22 '15 at 0:15
5

This is too difficult to achieve. What do you want to get from \mile\per\second? And what from \meter\per\hour? It seems that you only want to change one single case and for this, you should define its own unit. \DeclareSIUnit\mph{mph} is clear and easy to use and you still have the possibility to redefine it later on.

% arara: pdflatex

\documentclass{article}
\usepackage{siunitx}
\sisetup{per-mode=fraction}
%\DeclareSIUnit{\mile}{mi} % if you want/need to change back
\DeclareSIUnit{\mph}{mph}
%\DeclareSIUnit{\mph}{\mile\per\hour} % if you want/need to change back

\begin{document}
    \SI{42}{\mph}
\end{document}

enter image description here

  • 1
    Thanks for the answer, but see my comment about the xml source of these projects. I keep asking question X, and being told that I should be asking question Y instead. But I know more details of my project than I want to go into here, and I really am asking question X. If the answer to question X is that it can't be done, then I can live with that. – alex.jordan Jan 21 '15 at 6:59
  • @alex.jordan Yes, I got you. But I would not know how to do that. Tweaking (patching) around in siunitx might solve something, but I don't dare. As you can see from your posts last edit, the siuntix-maintainer has found your question. Let's be patient and see, what he says. – LaRiFaRi Jan 21 '15 at 7:04

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.