Script TextEdit to export to PDF?

TextEdit has an “export to PDF” item on its menu. Is it possible to script this feature without using GUI scripting? I’ve wasted hours trying to use “save as”; it works for doc and similar formats, but not for PDF.

The problem I’m trying to solve is creating a PDF file from an OpenDocument .odt file using only built-in OS X tools. TextEdit opens .odt files, and I was hoping to use it to export a PDF, but I haven’t found a way to do this. If anyone has an answer, I’ll be grateful.

This should work for any document TextEdit can open:

use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "AppKit"

my makePDFFrom:(POSIX path of (choose file))
on makePDFFrom:posixPath
	-- make URL and build destination path
	set theURL to current application's |NSURL|'s fileURLWithPath:posixPath
	set destPath to theURL's |path|()'s stringByDeletingPathExtension()'s stringByAppendingPathExtension:"pdf"
	-- get doc's contents as styled text
	set {styledText, theError} to current application's NSAttributedString's alloc()'s initWithURL:theURL options:(missing value) documentAttributes:(missing value) |error|:(reference)
	if styledText = missing value then error (theError's localizedDescription() as text)
	-- set up printing specs
	set printInf to current application's NSPrintInfo's sharedPrintInfo()'s |copy|()
	printInf's setJobDisposition:(current application's NSPrintSaveJob)
	printInf's |dictionary|()'s setObject:destPath forKey:(current application's NSPrintSavePath)
	-- get dimensions of print area; you could instead set these
	set theSize to printInf's paperSize()
	set theLeft to printInf's leftMargin()
	set theRight to printInf's rightMargin()
	set theTop to printInf's topMargin()
	set theBottom to printInf's bottomMargin()
	-- make text view and add text
	set theView to current application's NSTextView's alloc()'s initWithFrame:{{0, 0}, {(width of theSize) - theLeft - theRight, (height of theSize) - theTop - theBottom}}
	theView's textStorage()'s setAttributedString:styledText
	-- set up and run print operation without showing dialog
	set theOp to current application's NSPrintOperation's printOperationWithView:theView printInfo:printInf
	theOp's setShowsPrintPanel:false
	theOp's setShowsProgressPanel:false
	theOp's runOperation()
end makePDFFrom:

It will use the default page size and margin values you print with, but you can change them to suit if you wish.

This is brilliant. Thank you! (I’ll ask a related question in another thread.)

This is indeed brilliant. I have an obscure problem: My rtf file has page breaks in it, but the pdf file has lost them. If I do Export as PDF… from TextEdit the page breaks are retained. I suppose that means that page breaks (they are simply occurrences of "\page " in the rtf file) are understood by TextEdit, but not by the generic printing operation used in your script. Any suggestions for keeping the page breaks?

Context: I am distributing a set of cooperating scripts that create various files, including one that is rtf. I need users to be able to run a single master script that runs all the other scripts, with no GUI interactions. (I know how to run AppleScripts and JavaScripts from the command line.) I don’t want to require users to install any software other than my scripts. Your script is the only way to natively produce PDF from rtf I have found, after a great deal of searching.

Model: MacBook Pro 15" (2017)
AppleScript: 2.4
Browser: Safari 13.0.4
Operating System: macOS 10.13

There doesn’t seem to be any Cocoa support for page breaks. The only workaround I can suggest is that you break up the attributed string your self, print each page separately (use the same view), then collate the pages using PDFDocument.