# Transforming a statement into a mathematical expression

Is there a way, where I could automatically transform a string (using a command) like:

(1/SF) * (MDD\_a) * (1/LDD\_b) * (MBS\_b) * (1/SSA\_ab)


into a mathematical expression like:

$(\frac{1}{SF}) * (MDD\_a) * (\frac{1}{LDD\_b}) * (MBS\_b) * (\frac{1}{SSA\_ab})$


when then looks like:

I have several dynamic statements of the above form, which I would automatically transform to a mathematical expression.

• no. as displayed math term i guess that you need to rewrite it into $\frac{1}{\mathrm{SF}}\mathrm{MDD}_a\frac{1}{\mathrm{LDD}_b}\mathrm{MBS}_b \frac{1}{\mathrm{SSA}_{ab}} = \frac{\mathrm{MDD}_a}{\mathrm{SF}}\frac{\mathrm{MBS}_b}{\mathrm{LDD}_b} \frac{1}{\mathrm{SSA}_{ab}} = ...$ – Zarko May 13 '19 at 8:06
• @Zarko How could I write a command that transforms the text like (1/SF) * (MDD\_a) * (1/LDD\_b) * (MBS\_b) * (1/SSA\_ab) into a mathematical expression? – Amanda May 13 '19 at 8:15
• presumably whatever is generating the original knows it is for tex since it is using \_ not _ in which case it would be much more reliable if it generated the fractions using \frac rather than an infix / – David Carlisle May 13 '19 at 8:44
• @Mico I am using LuaLatex – Amanda May 13 '19 at 10:12
• @Mico Can go without the parentheses. – Amanda May 13 '19 at 10:19

Here's a LuaLaTeX-based solution, which makes use of Lua's powerful string.gsub and string.sub functions.

%%% Must be compiled under LuaLaTeX
\documentclass{article}
\usepackage{luacode} % for 'luacode' environment
\begin{luacode}

function nicemath ( s )
s = s:gsub ( "%(([%w%_]+)/([%w%_]+)%)","\\frac{%1}{%2}" )
s = s:gsub ( "(%a+)_(%a+)" , "%1_{%2}" )
s = s:gsub ( "%u+" , "\\mathrm{%0}" )
s = s:gsub ( "%*" , "\\cdot " )
s = s:gsub ( "%b()", function ( x ) return x:sub ( 2 , -2 ) end ) -- optional
tex.sprint ( s )
end

