4

I am trying to create an easier way to write math-formulas in tex for multiple assignments. At the current time, I am almost there. This example might not seem very intuitive, but I had to leave out a great deal to make it small enough.

What I am trying to accomplish in this example, is simply some string replacement. For every occurrence of string defined in \allvars, replace them with whatever \varprint{string for \allvars} outputs. However, I have messed up the expansion here, and have tried a few other ways, but I just don't quite understand really. The string-replacement works as expected, but I need StrSubstitute to rerun with its own output on the next index in allvars. Any help on this is greatly appreciated.

\documentclass[11pt]{article}
\usepackage{xinttools, xstring}
\newcommand{\allvars}{sideA,sideB,sideC}
\newcommand{\varPrint}[1]{%
great(#1)
} % just a command used in this example. in real document, a more advanced output is to be expected from this.
\newcommand{\matte}[1]{%
    \edef\mattetempB{#1}
        \xintFor ##1 in {\allvars}\do%
     {\def\mattetempB{%
        \StrSubstitute{\mattetempB}{##1}%
        {\varPrint{##1}}%
        }%
     }%
     \mattetemp
    }%


\begin{document}
\matte{sideA+sideB=sideC},\\

Would like to see something like the following:\\

great(sideA)+great(sideB)=great(sideC)\\

But only sees:\\

sideA+sideB=great(sideC) ,

\end{document}
8
  • 2
    \StrSubstitute definitely doesn't work in \edef.
    – egreg
    Dec 18, 2015 at 10:01
  • ok, thanks. I have just been trying different things on it. Do you know how to move forward?
    – Runar
    Dec 18, 2015 at 10:10
  • 1
    To catch the output of \StrSubstitute, you'll need to use the optional output parameter; something like \StrSubstitute{}{}{}[\OutputMacro]. Then afterwards you can use \def\mattetemp{\OutputMacro}. Dec 18, 2015 at 10:13
  • So you sort of reinventing the wheel? The easiest way to write TeX formulas is to write them as regular TeX code. Dec 18, 2015 at 10:14
  • 1
    You're welcome! As I was struggeling a lot with this myself a few years back I'm glad to be able to spare you the trouble. Dec 18, 2015 at 10:42

2 Answers 2

3

The macros in the xstring package output text directly, which can't be used to feed into other macros. To return text that can be used for further manipulation you can use the trailing optional parameter which will save the output in the macro specified there. So instead of something like

\newcommand{\MySubst}{\StrSubstitute{abracadabra}{a}{o}}

you'll first need to save the output and do your definition afterwards:

\StrSubstitute{abracadabra}{a}{o}[\MyOutput]
\newcommand{\MySubst}{\MyOutput}
4
  • Thanks, I really should have thought of that. I was looking at that very piece in the documentation for xstring, but I was too focused on expansion.
    – Runar
    Dec 18, 2015 at 11:02
  • 1
    I know what you mean. When I was struggling with this I kept wondering why it wasn't working when it obviousely put out the expected text. Especially bad if you're used to just using a function to return the argument of another function as you would do in e.g. Python. Dec 18, 2015 at 11:26
  • perhaps using \edef{\MySubst}{\MyOutput} (or xdef for global scope) could be envisioned else any later use of \StrSubstitute will have to use something else than \MyOutput else will overwrite it, hence also \MySubst will change.
    – user4686
    Dec 18, 2015 at 11:48
  • during testing you can use \typeout{\meaning\foo}, or even \ttfamily \meaning\foo to see what \foo really looks like (and not only its textual output).
    – user4686
    Dec 18, 2015 at 11:54
2

Here's a more generic version, based on l3regex.

\documentclass{article}
\usepackage{xparse,l3regex,siunitx}

\ExplSyntaxOn

\prop_new:N \g_runart_variables_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 formatting
  \prop_gput:Nnn \g_runart_variables_prop { #1 } { #2 }
 }

\NewDocumentCommand{\removevariable}{m}
 { % #1 is the name
  \prop_gremove:Nn \g_runart_variables_prop { #1 }
 }

\NewDocumentCommand{\matte}{m}
 { % #1 is the expression to output
  \tl_set:Nn \l__runart_variables_matte_tl { #1 }
  \prop_map_inline:Nn \g_runart_variables_prop
   {
    \tl_set:Nn \l__runart_variables_item_tl { ##2 }
    \regex_replace_all:nnN
     { ##1 }
     { \u{l__runart_variables_item_tl} }
     \l__runart_variables_matte_tl
   }
  \tl_use:N \l__runart_variables_matte_tl
 }

\cs_new_protected:Nn \runart_variable_use:n
 {
  \prop_item:Nn \g_runart_variables_prop { #1 }
 }
\ExplSyntaxOff

\definevariable{a_car}{\SI{20}{\metre\per\second}}
\definevariable{v_car}{\SI{40}{\metre}}
\definevariable{t_car}{\SI{2}{\second}}

\begin{document}

\[
\matte{
  a_car=\frac{v_car}{t_car}
}
\]

\end{document}

enter image description here

3
  • This does almost all I am trying to do. I do have some problems using it in my script. Any hints for what to change? I currently define vars this way: \NewDocumentCommand{\varSet}{mmmmo} { \prop_gclear_new:c { g_giacomo_var_#1_prop } \prop_gput:cnx { g_giacomo_var_#1_prop } { value } { #2 } \prop_gput:cnn { g_giacomo_var_#1_prop } { unit } { #3 } \prop_gput:cnn { g_giacomo_var_#1_prop } { name } { #4 } }
    – Runar
    Dec 18, 2015 at 12:08
  • 1
    @runartrollet Please, make a new question linking to this one. The setting is much more complicated than you showed here.
    – egreg
    Dec 18, 2015 at 12:34
  • I agree. Here is the new question. tex.stackexchange.com/questions/283760/expandable-math
    – Runar
    Dec 18, 2015 at 12:54

You must log in to answer this question.

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