Hello, all. Wondering if any of you Applescript wizards can give me a few pointers here. I’ve managed to cobble together a script that allows me to do a quick review of what I’ve been working on. I copy the archive from my main task file, and invoke the script via Textexpander to paste the archive into an NValt note, with totals for each tag. Since the “archive as done” script I’m using automatically grabs the project as a tag, that means I can quickly get a rough idea of how much work I’ve put in on various different areas/projects etc.
And no, I never did get my head around the CLI…
I have two questions. One specific query, and one more nebulous.
1: My command of regular expressions is pretty weak at the moment. The script doesn’t handle multiword tags particularly well, say, for example if the tag has a value e.g. @project(attack the DeathStar:). Any suggestions for an update that might capture tags like this?
TLDR— the reg exp is in this line: “set taglist to find text " @[a-zA-Z]+[(]?[a-zA-Z0-9-]+” in theClipboard with regexp, all occurrences and string result"
2: Any suggestions for more efficient functioning code would be appreciated. Still learning, here.
Here’s the script. Thanks in advance for any suggestions.
-- this counts tasks and projects from the clipboard, but we can switch to front most document for ease...
set theClipboard to the clipboard as text
set theClipboard to stripChar(theClipboard, tab)
set tid to AppleScript's text item delimiters
set AppleScript's text item delimiters to "
- "
set aList to the text items in the theClipboard
set theTasks to (the count aList) - 1
set AppleScript's text item delimiters to "# "
set aList to the text items in the theClipboard
set theProjects to (the count aList) - 1
set AppleScript's text item delimiters to tid
set taglist to find text " @[a-zA-Z]+[(]?[a-zA-Z0-9-]+" in theClipboard with regexp, all occurrences and string result
set olddelimiter to AppleScript's text item delimiters
set AppleScript's text item delimiters to " "
set AppleScript's text item delimiters to olddelimiter
set nTags to (the count taglist) - 1
set theList to {}
repeat with theWord in (every text item in taglist)
copy theWord & "—, " & countMatches(taglist, (contents of theWord)) as string to end of theList
end repeat
set tagOccur to removeduplicates(theList)
considering numeric strings
set tagOccur to simple_sort(tagOccur)
end considering
set tagOccur to replaceString(tagOccur, " @", "
")
set finalStats to "Tasks: " & theTasks & "; Projects: " & theProjects & "
" & tagOccur & "
---- " & "
" & theClipboard
set the clipboard to finalStats
tell application "System Events" to keystroke "v" using command down
-- FUNCTIONS AND SUBROUTINES
-- account for any tabs
on stripChar(str, chrs)
tell AppleScript
set oldTIDs to text item delimiters
set text item delimiters to characters of chrs
set TIs to text items of str
set text item delimiters to ""
set str to TIs as string
set text item delimiters to oldTIDs
end tell
return str
end stripChar
on countMatches(lst, val)
local lst, val, counter
try
if lst's class is not list then error "not a list." number -1704
script k
property l : lst
end script
set len to count k's l
set counter to 0
repeat with i from 1 to len
if k's l's item i is val then set counter to counter + 1
end repeat
return counter
on error eMsg number eNum
error "Can't countMatches: " & eMsg number eNum
end try
end countMatches
on removeduplicates(lst)
local lst, itemRef, res, itm
try
if lst's class is not list then error "not a list." number -1704
script k
property l : lst
property res : {}
end script
repeat with itemRef in k's l
set itm to itemRef's contents
-- note: minor speed optimisation when removing duplicates
-- from ordered lists: assemble new list in reverse so
-- 'contains' operator checks most recent item first
if k's res does not contain {itm} then ¬
set k's res's beginning to itm
end repeat
return k's res's reverse
on error eMsg number eNum
error "Can't removeDuplicates: " & eMsg number eNum
end try
end removeduplicates
on simple_sort(my_list)
set the index_list to {}
set the sorted_list to {}
repeat (the number of items in my_list) times
set the low_item to ""
repeat with i from 1 to (number of items in my_list)
if i is not in the index_list then
set this_item to item i of my_list as text
if the low_item is "" then
set the low_item to this_item
set the low_item_index to i
else if this_item comes before the low_item then
set the low_item to this_item
set the low_item_index to i
end if
end if
end repeat
set the end of sorted_list to the low_item
set the end of the index_list to the low_item_index
end repeat
return the sorted_list
end simple_sort
on replaceString(theText, oldString, newString)
local ASTID, theText, oldString, newString, lst
set ASTID to AppleScript's text item delimiters
try
considering case
set AppleScript's text item delimiters to oldString
set lst to every text item of theText
set AppleScript's text item delimiters to newString
set theText to lst as string
end considering
set AppleScript's text item delimiters to ASTID
return theText
on error eMsg number eNum
set AppleScript's text item delimiters to ASTID
error "Can't replaceString: " & eMsg number eNum
end try
end replaceString