Why is this giving a super messed up PDF with no images? What am I doing wrong?
use AppleScript version "2.8"
use scripting additions
use framework "Foundation"
use framework "AppKit"
-- dimensions of print area:
property thePaperSize : {height:479, width:516}
property theLeft : 0
property theRight : 0
property theTop : 0
property theBottom : 0
on run argv
set course to "course1"
set theyear to "2023"
set semester to "Spring"
set exam to item 1 of argv
set session to item 2 of argv
set chapters to item 3 of argv
if semester="Spring" then
set sem_num to "1"
else if semester="Summer" then
set sem_num to "2"
else if semester="Fall" then
set sem_num to "3"
else
return "wrong semester"
end if
set inpath to "/Users/Dropbox/"& course &" - " & "Current/" & theyear & "-"& sem_num &"-"& semester &"/2." & " " & "Chapter" & " " & "Reviews/" & ¬
"Exam" & " " & exam & " " & "Session" & " " & session & "/"& course &" Exam " & exam & " Session " & session & " (Ch "& chapters &").docx"
-- choose Word document file, make URL and build destination path
set posixPath to inpath
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)
-- make text view and add text
set theView to current application's NSTextView's alloc()'s initWithFrame:{{0, 0}, {(width of thePaperSize) - theLeft - theRight, (height of thePaperSize) - 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 run
I have a GUI Apple script that does this for me too. Problem is that it breaks with every single OS update (when buttons and overall layout change). I wanted to have a script that I could use from the command line without any GUI involved. Is your suggestion like that?
Other approach is but not what you exatly want but it will solve you GUI scripting issue
If you open the print dialog you could see there is Save as PDF
You could make this a keyboard shortcut for application Word.
Now you could use key code to get a save dialog for you to save the file.
The problem could be to set the save path if you like to do everything with AppleScript.
Something like this, the first key code get print dialog and second is custom for Save as PDF and the last keystroke will click return on keyboard. It looks like the save path is the same path as the document was open in.
set thePath to POSIX path of (path to desktop) & "testDoc.docx"
tell application "Microsoft Word" to open thePath
tell application "System Events" to tell application process "Microsoft Word"
set frontmost to true
key code 35 using {command down}
key code 35 using {control down} --> custom app shortcut
delay 2
keystroke return
end tell
delay 0.5
tell application "Microsoft Word" to quit
@scienception
In addition to excellent suggestions from @Fredrik71: If you do have Word then you don’t need GUI scripting - you can use Word’s own AppleScript commands (if I understand your question correctly).
for password protection you’ll need to create PDF first, then use PDFKit to assign security settings including password.
as to specific layout: normally, all layout options should be covered by Word’s AppleScript dictionary (although some of them you may need to apply to the document itself first rather then set them up as print settings).
@scienception
Many things you like to do… would category as GUI Scripting.
But if here is an version from Yvan that us Word Scriptable features.
set thePath to POSIX path of (path to desktop) & "testDoc.docx"
tell application "Microsoft Word"
open POSIX file thePath
delay 1
tell front document
set savePath to POSIX path of (path to desktop) & "testDoc.pdf"
save as file format format PDF file name savePath
end tell
quit
end tell
@scienception
I made a GUI Script for you to try, open Word and run the Script
The variable presetsNames is a list of every name of the Preset:
So you could make your custom ones. I could also say before tell menu 1
there is a click. The reason is the names of every menu item doesn’t reveal themselves
without the click. So to be able to do GUI Script is to get every step in some order.
It took me some time to understand it at begining.
I use: class of UI elements to reveal the class of Ui elemens and navigate and also guessing the path. Its not always straitforward.
tell application "System Events" to tell application process "Microsoft Word"
set frontmost to true
key code 35 using {command down} --> Print dialog
tell window 1 to tell pop up button 2
click
tell menu 1
set presetsNames to name of menu items
click menu item "Last Used Settings"
end tell
end tell
end tell
You can find these in the Word dictionary. It is expansive so you might search for ‘page setup’.
This may give you something to start with but you should be able to work with more than just margins:
tell application "Microsoft Word"
set top margin of page setup of document 1 to 24
-- to return the page setup object…
-- properties of page setup of document 1
left margin of page setup of document 1
--> 90.0
top margin of page setup of document 1
--> 24.0
right margin of page setup of document 1
--> 90.0
bottom margin of page setup of document 1
--> 72
set left margin of page setup of document 1 to 36
left margin of page setup of document 1
--> 36.0
-- you can use inches like so
set left margin of page setup of document 1 to (inches to points inches 0.75)
left margin of page setup of document 1
--> 54.0
-- and metric like so but note the spelling
set right margin of page setup of document 1 to (centimeters to points centimeters 2)
right margin of page setup of document 1
--> 56.70000076294
end tell
You can also use millimeters, lines —and best of all— picas (i.e. 12 points).
@zevrix… by the way, that’s not a custom size… that’s Letter in millimetres.
tell application "System Events" to tell application process "Microsoft Word"
set frontmost to true
tell menu bar 1 to tell menu bar item "File"
tell menu 1
click menu item "Page Setup..."
end tell
end tell
tell window 1 to tell pop up button 2
click
tell menu 1 to set paperSizeNames to its name of menu items
(*
{"8x10 203 by 254 mm", "10x12 254 by 305 mm", "A3 297 by 420 mm", "A4 210 by 297 mm", "A5 148 by 210 mm", "Envelope #10 105 by 241 mm", "Envelope Choukei 3 120 by 235 mm", "Envelope DL 110 by 220 mm", "Executive 184 by 267 mm", "Super B/A3 330 by 483 mm", "Tabloid 279 by 432 mm", "Tabloid Oversize 305 by 457 mm", "US Legal 216 by 356 mm", "US Letter 216 by 279 mm", missing value, "Manage Custom Sizes…"}
*)
tell menu 1 to click menu item "A3 297 by 420 mm"
end tell
end tell