# Repetitive replacement for expressing fractions in LaTeX

I am converting natural math expressions with fractions to Latex code.

What I have done seems to work on examples I've tested, but I'm not sure if the algorithm is safe. And maybe the string part could be improved.

Maybe a better approach could be replace the / from left to right, but how in my case target the next?

• By a generic pattern that matches the 3 cases at once.
• By selecting specific / and passing tests on it and remplacing it after.

I don't know how to make that.

Some examples

((a)/(b))/(c)   ->   \dfrac{\dfrac{a}{b}}{c}
(a)/((b)/(c))   ->   \dfrac{a}{\dfrac{b}{c}}
(a)/(b)/(c)/(d)    ->   \dfrac{\dfrac{\dfrac{a}{b}}{c}}{d}
((a)/(b))/((c)/(d)) ->    \dfrac{\dfrac{a}{b}}{\dfrac{c}{d}}


My try :

function ToFrac (s)
while s:find ("/") ~= nil
do

-- Remplace : \dfrac{}{}/() -> \dfrac{\dfrac...}{}
if ( s:find ( '\\dfrac%b{}%b{}/%b()' , j ) ~= nil )
then
x,y,num,den = s:find( '(\\dfrac%b{}%b{})/(%b())' )
den = den:gsub( '.(.+).' , '%1' )
s = s:gsub( '(\\dfrac%b{}%b{})/(%b())',
"\\dfrac{"..num.."}{"..den.."}" , 1 )
end

print ('### -- ', s)

-- Remplace : ()/\dfrac{}{} -> \dfrac{()}{\dfrac...}
if ( s:find ( '(%b()/\\dfrac%b{}%b{}' ) ~= nil )
then
x,y,num,den = s:find( '((%b())/(\\dfrac%b{}%b{})' )
num = num:gsub( '.(.+).' , '%1' )
s = s:gsub( '((%b())/()\\dfrac%b{}%b{})',
"\\dfrac{"..num.."}{"..den.."}" , 1 )
end

print ('### -- ', s)

-- Remplace : ()/() -> \dfrac{}{}
if ( s:find ( '%b()/%b()' , 1 ) ~= nil )
then
x,y,num,den = s:find( '(%b())/(%b())' )
num = num:gsub( '.(.+).' , '%1' )
den = den:gsub( '.(.+).' , '%1' )
s = s:gsub( '(%b())/(%b())',
"\\dfrac{"..num.."}{"..den.."}" , 1 )
end

print ('### -- ', s)

end -- while

return (s)

end

s = "((a)/(b))/(c)"
print (s, ToFrac(s))

s = "(a)/((b)/(c))"
print (s, ToFrac(s))

s = "(a)/(b)/(c)/(d)"
print (s, ToFrac(s))

s = "((a)/(b))/((c)/(d))"
print (s, ToFrac(s))

• Can you explain a bit more exactly what your code is doing? Preferably with input/output examples? – Simon Forsberg Jul 20 '15 at 21:25
• I put some examples. – Tarass Jul 21 '15 at 5:12
• In your third example, the parentheses don't match. – 200_success Jul 21 '15 at 5:44
• I made the correction. – Tarass Jul 21 '15 at 5:53
• I can't do it now, but I think the right solution is to index each / as /i, then replace each /i one by one using the right pattern. – Tarass Jul 21 '15 at 5:56

You can use a recursive function with the pattern %b() as follows:

function ToFrac( sInput )
local tStack = {}
for sOperand in sInput:gmatch "%b()" do
table.insert( tStack, sOperand:sub(2, -2) )
end
while true do
if #tStack <= 1 then break end
local sNumerator = table.remove( tStack, 1 )
if sNumerator:find '/' then sNumerator = ToFrac( sNumerator ) end
local sDenominator = table.remove( tStack, 1 )
if sDenominator:find '/' then sDenominator = ToFrac( sDenominator ) end
table.insert( tStack, 1, ([[\dfrac{%s}{%s}]]):format(sNumerator, sDenominator) )
end
return tStack
end


Here, I'm storing the operands as nodes in a stack. I tested the above function for the inputs:

local s = {
"((a)/(b))/(c)",
"(a)/((b)/(c))",
"(a)/((b)/(c))/(d)",
"(a)/(b)/(c)/(d)",
"((a)/(b))/((c)/(d))",
}

for k, v in pairs(s) do
print( v, ToFrac(v) )
end


The final results were:

((a)/(b))/(c)   \dfrac{\dfrac{a}{b}}{c}
(a)/((b)/(c))   \dfrac{a}{\dfrac{b}{c}}
(a)/((b)/(c))/(d)   \dfrac{\dfrac{a}{\dfrac{b}{c}}}{d}
(a)/(b)/(c)/(d) \dfrac{\dfrac{\dfrac{a}{b}}{c}}{d}
((a)/(b))/((c)/(d)) \dfrac{\dfrac{a}{b}}{\dfrac{c}{d}}