-- tag_table.applescript -- Tested: macOS 10.14.6 (18G95) -- Updated 2023-03-14: macOS 13.2.1, Revisions -- VikingOSX, 2019-09-04, Apple Support Communities, no warranties use framework "Foundation" use AppleScript version "2.4" -- Yosemite use scripting additions property NSString : a reference to current application's NSString property NSCharacterSet : a reference to current application's NSCharacterSet property |NSURL| : a reference to current application's |NSURL| property NSURLTagNamesKey : a reference to current application's NSURLTagNamesKey property NSDictionary : a reference to current application's NSDictionary -- set the following to false to generate a CSV or true for a Numbers spreadsheet property NumTbl : true -- whether we directly build Numbers table or write CSV file property outDoc_nbr : ((path to desktop as text) & "tags_out.numbers") as text -- csvdata is a list of row lists property csvdata : {} as list property csvdelim : ";" -- don't change this! property tblName : "File Paths and their Tag names" set HFSLst to {} set POSIXLst to {} set start_folder to (choose folder with prompt "Select Start Folder:" default location (path to desktop) without invisibles, multiple selections allowed and showing package contents) tell application "Finder" set HFSLst to (every item in folder start_folder whose name extension is "txt") as alias list end tell if (count of HFSLst) = 0 then return -- change the AppleScript paths to UNIX paths repeat with anItem in HFSLst copy POSIX path of anItem to the end of POSIXLst end repeat -- header row first copy ("File Paths" & csvdelim & "Tag Names") as list to the end of csvdata repeat with anItem in POSIXLst -- return list of tags on this file set tagList to my tags_string(anItem) as text copy (anItem & csvdelim & tagList) as list to the end of csvdata end repeat if NumTbl then my generate_numbers_table(csvdata) else set outfile to (choose file name with prompt "Choose CSV output filename:" default name "tags.csv" default location (path to desktop)) my write_csv(outfile) end if return on write_csv(afile) try set fRef to (open for access afile with write permission) set eof fRef to 0 -- overwrite repeat with aline in csvdata write (aline as text) & linefeed to fRef end repeat close access fRef on error try close access fRef end try end try return end write_csv on generate_numbers_table(alist) -- generate a new two-column table in Numbers with filenames and associated tag names -- close any previous Numbers document with table before running this. tell application "Numbers" activate set thisDocument to (make new document with properties {document template:template "Blank"}) delay 1 set rowCount to count of alist set columnCount to (count of item 1 of alist) + 1 tell thisDocument tell active sheet delete first table of it -- get rid of initial template table set thisTbl to ¬ make new table with properties {row count:rowCount, column count:columnCount, header column count:0, header row count:1, name:tblName} tell thisTbl set width of column 1 to 300.0 set width of column 2 to 250.0 set rowIndex to 0 set columnIndex to 0 if header row count = 1 then set background color of row 1 to {27993, 37494, 57797} -- light blue end if repeat with i from 1 to count of the alist set thisRowData to my split_row(item i of alist, csvdelim) as list tell row (rowIndex + i) repeat with j from 1 to the count of thisRowData tell cell (columnIndex + j) set value to (item j of thisRowData) as text set alignment to left set vertical alignment to bottom end tell end repeat end tell end repeat end tell end tell end tell -- save thisDocument in outDoc_nbr close document 1 saving yes saving in file outDoc_nbr end tell tell application "Numbers" to if it is running then quit return end generate_numbers_table on split_row(adata, adelim) -- adata: in the row, separate the filepath from the tag string set nstr to NSString's alloc()'s initWithString:(adata as text) set aset to NSCharacterSet's characterSetWithCharactersInString:adelim return (nstr's componentsSeparatedByCharactersInSet:aset) as list end split_row on tags_string(apath) -- Returns a string of tags on file, or empty list if no tags on file -- apath: POSIX path to file set thisKey to {"NSURLTagNamesKey"} set metadata to NSDictionary's dictionary() set aurl to |NSURL|'s fileURLWithPath:apath set metadata to aurl's resourceValuesForKeys:thisKey |error|:(missing value) if (metadata's objectForKey:NSURLTagNamesKey) is missing value then return {""} as list return ((metadata's objectForKey:NSURLTagNamesKey)'s componentsJoinedByString:", ") as text end tags_string