Notes on the Storyist File Format

A Storyist file is just a Zip archive with the “.story” extension. Unzip it and you’ll find that

  • Formatted text files (manuscripts, scripts, notes, etc.) are stored in OpenDocument Format (ODF), an ISO/IEC standard for document encoding.
  • The metadata (section notes, plot notes, etc.) is stored in Resource Description Framework (RDF) format, a W3 standard used for the semantic web.

A typical archive contains the following files:

  • contents.rdf - the manifest of the archive (RDF).
  • story.xml - the manuscript (ODF).
  • story.rdf - the project metadata, including plot, character, and setting data (RDF).
  • stats.json - the project word count data (JSON).
  • notes/ - a directory containing the project’s text files.
  • images/ - a directory containing the project’s image files. Storyist supports any image format that Cocoa’s NSImage class supports.
  • vocabulary.owl - if you have added custom fields, this file will contain your extensions to the metadata “schema”. (RDF/OWL)

Each is described in more detail below.

The Manifest (contents.rdf)

The manifest contains information about the key components of the file, including references to the metadata and a document identifier.

<?xml version="1.0" encoding="utf-8"?>
<rdf:RDF 
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 
    xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#" 
    xmlns:st="http://storyist.com/rdf-syntax/1.0/" 
    xmlns:stcont="http://storyist.com/rdf-syntax/1.0/contents/">
    <rdf:Description rdf:about="">
        <st:model rdf:resource="story.rdf"/>
        <st:vocabulary rdf:resource="vocabulary.owl"/>
        <stcont:preferences rdf:resource="preferences.rdf"/>
        <stcont:documentID>
            A1F17B20-EC48-437C-A00A-E1F405DB1A40
        </stcont:documentID>
    </rdf:Description>
</rdf:RDF>

Storyist defines two namespaces for use in the manifest: http://storyist.com/rdf-syntax/1.0/ and http://storyist.com/rdf-syntax/1.0/contents/.

  • The st:model property is a reference to the project’s metadata model (schema). It is usually named story.rdf, but can be any name.
  • The st:vocabulary property is a reference to a user’s project-specific customization of the metadata model.
  • The stcont:preferences property is a reference to the preferences file containing project-specific view settings. It is usually named preferences.rdf, but can be any name.
  • The stcont:documentID is a universally unique identifier.

Note: The manifest does not currently reference the text file entries.

The Manuscript (story.xml)

The manuscript (or script) is stored as a single XML document in OpenDocument v1.0 format. Storyist adds two attributes to the <style:style> element, both in the http://storyist.com/odf/1.0/ namespace. They are:

  • tab-style-name - specifies the style to be applied to the current paragraph when the Tab key is pressed. If this attribute is omitted, no style is bound to the Tab key.
  • pagination - specifies the pagination mode to be used for the style. The default is “normal”, which is used for documents other than screenplays. Other values are “scene-heading”, “action”, “character”, “parenthetical”, “dialogue”, ”shot”, and “transition”.

Document Settings

The ODF specification allows for application-specific settings in the <office:settings> element. Storyist defines two top-level configuration items: st:outlineSettings and st:documentSettings.

<office:settings>
    <config:config-item-set config:name="st:outlineSettings">
        <config:config-item-map-indexed config:name="outlineLevelSettings">
            <config:config-item-map-entry>
                <config:config-item 
                    config:name="defaultStyle" 
                    config:type="string">Section_20_Text
                </config:config-item>
                <config:config-item 
                    config:name="displayName" 
                    config:type="string">Section
                </config:config-item>
            </config:config-item-map-entry>
            <config:config-item-map-entry>
                <config:config-item 
                    config:name="defaultStyle" 
                    config:type="string">Chapter_20_Title
                </config:config-item>
                <config:config-item 
                    config:name="displayName" 
                    config:type="string">Chapter
                </config:config-item>
            </config:config-item-map-entry>
        </config:config-item-map-indexed>
        <config:config-item 
            config:name="defaultContentStyle" 
            config:type="string">Section_20_Title
        </config:config-item>
    </config:config-item-set>
    <config:config-item-set config:name="st:documentSettings">
        <config:config-item 
            config:name="showSectionTitles" 
            config:type="boolean">false
        </config:config-item>
    </config:config-item-set>
</office:settings>

The st:outlineSettings configuration item set contains two items. The first, outlineLevelSettings, is an index item map (array) that specifies the default values to be applied for given heading level. The first entry in this item contains the settings for body text, the second for heading level 1, the third for heading level 2, and so on.

Each entry specifies:

  • defaultStyle - the name of the style to be applied by default.
  • displayName- the string to be used in the interface (e.g. the Project pane) to display the outline item. This is useful, for example for indicating that “Chapter” (the display name) uses the style named “Chapter_20_Title” (the default style).

For example:

<config:config-item-map-entry>
  <config:config-item config:name="defaultStyle" config:type="string">Chapter_20_Title</config:config-item>
  <config:config-item config:name="displayName" config:type="string">Chapter</config:config-item>
