Converting units in text

Hey all,

I would like to create a script where all the units of the copied text in the clipboard to be replaced with metric measurements instead of the imperial.

i.e. “2 oz of water at 212°F” to become “57 gr. of water at 100°C”

I need this only for oz to grams and from Fahrenheit to Celsius conversions.

Is there any clever way to simplify the process, or should I create multiple if commands?

Hi.

It would be simple to write a couple of fast handlers to do the unit conversions. Alternatively, AppleScript’s unit coercions happen to include ounces, grams, degrees Fahrenheit, and degrees Celsius:

2 as ounces as grams as real --> 56.69905

212 as degrees Fahrenheit as degrees Celsius as real --> 100.0

Yes, I am aware of this and thank you.

My question is how to get only the numbers that are in front of the units in a string of text.

So, in this specific example, how to get only the numbers 2 and 212, in order to perform the conversions?


tell "2 oz of water at 212°F"
	{word 1 as ounces as grams as real, word -3 as degrees Fahrenheit as degrees Celsius as real}
end tell

Thank you man!

And what about if there is a list of items?

  • 3 oz acid A
  • 2 items B at XX°F
  • 8 oz acid C
  • 4 oz element D
  • 2 oz water at XX°F

How can I extract from this list only the numbers before the ounces and the temperature degrees?

The logic and structure of the elements of your list is not clear. You will have to explain in more detail. For example, what is “acid A” in the expression “* 3 oz acid A”.

They are chemical elements. So just text, strings.

But to make it more clear, imagine it as a list of ingredients and the steps for a cooking recipe.
Chemistry is the same.

Thus, imagine a string like in a cook book:

“We mix 2 oz Parmesan cheese with 15 springs fresh parsley, 4 oz yellow onions, 1 garlic clove and 24 oz ground beef and we bake at 212°F.”

What I am looking for is to search in it for the strings “oz” and “°F” in the text, to get all the numbers in front of them, to make the rounded conversions and then to get the text replacements “oz” to “gr.” and “°F” to “°C”.

So the previous string to become:

“We mix 57 gr. Parmesan cheese with 15 springs fresh parsley, 113 gr. yellow onions, 1 garlic clove and 680 gr. ground beef and we bake at 100°C.”

What I have noticed, that might help you, is that there are space characters before and after the numbers in front of every “oz” references and only one space character before the number in front of the temperatures.

use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions

local myStringList, mynum, stempList, i, atid

set myStringList to {"3 oz acid A", "2 items B at 105°F", "8 oz acid C", "4 oz element D", "2 oz water at 212°F"}
set atid to text item delimiters -- save the current text item delimters

repeat with i from 1 to count of myStringList
	set text item delimiters to " oz "
	set myList to text items of item i of myStringList
	set text item delimiters to " "
	if (count of myList) > 1 then
		set stempList to words of item 1 of myList
		set mynum to (last item of stempList) as number
		set mynum to (28.34952 * mynum) * 100 div 1 / 100 -- creates 2 decimal places
		set last item of stempList to (mynum as text)
		set item 1 of myList to stempList as text
		set text item delimiters to " grams "
		set item i of myStringList to myList as text
	end if
end repeat
repeat with i from 1 to count of myStringList
	set text item delimiters to "°F"
	set myList to text items of item i of myStringList
	set text item delimiters to " "
	if (count of myList) > 1 then
		set stempList to words of item 1 of myList
		set mynum to (last item of stempList) as number
		set mynum to (mynum - 32) * 5 / 9 * 100 div 1 / 100 -- creates 2 decimal places
		set last item of stempList to (mynum as text)
		set item 1 of myList to stempList as text
		set text item delimiters to "°C"
		set item i of myStringList to myList as text
	end if
end repeat
set text item delimiters to atid -- restore the saved text item delimters


set theText to "We mix 2 oz Parmesan cheese with 15 springs fresh parsley, 4 oz yellow onions, 1 garlic clove and 24 oz ground beef and we bake at 212°F."

set AppleScript's text item delimiters to " oz "
set temp to text items of theText
set newText to ""
repeat with i from 1 to (count temp) - 1
	tell (item i of temp)
		set beforeOz to text 1 thru -((length of word -1) + 1)
		set newText to newText & beforeOz & (word -1 as ounces as grams as integer) & " gr. "
	end tell
end repeat
set newText to newText & item -1 of temp

set AppleScript's text item delimiters to "°F"
set temp to text items of newText
set resultText to ""
repeat with i from 1 to (count temp) - 1
	tell (item i of temp)
		set beforeFar to text 1 thru -((length of word -1) + 1)
		set resultText to resultText & beforeFar & (word -1 as degrees Fahrenheit as degrees Celsius as integer) & "°C"
	end tell
end repeat
set resultText to resultText & item -1 of temp

Just by way of overkill:

use AppleScript version "2.4" -- OS X 10.10 (Yosemite) or later
use framework "Foundation"
use scripting additions

on convertUnits(theText)
	script ozConverter
		property pattern : "(?i)\\b([0-9]++)\\s?oz\\b"
		property newUnit : " gr."
		
		on convert(oz)
			return oz * 28.349525
		end convert
		
		on edit(theText)
			set regex to current application's class "NSRegularExpression"'s ¬
				regularExpressionWithPattern:(my pattern) options:(0) |error|:(missing value)
			set theMatches to (regex's matchesInString:(theText) options:(0) range:({0, theText's |length|()}))
			repeat with m from (count theMatches) to 1 by -1
				set thisMatch to item m of theMatches
				set amount to (theText's substringWithRange:(thisMatch's rangeAtIndex:(1))) as text as number
				set newAmount to my convert(amount) as integer as text
				tell theText to replaceCharactersInRange:(thisMatch's range()) withString:(newAmount & my newUnit)
			end repeat
		end edit
	end script
	
	script fahrConverter
		property parent : ozConverter
		property pattern : "(?i)((?:\\b|(?<=\\s)-)[0-9\\.]++)(?:°\\s?F(?:ahrenheit)?\\b|\\u2109)"
		property newUnit : "°C"
		
		on convert(fahr)
			return (fahr - 32) * 5 / 9
		end convert
	end script
	
	set theText to current application's class "NSMutableString"'s stringWithString:(theText)
	tell ozConverter to edit(theText)
	tell fahrConverter to edit(theText)
	return theText as text
end convertUnits

-- set the clipboard to "We mix 2 oz Parmesan cheese with 15 sprigs fresh parsley, 4 oz yellow onions, 1 garlic clove and 24 oz ground beef and we bake at 212°F."
convertUnits(the clipboard)

Oh wow!!! I have no words!

Thank you all guys!

You saved me for one more time!