\end{luacode}
\newcommand\nicemath[1]{\directlua{nicemath(\luastringN{#1})}}

\begin{document}
$\nicemath{(1/SF) * (MDD_a) * (1/LDD_b) * (MBS_b) * (1/SSA_ab)}$
\end{document}


I start with using the exact and very unusual answer at Translate in-line equations to TeX code (Any Package?) (no changes) to interpret and translate the user's input.

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{lmodern}
\usepackage{listofitems,ifthen}

\def\QS[#1]{%
\if+\Qsep[#1]+\else%
\if-\Qsep[#1]-\else%
\if/\Qsep[#1]\over\else%
\if=\Qsep[#1]=\else%
\if^\Qsep[#1]^\else%
\if(\Qsep[#1]\bgroup\left(\else%
\if)\Qsep[#1]\right)\egroup\else%
\if[\Qsep[#1]\bgroup\else%
\if]\Qsep[#1]\egroup\else%
\if*\Qsep[#1]\cdot\else%
\if_\Qsep[#1]\expandafter\theund\else%
\csname \Qsep[#1]\endcsname\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi%
}%

\def\theund#1[#2]{_{\mathrm{#1[#2]}}}%

\setsepchar[@]{=@(||)||[||]@^@/||*@+||-@_@alpha||beta||pi||cos||sin||tan}

\makeatletter

\expandafter{\expandafter\Q\expandafter[\tmp]}}
\expandafter{\expandafter\QS\expandafter[\tmp]}}

\makeatother

\newcommand\interpreteq[1]{%
\def\Z{}%
\presentQ%
\Z%
}

\newcounter{lindex}
\def\presentQ{% =
\setcounter{lindex}{0}%
\whiledo{\value{lindex}<\listlen\Q[]}{%
\stepcounter{lindex}%
\presentQA[\thelindex]%
\ifnum\value{lindex}<\listlen\Q[]\relax%
\gQS[\thelindex]%
\fi%
}%
}
\newcounter{lindexA}
\def\presentQA[#1]{% ()
\setcounter{lindexA}{0}%
\whiledo{\value{lindexA}<\listlen\Q[#1]}{%
\stepcounter{lindexA}%
\presentQB[#1,\thelindexA]%
\ifnum\value{lindexA}<\listlen\Q[#1]\relax%
\gQS[#1,\thelindexA]%
\fi%
}
}
\newcounter{lindexB}
\def\presentQB[#1]{% ^
\setcounter{lindexB}{0}%
\whiledo{\value{lindexB}<\listlen\Q[#1]}{%
\stepcounter{lindexB}%
\presentQC[#1,\thelindexB]%
\ifnum\value{lindexB}<\listlen\Q[#1]\relax%
\gQS[#1,\thelindexB]%
\fi%
}
}
\newcounter{lindexC}
\def\presentQC[#1]{% /*
\setcounter{lindexC}{0}%
\whiledo{\value{lindexC}<\listlen\Q[#1]}{%
\stepcounter{lindexC}%
\presentQD[#1,\thelindexC]%
\ifnum\value{lindexC}<\listlen\Q[#1]\relax%
\gQS[#1,\thelindexC]%
\fi%
}
}
\newcounter{lindexD}
\def\presentQD[#1]{% +-
\setcounter{lindexD}{0}%
\whiledo{\value{lindexD}<\listlen\Q[#1]}{%
\stepcounter{lindexD}%
\presentQE[#1,\thelindexD]%
\ifnum\value{lindexD}<\listlen\Q[#1]\relax%
\gQS[#1,\thelindexD]%
\fi%
}
}
\newcounter{lindexE}
\def\presentQE[#1]{% _
\setcounter{lindexE}{0}%
\whiledo{\value{lindexE}<\listlen\Q[#1]}{%
\stepcounter{lindexE}%
\presentQF[#1,\thelindexE]%
\ifnum\value{lindexE}<\listlen\Q[#1]\relax%
\gQS[#1,\thelindexE]%
\fi%
}
}
\newcounter{lindexF}
\def\presentQF[#1]{% alpha beta pi cos sin tan
\setcounter{lindexF}{0}%
\whiledo{\value{lindexF}<\listlen\Q[#1]}{%
\stepcounter{lindexF}%
\gQ[#1,\thelindexF]%
\ifnum\value{lindexF}<\listlen\Q[#1]\relax%
\gQS[#1,\thelindexF]%
\fi%
}
}

% THESE ARE THE REDEFITIIONS FOR TRANSLATION
\usepackage{environ}

\def\QSALT[#1]{%
\if+\Qsep[#1]+\else%
\if-\Qsep[#1]-\else%
\if/\Qsep[#1]\over\else%
\if=\Qsep[#1]=\else%
\if^\Qsep[#1]^\else%
\if(\Qsep[#1]{\left(\else%
\if)\Qsep[#1]\right)}\else%
\if[\Qsep[#1]{\else%
\if]\Qsep[#1]}\else%
\if*\Qsep[#1]\cdot\else%
\if_\Qsep[#1]\expandafter\theundALT\else%
\expandafter\noexpand\csname \Qsep[#1]\endcsname\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi%
}%

\def\theundALT#1[#2]{_{\noexpand\mathrm{#1[#2]}}}%

\makeatletter
\newcommand\translateeq[1]{%
\bgroup%
\let\QS\QSALT%
\def\Z{}%
\presentQ%
\protected@edef\ZZ{\Z}
\par\medskip\noindent%
\parbox{\linewidth}{\detokenize\expandafter{\ZZ}}%
\par\medskip%
\egroup%
}
\makeatother

\NewEnviron{translateeqs}{\expandafter\nexteqn\BODY\par\relax}

\long\def\nexteqn#1\par#2\relax{%
\translateeq{#1}\ifx\relax#2\else\nexteqn#2\relax\fi%
}
\begin{document}
\textbf{INTERPRETATING EQUATIONS}
$\interpreteq{(1/SF) * (MDD\_a) * (1/LDD\_b) * (MBS\_b) * (1/SSA\_ab)}$

\textbf{TRANSLATING EQUATIONS}

\translateeq{(1/SF) * (MDD\_a) * (1/LDD\_b) * (MBS\_b) * (1/SSA\_ab)}

\end{document}


Modifications can be made to reflect a different appearance.

For example, if \_ were, inside the definitions of \interpreteq and \translateeq, redefined as

\def\_{_}


and added to the parsing list via:

\setsepchar[@]{=@(||)||[||]@^@/||*@+||-@_||\_@alpha||beta||pi||cos||sin||tan}


then the result would look even better:

If the OP really wanted an asterisk rather than a \cdot in the output, then replacing \cdot with * in the definition of \QS and \QSALT would suffice, for example:

\def\QS[#1]{%
\if+\Qsep[#1]+\else%
\if-\Qsep[#1]-\else%
\if/\Qsep[#1]\over\else%
\if=\Qsep[#1]=\else%
\if^\Qsep[#1]^\else%
\if(\Qsep[#1]\bgroup\left(\else%
\if)\Qsep[#1]\right)\egroup\else%
\if[\Qsep[#1]\bgroup\else%
\if]\Qsep[#1]\egroup\else%
\if*\Qsep[#1]*\else%
\if_\Qsep[#1]\expandafter\theund\else%
\csname \Qsep[#1]\endcsname\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi%
}%


• I am using lualtex to render the document. As I do tex.print("$\string\\interpreteq{".. row_val .."}$"), I get an error saying ibb.co/yq1fQ5n – Amanda May 13 '19 at 10:51
• @Amanda I am unable to access your error (site is blocked to me.). Plus, I don't speak lualatex, which may also be an impediment to my understanding your problem. – Steven B. Segletes May 13 '19 at 10:52
• It says, Ambiguous; you need another { and }. \QS ... \if -\Qsep [#1] -\else \if /\Qsep [#1]\over .. – Amanda May 13 '19 at 11:12
• @Amanda I have never seen such a warning and don't know how to interpret it in light of the listofitems package. It might have something to do with the way you structured your tex.print command, but I am not the one to help you in that regard. – Steven B. Segletes May 13 '19 at 11:16

When you place the parentheses a little bit different, you can use ConTeXt's asciimath module.

\usemodule[asciimath]

\starttext

\startformula
\asciimath{1/(SF) * MDD_a * 1/(LDD_b) * MBS_b * 1/(SSA_(ab))}
\stopformula

\stoptext