</config:config-item-map-entry>

The second map contains information specific to screenplays–arrays of script completions.

<config:config-item-map-named config:name="completions">
    <config:config-item-map-indexed config:name="times">
        <config:config-item-map-entry>
            <config:config-item 
                config:name="stringValue" 
                config:type="string">DAY
            </config:config-item>
        </config:config-item-map-entry>
        <config:config-item-map-entry>
            <config:config-item 
                config:name="stringValue" 
                config:type="string">NIGHT
            </config:config-item>
        </config:config-item-map-entry>
        <config:config-item-map-entry>
            <config:config-item 
                config:name="stringValue" 
                config:type="string">MOMENTS LATER
            </config:config-item>
        </config:config-item-map-entry>
        <config:config-item-map-entry>
            <config:config-item 
                config:name="stringValue" 
                config:type="string">CONTINUOUS
            </config:config-item>
        </config:config-item-map-entry>
        ...
    </config:config-item-map-indexed>
    <config:config-item-map-indexed config:name="locations">
        ...
    </config:config-item-map-indexed>
    <config:config-item-map-indexed config:name="characters">
        ...
    </config:config-item-map-indexed>
    <config:config-item-map-indexed config:name="extensions">
        ...
    </config:config-item-map-indexed>
    <config:config-item-map-indexed config:name="transitions">
        ...
    </config:config-item-map-indexed>
    <config:config-item-map-indexed config:name="sceneIntros">
        ...
    </config:config-item-map-indexed>
</config:config-item-map-named>

The Project Metadata (story.rdf and vocabulary.owl)

Storyist stores project metadata (character, plot, and setting information) in an RDF file using the OWL representation for objects.

Storyist defines two extension attributes to the OWL ontology that can appear in both the <owl:ObjectProperty> and <owl:DatatypeProperty> elements.

  • sts:key - specifies a key that is unique to the project definition
  • sts:deleteRule - specifies what happens to properties of objects that refer to a given object when the object is deleted from the model. The current implementation supports only “Nullify”, which is the default value.

When the user adds fields to story sheets, Storyist creates new OWL vocabulary entries for them and stores them with the project, usually in the vocabulary.owl file.

The example below shows the result of adding a single field named “My Field” to a character.

<?xml version="1.0" encoding="utf-8"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 
    xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#" 
    xmlns:owl="http://www.w3.org/2002/07/owl#"
    xmlns:sts="http://storyist.com/rdf-schema/1.0/">
    <owl:DatatypeProperty 
        rdf:about="http://storyist.com/rdf-syntax/1.0/extensions/myField">
        <rdfs:label>My Field</rdfs:label>
        <sts:key>myField</sts:key>
        <rdfs:domain rdf:resource="http://storyist.com/rdf-syntax/1.0/Character"/>
        <rdfs:range rdf:resource="http://www.w3.org/2001/XMLSchema#string"/>
    </owl:DatatypeProperty>
</rdf:RDF>

The complete OWL ontology (schema) can be found in the file named StoryistVocabulary.owl in the Contents/Resources folder inside the Storyist application.

Project Stats (stats.json)

The project stats file (encoded using the JSON format) contains a list of session times and word counts for the project.

{
    "projectStats" : {
        "wordCountGoal":"50000",
        "startDate":"2016-02-03 10:11:43 -0800",
        "endWordCount":"726"
    },
    "sessions" : [ 
        {
            "wordCountGoal":"1667",
            "startDate":"2016-02-03 10:11:43 -0800",
            "endWordCount":"42"
        }
    ]
}

Working with Story Files

Using the Terminal

To view the contents of the story file, you’ll first need to unzip the file.

$ unzip Test.story -d <folder>

Where “Test.story” is the name of your story file and <folder> is the name of a folder to be created to hold the story file contents.

You can create a story file as follows:

$ cd <folder>
$ zip -r ../Test1.story *

Editing with Emacs

If you use the One True Editor, editing is easy. Add the following to your .emacs file and you’ll be able to open and edit Storyist .story files directly.

(setq auto-mode-alist
(append '(
("\\.story"  . archive-mode)
) auto-mode-alist))

Source Code for Reading and Writing XML Files

There are a number of options for reading and writing XML files. These include:

  • LibXML - an open source C library that provides both a tree-based API and a SAX API. In addition to the C API, it provides bindings for most popular scripting languages.
  • NSXML - Cocoa classes that provide a tree-based API
  • NSXMLParser - A Cocoa class that provides an event-driven (SAX) API.

Source Code for Reading and Writing RDF Files

Storyist uses the RDF/XML (abbreviated) encoding of RDF files, so all of the above tools can be used to read and write RDF files. Additionally, the open source Redland RDF Libraries provide a full suite of RDF tools, including bindings for scripting languages. (Storyist Software contributed the implementation of the RDF/XML-abbrev serializer).