In trying to parse if statements that might be nested, I've come up with a recursive solution:
on findIfs(str)
#base case: no ifs remain to be parsed, so return str as is
if ((offset of "${" in str) = 0) or ((offset of "$?" in str) = 0) or ((offset of "$:" in str) = 0) or ((offset of "$}" in str) = 0) then
return str
else #we have an if to parse
display dialog "parsing: " & str
#find the first left brace and question mark, and the last right brace and colon
set reversedStr to (reverse of (characters of str) as string)
set startIndex to offset of "${" in str
set ifIndex to offset of "$?" in str
set elseIndex to (length of str) - (offset of ":$" in reversedStr)
set endIndex to (length of str) - (offset of "}$" in reversedStr)
#evaluate the condition (between the left brace and question mark) and strip all but the if or else part from str
if evaluateBoolean(characters (startIndex + 2) through (ifIndex - 1) of str as string) then #use the if
display dialog "choosing if"
return cutFromString(str, {{startIndex, (ifIndex + 1)}, {elseIndex, (endIndex + 1)}})
else #use the else
display dialog "choosing else"
return cutFromString(str, {{startIndex, (elseIndex + 1)}, {endIndex, (endIndex + 1)}})
end if
#run it again to catch any nested ifs
return findIfs(str)
end if
end findIfs
The evaluateBoolean function is just there to return false for missing value, 0, an empty string, and so on, and true otherwise. The cutFromString function is the issue here. I use it to quickly return the original template string, or a substring thereof depending on where we are in the recursion, with the conditional keyword completely removed and the if or else section removed depending on if the conditional keyword evaluated to true or false. So, I need to cut the ${ through $? all the time, then cut either the if or else section and return the newly trimmed string for further consideration by the findIfs function. If I hard-code removing things based on the offsets I calculate near the start, however, I run the risk of getting errors like "can't get character 1 through 0" or "can't get characters 33 through 33". That's why I was hoping for a function to do all the logic needed to take care of possible problems like that, and just give me back the string sans the bits I don't want to keep.
As stated earlier, the problem here is that I cannot remove all the sections I need to, since removing one throws off the offsets of the rest. I keep coming up with complex solutions, like sorting the pairs of offsets from least to greatest and then tracking the amount by which each removal shifts the rest of the string, but I feel like there has to be a simpler way. I'd rather avoid text item delimiters since it is possible that a user could set two ifs or elses in a template to the same value, so removing one would remove both. The findIfs function works from the outside in, so I could not isolate the statement I'm working with to avoid problems like that. Also, script extensions are not great, since this is all part of those scripts I've been working on that speak information and so everything needs to be totally portable and require nothing more than unzipping a folder no matter which computer the user is on.
So, the bottom line of this very long post: I need a way to remove chunks from a string given the string and the sets of numbers, like {{1,3}, {8,16}}. Any suggestions will be great, and sorry this was so long. Please tell me if I should provide more functions (I have a partial implementation of a solution, but it fails miserably, hence this email). Thanks in advance!
Have a great day,
Alex (msg sent from Mac Mini)
email@hidden
Do not post admin requests to the list. They will be ignored.
AppleScript-Users mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
Archives: