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}
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

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

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.