Hey, script guru!
Wrote a script for converting pages, numbers, keynotes of documents to Microsoft formats. It works. But maybe it’s possible to optimize it.
I don’t like how “display dialog” is made, but I don’t understand how to do otherwise, so as not to repeat the same thing 3 times in the code.
And maybe it doesn’t make sense to filter by extensions at the very beginning, but to use a sample of all files?
set end of Selected_Items to Filtered_Item as alias
Is optimization possible?
tell application "Finder"
set the_Selection to selection
set Selected_Items to {}
--Go through each file in the sample, and filter by pages, numbers, keys extensions
repeat with Filtered_Item in the_Selection
if class of Filtered_Item is document file and name extension of Filtered_Item is in ["pages", "numbers", "key"] then ¬
set end of Selected_Items to Filtered_Item as alias
end repeat
--go through each filtered file
repeat with Selected_Item in Selected_Items as alias list
--get a file name without an extension and an extension in the form of text
tell application "System Events" to tell disk item (Selected_Item as text) to set {Item_Name, Item_Extension} to {name, name extension}
if Item_Extension is not "" then set Item_Name to text 1 thru -((count Item_Extension) + 2) of Item_Name
--Get the file's root directory
set Root_Folder to container of Selected_Item
--If the pages file
if Item_Extension is "pages" then
--Generate the name of the converted file
set Converted_Item to ((Root_Folder as text) & Item_Name as text) & ".docx"
--Checking the existence
if exists file Converted_Item then
display dialog "Document" & space & quoted form of (name of file Converted_Item as text) & space & ¬
"Was converted earlier than" buttons {"Cancel", "Delete"} cancel button 1 with icon caution
-- Delete an existing file to the trash
delete file Converted_Item
end if
tell application "Pages"
set to_Convert to open Selected_Item
export to_Convert to file Converted_Item as Microsoft Word
close to_Convert saving no
end tell
end if
--If the numbers file
if Item_Extension is "numbers" then
--Generate the name of the converted file
set Converted_Item to ((Root_Folder as text) & Item_Name as text) & ".xlsx"
--Checking the existence
if exists file Converted_Item then
display dialog "Document" & space & quoted form of (name of file Converted_Item as text) & space & ¬
"Was converted earlier than" buttons {"Cancel", "Delete"} cancel button 1 with icon caution
-- Delete an existing file to the trash
delete file Converted_Item
end if
tell application "Numbers"
set to_Convert to open Selected_Item
export to_Convert to file Converted_Item as Microsoft Excel
close to_Convert saving no
end tell
end if
--If the key file
if Item_Extension is "key" then
--Generate the name of the converted file
set Converted_Item to ((Root_Folder as text) & Item_Name as text) & ".pptx"
--Checking the existence
if exists file Converted_Item then
display dialog "Document" & space & quoted form of (name of file Converted_Item as text) & space & ¬
"Was converted earlier than" buttons {"Cancel", "Delete"} cancel button 1 with icon caution
-- Delete an existing file to the trash
delete file Converted_Item
end if
tell application "Keynote"
set to_Convert to open Selected_Item
export to_Convert to file Converted_Item as Microsoft PowerPoint
close to_Convert saving no
end tell
end if
end repeat
end tell
When you filter the selected files by extension, you already know that they match the desired type of document… so you shouldn’t need to check again whether the extension exists or not. You should be able to just work with the name. BTW, shouldn’t your list of extensions use {}
rather than []
?
You have a separate repeat loop for each document type. You could probably just have one loop that works for all extensions. You would likely have to put the corresponding microsoft extensions (e.g. docx) in a list that matches the apple extension list. Also, a list of the applications as well.
Although, given that Selected_Items should only contains desired document types, maybe you could just open them (and add a delay) and then export them using whatever the current application would then be.
@V.Yakob,
You have some extra stuff in your script here. For example, instead of getting the container, you can get the System Events path property, which makes it easier to get the destination file path.
Also, there are a lot of nested tell blocks, which is not recommended for ease of debugging errors. Also, when there are clearly defined tasks in the script, it is again recommended to separate them as handlers.
Also, the export command works out of sync with the script. Therefore, it is imperative to check that the export has ended before closing the document.
Such code becomes clear and understandable, but if you don’t like it (that I changed the structure of your script), you can easily return the structure of the script yourself after you understand how it works.
tell application "Finder"
set Selected_Items to {}
repeat with Filtered_Item in (get selection)
if class of Filtered_Item is document file and name extension of Filtered_Item is in ["pages", "numbers", "key"] then ¬
set end of Selected_Items to Filtered_Item as alias
end repeat
end tell
repeat with Selected_Item in Selected_Items
tell application "System Events"
tell disk item (Selected_Item as text) to set {Item_Name, Item_Extension} to {path, name extension}
set Item_Name to text 1 thru -((count Item_Extension) + 2) of Item_Name
end tell
if Item_Extension is "pages" then
my PagesExport(Item_Name, Selected_Item)
else if Item_Extension is "numbers" then
my NumbersExport(Item_Name, Selected_Item)
else if Item_Extension is "key" then
my KeyNoteExport(Item_Name, Selected_Item)
end if
end repeat
--====================================== HANDLERS ==========================================-----
on repeatUntil_FileExists(hfsPath)
repeat
try
alias hfsPath
exit repeat
end try
delay 0.1
end repeat
end repeatUntil_FileExists
on KeyNoteExport(Item_Name, Selected_Item)
set Converted_Item to Item_Name & ".pptx"
try
tell application "System Events" to delete file Converted_Item
end try
tell application "Keynote"
activate
set to_Convert to open file Selected_Item
export to_Convert to file Converted_Item as Microsoft PowerPoint
my repeatUntil_FileExists(Converted_Item)
close to_Convert saving no
end tell
end KeyNoteExport
on PagesExport(Item_Name, Selected_Item)
set Converted_Item to Item_Name & ".docx"
try
tell application "System Events" to delete file Converted_Item
end try
tell application "Pages"
activate
set to_Convert to open file Selected_Item
export to_Convert to file Converted_Item as Microsoft Word
my repeatUntil_FileExists(Converted_Item)
close to_Convert saving no
end tell
end PagesExport
on NumbersExport(Item_Name, Selected_Item)
set Converted_Item to Item_Name & ".xlsx"
try
tell application "System Events" to delete file Converted_Item
end try
tell application "Numbers"
activate
set to_Convert to open file Selected_Item
export to_Convert to file Converted_Item as Microsoft Excel
my repeatUntil_FileExists(Converted_Item)
close to_Convert saving no
end tell
end NumbersExport
@KniazidisR
Thanx for your support, I changed the variables, and in general I figured it out, that’s what happened.
I removed “activate” in the handlers because “display dialog” messages pop up behind the window and it is inconvenient to interact with it.
tell application "Finder"
set SelectedItems to {}
repeat with FilteredItem in (get selection)
if class of FilteredItem is document file and name extension of FilteredItem is in {"pages", "numbers", "key"} then ¬
set end of SelectedItems to FilteredItem as alias
end repeat
end tell
repeat with SelectedItem in SelectedItems
tell application "System Events"
tell disk item (SelectedItem as text) to set {ItemName, ItemExtension} to {path, name extension}
set ItemName to text 1 thru -((count ItemExtension) + 2) of ItemName
end tell
if ItemExtension is "pages" then
my PagesExport(ItemName, SelectedItem)
else if ItemExtension is "numbers" then
my NumbersExport(ItemName, SelectedItem)
else if ItemExtension is "key" then
my KeyNoteExport(ItemName, SelectedItem)
end if
end repeat
--Handlers
on AlertIfConvertedExist(thisItem)
tell application "Finder"
if exists file thisItem then
display dialog "The document" & space & quoted form of (name of file thisItem as text) & space & ¬
"has been converted before" buttons {"Cancel", "Delete"} cancel button 1 with icon caution
delete file thisItem
end if
end tell
end AlertIfConvertedExist
on CheckConvertedFile(thisItem)
repeat
try
alias thisItem
exit repeat
end try
delay 0.1
end repeat
end CheckConvertedFile
on PagesExport(ItemName, SelectedItem)
set ConvertedItem to ItemName & ".docx"
my AlertIfConvertedExist(ConvertedItem)
tell application "Pages"
set toConvert to open file SelectedItem
export toConvert to file ConvertedItem as Microsoft Word
my CheckConvertedFile(ConvertedItem)
close toConvert saving no
end tell
end PagesExport
on NumbersExport(ItemName, SelectedItem)
set ConvertedItem to ItemName & ".xlsx"
my AlertIfConvertedExist(ConvertedItem)
tell application "Numbers"
set toConvert to open file SelectedItem
export toConvert to file ConvertedItem as Microsoft Excel
my CheckConvertedFile(ConvertedItem)
close toConvert saving no
end tell
end NumbersExport
on KeyNoteExport(ItemName, SelectedItem)
set ConvertedItem to ItemName & ".pptx"
my AlertIfConvertedExist(ConvertedItem)
tell application "Keynote"
set toConvert to open file SelectedItem
export toConvert to file ConvertedItem as Microsoft PowerPoint
my CheckConvertedFile(ConvertedItem)
close toConvert saving no
end tell
end KeyNoteExport
But I couldn’t interact with a file without a “Finder.”
If it is faster to work with the file system through “System Events”, is it possible to use it?
on AlertIfConvertedExist(thisItem)
(*
tell application "System Events" to set Status to not (exists file thisItem as alias)
log Status
if Status is equal to false then
display dialog "The document" & space & quoted form of (name of file thisItem) & space & ¬
"has been converted before" buttons {"Cancel", "Delete"} cancel button 1 with icon caution
delete file thisItem
end if
*)
(*
tell application "Finder"
if exists file thisItem then
display dialog "The document" & space & quoted form of (name of file thisItem as text) & space & ¬
"has been converted before" buttons {"Cancel", "Delete"} cancel button 1 with icon caution
delete file thisItem
end if
end tell
*)
-- (*
tell application "Finder"
try
get file thisItem
display dialog "The document" & space & quoted form of (name of file thisItem as text) & space & ¬
"has been converted before" buttons {"Cancel", "Delete"} cancel button 1 with icon caution
delete file thisItem
end try
end tell
-- *)
end AlertIfConvertedExist
It is possible and better to bypass the Finder when checking the existence of a file and deleting it.
But it’s not clear what the purpose of the display dialog you insist on is. Because you set 2 buttons - Cancel and Delete. If you click Cancel, the script will simply terminate without processing the rest of the files.
@KniazidisR How else can I warn the user that the document already exists and will be rewritten?
Usually, after exporting Pages - MS Word, need to adjust, change the font, change the position of the image or something else from the design, which in MS Word may not be displayed as in Pages.
I made changes to the script. It will now respond to the user’s choice in the display dialog.
tell application "Finder"
set SelectedItems to {}
repeat with FilteredItem in (get selection)
if class of FilteredItem is document file and name extension of FilteredItem is in {"pages", "numbers", "key"} then ¬
set end of SelectedItems to FilteredItem as alias
end repeat
end tell
repeat with SelectedItem in SelectedItems
tell application "System Events"
tell disk item (SelectedItem as text) to set {ItemName, ItemExtension} to {path, name extension}
set ItemName to text 1 thru -((count ItemExtension) + 2) of ItemName
end tell
if ItemExtension is "pages" then
my PagesExport(ItemName, SelectedItem)
else if ItemExtension is "numbers" then
my NumbersExport(ItemName, SelectedItem)
else if ItemExtension is "key" then
my KeyNoteExport(ItemName, SelectedItem)
end if
end repeat
--Handlers
on AlertIfConvertedExist(thisItem)
try
alias thisItem
tell application "Finder" to display dialog "The document" & space & thisItem & return & ¬
"has been converted before" buttons {"Skip export", "Delete"} with icon caution
if button returned of result is "Delete" then return "toDelete"
return "toSkip"
end try
return "toExport"
end AlertIfConvertedExist
on CheckConvertedFile(thisItem)
repeat
try
alias thisItem
exit repeat
end try
delay 0.1
end repeat
end CheckConvertedFile
on PagesExport(ItemName, SelectedItem)
set ConvertedItem to ItemName & ".docx"
set aResult to my AlertIfConvertedExist(ConvertedItem)
if aResult is "toSkip" then return
if aResult is "toDelete" then tell application "System Events" to delete file ConvertedItem
tell application "Pages"
activate
set toConvert to open file SelectedItem
export toConvert to file ConvertedItem as Microsoft Word
my CheckConvertedFile(ConvertedItem)
close toConvert saving no
end tell
end PagesExport
on NumbersExport(ItemName, SelectedItem)
set ConvertedItem to ItemName & ".xlsx"
set aResult to my AlertIfConvertedExist(ConvertedItem)
if aResult is "toSkip" then return
if aResult is "toDelete" then tell application "System Events" to delete file ConvertedItem
tell application "Numbers"
activate
set toConvert to open file SelectedItem
export toConvert to file ConvertedItem as Microsoft Excel
my CheckConvertedFile(ConvertedItem)
close toConvert saving no
end tell
end NumbersExport
on KeyNoteExport(ItemName, SelectedItem)
set ConvertedItem to ItemName & ".pptx"
set aResult to my AlertIfConvertedExist(ConvertedItem)
if aResult is "toSkip" then return
if aResult is "toDelete" then tell application "System Events" to delete file ConvertedItem
tell application "Keynote"
activate
set toConvert to open file SelectedItem
export toConvert to file ConvertedItem as Microsoft PowerPoint
my CheckConvertedFile(ConvertedItem)
close toConvert saving no
end tell
end KeyNoteExport
1 Like
@KniazidisR Excellent! Thanx!
I have improved the display of the file name in the “dispaly dialog” – only the file name is displayed.
--Orig https://www.macscripter.net/t/convert-pages-numbers-and-keys-to-ms-formats/74692
tell application "Finder"
set SelectedItems to {}
--Filter from the selected files. The array is created only from files with the specified extensions
repeat with FilteredItem in (get selection)
if class of FilteredItem is document file and name extension of FilteredItem is in {"pages", "numbers", "key"} then ¬
set end of SelectedItems to FilteredItem as alias
end repeat
end tell
--Go through each file and run the handler depending on the file extension
repeat with SelectedItem in SelectedItems
tell application "System Events"
tell disk item (SelectedItem as text) to set {ItemName, ItemExtension} to {path, name extension}
set ItemName to text 1 thru -((count ItemExtension) + 2) of ItemName
end tell
if ItemExtension is "pages" then
my PagesExport(ItemName, SelectedItem)
else if ItemExtension is "numbers" then
my NumbersExport(ItemName, SelectedItem)
else if ItemExtension is "key" then
my KeyNoteExport(ItemName, SelectedItem)
end if
end repeat
--Handlers
--Checking the file for existence before export
on AlertIfConvertedExist(thisItem)
try
alias thisItem
set text item delimiters to ":"
set FileName to text item -1 of thisItem as text
tell application "Finder" to display dialog "The document" & space & quoted form of FileName & space & ¬
"has been converted before." buttons {"Skip", "Replace"} with icon caution
if button returned of result is "Replace" then return "toDelete"
return "toSkip"
end try
return "toExport"
end AlertIfConvertedExist
--Checking the completion of export
on CheckConvertedFile(thisItem)
repeat
try
alias thisItem
exit repeat
end try
delay 0.1
end repeat
end CheckConvertedFile
--Export pages -> docx
on PagesExport(ItemName, SelectedItem)
set ConvertedItem to ItemName & ".docx"
set aResult to my AlertIfConvertedExist(ConvertedItem)
if aResult is "toSkip" then return
if aResult is "toDelete" then tell application "System Events" to delete file ConvertedItem
tell application "Pages"
set toExport to open file SelectedItem
export toExport to file ConvertedItem as Microsoft Word
my CheckConvertedFile(ConvertedItem)
close toExport saving no
end tell
end PagesExport
--Export numbers -> xlsx
on NumbersExport(ItemName, SelectedItem)
set ConvertedItem to ItemName & ".xlsx"
set aResult to my AlertIfConvertedExist(ConvertedItem)
if aResult is "toSkip" then return
if aResult is "toDelete" then tell application "System Events" to delete file ConvertedItem
tell application "Numbers"
set toExport to open file SelectedItem
export toExport to file ConvertedItem as Microsoft Excel
my CheckConvertedFile(ConvertedItem)
close toExport saving no
end tell
end NumbersExport
--Export key -> pptx
on KeyNoteExport(ItemName, SelectedItem)
set ConvertedItem to ItemName & ".pptx"
set aResult to my AlertIfConvertedExist(ConvertedItem)
if aResult is "toSkip" then return
if aResult is "toDelete" then tell application "System Events" to delete file ConvertedItem
tell application "Keynote"
set toExport to open file SelectedItem
export toExport to file ConvertedItem as Microsoft PowerPoint
my CheckConvertedFile(ConvertedItem)
close toExport saving no
end tell
end KeyNoteExport
Every time thanx to the community, my skills in AppleScript get better!
I was trying to make this work, since I am using some applescript automations to do the same, but separated by filetypes, and I wanted to try this “all in one” solution, but I can’t make it work.
I am using automator for this, creating a quick action, using the “Run Applescript” action, pasting the script to is, but when I activate it in Finder, nothing happens. Could you help me out?
Thanks!
PS: If you work with iWork files, maybe you can share some other interesting automations/scripts that you have
Hi!
Open shortcuts, open shortcuts settings and check the Allow Running Scripts checkbox.
Create a new with name “Export to MS format”, add an AppleScript step and paste the script.
Click on i on the left. On the Details tab, check the box on use as quick action, Finder.
Click on “Run AppleScript with input”, select “shortcut input”, click on “Images and 18 more”, Select All,
Deselect all, check the checkbox on Files.
It should turn out: Receive Files input from QuickActions.
Select files for export, right-click, Quick Actions - Export to MS format.
macOS will ask a few questions about the security of accessing file shortcuts, after agreeing, the files will be created.