Edit a Ulysses style in Editorial, then install it in Ulysses for iPad.
Peter Hopcroft, April 2015
- Change extension name in documentation
- This does not trap errors if files don't exist or are empty.
- A proper Ulysses style has three files, but Preview.png is not necessary for this, and I don't include it.
BEFORE USING THIS WORKFLOW
You need to download an existing Ulysses style and set up the files in an
Editorial folder. Below shows how I do it on my iPad:
- In Editorial's settings, set .plist and .ulss as plain text extensions.
- Go to the Ulysses app style exchange and download (I use a browser, icab mobile) a style that is similar to the one you want. This style must not be in Ulysses already, because we will use its file name (identifier in Info.plist).
- Rename the style's extension from .ulstyle to .zip (I use dropbox))
- Unzip it (I use icab mobile): there are 3 files:
a stylesheet file (nn...nn.ulss for PDF or RTF, nnn.css for other types)
preview.png (ignore the.png)
- In an Editorial folder, create four files:
a stylesheet file (empty) (same name as the unzipped stylesheet file)
ulss-copy.txt (type anything in it)
ulss-backup.txt (type anything in it)
- Copy and paste the contents of your unzipped Info.plist into your empty Editorial Info.plist.
- Copy and paste the contents of your unzipped stylesheet file into your empty Editorial stylesheet file.
- In Info.plist, change the displayName string to your new name for the style.
USING THIS WORKFLOW IN EDITORIAL
- Edit the stylesheet file (the Ulysses website has a style guide). Info.plist has fonts and dimensions, but I don't need to change them.
- Open a different file in the same Editorial folder. This saves the file you just edited, otherwise your last change can be ignored (Editorial bug).
- Run this workflow. At the openin display, tap Ulysses. Ulysses opens and gives a HUD 'style installed'. Enjoy. You can also tap the .ulstyle file in the Editorial folder to openin.
- If you want to change the style again, first delete the style from Ulysses's Custom Styles menu (swipe left, Delete). Then wait in Ulysses for up to 10 seconds for the delete to happen (maybe it syncs to iCloud; I have WiFi on) then switch back to Editorial.
from io import BytesIO
# name some files
root = 'local' # 'local' or 'dropbox'
r, rel_doc_path = editor.to_relative_path(editor.get_path())
rel_doc_dir, fn = os.path.split(rel_doc_path)
plist_file_name = 'Info.plist'
plist_rel_path = os.path.join(rel_doc_dir, plist_file_name)
copy_rel_path = os.path.join(rel_doc_dir, 'ulss-copy.txt')
backup_rel_path = os.path.join(rel_doc_dir, 'ulss-backup.txt')
# extract the style's file number and display name from plist
plist_str = editor.get_file_contents(plist_rel_path, root)
b, s, a = plist_str.partition ('styleSheet</key><string>')
stylesheet_file_name, s, a = a.partition ('</string>') # name + ext
b, s, a = plist_str.partition ('displayName</key><string>')
display_name, s, a = a.partition ('</string>')
# name more files
style_file_name = display_name + '.ulstyle'
style_rel_path = os.path.join(rel_doc_dir, style_file_name)
stylesheet_rel_path = os.path.join(rel_doc_dir, stylesheet_file_name)
# backup the .ulss file
ulss = editor.get_file_contents(copy_rel_path) # backup
editor.set_file_contents(backup_rel_path, ulss, root)
ulss = editor.get_file_contents(stylesheet_rel_path) # copy
editor.set_file_contents(copy_rel_path, ulss, root)
# zip the .plist and.ulss files to make the .ulstyle file
d, fe = os.path.split(editor.get_path() ) # now need absolute paths
zip_buffer = BytesIO()
with zipfile.ZipFile(zip_buffer, 'w', zipfile.ZIP_DEFLATED) as zf:
zf.write(os.path.join (d, stylesheet_file_name), stylesheet_file_name)
zf.write(os.path.join (d, plist_file_name), plist_file_name)
zip_data = zip_buffer.getvalue()
editor.set_file_contents(style_rel_path, zip_data, root)
# open style in Ulysses
console.open_in(os.path.join (d, style_file_name))