In my last blog post, I talked about all the things that weren’t coming in Scrivener 2.0. Now it’s time to talk about some of the goodies that are coming. Right upfront I ought to say that the focus has been very much on improving Scrivener’s existing feature-set by better integrating various aspects of the interface and making Scrivener easier and more pleasurable to use in general. I always think very carefully before adding new features - it’s impossible to please everybody because every user has something different on his or her wish list, and if you try you just end up with software that is bloated and difficult to use. So, I make no apology for concentrating on the core features rather than trying to shoehorn in features I don’t think belong. And yes, that’s my way of saying that you won’t find anything particularly whizz-bang in this list - but you should see a solid set of features that you will find useful in the endeavour for which Scrivener was designed: writing.
Earlier this week I completed the last major block of code for Scrivener 2.0 - at last. Now all that remains is a number of small issues and tweaks and then two months of beta-testing and bug-fixing before the release in October (barring any major catastrophes or problems that crop up during beta-testing).
This morning someone asked me how big Scrivener’s code base is, and I didn’t know how to answer - yet it’s something I’ve been wondering myself. It comes up occasionally, usually in two situations: 1) Someone writes to me wanting to know how much code it took to create Scrivener, because they have an idea for a program and wonder what’s involved; 2) Someone is insisting that I could port Scrivener to platform X or “just add” Y “easily enough” and is getting uppity that I’ve said no, so I want to puff out my chest and huff, “Look, I have written six billion lines of code mostly unique to the Mac platform and I’ve already got grey in my hair - coding Scrivener ain’t like dusting crops, kid!” (These exchanges usually end with me apologising for something.)
I’ve long been intending to add some technical, coding-related content to this blog. I’ve always admired the blogs of other developers who share some of the coding problems they have faced and solutions they have reached, and in developing Scrivener there are a number of issues that I’ve come across and found solutions for that I’m sure could be useful to other developers. So, this is the first more techie, coding-orientated post to make it to the blog. Those with no interest in Cocoa development, look away now. I have recently been rewriting Scrivener’s file format. As you may or may not know, .scriv files are packages – essentially folders that on OS X just look like, and are treated the same as, files. Were you to move a .scriv file to a different platform, it would appear as a regular folder. On OS X, you can ctrl-click on a .scriv file in the Finder and select “Show Package Contents”. File packages are great for programs such as Scrivener. Regular files usually have to be loaded into the program’s memory in their entirety when loaded; with a file package, the program can just look inside it and open whatever it needs as and when it needs it. Given that Scrivener can import movie, sound, PDF and image files, you can imagine how much memory might get eaten up if it had to load everything into memory right from the get-go. Instead, with its package format, it can just load the binder structure file and then load up each document as you select it in the binder, and flush from memory any large files that aren’t currently being used. For Scrivener 2.0, .scriv files will still be file packages, but I’ve been doing some work on the format of the files inside the .scriv file. Currently all text files are saved internally as RTFD files (RTFD stands for “rich text format directory”). RTF files are a standard rich text format that can be opened on all major platforms (they are essentially plain text files with formatting mark-up), and were designed by Microsoft; RTF files support pretty much everything that Word documents do. RTFD is Apple’s extension of this format. An RTFD file is a file package in itself (as with .scriv files, you can ctrl-click on them in the Finder and select “Show Package Contents” – you will find a TXT.rtf file inside there, for instance, which holds the actual text). Apple designed the format so that such files could also hold QuickTime files and any other file type; but the trouble is that RTFD files can only be opened on Macs. Most of the other files inside .scriv packages use the Apple .plist format – I may have given some of them the .xml extension (.plist files are technically XML files), but internally they are just Apple .plists. (.plist stands for “property list”). This format for Scrivener files was generally a great and solid 1.x file format. It works, and it doesn’t take too much code to maintain on my part – the Cocoa frameworks make it very easy to write to RTFD and PLIST formats. However, for 2.0 I wanted to make Scrivener’s format less platform-specific. The current format has two main flaws: 1) Its use of .plist and .rtfd files means it’s a format that can only be read on the Mac. Although I personally have no plans to switch to or code for other platforms, this would be a significant hurdle for anyone we wanted to work with to port Scrivener to, say, Windows. 2) The .plist format is not human-readable – at least, not when used with the sort of data that Scrivener has to write out. This makes it difficult for anyone on any platform, including the Mac, to write utilities that might work with the Scrivener format. For these reasons, I am in the process of making the following changes to the .scriv package format: 1) The .scriv package will no longer contain all files in the root folder. Instead, subdirectories will be used to make it easier to navigate. That way, should it be ported to a different platform that doesn’t support packages, it will be easy for the user to find the file required to open the project. And in general it’s just neater, of course. 2) I will no longer use the RTFD format and will switch to using RTF instead. The only reason I didn’t use RTF to begin with was that Apple’s standard RTF reader and writer – the one provided in the Cocoa frameworks – ignores images. That is, it fails to load or save images in the text. Over the years this is something I’ve fixed myself, though, so I use a modified version of the RTF reader/writer to save and load RTF files that retain images with no problems. This not only means that all the text files stored inside a .scriv file are now platform-independent, but also that they are using a file format that has been around for over twenty years. It’s also a format that can be opened in a plain-text reader. 3) Instead of using .plist files, I am creating my own XML file formats where applicable. (There are other changes too – for instance I am now using a checksum file that can tell which files have been changed since the last session; this means that should Scrivener crash, you will no longer be faced with the time-consuming “Synchronising…” panel, as Scrivener will be able to update only the search indexes for the files that have changed rather than going through every single file in the project.) Needless to say, writing my own XML file formats is the most time-intensive part of this process. Fortunately, Cocoa has some excellent and easy-to-use classes for generating and reading XML – the NSXML… classes. For instance, suppose I wanted to create the following XML:
So. The iPad. (You may have heard of it. It’s a neat little gadget Apple released last week without much fanfare.) There are commentators out there declaring it the world’s most expensive Etch-a-Sketch (unfair; it has no stylus), and others praising it as being as “magical” and “revolutionary” as Steve Jobs and Jonathan Ive would have us believe. My own opinion on the device is somewhat schizophrenic (in the colloquial sense, obviously). I’m split between my thoughts as a user and my thoughts as a Mac developer.
For all those scriptwriters out there, and for all those who don’t already know, Final Draft 8 was finally released not long ago. Final Draft is, of course, the industry standard of scriptwriting programs, and version 8 brings with it a raft of new features and an overhaul to the interface that makes it feel much more like a native Mac app than previous versions. I won’t go into the various new features - navigator, improved index card navigation, new interface, and so on - here; instead, I just thought I’d say a few words about Final Draft’s relationship with Scrivener.
So, in overhauling Scrivener's toolbar graphics and other graphic elements for 2.0, I noticed that a lot of OS X apps handle toolbar images a little more elegantly than Scrivener 1.x. Scrivener's toolbar looks fine when the icon size is set to normal, but if you set the it to use the small image size, the images get rescaled and don't look so hot. A lot of apps - look at Pages for instance - look great at both sizes, because they provide custom images for each rather than just allowing the toolbar to scale the larger images down when the small size option is selected. with Scrivener 1.x, though, I only created images for the larger size.
I was waiting on overhauling images such as these to see if Snow Leopard introduced resolution independence - when that comes just about every image in every OS X app is going to need recreating at a much larger scale by professional artists. But seeing as that doesn't seem to be on the agenda for 10.6 (which makes me sigh with relief as a developer even if the end-user part of me would like to see it), I have started in on overhauling the icon set.
The way OS X toolbars handle selecting the small or large image for a particular toolbar icon is to look in the one image file for both images; that is, it expects both images to be bundled into the same .tif or .icns file (the larger one at 32x32 pixels and the smaller one at 24x24). OS X comes with a tool that will create .icns files easily enough, but being obtuse I decided I wanted to keep the toolbar icons as .tif files (which is how most Apple apps do it). The trouble is, Photoshop doesn't support .tif files containing multiple images. So I Googled around to find a tool which would, but either my search terms were rubbish or the only tools that really do this sort of thing are paid-for, fully-featured apps, and I realised I could write my own tool to do this much more quickly than I could find one from searching through Google results - after all, all it needs to do is take two image files already created in Photoshop, one for the small size and one for the larger size, and bundle them both into the one .tif file.
So, here is my ten-minute app that does exactly this:
It's pretty self-explanatory - you just drag a 32x32 image into the 32x32 image well and a 24x24 image into the 24x24 well, and then hit Save to create a .tif file that combines the two, suitable for use in toolbars.
EDIT: I've updated it so that you can open existing multi-page .tif files and export the small or large icons out as separate files.
Who knows, maybe it will come in useful for somebody else putting their toolbar images together. Probably not; given that a lot of developers do this already, presumably there is already an abundance of tools out there that do this that I just missed, but it was a diverting ten-minute break from the intense coding I'm doing on Scrivener 2.0 at the moment. Which rocks, by the way.