I have a comma-separated array of strings, which I got from reading Pro Tools' AudioSuite menu with AppleScript. It looks like this (I extracted a few lines from the FabFilter block):
The array format is basically Plugin Name__Tag (which is actually a submenu, but Tag sounds more intuitive). A plugin name may have one or more tags, one per string.
At this point, I would like to group all tags bound to a plugin name, and make a single string out of those: Plugin Name_Tag1_Tag2_Tag3 etcetera.
I was thinking of using a "For Each" block in Keyboard Maestro, grouping all substrings by plugin name (reading strings up to the comma character), and build a new composite array.
In other words, RegEx for each string in the array should do the following:
Match everything up to "__";
For each match in 1), match everything after "__", until comma, and build the new string.
RegExes for 1) and 2) are
.+?(?=__)
and
[^,]+
Is there a way to combine the two RegEx expressions? Or should I keep two separate loops, one for plugin names and one for their tags?
It might actually be easier to do this in the AppleScript you use to collect them, then return a return-delimited list to KM. When you read the menu in AS, are you getting a list back (rather than a string)?
Hello Nige_S, I'm trying to make it simple...
Through AppleScript I get a list of menu items, structured like this:
menu item "FabFilter Pro-Q 3" of menu "EQ" of menu item "EQ" of menu "AudioSuite" of menu bar item "AudioSuite" of menu bar 1 of application process "Pro Tools"
The first "EQ" is actually a plug-in submenu, or "tag" (EQ, Dynamics, Reverb, Delay etc. etc.).
Then there's the "vendor" submenu, in this case FabFilter (not in the above example).
Then there's redundant infos.
I already simplified the list and kept only what I really need.
And I already filtered all tags, so that the vendor name comes right after the plugin name: FabFilter Pro-Q 3__FabFilter__Tag1__Tag2 etc.
The double underscore is totally arbitrary.
I was wondering about the quickest way of getting the Tag1__Tag2 part.
That sounds like my cue! I can do overcomplicated... Plus, very rusty with AS records
This would go at the end of the AppleScript that collects the menu items and assumes they are being presented as a list (as in the first line):
AppleScript
set theList to {"FabFilter Pro-Q 3__EQ", "FabFilter Pro-C 2__Dynamics", "FabFilter Pro-MB__Dynamics", "FabFilter Pro-R__Reverb", "FabFilter Pro-DS__Dynamics", "FabFilter Pro-L 2__Dynamics", "FabFilter Timeless 3__Delay", "FabFilter Pro-C 2__Harmonic"}
set theListofRecords to {{|name|:null, tag:null}}
set AppleScript's text item delimiters to "__"
repeat with eachItem in theList
set tmpName to text item 1 of contents of eachItem
set tmpTag to text item 2 of contents of eachItem
set foundFlag to false
repeat with eachRecord in theListofRecords
if eachRecord contains {|name|:tmpName} then
set tag of eachRecord to (tag of eachRecord & "__" & tmpTag)
set foundFlag to true
exit repeat
end if
end repeat
if not foundFlag then copy {|name|:tmpName, tag:tmpTag} to end of theListofRecords
end repeat
set theListofRecords to rest of theListofRecords
set outText to {}
repeat with eachRecord in theListofRecords
copy (|name| of eachRecord & "__" & tag of eachRecord) to end of outText
end repeat
set AppleScript's text item delimiters to linefeed
return outText as text
You could easily sort the output in KM with a "Filter" action -- downside is that the tags themselves aren't sorted, though you could fix that.
All of which made me wonder -- can we do it in similar fashion in KM? And sort the tags? I do keep promising to try and understand Dictionaries... And so:
Duplicates should, I think, fall away automatically if we define the accumulation in terms of key:value dictionaries (JS Objects) rather than ordered lists (JS Arrays),
seeding .reduce with {} rather than with [].
Works like a charm, no need to change anything!!
Of course the array gets used in a "Prompt with list" action.
Thank you @ComplexPoint and all for your help and commitment!!!