Batch convert .rtf files to .textclippings

Dear Macscripters,

I searched the internet and this forum, but couldn’t find the solution unfortunately.

I have a folder with hundreds of .rtf-files, each containing some formatted letters and numbers.
I want to batch convert each of these files to a folder with the same amount of textclippings keeping the formatted letters and numbers.
Is this possible with Applescript? Do you have a solution?

Thank you and all the best

Model: Macbook Pro 16
AppleScript: 2.8
Browser: Safari 605.1.15
Operating System: macOS 12

The textClipping format use property list or resource fork.
The example I made I could see it has the dictionary key UTI-Data and key:public.rtf that store string of rtf data.

I’m guessing…

  1. read the rtf file and get the last path name (filename)
  2. make new NSDictionary UTI-Data and store the key:public.rtf with value:rtf string data
  3. run in repeat loop for all your files.

I believe you could read the content of data of rtf and return it as encoded UTF string
to set the value for the key.

Sorry I have not done this before.

Thank you Fredrik71,

that goes far beyond my horizons and skills. I have no idea what the code should look like.

Nevertheless, thank you very much.

Maybe someone else could help you, I did little experiment, not sure…

The code ask for textClipping, so I could know the structure.
Later in the code I try to build a new dictionary to output in the console.
If I write that one to file as textClipping or if I have miss something I do not know yet.

I have to do more testing to compare the original textClipping with a new one.

use framework "Foundation"
use scripting additions

set thePath to POSIX path of (choose file)
set theURL to current application's |NSURL|'s fileURLWithPath:thePath
set theDict to current application's NSDictionary's dictionaryWithContentsOfURL:theURL |error|:(missing value)
set rtfData to |public.rtf| of |uti-data| of (theDict as record)

set newDict to current application's NSMutableDictionary's dictionary()
set theObjects to current application's NSMutableDictionary's dictionary()
theObjects's setObject:rtfData forKey:"public.rtf"
newDict's setObject:theObjects forKey:"uti-data"
return newDict as record

@HoHollo

You could try this… I made some rtf files with rtf data and run the script below.
Next I drag and drop whose into TextEdit and it contains the text attribute in the rtf data.
I only used the UTI-Data, public-rtf keys and set the “com.apple.traditional-mac-plain-text” key to empty string. I first thought I need it but maybe not. That key contains data and not string.
So I’m not sure.

Its was a quick script to I guess it could be improved.

use framework "Foundation"
use scripting additions

set theFiles to (choose file of type {"public.rtf"} with multiple selections allowed)

set countFiles to count theFiles
set posixFileList to {}
repeat with i from 1 to countFiles
	tell application "Finder" to set parentFolder to (container of item i of theFiles) as text
	set parentFolder to POSIX path of parentFolder
	
	set posixFile to POSIX path of (item i of theFiles)
	set theURL to (current application's |NSURL|'s fileURLWithPath:posixFile)
	
	set basename to theURL's lastPathComponent()
	set basename to item 1 of (its stringToList(basename as text))
	
	set theString to (current application's NSString's stringWithContentsOfURL:theURL encoding:(current application's NSUTF8StringEncoding) |error|:(missing value))
	set plainText to ""
	set rtfString to theString as text
	
	set theURL to (current application's |NSURL|'s fileURLWithPath:(parentFolder & basename & ".textClipping"))
	set newDict to current application's NSMutableDictionary's dictionary()
	set theObjects to current application's NSMutableDictionary's dictionary()
	(theObjects's setObject:plainText forKey:"com.apple.traditional-mac-plain-text")
	(theObjects's setObject:rtfString forKey:"public.rtf")
	(newDict's setObject:theObjects forKey:"UTI-Data")
	(newDict's writeToURL:theURL atomically:true)
end repeat

on stringToList(textInput)
	set ASTID to AppleScript's text item delimiters
	set AppleScript's text item delimiters to "."
	set theResult to every text item of textInput
	set AppleScript's text item delimiters to ASTID
	return theResult
end stringToList

Hello Fredrik71,

thank you very much for the script. Much appreciated. Works like a charm.
Is there a way that the contents (Rich-Text) of the textclipping can be previewed in Spotlight with Quickview?

Thank you again.

Thanks for sharing very cool script, Fredrik71!!

I refined it little and made it useful handler for me:


use framework "Foundation"
use scripting additions

set theFiles to (choose file of type {"public.rtf"} with multiple selections allowed)
createTextClippings(theFiles)

on createTextClippings(theFiles) -- theFiles is aliases list parameter
	repeat with theFile in theFiles
		-- Get the source's Posix path, NSURL, basename
		set posixPath to POSIX path of theFile
		set containerPosixPath to (((current application's NSString's stringWithString:posixPath)'s stringByDeletingLastPathComponent()) as text) & "/"
		set theURL to (current application's |NSURL|'s fileURLWithPath:posixPath)
		set basename to theURL's lastPathComponent()'s stringByDeletingPathExtension()
		-- Create the dictionary for text clipping file
		set rtfString to (current application's NSString's stringWithContentsOfURL:theURL encoding:(current application's NSUTF8StringEncoding) |error|:(missing value))
		set theObjects to current application's NSMutableDictionary's dictionary()
		(theObjects's setObject:rtfString forKey:"public.rtf")
		set newDict to current application's NSMutableDictionary's dictionary()
		(newDict's setObject:theObjects forKey:"UTI-Data")
		-- Write .textclipping file at parent directory
		set theURL to (current application's |NSURL|'s fileURLWithPath:(containerPosixPath & basename & ".textClipping"))
		(newDict's writeToURL:theURL atomically:true)
	end repeat
end createTextClippings

You could open a textClipping with Finder… so you do not need Quicklook

Simple script to show you.

-- choose a textClipping file
set theFile to choose file of type {"textClipping"}
tell application "Finder"
	activate
	set theClipping to open theFile
	tell front window
		set bounds to {410, 300, 900, 800}
		set position to {20, 75}
	end tell
end tell

That’s awesome!

Thank you Fredrik71

I steal from @KniazidisR to make it my version :wink:

use framework "Foundation"
use scripting additions

set theFiles to (choose file of type {"public.rtf"} with multiple selections allowed)

(**
* [createClippingFromRTF(alias list)]
*)

its createClippingFromRTF(theFiles)
on createClippingFromRTF(theFiles)
	repeat with theFile in theFiles
		set thePath to POSIX path of theFile
		set theFolder to (current application's NSString's stringWithString:thePath)
		set theParentFolder to theFolder's stringByDeletingLastPathComponent()
		set theURL to (current application's |NSURL|'s fileURLWithPath:thePath)
		set basename to theURL's lastPathComponent()'s stringByDeletingPathExtension()
		set rtfString to (current application's NSString's stringWithContentsOfURL:theURL encoding:(current application's NSUTF8StringEncoding) |error|:(missing value))
		set theObjects to current application's NSMutableDictionary's dictionary()
		(theObjects's setObject:rtfString forKey:"public.rtf")
		set theDict to current application's NSMutableDictionary's dictionary()
		(theDict's setObject:theObjects forKey:"UTI-Data")
		-- Save the files in the same folder as source.
		set saveURL to (current application's |NSURL|'s fileURLWithPath:((theParentFolder as text) & "/" & (basename as text) & ".textClipping"))
		set theResult to (theDict's writeToURL:saveURL |error|:(reference))
		if (item 1 of result) is true then display alert "Success..."
		return
	end repeat
end createClippingFromRTF