RapidWeaver Sandwich (.rwsw) README
===================================
This is a RapidWeaver Sandwich (.rwsw) file, which is designed to be a "bundle"
(directory) on Mac OS X. If you are reading this, it's assumed that you're
somewhat curious about the innards of how RapidWeaver stores its data. Feel
free to do this: the RapidWeaver file format is designed to be open and
hackable, and we welcome tools that can read our file format! Here's what you
need to know about the RapidWeaver file format to play with it.
Note that this README.txt file is designed to give you the minimum amount of
information necessary to peek and poke around the .rwsw bundle. For more
extensive information on the RapidWeaver Sandwich file format, please
visit the Realmac Software website at
and check out our developer documentation.
Sandwiches
----------
* Every directory must have a Contents.plist file, which is an Apple
Property List file; man plist(5) for more details. A directory that has a
Contents.plist file in it is called a "Sandwich". All directories must
be sandwiches, i.e. all directories _must_ have a Contents.plist file in
them. For robustness and interoperability reasons, most (or all) plist
files you encounter will be stored as XML, but you may also encounter binary
plist files for Contents.plist files that can become potentionally large
sizes (100k+), and whose contents are not critical for your data integrity.
* A sandwich's Contents.plist file has a dictionary for its Root property.
This top-level dictionary has two keys: Type, which indicates the type of
data this directory stores (e.g. "Page Attributes" or "Publishing
Manifest"), and a second key named SandwichFillings.
Sandwich Fillings
-----------------
* The SandwichFillings key in the Contents.plist dictionary is an array of
dictionaries. Each of these dictionaries is called a "Sandwich Filling",
and the offset into the array reflects different versions. As an example,
an array of three dictionaries has three sandwich fillings: a version 0
filling, version 1 filling, and a version 2 filling.
* The array of sandwich filling versions is meant for easy forward and
backward compatibility. Backward compatibility is achieved by an
application only reading sandwich fillings up to a particular version that
it understands. For example, RapidWeaver 4.0 may only understand version
0 of a particular sandwich type, but RapidWeaver 4.1 may understand both
version 0 and version 1. (It is implicit that if an application understands
version n, it will understand versions [0..n]). Forward compatibilty is
achieved by an application simply ignoring version numbers that it does not
understand, and re-writing those sandwich filling versions out verbatim when
it re-saves the file.
* Each sandwich filling has three keys: Files (an array), Subsandwiches (also
an array), and Dictionary (surprise surprise, a dictionary).
* The Files key contain filenames in the current sandwich directory that
are referenced by that version of the sandwich. This enables version
0 of a sandwich filling to reference OLDFILE.blob that may contain some
data, and version 1 of a sandwich filling that references NEWFILE.blob,
which contains additional information supplementing OLDFILE.blob. Note
that files referenced by the Files array are required to be regular
files or directories, so no symbolic links (or special block
devices...) are allowed to reside in a sandwich.
* For performance reasons, referenced files usually share multiple hardlinks.
(This applies to this README.txt file as well -- it is hardlinked to the
Resources/Sandwich-README.txt in the RapidWeaver.app application bundle,
and therefore has the same inode number.) If you are editing files manually,
make sure to check that the editor you are using saves to a different file
inode, otherwise other Sandwich documents on the same volume will share the
changes you've just made! (For example, in Vim, make sure you do
":set backupcopy=breakhardlink".)
* The Subsandwiches array refers to further sandwich directories inside this
sandwich.
* The Dictionary key contains an arbitrary key-value dictioanry that holds
information too small to efficiently stored as separate files. This is
useful for storing short strings, numbers, and boolean values for the
application.
Attributed String and Archive Files
-----------------------------------
* Sandwiches may contain files with a .as extension. This is a native Cocoa
representation of the NSAttributedString class, serialised directly to disk
via NSKeyedArchiver. While the .rtf and .rtfd file formats are de-facto
standards for storing NSAttributedStrings to disk in a directly editable
fashion, those file formats do not store any custom attributes in the file
format, which RapidWeaver uses extensively. As such, .rtf and .rtfd files
are lossy formats for RapidWeaver and cannot be used to store all data in
a text field. For best performance and data reliability, we chose to use
Cocoa's native archiving mechanism to store attributed strings to disk.
* We provide a command-line BSD tool in the RapidWeaver.app application bundle
named "astool" that can manipulate attributed string files. See the
astool(1) manpage (in the Resources/ directory of the RapidWeaver.app
bundle) for more information. You are also welcome to write your own
simple Cocoa programs to read and write .as files, of course: simply use
+[NSKeyedUnarchiver unarchiveObjectWithFile:] to instantiate an
NSAttributedString object from the file on disk.
* Files with a .archive extension are similar to .as files in that they are
direct Cocoa archives of objects, but may be an arbitrary class. Manipulate
them at your own risk.
* It may be useful to know that Cocoa archives are stored as binary property
list files; you can, in fact, rename the files to have a .plist extension
and open the files up in Apple's standard Property List editor that comes
bundled with the Xcode Tools. Good luck trying to make sense of the
archive, though :).
- Realmac Software