4

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:

enter image description here

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 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 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 at 8:44
  • 1
    @Mico I am using LuaLatex – Amanda May 13 at 10:12
  • 1
    @Mico Can go without the parentheses. – Amanda May 13 at 10:19
3

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

enter image description here

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

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

\def\gQ[#1]{\edef\tmp{#1}\expandafter\g@addto@macro\expandafter\Z%
  \expandafter{\expandafter\Q\expandafter[\tmp]}}
\def\gQS[#1]{\edef\tmp{#1}\expandafter\g@addto@macro\expandafter\Z%
  \expandafter{\expandafter\QS\expandafter[\tmp]}}

\makeatother

\newcommand\interpreteq[1]{%
  \def\Z{}%
  \greadlist*\Q{#1}%
  \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{}%
  \greadlist*\Q{#1}%
  \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}

enter image description here

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:

enter image description here

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

enter image description here

  • 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 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 at 10:52
  • It says, Ambiguous; you need another { and }. \QS ... \if -\Qsep [#1] -\else \if /\Qsep [#1]\over .. – Amanda May 13 at 11:12
  • 1
    @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 at 11:16
2

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

enter image description here

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.