I have tried replaceing all the fonts in keynote using Format/fonts/replace font. But automating it using python. My code is working until opening the replace font dialogue box but after that it can't detect dont replace popup button.enter image description here
I dont know what else to do to select this option for all of these fonts.
import os
import tkinter as tk
from tkinter import filedialog, messagebox
import subprocess
# Function to select the main folder
def select_folder():
folder_path = filedialog.askdirectory()
folder_entry.delete(0, tk.END)
folder_entry.insert(0, folder_path)
# Function to execute the font replacement script
def execute_script():
folder_path = folder_entry.get()
if not os.path.isdir(folder_path):
messagebox.showerror("Error", "Please select a valid folder.")
return
try:
for root, dirs, files in os.walk(folder_path):
for dir_name in dirs:
if dir_name in ["FR", "CN", "JP", "KR", "BR"]:
language_folder = os.path.join(root, dir_name)
for sub_root, _, sub_files in os.walk(language_folder):
for file_name in sub_files:
if file_name.endswith(('.key', '.numbers', '.pages')):
file_path = os.path.join(sub_root, file_name)
replace_fonts(file_path, dir_name)
messagebox.showinfo("Success", "Font replacement completed successfully.")
except Exception as e:
messagebox.showerror("Error", f"An error occurred: {str(e)}")
# Function to replace fonts using AppleScript
def replace_fonts(file_path, folder_name):
font_mapping = {
"FR": "SF Hello",
"CN": "SF Hello +SC",
"JP": "SF Hello +JP",
"KR": "SF Hello +KR",
"BR": "SF Hello"
}
target_font = font_mapping.get(folder_name, "SF Hello")
# Escape file path for AppleScript
escaped_file_path = file_path.replace('"', '\\"')
applescript_code = f'''
tell application "Finder"
open POSIX file "{escaped_file_path}"
end tell
delay 3
tell application "System Events"
tell process "Keynote"
-- Open Replace Fonts dialog
click menu item "Replace Fonts…" of menu "Font" of menu item "Font" of menu "Format" of menu bar item "Format" of menu bar 1
delay 3
-- Access the Replace Fonts dialog
set fontDialog to sheet 1 of window 1
set fontTable to table 1 of scroll area 1 of fontDialog
set rowCount to count of rows of fontTable
-- Iterate through each row and replace fonts
repeat with i from 1 to rowCount
set fontRow to row i of fontTable
set popUpButton to pop up button of fontRow -- Usually the second pop-up is the replacement target
click popUpButton
delay 1
click menu item "{target_font}" of menu 1 of popUpButton
delay 1
end repeat
-- Confirm the replacements
click button "Replace Fonts" of fontDialog
end tell
end tell
delay 3
tell application "Keynote"
save front document
close front document
end tell
'''
# Run the AppleScript using subprocess
result = subprocess.run(["osascript", "-e", applescript_code], text=True, capture_output=True)
if result.returncode != 0:
raise RuntimeError(f"AppleScript error: {result.stderr}")
# Create the main UI window
root = tk.Tk()
root.title("Font Replacement Script")
# UI Elements
frame = tk.Frame(root)
frame.pack(padx=10, pady=10)
folder_label = tk.Label(frame, text="Select Main Folder:")
folder_label.grid(row=0, column=0, pady=5)
folder_entry = tk.Entry(frame, width=50)
folder_entry.grid(row=0, column=1, pady=5)
browse_button = tk.Button(frame, text="Browse", command=select_folder)
browse_button.grid(row=0, column=2, padx=5)
execute_button = tk.Button(frame, text="Execute", command=execute_script)
execute_button.grid(row=1, column=0, columnspan=3, pady=10)
# Run the main loop
root.mainloop()
I tried selecting the element in multiple ways but no luck. Also tried it using the Accessibility option in Xcode but nothing.
I just want this script to replace all the fonts to one single specific font.
I have tried replaceing all the fonts in keynote using Format/fonts/replace font. But automating it using python. My code is working until opening the replace font dialogue box but after that it can't detect dont replace popup button.enter image description here
I dont know what else to do to select this option for all of these fonts.
import os
import tkinter as tk
from tkinter import filedialog, messagebox
import subprocess
# Function to select the main folder
def select_folder():
folder_path = filedialog.askdirectory()
folder_entry.delete(0, tk.END)
folder_entry.insert(0, folder_path)
# Function to execute the font replacement script
def execute_script():
folder_path = folder_entry.get()
if not os.path.isdir(folder_path):
messagebox.showerror("Error", "Please select a valid folder.")
return
try:
for root, dirs, files in os.walk(folder_path):
for dir_name in dirs:
if dir_name in ["FR", "CN", "JP", "KR", "BR"]:
language_folder = os.path.join(root, dir_name)
for sub_root, _, sub_files in os.walk(language_folder):
for file_name in sub_files:
if file_name.endswith(('.key', '.numbers', '.pages')):
file_path = os.path.join(sub_root, file_name)
replace_fonts(file_path, dir_name)
messagebox.showinfo("Success", "Font replacement completed successfully.")
except Exception as e:
messagebox.showerror("Error", f"An error occurred: {str(e)}")
# Function to replace fonts using AppleScript
def replace_fonts(file_path, folder_name):
font_mapping = {
"FR": "SF Hello",
"CN": "SF Hello +SC",
"JP": "SF Hello +JP",
"KR": "SF Hello +KR",
"BR": "SF Hello"
}
target_font = font_mapping.get(folder_name, "SF Hello")
# Escape file path for AppleScript
escaped_file_path = file_path.replace('"', '\\"')
applescript_code = f'''
tell application "Finder"
open POSIX file "{escaped_file_path}"
end tell
delay 3
tell application "System Events"
tell process "Keynote"
-- Open Replace Fonts dialog
click menu item "Replace Fonts…" of menu "Font" of menu item "Font" of menu "Format" of menu bar item "Format" of menu bar 1
delay 3
-- Access the Replace Fonts dialog
set fontDialog to sheet 1 of window 1
set fontTable to table 1 of scroll area 1 of fontDialog
set rowCount to count of rows of fontTable
-- Iterate through each row and replace fonts
repeat with i from 1 to rowCount
set fontRow to row i of fontTable
set popUpButton to pop up button of fontRow -- Usually the second pop-up is the replacement target
click popUpButton
delay 1
click menu item "{target_font}" of menu 1 of popUpButton
delay 1
end repeat
-- Confirm the replacements
click button "Replace Fonts" of fontDialog
end tell
end tell
delay 3
tell application "Keynote"
save front document
close front document
end tell
'''
# Run the AppleScript using subprocess
result = subprocess.run(["osascript", "-e", applescript_code], text=True, capture_output=True)
if result.returncode != 0:
raise RuntimeError(f"AppleScript error: {result.stderr}")
# Create the main UI window
root = tk.Tk()
root.title("Font Replacement Script")
# UI Elements
frame = tk.Frame(root)
frame.pack(padx=10, pady=10)
folder_label = tk.Label(frame, text="Select Main Folder:")
folder_label.grid(row=0, column=0, pady=5)
folder_entry = tk.Entry(frame, width=50)
folder_entry.grid(row=0, column=1, pady=5)
browse_button = tk.Button(frame, text="Browse", command=select_folder)
browse_button.grid(row=0, column=2, padx=5)
execute_button = tk.Button(frame, text="Execute", command=execute_script)
execute_button.grid(row=1, column=0, columnspan=3, pady=10)
# Run the main loop
root.mainloop()
I tried selecting the element in multiple ways but no luck. Also tried it using the Accessibility option in Xcode but nothing.
I just want this script to replace all the fonts to one single specific font.
Share Improve this question asked Jan 20 at 0:42 John SnowJohn Snow 11 Answer
Reset to default 0If your only goal is replace the fonts in the presentation with a single common font, you're doing it the hard way. Keynote is fully scriptable; no need to resort to GUI scripting.
Try this:
tell application "Keynote"
tell first document
tell every slide
tell every text item
(*
I used Lucida Blackletter for testing, because I happen to like it
insert the display name or PostScript name of the font you want
*)
set font of object text to "Lucida Blackletter"
end tell
end tell
end tell
end tell