Search & Replace fonts in the editor

Suggestion: Expand the functionality of the current editor “Edit/Find/Find by Formatting” command by a “Search and Replace Font1/Size1 with Font2/Size2”. This would help to overcome some severe limitations when using the “Preserve Formatting” feature with format presets.

Example: Technical or software-related texts require to emphasize single words or code fragments with a separate font, e.g. Courier. In Markdown, this is easily achieved by using backtick quotes (), like: Use the printf()` function. When writing large user manuals, however, a more sophisticated text application like Scrivener comes in handy.

Scrivener’s Compile has only weak support for a second text font. What I do: define a new word character attribute format preset with the extra font (let’s say Courier) and the “preserve formatting” option, let’s say “My Code Preset”. Afterwards, I can select a single word and apply the preset “My Code Preset”. This word will now appear in Courier font in any Compile output, no matter what font override is defined for the base text.

This works well – unless I want to change the preserved font later (or want to change the base font size in compile overwrites). Then it becomes an overkill because I have to change every single preserved code word/block manually. An automated search&replace for font/size in the editor would resolve this problem (without having to introduce styles in Scrivener).

–Peter–

Thanks Peter, It’s not a bad idea, but we’ve got some better plans on the horizon that will essentially nullify the need for something like this. Well, I should say that there may always be a minor need for format search & replace, but the idea is to try and minimise that as much as possible.

Meanwhile, do note that there are some options in the Formatting compile pane that may help you out. Preserve Formatting by default preserves everything, but if you click the “Options” button along the top of that pane, you’ll find some settings that make it so you can have the font and various other settings modified anyway.

Thanks AmberV. I’m eagerly looking forward to the things to come!
Any solution that eases the accentuation of single words in a sentence by a separate font (rather than using bold, italic or capitalization) will greatly increase the value of Scrivener for technical writers, especially in computer science. As described in my post, it can be done with the current Scrivener version using the “Preserve Formatting” feature (in the editor) for single words, parts of a sentence, or entire paragraphs. But that is not user-friendly because the preserved emphasis font, once it has been chosen and used in multiple places, cannot be easily changed across an entire document. The “Options” in the Compile Formatting pane can not do that.

–Peter–

Hello,

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<xx> with \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 \f3\fs24.

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. roman, swiss, 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 :slight_smile: 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.

–Peter–

I don’t have much use for markdown in my own writing, but since Scrivener supports MultiMarkDown syntax, couldn’t you write using markdown and the MMD superset of features, and then compile using the MMD output options?

Markdown is not well suited to produce highly structured and custom formatted text output such as, for example, books or user manuals. Furthermore, it would not solve my problem at all: To replace the emphasis font and font size (within two Markdown backtick quotes or a code block) with a font of my choice, I would have to edit a CSS file. This is much more complicated than doing it in RTF markup (like I do in my workaround).

In addition, note that Markdown in Scrivener bypasses most of the neat formatting overwrite features in the “Compile” menu. (They are not available in any of the Markdown output options.) Furthermore, Scrivener’s Markdown compile output options are very limited. You can only produce raw Markdown, HTML (with rather inconvenient support for CSS styles), RTF (minimalistic, and without custom font overwrites and images), LaTex and LaTex-to-PDF (both with only minimal support for using LaTex document classes/packages directly), or FODT (usable only with LibreOffice). That’s pretty cool for people who want to produce some Markdown or LaTex output without learning how to use Markdown or LaTex. But to be honest, with Markdown I prefer to use specialized apps such as, for example, MultiMarkdown Composer (http://multimarkdown.com) and Marked (http://marked2app.com).

In my opinion, Scrivener’s strengths are in the combination of information management features (gather / organize / annotate / navigate / search / manage / integrate your texts, resources and metadata), authoring and project management capabilities, and the very customizable production of high-quality output for multiple media channels. With Markdown in Scrivener (compared to using Scrivener’s rich text editor), you’ll loose most of the flexibility and simplicity in output formatting, and you cannot benefit from some of the versatile features with annotations and comments. Using a format markup language within Scrivener is like riding a horse on roller skates (i.e. you’ll end up in the roadside ditch).

Anyway, font emphasis is already built nicely into Scrivener’s editor (better to say: into the RTF text model Scrivener uses) via the “Preserve Formatting” option in the editor’s Format menu (not be be confused with the formatting overwrite options in the Compile menu). But it lacks an easy way to change a font throughout a binder document that uses multiple fonts.

Such as the Scrivener manual for instance?

:smiling_imp:

This example isn’t quite fair. The good-looking Scrivener PDF manual is a tribute to LaTeX (and XSLT), not Markdown. (BTW: The Scrivener manual’s project file is a great source of inspiration when working with Markdown in Scrivener. It can be downloaded here: http://www.literatureandlatte.com/support.php#Scrivener .)

I’m sorry if you misunderstood my statement. I didn’t say that Markdown “is bad” but that it “is not well suited” for what I want, i.e. gain control of structure and output formatting. As I said: It’s pretty cool how Scrivener provides easy-to-use integration of Markdown/LaTeX (though it is by far not the only one). No question about that. If you like Markdown but don’t know LaTeX, then go for it if the default output (document classes under “Compile LaTeX Options”) fits your needs.

But my point is customization: What if I wanted to write the Scrivener manual, but with my own fonts, different table styles, custom figure captions, different page margin, headers, footers etc ? This requires to dive deeply into the the output specs, like CSS or, in this example, LaTeX classes and even XSLT. This requires profound knowledge about LaTeX. I could do that since I’ve used LaTeX for over 15 years. In that case, however, I never would think of using Scrivener or Markdown but write my book/manual with LaTeX right away. (LaTeX enables me to define and control everything, and the Scrivener manual would look even better with this approach.) In contrast, if you don’t know LaTeX, the Markdown front-end approach (with Scrivener or any other Markdown enabled app) will leave you with almost no output customization options.

Everything comes at a price, and in many cases LaTeX is not worth the effort. What attracts me in Scrivener (aside of its powerful content management features) is to work with plain text (and a bit of rich text), but still have quite powerful, yet easy-to-use output customization options via the Compile menu. Very simple, very powerful. Markdown in Scrivener steals them.