Proportional Recipes
Share
Explore

# The making ofThe making of

## Regex replacement to multiply numbers?

The most challenging part to do this proportional recipe editor is to replace numbers inside cells by adjusted numbers, each row independently. As of 7/21/2020, Coda does not have yet RegexReplace that accepts an arbitrary function as replacement argument, only a string.
Here is the work-around. For example, below is a pair of a regular expression and a replacement expression that together can replace 15 with 30 and 4 with 8, in a way that is easy to extend, for example:
Input = “
For this recipe, I need 4 eggs and 15 bananas
Output1 = RegexReplace(Input + "
||||15:30,4:8
","\b(\d+)\b(?=[\s\S]*)\b\1:([^,]+)","\$2")
=”
For this recipe, I need 8 eggs and 30 bananas||||15:30,4:8
Output2 = RegexReplace(Output1, "\|\|\|\|.*", "")
=”
For this recipe, I need 8 eggs and 30 bananas
The idea above is to append the replacement map at the end of the original string, to find all the numbers to replace in the string, and apply a replacement only if, by using a forward lookup, it can find a binding from the same number (\1) to the mapped value, which is the second captured group (and that’s why we replace it with \$2).
Now we just need to generate a replacement map with the current multiplier for all numbers (in our case, from 6 to
2000
) and for all the small numbers that can appear in recipes (
0.250.330.50.660.751.251.51.7512.523.534.545.55
). I used Sequence and ListCombine to put all of these numbers into a list.
I used a similar trick to format the replacements themselves, so that we can have nice-looking ¼, 1½ and so on.
This entire replacement is computed in the invisible column “Replacement” of each recipe, and applied to Result Raw, Ingredients Raw and Instructions Raw so that the main page displays only rendered numbers in Result, Ingredients and Instructions.

## I would like to edit the rendered version of the recipe directly...

In that case, you would love to have bidirectional evaluation (Mayer, Chugh and Kuncak, 2018)... see below what we can do with such a feature. currently develops bidirectional engines that might one day be applicable to Coda, if there is interest from the community.