Skip to content

Instantly share code, notes, and snippets.

@okay-type
Last active February 25, 2023 21:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save okay-type/b6a63ff8a56874d77758afda580dbcda to your computer and use it in GitHub Desktop.
Save okay-type/b6a63ff8a56874d77758afda580dbcda to your computer and use it in GitHub Desktop.
A UI to do something to a bunch of ufo files
from vanilla import *
import os
from AppKit import NSFilenamesPboardType, NSDragOperationCopy
import re
from mojo.roboFont import AllFonts, CurrentFont, OpenFont
class Bulk_UFOs():
"""
Okay Type Bulk_UFO tool
A UI to do something to a bunch of ufo files
- current UFO
- all open UFOs
- drag & drop a list of files (default is UFOs, see formats option for)
::
# Step One : Make a start up script
#
# save this file somewhere
# make a new Robofont script with the sys.path sample code below
# replace '/Users/Path/To/The/Folder/Containing/Bulk.py' with the full path to this module
# save that script and add it to Robofont's Start Up Scripts (Preferences > Extensions > Start Up Scripts)
import sys
sys.path.insert(0, '/Users/Path/To/The/Folder/Containing/Bulk.py')
::
# Step Two : Import and use the module
#
# create a new Robofont script
# import this module
# write a function
# send that function to this module
from Bulk import Bulk_UFOs
# ^^^ "Bulk" is the name of this file
# ^^^ "Bulk_UFOs" is the class name of this module
def update_stuff_demo(RFont):
familyName = RFont.info.familyName
styleName = RFont.info.styleName
print('Updating', familyName, styleName, '...')
# send that function () to this tool
Bulk_UFOs(update_stuff_demo, 'Title')
::
**action** A function that accepts a single RFont (omit the parenthesis from the end, like a callback).
**title** Optional - The title to be displayed in the window to remind the user of what they are about to do.
**formats** Optional - A list of file formats to accept. Default is formats=['.ufo']. If you add formats Robofont can't open you need to set openclose=False
**openclose** Optional - When using the file list, openclose=False will pass the file paths to the function as a string. The default openclose=True will open/close the files and pass them to the function as an RFont.
**save** Optional - If False, the script do a dry-run without saving the files
"""
def __init__(self, action, title='Do Something', formats=['.ufo'], openclose=True, save=True):
self.action = action
self.formats = formats
self.openclose = openclose
self.save = save
L = 10 # left
W = 200 - L * 2 # width
T = L * 1 # top
H = 25 # vertical unit
winHeight = 15
self.w = Window((200, winHeight * H), str(title))
self.w.fileList = List(
(W + (L * 3), T, 580, -T),
[],
columnDescriptions=[
{'title': 'Files', 'allowsSorting': True}], # files
showColumnTitles=False,
allowsMultipleSelection=True,
enableDelete=True,
otherApplicationDropSettings=dict(
type=NSFilenamesPboardType,
operation=NSDragOperationCopy,
callback=self.dropCallback
),
)
self.w.version_text = TextBox((L, T + 4, W, H), title)
T += H
self.w.line = HorizontalLine((L, T, W, H))
T += H
self.w.target = TextBox((L, T + 4, W, H), 'In these files')
T += H
self.w.files_to_process = RadioGroup(
(L, T, W, H * 3),
['current ufo', 'all open ufos', 'file list'],
callback=self.files_to_process,
)
self.w.files_to_process.set(2)
T += H * 3
self.w.line2 = HorizontalLine((L, T, W, H))
T += H
self.w.go = Button((L, T, W, H), 'LET\'S DO IT!', callback=self.process_files)
self.w.open()
self.files_to_process(self.w.files_to_process)
def dropCallback(self, sender, dropInfo):
isProposal = dropInfo['isProposal']
# supportedFontFileFormats = ['.ufo', '.ttf', '.otf']
supportedFontFileFormats = self.formats
existingPaths = sender.get()
paths = dropInfo['data']
paths = [path for path in paths if path not in existingPaths]
paths = [path for path in paths if os.path.splitext(path)[-1].lower() in supportedFontFileFormats or os.path.isdir(path)]
if not paths:
return False
if not isProposal:
for path in paths:
item = {}
item['Files'] = path
self.w.fileList.append(item)
return True
def files_to_process(self, sender):
if sender.get() == 2:
xywh = list(self.w.getPosSize())
xywh[2] = 800
self.w.setPosSize(xywh)
else:
xywh = list(self.w.getPosSize())
xywh[2] = 200
self.w.setPosSize(xywh)
def process_files(self, sender):
ui_source_select = self.w.files_to_process.get()
files_to_process = []
rfonts_to_close = []
if ui_source_select == 0:
files_to_process = [CurrentFont()]
elif ui_source_select == 1:
files_to_process = AllFonts()
elif ui_source_select == 2:
for item in self.w.fileList:
if self.openclose == True:
f = OpenFont(item['Files'], showInterface=False)
rfonts_to_close.append(f)
files_to_process = rfonts_to_close
else:
files_to_process.append(item['Files'])
for f in files_to_process:
self.action(f)
if len(rfonts_to_close) > 0:
for f in rfonts_to_close:
if self.save == True:
f.save()
f.close()
self.w.close()
from Bulk import Bulk_UFOs
def check_filepath_demo(path):
print('check filepath demo', path)
Bulk_UFOs(check_filepath_demo, 'Test Files', formats=['.ttf'], openclose=False, save=False)
from Bulk import Bulk_UFOs
def check_rfont_demo(RFont):
familyName = RFont.info.familyName
styleName = RFont.info.styleName
print('check rfont demo', familyName, styleName)
Bulk_UFOs(update_rfont_demo, 'Test RFont')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment