2

I am trying to store SI-units in variables so that I can manipulate the number mathematically and show it afterwards with the correct prefix and exponent according to our schools scientific notation for engineers. I came across a code to store these easily, but for some reason it fails when I set the SIsetup exponent-to-prefix to true. Is there any way around this?

\documentclass{article}
\usepackage[per-mode=fraction]{siunitx} % also loads xparse and expl3
\sisetup
  {
    exponent-to-prefix = true        ,
    round-mode         = figures     ,
    round-precision    = 3           ,
    scientific-notation = engineering,
  }


\ExplSyntaxOn
\NewDocumentCommand{\setvariable}{mmm}
 {
  \prop_gclear_new:c { g_giacomo_var_#1_prop }
  \prop_gput:cnn { g_giacomo_var_#1_prop } { value } { #2 }
  \prop_gput:cnn { g_giacomo_var_#1_prop } { unit } { #3 }
 }

\NewDocumentCommand{\printvariable}{sm}
 {
  \IfBooleanTF{#1}
   {
    \num { \__giacomo_get:nn { #2 } { value } }
   }
   {
    \SI { \__giacomo_get:nn { #2 } { value } }
        { \__giacomo_get:nn { #2 } { unit } }
   }
 }

% syntactic sugar
\DeclareExpandableDocumentCommand{\getvalue}{m}
 {
  \__giacomo_get:nn { #1 } { value }
 }
\cs_new:Npn \__giacomo_get:nn #1 #2
 {
  \prop_item:cn { g_giacomo_var_#1_prop } { #2 }
 }
\cs_set_eq:NN \fpeval \fp_eval:n
\ExplSyntaxOff

\setvariable{Length}{800000}{\metre}

\begin{document}

\SI{800000}{\metre}

\printvariable{Length}

\end{document}

1 Answer 1

2

When exponent-to-prefix is set to true, the code enters an infinite loop.

Workaround: full expand the second argument before \SI sees it.

\documentclass{article}
\usepackage[per-mode=fraction]{siunitx} % also loads xparse and expl3
\sisetup
  {
    exponent-to-prefix = true        ,
    round-mode         = figures     ,
    round-precision    = 3           ,
    scientific-notation = engineering,
  }


\ExplSyntaxOn
\NewDocumentCommand{\setvariable}{mmm}
 {
  \prop_gclear_new:c { g_giacomo_var_#1_prop }
  \prop_gput:cnn { g_giacomo_var_#1_prop } { value } { #2 }
  \prop_gput:cnn { g_giacomo_var_#1_prop } { unit } { #3 }
 }

\NewDocumentCommand{\printvariable}{sm}
 {
  \IfBooleanTF{#1}
   {
    \num { \__giacomo_get:nn { #2 } { value } }
   }
   {
    \exp_args:Nnx \SI { \__giacomo_get:nn { #2 } { value } }
        { \__giacomo_get:nn { #2 } { unit } }
   }
 }

% syntactic sugar
\DeclareExpandableDocumentCommand{\getvalue}{m}
 {
  \__giacomo_get:nn { #1 } { value }
 }
\cs_new:Npn \__giacomo_get:nn #1 #2
 {
  \prop_item:cn { g_giacomo_var_#1_prop } { #2 }
 }
\cs_set_eq:NN \fpeval \fp_eval:n

\ExplSyntaxOff

\setvariable{Length}{800000}{\metre}

\begin{document}

\SI{800000}{\metre}

\printvariable{Length}

\printvariable*{Length}

\end{document}

enter image description here

1
  • 1
    Thanks, this solved my problem. Very grateful, now my paper will be perfect.
    – Runar
    Commented Oct 16, 2015 at 9:32

You must log in to answer this question.

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