This is a follow-up with a low-level workaround (aimed at other Scrivener users who are suffering from the lack of font replacement in Scrivener’s editor). The goal: In a binder document, I want to replace all occurrences of a specific font X or/and font size xx with a new font Y or/and font size yy. This makes most sense for text that has set “Preserve Formatting”, but the workaround can be applied to any font used in a Scrivener editor document. The workaround directly edits the font table in the underlying RTF file of the binder document.
1. Identify the RTF file name of the binder document. For example, do a ‘Copy Document Link’ on the binder document, paste the link somewhere, and note the integer number at the end of the link (…?id=). Your document has file name .rtf, e.g. “35.rtf”.
2. Close your Scrivener project. (Reopening is required later because Scrivener does not detect external changes to files, thus the RTF file has to be re-sourced after we applied the changes).
3. In the Mac Finder, locate and select your Scrivener *.scriv project file (which contains the binder document to be changed), choose Finder context menu ‘Show Package Contents’, navigate into the directory Files/Docs, and locate the file .rtf (replace with the integer number you got in step 1, e.g. “35.rtf”).
4. In a text editor, open the file .rtf in plain (!) text mode, so that you can see the RTF markup. (Any plain text editor will do, e.g. TextWrangler, BBedit, Textmate, or Sublime Text. You cannot use TextEdit unless you have enabled the preferences setting to open RTF files in plain text mode.)
5. In the file’s RTF prolog font table (starting with RTF marker
\fonttbl), look for the font format entry that contains the font X you want to replace with new font Y. Font table entries start with RTF marker
\f<M>, where is an integer number. In that entry, replace the font name X with the name of the new font Y. Here, Y has to be the Postscript name of the font. If you feel unsure, open Mac Font Book, search and select font Y, and click the Info button to see its Postscript name. That’s it for the font replacement.
6. Optional: If you want to change the font size, start the search & replace function of your text editor, and replace every occurrence
\f<M>\fs<yy> within the RTF file. Here, is the format number you identified in the previous step 5, is the current font size used in the RTF file, and is the new font size to be used. Important: RTF font sizes are in half-points (not points!), i.e. \fs25 means 12.5 point. For example, if my font is defined in font format entry f3, and I want to replace all 11 point sizes with 12 point, then I have to search for all occurrences of
\f3\fs22, and replace them with
7. Save the file .rtf, reopen the Scrivener project, and open the binder document in the Scrivener editor. All text that had font X with size xx before will now have font Y with font size yy.
Note that this procedure can save you hours of frustrating work: If there are hundreds of words and/or text blocks were you want to change the font, you would have to manually reformat every single font occurrence in Scrivener (because it does not have a Search&Replace function for fonts). In contrast, the workaround does it with a single replacement of one string (the font name in the respective format entry of the RTF prolog)!
Closing remarks: A full RTF format entry in a Scrivener RTF file has the form
\f<fontnum>\f<fontfamily>\fcharset<N> <fontname>. Here, is the integer number of the format entry, is a font family identifier (e.g.
decor etc.), is an integer 0…255 denoting a character set, and is the system font dictionary (or Postscript) name of the font. Two special values are nil for the font family (
\fnil), which means “Unknown or default fonts” (the default), and character set 0 (
\fcharset0), which means ANSI.
For example, I regularly use the font TheSansMonoCd-W2ExtraLight to emphasize technical terms in a text. (This is the emphasis font typically used in O’Reilly books.) It’s format entry in the Scrivener RTF prolog font table looks like that:
\f<M>\fnil\fcharset0 TheSansMonoCd-W2ExtraLight (where will be the actual format entry number). In contrast, the font “Helvetica” would have the entry:
\f<M>\fswiss\fcharset0 Helvetica, i.e. it has font family “swiss”.
However, most text editors ignore both the font family and character set. As far as I can see, this is also true with Scrivener since it uses the Mac OS X text framework. Therefore, the actual values of
\f<fontfamily>\fcharset<N> don’t matter, most fonts will have
\fnil\fcharset0, and it is also valid to omit both markers. In fact, both entries
\f<M>\fnil\fcharset0 Helvetica and
\f<M> Helvetica will work as well. In consequence, you don’t have to care about the font family and character set markers when using this workaround. Just leave them as they are, and only replace the in the respective format entry. If you feel uncomfortable with this fuzzy approach, there is an “exact” way to do it: In Scrivener, create a dummy binder document with some text. In the Scrivener editor, format the text with the new font that you want to use as the replacement font. Then, perform the same steps 3 - 5 (as described above) to look up the font format entry of the new font in the RTF file which belongs to the dummy binder document. Copy the font name including font family and character set markers, and past it over into the format entry of the “hot” RTF file (where you want to change the font).
In my example with TheSansMonoCd and Helvetica, I would copy
\fswiss\fcharset0 Helvetica from the “dummy” document, and paste it over the
\fnil\fcharset0 TheSansMonoCd-W2ExtraLight in my “hot” document (to replace TheSansMonoCD with Helvetica font). Be careful NOT to overwrite any font format entry number markers because they are specific to each RTF file (and the number of fonts used therein)! This approach takes a little more time, but it has an additional advantage: you don’t need Mac Font Book to look up the exact Postscript name of the new font.
Note: This workaround comes without a warranty. It works as long as you avoid mistakes Wrong replacements of font names and RTF font size markers may be disruptive, and may render the RTF file unreadable by Scrivener. In addition, the workaround works with Scrivener 2.5 (and older) but may not work anymore when L&L changes Scrivener’s underlying text model in the future.