1

This is a followup to Egregs answer in the question Deleting defined variables or assign within group, I am trying to expand the code, but got into trouble while attempting some calculations with fpeval on variables. Basicly, I am trying to create a command which would take this input \mycalculation{a_car*2} and it would find every defined variable and replace it with its value(no matter how many variables are inside the argument). Say a_caris set to 20. The result would be 40. Now, this needs to be fully expanded.

I have tried many different ways to do this, but I cannot really get something to work. I have therefore edited the MWE from Egregs answers I got previously to show a rather naïve attempt at solving it.

\documentclass{article}
\usepackage{xparse,l3regex,siunitx,xcolor}
\usepackage[nomessages]{fp}

\ExplSyntaxOn

\cs_set_eq:NN \fpeval \fp_eval:n 

\seq_new:N \g_runart_variables_seq
\prop_new:N \l__runart_variables_temp_prop
\tl_new:N \l__runart_variables_matte_tl
\tl_new:N \l__runart_variables_item_tl

\NewDocumentCommand{\definevariable}{mm}
 { % #1 is the name, #2 is the key-value set
  \seq_if_in:NnF \g_runart_variables_seq { #1 }
   {
    \seq_gput_right:Nn \g_runart_variables_seq { #1 }
   }
  \prop_clear:N \l__runart_variables_temp_prop
  \keys_set:nn { runart/variables } { #2 }
  \prop_gclear_new:c { g_runart_var_#1_prop }
  \prop_gset_eq:cN { g_runart_var_#1_prop } \l__runart_variables_temp_prop
 }

% syntactic sugar
\cs_new_protected:Nn \__runart_put:nn
 {
  \prop_put:Nnn \l__runart_variables_temp_prop { #1 } { #2 }
 }

% keys
\keys_define:nn { runart/variables }
 {
  value .code:n = \__runart_put:nn { value } { #1 },
  value .value_required:n = true,
  unit .code:n = \__runart_put:nn { unit } { #1 },
  unit .value_required:n = true,
  name .code:n = \__runart_put:nn { name } { #1 },
  name .value_required:n = true,
  sisetup .code:n = \__runart_put:nn { sisetup } { #1 },
 }
\NewDocumentCommand{\mattevar}{m}
 { % #1 is the expression to output
  \__runart_matte_or_formal:nn { runart_variable_use_value:n } { #1 }
 }
\NewDocumentCommand{\matte}{m}
 { % #1 is the expression to output
  \__runart_matte_or_formal:nn { runart_variable_use_matte:n } { #1 }
 }
\NewDocumentCommand{\formal}{m}
 {
  \__runart_matte_or_formal:nn { runart_variable_use_formal:n } { #1 }
 }

\cs_new_protected:Nn \__runart_matte_or_formal:nn
 {
  \tl_set:Nn \l__runart_variables_matte_tl { #2 }
  \seq_map_inline:Nn \g_runart_variables_seq
   {
    \regex_replace_all:nnN
     { ##1 }
     { \c{#1} \cB\{ ##1 \cE\} }
     \l__runart_variables_matte_tl
   }
  \tl_use:N \l__runart_variables_matte_tl
 }

\cs_new:Nn \__runart_use_prop:nn
 {
  \prop_if_in:cnTF { g_runart_var_#1_prop } { #2 }
   {
    \prop_item:cn { g_runart_var_#1_prop } { #2 }
   }
   {
    \str_case:nn { #2 }
     {
      {value}{999999}
      {unit}{\metre}
      {name}{undefined}
     }
   }
 }
\cs_generate_variant:Nn \tl_if_empty:nTF { f }

\cs_new_protected:Nn \runart_variable_use_matte:n
 {
  \use:x % it's necessary to expand the optional argument
   {
    \SI
     [\__runart_use_prop:nn { #1 } {sisetup}]
     {\__runart_use_prop:nn { #1 } {value}}
     {\__runart_use_prop:nn { #1 } {unit}}
   }
 }

\cs_new_protected:Nn \runart_variable_use_formal:n
 {
  \__runart_use_prop:nn { #1 } { name }
 }
\cs_new_protected:Nn \runart_variable_use_value:n
 {
  \__runart_use_prop:nn { #1 } { value }
 }
\ExplSyntaxOff

\begin{document}

\definevariable{a_car}
 {
  name=a_{\mathrm{car}},
  value=20,
  unit=\metre\per\second,
 }

 \mattevar{a_car*2}
\fpeval{\mattevar{a_car*2}}
\end{document}
Runar
  • 6,082
  • The operation of automatically substituting a_car with the assigned value is not (and can't be) expandable. If you accept a syntax such as \fpeval{\mattevar{a_car}*2} then it's doable. – egreg Jan 10 '16 at 17:27
  • Oh, no wonder all my attempts failed than. I already got the code you mentioned in the comment working. So, I guess there is no way around it, then? But its fine, just means I'll have to put in \mattevar alot. Thanks, mate. – Runar Jan 10 '16 at 17:32
  • I'm not sure what's the purpose of “full expandability”. In my opinion, you're trying to stretch too much an idea that's against the spirit of TeX and logical markup. – egreg Jan 10 '16 at 17:38
  • Yeah, I should probably just use spreadsheets for the calculations, and the the other values I am storing in the variables, then import that file. It will probably speed up the compile-time too. – Runar Jan 10 '16 at 17:57

0 Answers0