I have extracted some text as NSMutableAttributedStrings from a PDF, looping through the pages and joining them all together at the end. I did this in order to trim text from each page using RegEx. Now I think I would like to create a new PDF from this AttributedString, but I am having trouble figuring out how. Possible?
I suspect you’ll have to create an NSTextView, add the attributed string, then use dataWithPDFInsideRect:
to generate the PDF data.
A cheap trick could be to use the Pasteboard for that, as it can automatically convert between rich text (RTF), HTML and PDF. You put in the text in one format and then retrieve it in the other.
I don’t know the details for doing that in AppleScript, though.
Are you sure? I put some rtf on the pasteboard and tried this:
current application's NSPasteboard's generalPasteboard()'s availableTypeFromArray:{current application's NSPasteboardTypePDF}
The result was missing value.
You’re right. Despite me selling a clipboard recorder and making another clipboard tool (ShowClipboards) I can’t even get this right.
I so often see PDFs in the clipboard for text clips (mostly from Word and Excel that I have to keep looking at because the MS apps keep inserting non-permanent data into the clipboard that must not be recorded), that I right out assumed it would happen all the time.
Correct is that only automatic conversion between rich text and html does happen, but not with PDF.
BTW, I have code for rendering rich text and html into PDF, but that’s written in Xojo code. I’d be happy to share that code with Ian if he wants to give Xojo a try. It’s using the older WebKit framework and converting that to AppleScript is quite a lot of, I suspect. But then again, if it’s just text, using the workaround via a NSTextView is much easier.
Actually, I just checked and I have some code here that does it, using a print operation:
use AppleScript version "2.5" -- macOS 10.11 or later
use framework "Foundation"
use framework "AppKit"
use scripting additions
on saveStyledText:styledText asPDFToFile:newPath
-- create print info for saving to file
set destURL to current application's NSURL's fileURLWithPath:newPath
set printInfo to current application's NSPrintInfo's alloc()'s initWithDictionary:(current application's NSDictionary's dictionaryWithObject:destURL forKey:(current application's NSPrintJobSavingURL)) -- sets destination
printInfo's setJobDisposition:(current application's NSPrintSaveJob) -- save to file job
printInfo's setHorizontalPagination:(current application's NSClipPagination)
printInfo's setVerticalPagination:(current application's NSAutoPagination)
-- get page size and margins
set pageSize to printInfo's paperSize()
set theLeft to printInfo's leftMargin()
set theRight to printInfo's rightMargin()
set theTop to printInfo's topMargin()
-- make a very deep text view
set theView to current application's NSTextView's alloc()'s initWithFrame:{{0, 0}, {(pageSize's width) - theLeft - theRight, 3.0E+38}}
theView's setHorizontallyResizable:false
-- put in the text
theView's textStorage()'s setAttributedString:styledText
-- size to fit; must be done on the main thread
if current application's NSThread's isMainThread() then
theView's sizeToFit()
else
theView's performSelectorOnMainThread:"sizeToFit" withObject:(missing value) waitUntilDone:true
end if
-- create print operation and run it
set printOp to current application's NSPrintOperation's printOperationWithView:theView printInfo:printInfo
printOp's setShowsPrintPanel:false
printOp's setShowsProgressPanel:false
if current application's NSThread's isMainThread() then
set my theResult to printOp's runOperation()
else
my performSelectorOnMainThread:"runPrintOperation:" withObject:printOp waitUntilDone:true
end if
end saveStyledText:asPDFToFile:
on runPrintOperation:printOp -- on main thread
set my theResult to printOp's runOperation()
end runPrintOperation:
Huh, I had not been aware that I could tell the print system to print to a file.
So, this would then also handle pagination, to the view’s size, I guess?
Exactly. That’s what the NSAutoPagination
for verticalPagination
does in the code above.
Nice code. Thanks!
Is it possible to use some styled text from the clipboard and pass it to the code posted by Shane?
I tried using:
set styledText to the clipboard set thePDF to my saveStyledText:styledText asPDFToFile:"/Users/ldicroce/Desktop/newPDF.pdf"
but I got this error:
-[__NSCFString string]: unrecognized selector sent to instance 0x7fe13d42ea00
Thanks