I revised the File Compare script to use the swiftDialog app to both get the files that will be compared and to display the results in a markdown table. Please note the swiftDialog display options that alter window size in the showTable handler.
--Compare two text files and display result in a markdown table
--Requires swiftDialog app
--Revised 2024.09.05
use framework "Foundation"
use scripting additions
on main()
set {fileOne, fileTwo} to showDialog()
if (fileOne's isEqualToString:"") is true or (fileTwo's isEqualToString:"") is true then display dialog "A file was not selected" buttons {"OK"} cancel button 1 default button 1 with icon stop
set stringOne to current application's NSString's stringWithContentsOfFile:fileOne encoding:(current application's NSUTF8StringEncoding) |error|:(missing value)
if stringOne is (missing value) then display dialog "Text was not found in File One" buttons {"OK"} cancel button 1 default button 1 with icon stop
set stringOne to cleanString(stringOne)
set arrayOne to (stringOne's componentsSeparatedByString:linefeed)
set stringTwo to current application's NSString's stringWithContentsOfFile:fileTwo encoding:(current application's NSUTF8StringEncoding) |error|:(missing value)
if stringTwo is (missing value) then display dialog "Text was not found in File Two" buttons {"OK"} cancel button 1 default button 1 with icon stop
set stringTwo to cleanString(stringTwo)
set arrayTwo to (stringTwo's componentsSeparatedByString:linefeed)
set arrayOneUnique to current application's NSMutableArray's new()
set arrayTwoUnique to arrayTwo's mutableCopy()
set commonArray to current application's NSMutableArray's new()
repeat with anItem in arrayOne
if (arrayTwoUnique's containsObject:anItem) is true then --item in both arrays
(commonArray's addObject:anItem)
(arrayTwoUnique's removeObjectAtIndex:(arrayTwoUnique's indexOfObject:anItem))
else --item in arrayOne only
(arrayOneUnique's addObject:anItem)
end if
end repeat
set arrayCount to {arrayOneUnique's |count|(), arrayTwoUnique's |count|(), commonArray's |count|()}
set arrayCount to current application's NSArray's arrayWithArray:arrayCount
set arrayCount to (arrayCount's valueForKeyPath:"@max.self") as integer
set theTable to current application's NSMutableArray's new()
set emptyString to current application's NSString's stringWithString:""
repeat with i from 0 to (arrayCount - 1)
try
set columnOne to truncateString(commonArray's objectAtIndex:i)
on error
set columnOne to emptyString
end try
try
set columnTwo to truncateString(arrayOneUnique's objectAtIndex:i)
on error
set columnTwo to emptyString
end try
try
set columnThree to truncateString(arrayTwoUnique's objectAtIndex:i)
on error
set columnThree to emptyString
end try
set aRow to current application's NSString's stringWithFormat_("| %@ | %@ | %@ |", columnOne, columnTwo, columnThree)
(theTable's addObject:aRow)
end repeat
set theTable to (theTable's componentsJoinedByString:linefeed)
set theHeader to "| Both Files | File One Only | File Two Only |"
set theFormatter to "| :--- | :--- | :--- |"
set theLinefeed to linefeed
set theString to current application's NSString's stringWithFormat_("%@%@%@%@%@", theHeader, theLinefeed, theFormatter, theLinefeed, theTable) as text
showTable(theString)
end main
on showDialog()
try
set userInput to do shell script "/usr/local/bin/dialog --title 'File Compare' --titlefont 'size=15' --message 'Select two text files to compare:' --messagefont 'size=14' --messageposition top --button2 --width 400 --height 230 --hideicon --moveable --textfield 'File One,fileselect' --textfield 'File Two,fileselect'"
on error
error number -128
end try
set userInput to current application's NSMutableString's stringWithString:userInput
(userInput's replaceOccurrencesOfString:"(?m)^.* : (.*)$" withString:"$1" options:1024 range:{0, userInput's |length|()}) --option 1024 implements regex
return (userInput's componentsSeparatedByString:return)
end showDialog
on showTable(theString)
do shell script "/usr/local/bin/dialog --title none --message " & quoted form of theString & " --messagefont 'size=14' --hideicon --position top --moveable" --consider resizable, and width and height options
end showTable
on cleanString(theString) --disable any of the following
set theString to theString's stringByReplacingOccurrencesOfString:"([*#$>|])" withString:"\\\\$1" options:1024 range:{0, theString's |length|()} --escape markdown characters
set theString to theString's stringByReplacingOccurrencesOfString:"(?m)^\\h+|\\h+$" withString:"" options:1024 range:{0, theString's |length|()} --remove leading and trailing whitespace every line
set theString to theString's stringByReplacingOccurrencesOfString:"^\\s*\\R|\\s*$" withString:"" options:1024 range:{0, theString's |length|()} --remove blank lines at beginning and end of string
set theString to theString's stringByReplacingOccurrencesOfString:"(\\R)\\s*\\R" withString:"$1" options:1024 range:({0, theString's |length|()}) --remove blank lines except at beginning and end of string
end cleanString
on truncateString(theString) --truncate lines at 100 characters
set theRange to theString's rangeOfString:".{100}" options:1024
if theRange's |length| is 0 then return theString
return (theString's substringWithRange:theRange)'s stringByAppendingString:"..."
end truncateString
main()