# Help

- Introduction To Storyspace
- What’s New In Storyspace 3
- Basic Concepts
- Guard Fields
- Actions, Expressions, and Rules
- Requirements
- Read and Edit Mode
- The Built-In Notes 'start' and 'me'
- Sculptural Hypertext
- Using Maps
- Using Outlines
- Using Charts
- Using Treemaps
- Actions and Expressions
- Import
- Release Notes
- License, Copyright and Colophon
- Recent Changes

## Introduction To Storyspace

### A Tool For Hypertext Narrative

Storyspace is a tool for creating and reading complex narrative hypertext.

The original Storyspace was medium for many of the most significant early works in hypertext fiction. Some notable titles include

> Michael Joyce, afternoon, a story

> Stuart Moulthrop, Victory Garden

> Shelley Jackson, Patchwork Girl

> Kathryn Cramer, In Small & Large Pieces

> Mary Kim Arnold, Lust

> Bill Bly, We Descend

> Ed Falco, A Dream With Demons

but the majority of the titles of the so-called “golden age” of pioneering hypertext fiction were written in Storyspace.

Storyspace 3 reimplements and expands the original Storyspace. Storyspace 3 can import and perform existing Storyspace documents, and allows you to revise old documents and to create new narratives. Storyspace 3 features tremendous improvements in speed, typography, presentation, and greatly improved views.

Storyspace 3 also expands on the familiar Storyspace approach to linking, offering new opportunities to control the interconnection of the elements of your story.

On release, Storyspace 3 provides a reading environment for OS X computers. Future reading environments for iPad, for the Web, and for Windows 10 are planned.

### Getting Started With Hypertext Narrative

The accompanying document, Getting Started With Hypertext Narrative, discusses some ideas that underlie hypertext generally and hypertext fiction specifically. It examines a variety of questions about the craft of writing fiction and nonfiction that is open to change with every reading and that adapts to each new reader.

These help notes focus instead on the mechanics of using Storyspace.

### Tinderbox and Storyspace

Storyspace 3 is a completely new implementation of Storyspace using modern technology. Storyspace 3 and Tinderbox share a common foundation and resemble each other in many ways.

Tinderbox is a tool for notes, and it offers powerful agents and rules than let your notes help organize themselves while helping you discover emergent structure. Tinderbox also offers powerful and flexible export for working with other tools and building Web sites.

Storyspace is a tool for crafting hypertext narrative – both fiction and nonfiction. It offers powerful dynamic links that let documents adapt their behavior in response to the reader’s choices.

Tinderbox and Storyspace share the same file format and can use each other’s files interchangeably.

Note that in Tinderbox clacking a link in a note's text navigates the link. In Storyspace this only occurs if the note is in ‘Read’ mode; this ensures guard field logic is correctly applied.

## What’s New In Storyspace 3

This section provides a quick start for readers who are already familiar with Storyspace.

### Traditional Guard FIelds

Storyspace guard fields determine whether a link can be followed at any given point in the reading. Guard fields may take into account the reader’s past trajectory and actions during the reading, and have proven indispensable for large-scale narrative.

Storyspace 3 reads traditional Storyspace guard fields and automatically wraps them in a guard expression:

> traditional: `"prologue" | "yes"`

> modern: `guard("prologue" | "yes")`

With this small change, Storyspace 3 can import and perform existing Storyspace documents, and permits you to write new Storyspace hypertexts using traditional guard fields.

### New Guard Fields

Storyspace 3 also supports richer and more flexible guard fields that can incorporate any Tinderbox expression. If the expression’s result is true, the guard field is satisfied; if false, the guard field is not satisfied and the link it disabled.

The convenience functions visited() and unvisited() help make guard fields more legible. Some sample guard fields:

> `visited(/prologue) | visited(/help)`

> $Health(/hero) > 5

> every(child(/episode 1),$Visits>0 )

### Guard Fields and Text Links

In Storyspace 3, if a text link has a guard field and the guard field is not satisfied, the link is not drawn and the linked text is not colored.

### Read and Edit mode

The Storyspace 3 text pane provides two modes.

In Edit mode, clicking in the text pane moves the insertion point or selects text.

In Read mode, clicking in the text pane follows links.

### Sculptural Hypertext

Storyspace 3 also supports sculptural hypertext, which can be freely mixed with Storyspace’s familiar calligraphic hypertext.

When the reader tries to follow the default link from a writing space, Storyspace uses calligraphic links if any are available. If no links are available, Storyspace checks to see if there is a current deck – the name of “deck” of writing spaces. If a deck has been chosen, Storyspace selects an unvisited writing space from that deck.

Each writing space, when visited, may set, remove, or modify the current deck. Writing spaces may also specify requirements that must be satisfied before they can be visited; requirements thus serve a function parallel to guard fields.

### Attributes and Values

As in Tinderbox, Storyspace 3 associates hundreds of attributes with each writing space. Some of these attributes include the title and subtitle of the writing space, its text, and its position in the map view.

Guard fields and OnVisit actions are free to use attributes. Writers may define their own attributes, which may contain strings, sets, lists, numbers, dates, booleans, or other kinds of information.

### OnVisit Actions

A note’s OnVisit action is performed when the note is visited in Read mode. For example, one note’s OnVisit action might give the hero a sword:

> Name: Lady In The Lake

> OnVisit: `$Sword(/me)=true;`

Here, $Sword is a boolean user attribute. The OnVisit code is stored in the note's $OnVisit attribute.

### Requirements

Writing spaces may have $Requirements which must be satisfied if the space is to be visited. For example, a note in which Alice appears (“What Alice Said”) can only appear before Alice has left for Switzerland:

> Name: `What Alice Said`

> Requirements: `$AliceInSwitzerland==false`

### Shark links

Storyspace 3 defines a new link type, shark links with a special behavior. If the reader visits a note, and if that note has a shark link with a satisfied guard field, the shark link is followed immediately and automatically.

For example, if the protagonist tries to board a bus to New York but has no bus ticket, a shark link could escort him off the bus.

> From (source): All Aboard! New York!

> To (destination): A Stern Reprimand

> type: shark

> guard field: `$Ticket==false`

The note named “All Aboard! New York!” may have any number of inbound links. However we arrive, if we don't have a ticket, we don't visit the note about the bus’s departure, but instead visit “A Stern Reprimand”. If we later return and have a ticket, the guard field will be unsatisfied and the shark link will not interfere.

### BeforeVisit

Occasionally, a note may wish to perform an action before testing whether or not its Requirements are satisfied. The BeforeVisit action , if one is specified, is performed before Requirements are checked. The action's code is stored in the note's $BeforeVisit attribute.

### The Note “start”

When you create a new document, Storyspace automatically creates a note named “start”, which is the first note in outline order. This note represents the cover page or title page, the start of a new reading.

You may rename this note.

### The Note “me”

Storyspace also automatically creates the note “me”, which serves as a place in which Storyspace and your OnVisit actions can store information about the current reading.

### ResetAction

The ResetAction of each note is performed when beginning a new reading by choosing “Cover Page” from the Note menu. This action can be used to reset the initial conditions of each note. The action's code is stored in the note’s $ResetAction attribute. In some older documentation this action is referred to as the OnReset action.

Example: a story might initially have a locked door which readers cannot pass until they have acquired the corresponding key. During a reading, some readers might unlock this door; the ResetAction action ensures that the door is locked at the start of the new reading.

### Text substitution

In read mode, export code expressions that begin with a caret “^” are evaluated and replaced with their result. For example, the expression

> Health: ^value($Health)

would appear as the text

> Health: 10

and the expression

> ...`The hero is ^if($Health>5)fine ^else in trouble^endif.`

would appear as

> ....The hero is fine.

The following export codes may be used:

^value(expression ): evaluates an expression and replaces the placeholder with the corresponding value.

^include( path ): replaces the placeholder with the text of the note specified by path, where path may be the (unique) name of the note, the complete path of a note, or any other designator.

^if( expression ) true-clause ^endif:

^if( expression ) true-clause ^else false-clause ^endif: evaluates the expression. If the result is true, the placeholder is replaced by the text of the true-clause. If false, the placeholder is replaced by the text of the flase-clause.

^stretch(anchor, path, alternate-paths ) : the placeholder will be replaced by the text “anchor”, which will be a link anchor. If that link is clicked, the link text will be replaced by including the text of the note designated by path, provided that note’s $Requirements are met. Additional destinations may be supplied as a list of designators, separated by commas; each destination in turn will be tried until Tinderbox finds one which can be visited. If no destination can be visited, the placeholder will be replaced by the text anchor, but the anchor will not be linked.

### XML files

Storyspace 3 uses Tinderbox-style XML files. These cannot be read by older versions of Storyspace, but should prove far more flexible and reliable.

## Basic Concepts

- Writing Spaces and Links
- Attributes
- Key Attributes
- Aliases
- Making Writing Spaces (Notes)
- Making Links
- Prototypes
- Inheritance
- Breadcrumbs
- Using the Tab Bar

### Writing Spaces and Links

## Writing Spaces

Writing spaces are the basic units Storyspace. Storyspace writing spaces are equivalent to Tinderbox notes and we often call them “notes.” Each writing space has:

- title: the name of the note
- text
- attributes: other pieces of information about the note.

A Storyspace document is a collection of notes. You must create a document before you create notes. You can create many Storyspace documents, and individual Storyspace documents can comfortably contain thousands of notes.

You can open several different Storyspace documents at the same time.

## Hierarchy

Writing spaces can contain other writing spaces. This allows you to arrange notes in a hierarchy.

A writing space that contains other writing spaces is called a container. You could create chapters containing sections containing divisions; or topics containing subtopics; or any other hierarchy that fits your work.

You don’t need to create a hierarchy in your Storyspace document; you can leave all the notes at the same level.

In this manual, we use several terms to describe relationships in the hierarchy. A note’s container is often called its parent. Other notes in the same container are siblings; the first note (in outline order) in a given container is the eldest sibling, and the last note is the youngest sibling. Notes immediately inside a container are called its children; a note’s descendants include its children and also the descendants of the children. Notes that are not inside any container are top-level notes.

## Links

A link is a connection between one writing space and another. Links allow you to make connections between ideas, and allows readers to move between linked notes. A link can lead from a note as a whole, or from selected text within a note (like linked text on the Web).

Storyspace links may be anchored to specific text selections; these are called text links. Links may also be anchored to the entire writing space: these are called plain links or basic links.

When you click in a note while in Read Mode, Storyspace will select a link to follow. If you have clicked in a text link, Storyspace will follow it; otherwise, Storyspace will follow a basic link. Each link has its own priority; if several links might be followed, Storyspace will choose the link with the highest priority.

Links may be activated or deactivated by guard fields – logical expressions that might take into account what the reader has already seen and done. The link’s destination may itself specify requirements that must be satisfied before it may be visited. If a link’s guard field is not satisfied, or if the requirements of its destination are not satisfied, that link is not available.

You can also create a link to a URL—an external document on the Internet. Following the link will open that URL in your Web browser.

### Attributes

In addition to its title and text, each note has a long list of attributes that describe aspects of the note: its name, color, position, shape, and size. You can define your own attributes as well. Attributes let you put meaningful information in a known place.

For an informal note, you might simply write information in the note’s text:

> Read Gibbon’s Decline and Fall of the Roman Empire

In other contexts — research notes for a dissertation, say — you

might prefer to be a bit more formal:

> Author: Edward Gibbon

> Title: The Decline and Fall of the Roman Empire

Author and Title are examples of attributes; by putting the name of the author in a specific place, it is easy for us to distinguish a book by Gibbon from a book that is about baboons and gibbons.

Each attribute has a value; values can be numbers, character strings, boolean (true/false) values, dates, colors, files, and so forth. Whenever you rename, edit, or change a note, you are actually changing the value of one or more attributes of that note.

There are two types of attributes:

- System attributes: information built into all Storyspace documents such as the color of the note, or its width and height. Storyspace keeps this information about every note, and you may view, use, and change it.
- User attributes: you may add your own attributes that every note will have. For instance, you could add the attribute "Priority," and assign every note a priority level from one to five. Or in a bibliography, create the attribute "Type" and tag the note for each source as either "primary" or "secondary."

A few System attributes are

- Read-only attributes: information such as the date and time the note was created, or the date and time it was last modified. Other read-only attributes, such as TextLength and ChildCount, describe properties derived from the document’s current state and are inherently read-only. Storyspace keeps this information about every note, and you may view and use it, but you cannot change it.

Tip: attribute names are case sensitive—"Height" is not the same as "height."

You can inspect and change the value of any attribute in a note's Get Info... window (choose Get Info from the Note menu). Inherited values are in normal weight black text; values set specifically for this note are in bold blak text, and read-only values are in normal weight light gray text.

### Key Attributes

Storyspace keeps track of hundreds of attributes for each note, but a few attributes of each note are likely to be of particular interest to you. If you are making notes about books, for example, key attributes might include author, title, and ISBN number.

A note's key attributes are displayed at the top of its text pane, and at the top of the text window.

You choose the key attributes by setting the value of the attribute `$KeyAttributes` — just enter the names of the attributes you'd like to make key attributes, separating them with semi-colons.

To add an attribute to the note’s key attributes,

- Press the Key Attributes Button (labelled “+”) in the upper right-hand corner of the text pane
- Add the key attributes you prefer

Drag key attributes to up or down to rearrange them. Select any key attribute and press Delete to remove it.

Notes often inherit key attributes from their prototype.

### Key Attribute display differences

Attribute data types are discussed in more detail further below, but it is worth noting how attribute data types are displayed or edited slightly differently when a key attribute:

- String data types appear as a simple text field.
- Boolean data type displays as a checkbox.
- Color attributes display the color name and a swatch.
- Date type attributes are shown as the day, month and year plus hours and minutes, formatted according to the user's System Preference using the 'short' data format. If a date is entered manually and the time is omitted, the current system time is appended. Seconds are not used.
- Numeric attributes are displayed as numbers.
- List and Set attributes are shown as a single string with semicolons separating individual values.
- URL attributes show a globe icon to the left of the text field. Click the icon to open the URL in your web browser.
- File attributes show a folder to the left of the text field. Right-click the folder for a contextual menu of operations on that file; click the folder to open the file in the appropriate application.

### Key Attribute value pop-up lists

For String, List and Set data types, a triangle at the right end of the key attribute field opens a pop-up menu which shows all discrete values for that attribute in the current document; for list and sets the listing is of all discrete list values across the document. These menus are typically limited to no more than 99 values. For such attributes no pop-up list control if shown - so the absence of a disclosure triangle indicates many values. Values are case sensitive ('dog' and 'Dog' will be separate entries).

Clicking a list item sets a String attribute to that value or with Lists and Sets it is appended to existing values.

### Key Attribute value autocomplete

Where value lists are offered, autocompletion is available. As the user types a value it is completed with the nearest possible case sensitive match. Up and Down keys can be used whilst editing to scroll other possible list values for the stored value list.

### Aliases

Aliases let the same note appear in several places in the document; most changes made to the alias are automatically applied to the original note as well, and changes to the original will appear in the alias.

Agents create and hold aliases of notes that match the agent’s criteria. You can also create aliases manually.

To make an alias of a note:

- Select the note.
- Choose Make Alias from the Edit menu.

Aliases look like other notes, but the name of an alias is drawn in italics. Because some languages do not use italic typefaces, you can also request that the names of aliases be underlined using a checkbox in the General pane of Document Settings.

### Aliases and The Original Note

The attribute values of an alias are almost always identical to the values of the original note. For example, the $Color of an alias is the color of the original. If you make the original note red, the alias will be red; if you make the alias green, the original note will also be green.

If the original note is deleted, all its aliases are also deleted. Deleting an alias, on the other hand, has no effect on the original note.

### Making Writing Spaces (Notes)

## Creating A Writing Space (note)

In any view,

- select an existing note (by clicking on it)
- press Return

> or

- right-click in the window, then choose Create Writing Space from the contextual menu

or, in a map view,

- double-click the map background

Or, in any view,

- choose Create Writing Space from the Note menu.

To finish creating the note,

- type a name for the new note

## Selecting A Note

Click on any note to select it. If a note is already selected, it will be deselected and the note you click will be selected.

In outline and chart view, shift-click a note to extend the current selection to include all the notes between the selected note and the note you shift-clicked. In map view, shift-click simple adds the chosen note to the current selection.

⌘-click a note to add that note to the current selection. ⌘-click a selected note to deselect it.

Click in the background of the view to deselect all notes, or press ^⌘⌥-A (Edit ▸ Deselect All).

## Renaming A Note

To change a note’s name, select that note. Then

- Press ⇧⌘-Return and enter the new name, OR
- Click on the title and hold until the edit cursor appears, OR
- Edit the title in the right-hand pane

If you wish, Storyspace may compute the display expression in place of displaying the same name. For example, a container of tasks might display the number of tasks remaining to be done. Display expressions are entered in the Title pane of the Inspector (⌘-1).

### Making Links

In map view, a link widget appears beneath each selected note.

To make a link, click the link widget and drag the link to its destination.

If the destination is not conveniently to hand, drag the link to the parking space in the upper right-hand corner of the window.

After the link is parked, locate the destination. Then, click the parking space and drag the link to its destination.

## Text Links

Links may also be anchored to any span of text inside a note. To make a text link, select the text you wish to link. Then, click on the text link parking space above the text pane and drag the link to its destination — or to the main parking space.

In Read mode, clicking on a text link follows the link, or, if it’s a Web link, opens the link in your browser. If you want to edit linked text, option-click in the link to set the insertion point without following the link.

## Guard Fields

To edit the guard field of a link:

- Select the source of the link
- Click the link’s info button (the “i” icon at the link’s midpoint)
- Edit the guard field and press [Return]

### Prototypes

Often, the easiest way to describe a note is to explain how it differs from another note. We say that the first note serves as the prototype of the second: it shares all the properties of the prototype, except where we specify otherwise.

For example, a group of writing spaces might all describe the same event – that fateful after-prom party, say, where everything started to unravel. Some of these spaces might appear in disparate places in the story: some might be foreshadowing, some appear in their natural chronological position, others may be seen in retrospect. Perhaps some spaces might appear in different places in different reading. Some might not yet have a place: we write a piece of scene and we don’t know where it fits but we keep it around for possible use later.

For our convenience, we also give all these notes a common appearance. They’re green, because everything that happens on Saturday is green. They have a white border to show they’re after the prom, and they all share the badge “wine”. Adding all these settings to numerous notes would be tedious and error prone, but instead we add all these settings to a prototype and can then make all notes from this scene share that prototype. The prototype also makes it easy for us to locate pieces of this scene later, even if they’ve been moved to different containers.

Any writing space can serve as a prototype for other writing spaces. Prototypes let you specify the default value for an entire class of notes. Whenever Storyspace checks an attribute that you haven't specifically set, it will use the value from the prototype. Change an attribute in a prototype, and you change it for the notes that use that prototype.

A few attributes are inherent and are never inherited. For example, moving one the prom prototype would not move writing spaces that use it. .

To create a prototype,

- create a new note, or select an existing note to serve as a prototype
- Open the Properties Inspector (⌘-1)
- Select the Prototype pane
- Check the checkbox “Prototype”

This new note can now serves as a prototype for other notes.

In outline view, the note icon for notes which can serve as prototypes is surrounded by a light green circle.

To use a prototype,

- Select a note in map view, and right-click on the Prototype Tab beneath the note, OR
- Select a note in outline view and right-click on the note’s icon, OR
- Select a note, open the Properties inspector, and choose a prototype from the Prototype pull-down menu.

Your note will now use the selected prototype: it will inherit the values for most of its attributes from the prototype note. When you change the value of any of those attributes in the prototype, the value of that attribute in all of the notes that use that prototype will change as well.

### Using Prototypes

Any note can serve as a prototype for other notes. You don’t need to define prototypes in advance, and you should feel free to create new prototypes as your needs change.

Prototypes save typing. As you take notes, you may find that you sometimes repeat yourself, setting up a series of similar notes that describe similar sorts of things — people, or references, or issues you want to discuss with your staff. Prototypes can help you capture the common elements, making it easier and more pleasant to create notes.

A note can only have one prototype, but each prototype can be used by many different notes.

Prototype inheritance is efficient; don’t worry about memory or performance when using prototypes.

### Inheritance

Writing spaces inherit from their prototype; when you give a note a prototype, you’re telling Storyspace, "this note is just like its prototype, except for the differences I describe."

Whenever Storyspace looks up the value of an attribute, it reviews the following checklist:

- If the note has a value for that attribute, that’s the value.

Otherwise,

- If the note has a prototype, and if the prototype has a value, then we inherit the prototype’s value.

Otherwise,

- If the prototype itself has a prototype, we inherit that value.

Otherwise,

- We use the default value for that attribute.

Note that inheritance has nothing to do with the document hierarchy; a note’s prototype is not necessarily its container. For example, Amy’s Hangover and William’s Bad Idea might be two writing spaces. Each has the prototype “Prom”. One is inside the container “Things Unravel,” the other is inside “Looking Back.”

A note’s own values always override inheritance. For example, suppose that note Prototypical Task is gray. We create a new note called Today's Meeting that inherits from Prototypical Task. Initially, Today's Meeting inherits everything from its prototype, so it’s gray, too. But if we set the `Color` of Today's Meeting to blue, it turns blue. Other tasks remain gray.

Now, we make yet another note, Conference Call, which also inherits from Prototypical Task. It, too, is gray, because Prototypical Task is gray.

But perhaps we’d like all tasks to be green; we change the `Color` of Prototypical Task to green. Now, Conference Call turns green, because it inherits its Color from the prototype. Today's Meeting remains blue, because you gave it a specific color; a note’s own values always take precedence over inheritance.

### Breadcrumbs

When a view shows only one section of a document, such as a focused outline, a breadcrumb bar appears above the view.

The breadcrumb bar shows each ancestor of the note’s presented in the view. In the example above, the notes are contained in the agent named “By Date Of Birth”, and this agent in turn is contained in “Boston 1830-1865”.

Click on any item in the breadcrumb bar to change the focus from the current container to one of its ancestors. For example, click on “Boston 1830-1865” to see both the agent “By Date of Birth” and any other notes contained inside “Boston 1830-1865.”

### Using the Tab Bar

Tabs at the top of each Storyspace window let you switch instantly between different views of your notes. Each tab represents a specific view of a specific section of your document.

Click a tab to select it.

Click the + button at the right edge of the tab bar to add a new tab.

Slide tabs left and right to reorganize them in the tab bar.

Pull a tab down to open the tab in its own window.

When the mouse points at a tab, the tab’s close box becomes visible. Click the close box to delete the tab.

Right-click the tab for a useful menu, allowing you to change the view type or open a new window.

The View menu’s Tab submenu allows you to switch to the next tab (⌥⌘-]), the previous tab (⌥⌘-[), or to create a new tab.

The link parking space is found at the left edge of the tab bar.

## Guard Fields

Storyspace links have guard fields – expressions that determine whether the link may be followed at the current moment. Guard fields let some links change behavior depending on what the reader has seen and done earlier in the reading, and are indispensable to large hypertext narratives.

If the guard field is satisfied, the link may be followed; if not, the link is ignored and another link, if any, will be followed.

For additional background on guard fields and their use, see Getting Started With Hypertext Narrative.

New users are advised to skip the next section and go direct to “New Guard Fields” further below so as to start using current syntax. Existing users with old documents should consider revising old code to the current form to ensure ongoing compatibility.

### Traditional Guard Fields

Storyspace 3 fully supports the traditional guard field syntax used in previous versions of Storyspace.

Guard fields may test for the word on which the user clicked, even if that word has no text link. The guard field

> Nearly

will be satisfied if the user clicks on the word “Nearly” or “nearly” - note the match is case-insensitive. Guard fields may also test for whether the user has previously visited a writing space.

> “Prologue”

will be satisfied if the reader has visited the writing space named Prologue. Conditions may be combined;

> "Prologue"|"William"

will be satisfied if the reader has visited either Prologue or William.

> "Prologue" & nearly

will be satisfied only if the user has clicked on the word “nearly” and has already visited Prologue.

When Storyspace 3 reads a document that was composed in a previous version of Storyspace, it automatically identifies traditional guard fields thus:

> `guard(...traditional guard field...)`

If you wish, you may write new guard fields using this syntax as well. For example, a link with the guard field

> `guard("Prologue")`

will be followed only if the reader has already visited the prologue.

### New Guard Fields

In Storyspace 3, a guard field is a Tinderbox expression to be evaluated. If the result is false, the empty string, the date never, or the number zero, the guard field will not be satisfied. If the result is any other value, the guard field is satisfied.

When evaluating guard field expressions, the following keywords are bound:

> source

> destination

> this (bound to the link’s source)

Traditional guard fields may also be used by passing the traditional guard field without any additional quotes as the argument of the guard function:

> `guard(Prologue)`

is satisfied in the reader has clicked on the word “Prologue”.

> `guard("Prologue")`

is satisfied if the reader has visited the note named “Prologue”.

In addition, the source’s $ChosenWord will contain the most recently clicked word, if any.

New Syntax

In Storyspace 3, a guard field may use any Tinderbox expression. For example

> `$Visits("the castle")`

is true only if the note named "the castle" has been visited at least once, and

> `$ChosenWord=="ambition"`

is true only if the reader clicked on the word “ambition”. Testing the $ChosenWord value replaces the legacy form of testing guard(). Thus the following codes to the same thing but the second form is recommended this:

> `guard(ambition)` Old syntax: works but now deprecated.

> `$ChosenWord=="ambition"` Current syntax: recommended.

Some new convenience functions have been added to make guard fields easier to read and write. The expression

> visited("the castle")

is true if $Visits is greater than zero -- that is, if the note named the castle has been visited in this reading. Conversely,

> `unvisited("the castle")`

is true if $Visits is greater than zero. The shortcut

> `unvisited()`

is true if $Visits(destination) – the number of visits to the destination of the link, is zero.

The new syntax is clearer and more flexible. For example, the link

> `visited("the castle") & $Health(/characters/hero)>10`

if true only if the reader has visited the castle at least twice and if the hero’s health is at least 10. Here, we assume $Health is a numeric user attribute, and the note /characters/hero is used to keep track of the current status of the hero.

In map view, links with guard fields are distinguished by a small diamond, about a quarter of the way along the link. If the guard field is satisfied, the diiamond is solid; if the guard field is not satisfied, the diamond is hollow.

## Actions, Expressions, and Rules

Actions, Expressions, and Rules

## Requirements

Before a link can be followed, Storyspace 3 checks both

- the link’s guard field, and
- the destination’s Requirements expression.

If both are satisfied, the link can be followed. (An empty guard field and an empty Requirements expression are always considered to be satisfied.)

The Requirements expression imposes an additional constraint on all inbound links and is stored in the note's $Requirements attribute. For example, the note DepositQuarter

> Name: Deposit Quarter

> Requirements: `$PluggedIn==true`

can not be visited unless $PluggedIn is true. Individual link guard fields might impose additional conditions as well.

Requirements can be especially useful when a note’s accessibility depends on some state of the world. For example:

- If a note describes a chat with Barbara, it might be accessible only before Barbara has left for Switzerland.
- If a note describes the narrator’s first sight of the throne room, it might be accessible only after the narrator has acquired a pass granting access, and only on those days when the Queen is in residence.

More information on Requirements and their use may be found in Getting Started With Hypertext Narrative.

## Read and Edit Mode

The Storyspace text pane offers two modes.

Edit mode lets you edit the text of the writing space. Clicking in the text will move the insertion point or select text.

Read mode lets you explore the hypertext. Clicking in a text link will follow that text link. Clicking elsewhere will follow the highest-priority basic link, often called the default link. Because guard fields may disable some links and enable others, the same writing space may have different default links at different points in the reading.

When the text pane is active, pressing [Return] also follows the default link.

## The Built-In Notes 'start' and 'me'

New Storyspace documents have two built-in notes.

The writing space start is the first note in the document, the cover page or title page. It is the note at which new readings begin. (This writing space may be renamed; Storyspace identifies it from its position as the first note in outline order.)

The writing space me is not meant to be written in, and readers will seldom if ever visit it. Instead, it serves as a convenient location for Storyspace to record information about the current reading. It should not be renamed.

Some attributes of me have special significance:

- $Visits(/me) is reset to zero when a reading begins, and increases by one whenever a reader visits a writing space.
- $Deck(/me) is a set attribute that specifies the deck or decks currently in use when using sculptural hypertext.
- $ChosenWord(/me) is the word that the reader most recently clicked.

## Sculptural Hypertext

Conventional Storyspace hypertext is calligraphic: we start with disconnected writing spaces and draw links among them, choosing which things should be linked together.

We may also consider a model where a group of writing spaces are initially linked together, so that each might link to each. We then remove unwanted links; we call this sculptural hypertext.

Storyspace 3 integrates sculptural and calligraphic hypertext seamlessly. If a writing space has calligraphic links which can be followed, then Storyspace uses those. If no calligraphic links can be followed, then Storyspace looks at $Deck(/me) – the current decks – to see whether any decks of sculptural notes are in use. If there are any current decks and the reader asks to follow the default link, the Storyspace locates all the writing spaces in that deck which can be visited. If several writing spaces can be visited, Storyspace chooses the one that has not yet been visited. (If all have been visited, Storyspace chooses the one that has been least visited.) If several writing spaces have been visited the same number of times, Storyspace selects one at random.

For more discussion of sculptural hypertext and its uses, see Getting Started With Hypertext Narrative.

## Using Maps

The map view shows all the notes inside a container. You can arrange notes and containers as you like, perhaps placing related notes close together.

Map views provide great scope for expressing tentative, preliminary, or provisional relationships among your notes, and for discovering emergent structure. Storyspace provides a host of visual dimensions — shape, color, borders, badges, and many more — that you can use to express the properties of notes.

To place a note inside another note or inside a container, simply drop it inside another note or on a container.

To create a note in a map view

- double-click where you want to place the note, OR
- select a note and press Return (↩) to make a new note,

> OR

- choose Create Note… (⌘K) from the Note menu,

> OR

- right-click where to want to place the note and choose Create Note… from the menu

To rename a note in map view

- select it and ⇧⌘-Return

> OR

- select it and press Function-Return (fn↩)

> OR

- click and hold the note for a moment, and edit the note’s name in the map.

### Moving Around In Maps

Use the hand cursor to move the window. Simply click and drag the map background.

Use the horizontal and vertical scroll bars to move around in a view window. Use the scroll wheel, or two-fingered drag on the trackpad, to scroll the window.

To scroll directly to a specific note, simply type the first characters of the note’s name.

### Subtitle, Caption, and Text

A note always displays its title — either its $Name or, if it has a display expression, the result of evaluating $DisplayExpression. If the title does not fit in the available area, Storyspace will draw a truncated title.

If there is sufficient space, Storyspace will also draw that note’s subtitle beneath the title. If the note has a caption, the caption is drawn beneath the note.

If there is even more space, Storyspace will draw the note’s text beneath the title and subtitle.

- Details on displaying note text in the map

Subtitles and captions may be entered and modified in the Text Inspector.

You may also edit subtitles and captions by clicking them while a note is selected in the map. When editing the title, use tab to move to the subtitle and caption.

The appearance of the subtitle is controlled by the attributes $SubtitleColor, $SubtitleSize, and $SubtitleOpacity. The subtitle is most easily added or changed in the Subtitle panel of the Inspector (⌘-1).

### Changing fonts

To change the typeface used for a field in a note

- Select the note.
- Click on the field you want to change until it becomes editable.
- Choose Format>Font>Show Fonts or press ⌘-T.
- Select the font and size you prefer.

Italic fonts are usually reserved for aliases.

### Text In Maps

Normally, maps display the note’s title. If a note is sufficiently large, Storyspace will display some or all of the note’s text as well as the title.

The text display is a scaled representation of the note’s text. A suitable size is normally chosen automatically, but may be overridden by setting the attribute `$MapBodyTextSize`.

If $MapBodyTextSize is 0, Storyspace chooses a suitable font size.

If $BodyBodyTextSize is 1, no body text is drawn.

Otherwise, $MapBodyTextSize is the font size, in points, for drawing the note's body text.

### The Prototype Tab

When a note is selected in map view, a Prototype Tab appears beneath the note and shows the name of the note’s prototype.

If the document has no prototypes, no prototype tab is displayed.

To change a note’s prototype, right-click the prototype tab for a menu of available prototypes.

### Links

The map view shows the links between notes.

If both the source and destination of the link are in the map, the link is drawn as a line between the boxes. If the source or the destination of the link are outside the map, the link is drawn as a short arrow departing from or arriving at a note.

In this map, Cicero is linked to Brutus, Antony, and Caesar. Because Caesar is inside the container "In Gaul", only the start of the link to Caesar appears in the map.

In map view, links with guard fields are distinguished by a small diamond, about a quarter of the way along the link. If the guard field is satisfied, the diamond is solid; if the guard field is not satisfied, the diamond is hollow with a line drawn across the link.

### Adornments

Adornments are labels that you can add to the background of a map view to help organize the map. You can adjust the size, placement, color, and text color of an adornment. Maps may have many adornments, or none. Adornments do not appear in any other views. Adornments can serve to label neighborhoods in a map view, but they do not affect the hierarchy or the links of any notes.

To create an adornment

- choose Create Adornment… from the Note menu.

> OR

- right-click in the background of a map view and choose Create Adornment….

### Locking Adornments

It it often convenient to lock the position of large adornments. The attribute `$Lock` fixes an adornment's (or note's) position in the map, preventing it from being inadvertently moved.

To lock (or unlock) an adornment

- select the adornment
- click the Lock icon,

> OR

- select the adornment
- click the Lock checkbox in the More pane of the Properties Inspector.

### To make an adornment "sticky"

If an adornment is sticky, objects lying on the adornment will stick to the adornment when the adornment is moved. This makes it much easier to work with large, complex maps, allowing you to move whole sections of notes together.

To toggle 'sticky'

- select the adornment
- click the pushpin icon to make the adornment sticky,

> OR

- select the adornment
- click the Lock checkbox in the More pane of the Properties Inspector.

### Grids

Adornments may have an optional grid, letting you divide the adornment into equally-sized rows, columns, or into both rows and columns. For example, you might choose a grid of five columns, labelled “Monday” through “Friday”

To add or change a grid, click on the adornment’s Grid Button. The grid popover lets you select the color and appearance of the adornment grid. If you wish to add labels to the grid, enter the labels as a list, separated by semicolons, from left to right and from top to bottom.

Note that grid properties are controlled by corresponding attributes, such as $GridColumns, $GridRows, $GridColor, and $GridLabels. Thus, grid properties may be inherited from prototypes or altered by rules or actions.

#### Image Adornments

Images may be inserted into the background of a map view as image adornments. Like all adornments, image adornments do not appear in any other view and don't affect the hierarchy or the links of any notes. Adornments are never exported.

To create an image adornment, drag an image file into a map.

Images are inserted and displayed at 'actual size'. Resizing the adornment will crop the image. If a shape is set for the adornment, the image is cropped by the shape's boundaries.

The $Opacity attribute is supported for image attributes, allowing image adornments to be translucent.

### Badges

Badges are iconic images that may be used to distinguish some writing spaces.

To add a badge to a writing space

- Select a writing space
- Click the badge (if the note has one) or the badge button in the note’s upper right-hand corner
- Choose a badge from the popover

### User badges

Storyspace comes with a collection of built-in badges for a variety of uses. In addition, you can easily add your own badges.

Badges are .png image files stored in the application’s support folder. A size of 32px x 32px is recommended; larger images will be scaled automatically.

The badge folder is located in your Library folder:

`~Library/Application Support/Tinderbox/badges/`

You can view the support folder by choosing Reveal Support Folder in Finder from the Help menu.

To add a new collection of badges, simply add a folder of badges to the support folder. To add an individual badge, simple add it to the badge folder; it will automatically be added to the User badge collection.

### Cleanup

The Cleanup commands appear in the View menu, and are also available by right-clicking in the background of the map.

You can arrange the notes in a grid, a staggered grid, a row, a column, or a box.

Like Smart Adornments, automatic cleanup can help organize cluttered maps.

### Containers

In map view, containers display a miniature view of their contents.

Containers are always drawn with a distinctive shape with the title bar at the top and rounded corners at the bottom.

You can drag notes into the body of a container, or drag them out of the container to move them into the current map. You can make any note a container by dragging other notes into it.

Normally, container titles are a single line, drawn at the top of the container. If you wish to expand the size of the title bar, simply drag its lower edge (for containers) or upper edge (for agents).

In this container, the title bar has been enlarged to display a second line of the title (the exact depth of the titlebar is set/stored in $TitleHeight).

If the title bars is sufficiently tall, it may also display the container’s text or summary table.

### Display Expression

In maps and other views, Storyspace typically displays the note’s title (`$Name`) to identify the note.

Sometimes, you may want to display additional information: how much text the note contains, who is responsible for a project, or when a task is due.

The attribute `$DisplayExpression` lets you change the note’s label without changing the value of its `$Name`.

The `$DisplayExpression` attribute is simply an expression, just as used in rules, and actions. Whenever Storyspace needs to display the note, it evaluates the note’s `$DisplayExpression` and displays the result. If `$DisplayExpression` is empty, Storyspace displays the note’s `$Name`.

For example:

DisplayExpression | typical display
--- | ---
`$Name+" ("+$WordCount+" words)"` | Chapter 3 (7500 words)
`$Name+":"+format($DueDate,"l")` | Return books to library: 12/30/2008

## Using Outlines

An outline view shows the hierarchical structure of the document as an indented outline. It is easy to restructure the hierarchy of the document in an outline window, by dragging parts of the hierarchy to other parts of the hierarchy.

The outline view does not show any of the links in the document; use maps to explore links.

Outlines are best when you understand the structure of your information, and when it’s easy for you to put everything in its proper place. If you frequently find yourself puzzling over where to put a note, consider working in Map view for a while. You can always reorganize later.

You can have several outline windows open in different tabs or even in different windows, each focusing on different portions of your document.

### The disclosure triangle

A container — a note that contains other notes — appears in an outline view with a small triangle to its left.

When the triangle points down, the outline lists the children of the note. When the triangle points right, the children are hidden. A container which is hiding its children is sometimes said to be collapsed, and a container that displays its children is said to be expanded.

- click the disclosure triangle to expand or collapse the item.

> OR

- with a note selected, ⌥→ expands the item, and ⌥← turns it collapses it.

- choose Expand from the View window to turn the expand the selected item.
- hold down the ⌘ key while you click a disclosure triangle to expand or collapse that item and also all its younger siblings.
- hold down the ⌥ key while you click a triangle to toggle that triangle, and also expand or collapse all the descendants of that note.

### Editing a note title

To edit a note’s title in an outline, simply click and hold the title. After a brief delay, a frame will appear around the title and you may revise the title at you wish. The click-hold delay is the same duration as that used to trigger a file rename in Finder

Several key shortcuts are available when using the in-place note editor:

- Escape (⎋)will cancel editing and restore the previous title.
- Return (↩) will confirm the new title and terminate editing. Press Return a second time to create a new sibling note.

You may also finish editing by:

- clicking on the note’s icon,

OR

- selecting a different note

### Separators

A separator is a horizontal line in the outline view that may be colored and titled like other notes via the Note and Colors menus.

To add a separator:

- choose Create Separator… from the Note menu

> OR

- select any note
- open the Prototype pane of the Document inspector and check Separator.

### The Outline Icon

The “icon” that appears next to the disclosure triangle in the outline conveys a host of information in a very small space.

- The Color of the icon’s border is the color of the note.
- The “title bar” of the icon indicates whether the note is a container (title at the top) or an agent (title at the bottom). If an agent is turned off, it's title bar is hollow.
- The text lines inside the icon indicate whether the note contains any text, and roughly how long the text is.
- The interior color of the icon reflects how recently a note has been edited. A newly-created note is light blue. Over the course of a day, the note “dries” to a neutral white, and then over the span of a year it gradually yellows.

Right-click the icon to displays the note’s Prototype menu.

Double-click the icon to focus on or “hoist” the note, focusing the window on the note and its descendants.

### Focusing On Notes

Focusing or “hoisting” a note focuses the view on it and its descendants. Expanding the view returns the focus to the the note’s container. These commands are available in chart and outline views.

- select Focus View from the View menu

> OR

- select Expand View from the View menu

#### Identifying prototypes

In outline view, the note icon for notes which can serve as prototypes is now surrounded by a light green circle. This helps distinguish notes intended to serve as prototypes. See the Prototypes section of the Notes chapter for more information.

### Organizing Notes

You can drag notes in an outline window to rearrange the document’s hierarchy.

To move a note:

- Drop a note on the right half of another note to make it a child of the note you drop it on.
- Drop the note while it is over the left half of another note to make it a sibling of the note you drop it on.

As you drag, a blue highlight indicates where the dragged note would be moved. You can’t drag a note onto an alias, an agent, or onto one of its own descendants.

#### Indenting notes in the outline

- Press Tab (⇥) to indent the selected note one more level in the outline. If the note cannot be indented, Tab has no effect.
- Hold down the Shift key while you press Tab (⇧⇥) to unindent the selected note out one level in the outline.

Indent (⌘-]) and Unindent (⌘-[) are also available in the Note menu.

## Using Charts

A chart view shows the hierarchical structure of the document. A chart is also handy for seeing many notes in one window. It is easy to re-structure the hierarchy of the document in a chart window, by dragging parts of the hierarchy to other parts of the hierarchy.

Notes in chart view display their badges, and long titles will wrap to multiple lines. A chart view does not show any of the links in the document.

### The disclosure triangle

As in outlines, a disclosure triangle allows you to expand to collapse an container or agent.

### Focusing the View

Focusing a chart view lets you focus on a specific part of your work. It may be useful to keep several different charts open in separate tabs or even separate windows.

To focus on a note in chart view,

- Double-click the icon of the note to be focused on, OR
- Select the note and choose Focus View from the Note menu

### Organizing Notes

You can drag notes in a chart window to rearrange the document’s hierarchy.

- Drop the note on the right half of another note to make it a child of the that note.
- Drop the note while on the left half of another note to make it a sibling of the that note.

If you drop the note elsewhere in the chart window, it will snap back to its starting location. The drag highlight indicates where the dropped not will move. Notes cannot be moved inside one of their descendants, inside an agent, or inside an alias.

## Using Treemaps

A treemap shows the hierarchical structure of the document as a set of nested rectangles. Treemaps can display even more of the document hierarchy than chart view, permitting hundreds of notes tp be browsed in a single view.

To select any note in a treemap, click on the note’s title.

### Focusing the View

Focusing a treemap view lets you focus on a specific part of your work.

To focus on a note in chart view,

- Double-click the icon of the note to be focused on, OR
- Select the note and choose Focus View from the Note menu

Treemaps do not display adornments or separators. In addition, if a note is too small to display at the current window size and scale, that note will be omitted.

###

### Visualization and Treemaps

New treemaps assign equal weight to each note they display. You can instead set the area of each note to reflect some attribute or combination of attributes of the note. In addition, each note can be colored to reflect an attribute or combination of attributes of the note.

To customize a treemap visualization, click on the “i” button in the treemap tab.

This will display the treemap popover.

The Treemap Expression adjusts the relative area of each note. If the value of a note’s $TreemapExpression is less than or equal to zero, the note will be omitted entirely; otherwise, the note’s area will be proportional to the value of TreemapExpression. TreemapExpression is frequently simply an attribute value, such as $Price or $WordCount.

The Color Expression, if specified, adjusts the color applies to each note. The expression is evaluated for each note in the view, and is chosen from a linear gradient between two colors, the Start Color and the End Color. If the Color Expression is $WordCount, then notes with the smallest word count will use Start Color, those with the largest $WordCount will use End Color, and intermediate notes will use a blend of StartColor and EndColor.

## Actions and Expressions

### Actions, Expressions, and Rules

In many places, Storyspace allows you to change what information it displays or what actions it performs on notes that you have created or moved. These symbolic actions and expressions can provide great flexibility and can save you lots of time. For example:

- A container that holds a “reading list” can know that notes added to the list are likely to be books or articles, and can automatically set the size, appearance, and prototype of new notes.
- A container that holds a set of “chapters” for your book can display the current total word-count for all notes inside it.
- An agent that contains “urgent tasks” can automatically change their color in order to draw your attention.

An expression is simply something that has a value. For example, the expression `0.05*$Price` might calculate the sales tax on an item based on its price.

An action describes a change made on one or more notes. For example, the action`$Color(California)="red"` sets the color of the note named “California” to “red”.

Quotes in Action code: action code will fail is you use typographic (curly) quotes. Action code must use plain (straight) quotes.

Actions may be performed at a variety of times.

- The OnVisit action is performed when the reader visits a note in Read mode.
- The BeforeVisit action is performed when Storyspace is examining whether a note can be visited.
- The OnReset action is performed at the start of a reading.
- The ResetAction action is performed when a note is added to a container, is discovered by an agent, or is placed atop an adornment, and affects the note being added.
- A Rule is performed at frequent intervals, and affects the note that possesses the rule.

### Expressions

A Storyspace expression represents a value – something that could potentially be stored in an attribute. The following are expressions:

- 42
- "Now is the winter of our discontent"
- (7+6)/5
- $Price

Most actions simply store the result of an expression in an attribute. For example

`$Price=1.95`

sets the value of the attribute `Price` in the current note, and

`$Color="red"`

turns the current note red.

In addition to their use in actions, expressions have a variety of uses in Storyspace:

- link guard fields and `$Requirements` are expressions; when true, the link can be followed or the note can be visited.
- `$DisplayExpression` is an expression; if `$DisplayExpression` is not empty, then the value of `$DisplayName`, ands the title displayed for the note in maps and other views, is the result of evaluating `$DisplayExpression`.
- The value of `$HoverExpression`, if `$HoverExpression` is not empty, appears while the cursor hovers over a note in map or or outline view.
- The value of `$TableExpression` determines what appears in a note’s summary table.

### True and False

When evaluating an agent query or assigning a value to a Boolean attribute, the following values are all treated as equivalent to `false`.

- the keyword `false`
- the number 0
- the empty string ""
- the color #000000
- the date "never"

Any other value is treated as `true`.

### Actions

### Assigning Values

Most actions simply assign a value to an attribute.

> `$Color="red"`

Several actions may be combined, separated by a semicolon.

> `$Color="red";$BorderColor="white";`

To remove the value from the current note, restoring the inherited or default value, simply omit the value the follows the “=” sign.

> `$Color=;`

The conditional assignment operator |= will assign a value to an attribute only if that attribute’s value is currently false, zero, or empty.

> `$Priority |= "low"`

The conditional assignment operator &= will assign a value to an attribute only if that attribute’s value is not false, zero, or empty.

### Conditional Actions

A conditional action is performed only if a specified condition is satisfied.

> `if($DueDate<date("tomorrow")) {$Color="red";}`

Conditional actions may also specify what should be done if the condition is not satisfied.

> `if($DueDate<date("tomorrow")) {$Color="red";} else {$Color="green"}`

### Side Effects

If an action is simply an expression, the expression is evaluated and the result discarded. For example, the action

> `runCommand("open /Applications/iTunes.app")`

will ask your computer to open iTunes, and the action

> `notify("find concert tickets")`

will post a notice to your computer’s notification center.

### Repeated Actions

A repeated action is performed for every element in a list or set. For example:

> `$Result=0; $MyList.each(x){$Result=Result+x;}`

would take a list of numbers, add them up, and store the sum in $Result.

Repeated actions are uncommon.

### Attributes and Constants

### Attribute References

To refer to an attribute by name, precede the name with “$”. For example,

> `$Width`

refers to the width of this note, and the action

> `$Width=7;`

will set its width to 7.

To refer to the value of an attribute of a different note, follow the attribute name with a designator in parentheses. For example,

> `$Width(parent)`

refers to the width of the parent of this note,

> `$Width(Burbank)`

refers to the width of the note named "Burbank", and

> `$Width(/people/Roosevelt)`

refers to the width of the note named "Roosevelt" that is inside the container named "people".

A rich list of designators can be used with attribute references to specify which note’s attributes you wish to use. Common designators include parent, child, previousSibling, and nextSibling.

### Constants

Enclose string values in either (straight) single or double quotes:

> `$Name="Theodore Roosevelt"`

Double quotes are preferred; use single quotes when the quoted string contains double quotes.

> `$Name='She said, "Hello," before I had time to think.'`

Date constants are best expressed using the date operator:

> `date("today")`

> `date(12,25,1917)`

Color constants can be expressed using string equivalents, such as "red", "#FF9900", or "RGB(255,255,255)".

The boolean constants `true` and `false` are not quoted.

false | the boolean value `false`
"false" | a five-letter word

### Designators

Designators specify to which note an attribute reference refers. For example, in the expression

> `$Width(parent)`

the designator “parent” refers to the note that contains this note. If the designator is omitted, the reference refers to `this` note.

- In rules, `this` refers to the note whose rule is running.
- In agent queries, `this` refers to the note being examined by the agent.
- In agent actions, `this` refers to the newly-created alias that satisfies the agent’s query.
- In OnAdd actions, `this` refers to the note that is being added.

`this` | The note being examined by an agent, the note being added to an adornment, or the note whose rule is being run
`next` | The note that follows this note in outline order
`previous` | The note that precedes this note in outline order
`prevSibling` | The next older sibling of this note
`nextSibling` | The next younger sibling of this note
`firstSibling` | The first sibling of this note
`lastSibling` | The last sibling of this note
`parent` | The parent of this note
`grandparent` | The parent of the parent of this note
`child` | The first child of this note
`child[n]` | The nth child of this note, where n is a number. The first child is child[0]. If n is negative, the nth youngest child of this note: child[-1] is the youngest child.
`lastChild` | The last child of this note
`randomChild` | A randomly selected child of this note
`current` | The note that is currently being exported. When not used in an export template, current is equivalent to this. Where a note is exported to its own page, current is the same as this. If the note is included in another note's page, however, current refers to the page being exported.
`cover` | The first note in the document.
`source` | The link source (used only in link expressions)
`destination` | The link destination (used only in link expressions)
`agent` | Available only in agent queries and agent actions; refers to the agent that is currently examining the note.
`adornment` | Available only in adornment queries and adornment actions; refers to the smart adornment that is currently examining or performing an action on the note.
`original` | In aliases, refers to the original note associated with the alias and useful for addressing properties of the original such as `$Xpos` and `$Ypos` that are not inherent to the alias. Otherwise synonymous with this.
`source` | In guard fields, refers to the source of the link.
`destination` | In guard fields, refers to the destination of the link.

Designators may be combined. For example, `$Name(nextSibling(parent))` is the name of the next sibling of this note's container.

### Group Designators

Some operators accept a group designator that designates multiple notes. For example, `any(child,$Checked)` is true if the $Checked attribute of any of this note's children is set to true. Group designators include:

`children` | the immediate children of a note
`descendants` | all descendants of a note
`siblings` | all siblings of a note
`ancestors` | all ancestors of a note
`all` | all notes in the document

A list or set of pathnames may be used anywhere a group designator is required.

### find()

The special designator find() searches through the entire document to locate notes that satisfy an expression. For example:

`$Color( find($Status="Urgent"))="red"`

will locate every note whose $Status is "Urgent" and turn is red.

The find() designator acts in many ways like an agent. In general, prefer agents to using find(), because the agent’s results can be reused by other agents.

### Guard Fields

Storyspace offers several convenient functions for use in guard fields.

guard(guard field) is `true` if the legacy guard field inside the parentheses is true.

visited(/path/to/note) is `true` if that note has been visited in this reading. visited() with no arguments is true is equivalent to visited(destination), and is true if the destination has previously been visited.

unvisited(/path/to/note) is `true` if that note has not been visited in this reading. unvisited() with no arguments is true is equivalent to unvisited(destination), and is true if the destination has not been visited in this reading.

### Text Patterns

The operator `.contains()` tests whether a text pattern or regular expression appears in a note’s attribute. For example,

> `$Text.contains("frog")`

is true if the text of the note contains the string "frog". The .contains() operator is case-sensitive, but

> `$Text.icontains("frog")`

will match both "frog" and "Frog".

In older documents, you may encounter the obsolete syntax Text(pattern). This is equivalent to $Text.contains(pattern) — note that the '$' is omitted in the older syntax. This deprecated syntax continues to function but is harder to read than the modern .contains().

### Regular Expressions

A number of special characters represent “wild cards” and other classes of text patterns. Complete information on the regular expression engine may be found at:

> http://www.boost.org/libs/regex/doc/

#### Wildcard Characters

The period character, “.”, matches any single character.

The plus sign, “+”, matches one or more occurrences of the expression that precedes it. The pattern

> `!+`

will match one or more exclamation points, and the pattern

> `....+`

will match any string with at least four characters.

An asterisk matches zero or more occurrences of whatever precedes it;

> `10*`

matches 1, 10, or 1000.

The question mark “?” matches zero or one occurrence of whatever precedes it.

You can also specify the minimum and maximum number of repetitions:

> `Xa{2,4}Y`

will match XaaY, XaaaY, or XaaaaY, but won’t match XaaaaaaY.

#### Character Ranges

A set of characters to be matched may be enclosed in square brackets. For example,

> `[0123456789]`

will match any digit. Ranges of consecutive characters can be written more concisely:

> `[0-9]`

will match any digit, and

> `[A-Z][a-z]*`

will match any capitalized word. Beginning a set with the character “^” matches everything except the set;

> `[A-Z][^0-9]`

will match any capital letter provided it’s not followed by a digit.

Several special sequences represent common sets of characters:

> \w - any word character (including underscore)

> \W - any non-word character

> \< - the start of a word

> \> - the end of a word

> \s - any white space character

> \d - any digit

> \l - any lowercase letter

> \u - any uppercase letter

#### Anchors

The special character "^" matches the beginning of the text or attribute being searched. When searching the text of a note, ^ matches the beginning of any paragraph in the note.

The special character “$” matches the end of the text or attribute being searched. When searching the text of a note, $ matches the end of the paragraph in the note.

#### The \ [backslash] Character

The backslash character "\" removes the special meaning from the character that follows it. Use "\\" to search for the backslash character itself.

### Parentheses

Grouping expressions in parenthesis determines the scope of wildcards. For example,

> `Name=(\u\l+)+`

Would match “Rochester” and “SmallTalk”.

In addition, when Storyspace sees a parenthetical expression, it remembers the substring(s) that matched it and can use those substrings in actions. For example, the agent

> Query: `Text(^ color: (\w+)\b$)`

> Action: `$Color=$1`

scans the document for any notes that contain paragraphs like this:

> `Color: red`

If it finds any matching notes, the agent extracts the word that follows the string “Color: ” and changes the note’s color to match. Here, $1 stands for “whatever matched the first set of parenthesis”, $2 for the second set, and so forth. $0 stands for the entire matched string.

#### Back References

When agents search for regular expressions, the agent saves substrings that match parenthesized sub-expressions. These substrings or back references can be used in actions, and are especially useful for automatically extracting information from notes.

For example, an agent might search for notes that contain fields like this:

> From: Henry Higgins

by searching for the pattern

> From: (.+)$

An action can then refer to the name extracted following "From: " as $1

> `$Author=$1;`

The author will now be set to Henry Higgins. Subsequent subexpressions may be referred to as $2, $3, and so on.

### Local Variables

In addition to the note’s values, you can declare temporary variables for use only within the current action using the var statement:

> `var area; area=$Width*$Height; $MyNumber=area;`

Multiple local variables may be declared in one statement, separated by commas.

> `var x,y;` …

A local variable may be assigned an initial value as follows:

> `var taxRate(0.0625); $Total=$Price*(1+taxRate);`

### String Operators

#### + (concatenation)

The `+` operator joins two strings.

"We "+"few" | "We few"

#### * (repetition)

The `*` operator repeats a string multiple times.

"!" * 5 | "!!!!!"

#### .at("keyword")

Extracts a value from a list of keyword-value pairs in which the keyword and value are separated by colons. For example, suppose

`$MyString = "USA: North America; Canada: North America; France: Europe; Japan: Asia; default: unknown"`

Then

`$MyString.at("France") ==> "Europe"` `$MyString.at("Canada" => "North America"`

The special keyword "default" applies to any keyword not contained in the list. For convenience, when several keywords have the same value they may be separated by pipe characters “|”:

`"USA | Canada: North America; …"`

The at("keyword") operator or Lookup Table can often replace complex conditional logic. For example, if $Continents(/config) contains the string

`"USA: North America; Canada: North America; France: Europe; Japan: Asia; default: unknown"`

The we can simply write:

`$MyContinent = $Continents(/config).at($Country)`

rather than the long and error-prone

`if ($Country=="USA"){$MyContinent="North America"} else {if ($Country=="Canada") ……`

#### .capitalize

The .capitalize() operator transforms a string by capitalizing its initial letter.

"ostrich".capitalize() | "Ostrich"

See .lowercase() and .uppercase().

#### .contains

String.contains("pattern") - true if the string contains the quote-enclosed regular expression "pattern", which may be a regular expression or a string literal. Matches are case-sensitive. The pattern should always be enclosed in quotes. If $Text contains the string “Asia”, then:

`$Text.contains("Asia")` | true, since the text contains "Asia"
`$Text.contains("s.a")` | true, since the text contains an "s" which is followed by a character followed by an "a".

If a match is found, the actual matching text is bound to $0.

If the regular expression contains parenthesized sub-expressions, the matching sub-expressions are bound in order to $1…$99.

#### .empty

String.empty is true if the string is has no characters.

"".empty | true
"element".empty | false

#### .icontains

The case-insenstive variant of .contains(). If the note’s text contains the word “Asia”, then

`$Text.icontains("Asia")` | true, since the text contains "Asia"
`$Text.icontains("ASIA")` | false

#### .json

Returns the string in JSON-encoded form. Characters that have special meaning in JSON are escaped with backslashes.

#### .lowercase

Returns a copy of the string, transforming all capital letters to lower case.

See also .capitalize and .uppercase.

#### .paragraphs(N)

Returns first N paragraphs of the string.

#### .replace(pattern,replacement[,arguments])

If the regular expression "pattern" is found in the string, the matching portion of the string is replaced by the replacement string. Additional arguments allow replacement of multiple sub-expressions assuming extra back-references are created by "pattern".

#### .reverse

Reverses the sequence of characters in the string.

"ostrich".reverse() | "hcirtso"

The `.reverse` operator is most useful for gaining access to a part of a string relative to the end of the string, when the convenient operator provides access from the start. For example, $Text.paragraphs(1) returns the first paragraph of the text, and

> `$Text.reverse.paragraphs(1).reverse`

returns the final paragraph.

#### .size

Returns the number of characters in a string.

#### .split("pattern")

Splits a string into a list, dividing the string at designated "pattern"; the matched "pattern" characters are discarded.

"lions and tigers and bears".split(" and ") | "lions;tigers;bears"

#### .substr(start,length)

Extracts substrings form the string, starting at character number start (zero-based) and including up to length characters. A negative start value (1-based) may be used to cite a start counted from the end of the string.

> `"Hello, world".substr(0,5):` Hello

If the second argument is absent, the result runs from start through the end of the string.

> `"Hello, world".substr(7):` world

If start is negative, the substring begins -start characters from the end of the string.

> `"Hello, world".substr(-5):` world

#### .toNumber

Converts a string of digits to the corresponding number. If the string is empty, toNumber() returns zero. If the string cannot be parsed as a number, the result is undefined.

#### .tr(characters,replacements)

Replaces every occurrence of a character with a replacement character.

> `"Hello, world".tr(w,W) :` Hello, World

Multiple characters may be replaced at once:

> `"Hello, world".tr("aeiou","AEIOU"):` HEllO, wOrld

If no corresponding character appears in the replacement string, the matched character is deleted.

> `"Hello, world".tr(aeiou):` Hll, wrld

#### .uppercase

Returns a copy of the string, transforming all lowercase letters to upper case.

See .capitalize() and .lowercase().

#### .words(N)

Returns the first N words of the string, if the string has at least N words; otherwise, returns the entire string. If N is negative, returns the last N words of the string.

> "Now is the winter of…".words(2) => "Now is"

#### escapeHTML(string)

HTML and XML cannot contain certain reserved characters. This function converts any such characters found in the string to the corresponding XML entities. For example, '<' is replaced by '&lt;' and '&' is replaced by '&amp;'.

#### format(value, format-string)

Format(value,format_string) converts attributes to strings and lets you choose exactly how you prefer the data to appear. format() is useful for export and for preparing data for other programs and Web services.

For numbers, the first argument is the number of decimal places to which the number should be rounded. An optional third argument allows you to specify a total width for the formatted string.

For example, if $MyNum is 3.1415927, then

> `format($MyNum,2,7)` is " 3.14"

> `format($MyNum,2)` is 3.14

> `format($MyNum,0)` is 3

If value is a date, the format string is interpreted as follows:

L: local time, in long format, using the system format settings (example: Tuesday, April 29, 2003.)

l: local time, in short format, using the system format settings (example: 4-29-03)

d: day of the month (example: 29)

D: formats date 01-31, with leading zero

m: number of month (example: 4)

M: abbreviation of month (example: Apr)

MM: name of month (example:April) w: abbreviation of weekday (example: Tue)

M0: formats month numerically 01-12, with leading 0

W: name of weekday (example: Tuesday)

y: year (example: 2003)

t: time, in local format (example: 2:32 pm)

h: hour of the day on a 24-hour clock (example: 13:39)

H: hour of the day on a 12-hour clock (example: 1:39)

mm: minute of the hour (example:05 for five minutes after the hour)

s: second

p: AM or PM

*: date/time in RFC 822 format (example: Thu, 18 Feb 2004 19:12:00 0500)

=: date in ISO 8601 format (example: 2004-02-18)

U: date as Unix epoch (seconds since 1 January 1970)

For example:

> `format($Created,"L")`

formats the note's creation date a "long local date" such as "Sunday, March 23, 2007 1:26pm".

If value is a list or set, the format string is the delimiter that is to be used to separate discrete list elements

> `format($KeyAttributes,",")`

converts key attributes to a comma-separated list.

Optionally, you may supply four quoted string arguments besides value to format the set as an HTML list:

> format(value,list-prefix,item-prefix,item-suffix,list-suffix)

For example

> `format($MyList,"<ul>","<li>","</li>","</ul>")`

If value is a number, then the arguments are numeric and interpreted as follows:

format(value,precision, width)

In quoted string arguments here (as elsewhere), \" is converted to a quotation mark, \n to a carriage return, and \t to a tab.

#### idEncode(string)

Converts a string to form suitable for use as an HTML identifier. Punctuation and other characters that are neither letters or digits are replaced by underscores.

#### urlEncode(string)

The function

`urlEncode(value)`

returns a string in which characters (such as spaces) that may not occur in an internet URL are replaced by their encoded equivalents.

### Numeric Operators

#### Numeric Functions

The familiar mathematical operators + - * / operate on numeric expressions in the expected way.

Note that + and - have different meanings when applied to sets, and that + has yet another meaning (concatenation) when applied to strings.

#### Mathematical Operators

In all the following, the N argument is a number.

abs(N) computes the absolute value of is argument.

atan(N) computes arctangent, and returns its result in radians.

ceil(N) returns the first integer that is larger than N.

degrees(N) converts radians to degrees.

exp(N) returns the exponential of N, en.

floor(N) returns the first integer that is smaller than N.

log(N) computes the natural logarithm of its argument, which should be a number, a numeric attribute, or an expression that can be interpreted as a number.

mod(N,dividend) computes the remainder of A divided by B.

pow(N,K) raises N to the power of K.

radians(degrees) converts its argument, in degrees, to radians.

rand() returns a pseudo-random number between 0 and 1.

round(N) rounds the value of its argument to the nearest integer.

sin(N), cos(N), and tan(N) are the familiar trigonometric functions, taking arguments in radians.

sqrt(N) computes the square root of its argument.

#### sum(), sum_if, avg and avg_if()

In the following operators, the parameter expression may be an attribute reference, a literal number, or an expression.

sum(group,expression) computes the sum of a series of expressions. For example,

> `sum(child,$WordCount)`

computes the total word count of all the children of a note. 'group' may be any group designator {children,descendants,sibling,ancestor,all}. In addition, 'group' may take a single argument that designates a particular note other than this; for example

> `sum(children(/agents/books),$TextLength)`

sum_if(group,condition,expression) computes the sum of the values for expression for each item in the group, ignoring any notes for which if condition is not true. For example:

> `sum_if(children, $Checked, $Price)`

totals the prices of all the note's children which have been checked.

avg(group,expression) and avg_if(group,condition,expression) compute the mean of the values for expression for each item in the group. For example:

> `avg_if(group,condition,expression)`

computes the sum or the mean of a value computed in each note for a group that meets the designated condition.

> `sum_if(child,$Checked,$Qty*$Price)`

> `avg_if(child,$Checked,$Qty*$Price)`

compute the total price and the average price of checked items that are children of this note.

#### Converting Numbers to Strings

[Number].format(decimal_places[, width]) converts a number to a string. decimal_places specified the number of digits to be displayed after the decimal point, and may be zero to display an integer. If the optional width is specified, additional spaces will be added to the left of the number to pad the result to a minimum width. For example:

`$Price.format(2)`

converts the number $Price to a string, rounding to two decimal points.

If the argument to format is “l”, the number is formatted using local numeric formatting conventions. For example, commas are inserted before thousands and millions in the US.

If the argument to format is “$”, the number is formatted using local currency formatting conventions. For example, the number 1.5 would be formatted as $1.50” in the US, but “£1.50” in the UK.

If the argument to format is “$0”, the number is formatted using local currency and rounded to the nearest whole unit. For example, 1000.4 would be formatted as “$1000” in the US.

### Color Operators

#### Color Components

Color.red

Color.green

Color.blue

Three read/write properties allow the individual RGB color channel values to be read or set. The component value is a number (0-255). Values may set using a number 0-255 or a hex number string "#00" - "#ff".

> `$MyNumber=$Color.red`

> `$Color.red = 255`

Color.brightness - Read/write property allows a color's brightness level to be read or set using a value in the 0-100 range representing a percentage.

Color.saturation - Read/write property allows a color's saturation level to be read or set using a value in the 0-100 range representing a percentage.

Color.hue - Read/write property allow a color's hue to be read or set using a value in the 0-360 range representing a a circular degree.

#### Converting Colors to Strings

Color.format() - converts a color attribute to a string representation.

#### Converting Strings to Colors

Storyspace provides several flexible notations for interpreting colors.

Named colors are the preferred way to set and change colors in Storyspace. Named colors may be redefined, and new named colors added or deleted, in the Colors pane of the Document Inspector.

Hex colors, customarily used on the Web, begin with a # sign followed by six hexadecimal digits: #rrggbb, corresponding to the proportion of red, green, and blue in the color. #FFFFFF is white, #800000 is dark red, and #000000 is black.

RGB colors of the form RGB(red,green,blue) use decimal colors from 0 to 255 to describe the proportion of red, green, and blue in the color.

HSV colors of the form HSV(hue,saturation,value) describe the hue, saturation, and value of the color. Hue is a color wheel angle, in degrees, running from 0 to 360. 0 corresponds to red, 120 to blue, and 240 to green. Saturation and value run from 0 to 100. The value is the equivalent to brightness in HSB(hue, saturation, brightness)

#### Manipulating Colors

rgb(red,green,blue) -creates a color. Its arguments are integers ranging from 0 to 255. Arguments may also be expressions or attribute references.

> `$Color=rgb($MyRed,255,255)`

### Date Operators

#### Date Properties

Read/write properties allow various aspects of data/time data to be read or set.

Date.day (1-31)

Date.month (1-12)

Date.year (value of year)

Date.hour (0-23)

Date.minute (0-59)

Date.weekday (1-7) Monday = 1, Sunday = 7. Read-only

If the Date is `"never"`, all functions return 0 (zero). For example:

> `$Width = $DueDate.month`

> `$DueDate.day=1;`

#### Date Operators

Date.format("format-string") converts a date to a string, using the quoted date format string. For example, `$DueDate.format("l")` will format the value of $DueDate using the system’s short date format.

L: local time, in long format, using the system format settings (example: Tuesday, April 29, 2003.)

l: local time, in short format, using the system format settings (example: 4-29-03)

d: day of the month (example: 29)

D: formats date 01-31, with leading zero

m: number of month (example: 4)

M: abbreviation of month (example: Apr)

MM: name of month (example:April) w: abbreviation of weekday (example: Tue)

M0: formats month numerically 01-12, with leading 0

W: name of weekday (example: Tuesday)

y: year (example: 2003)

t: time, in local format (example: 2:32 pm)

h: hour of the day on a 24-hour clock (example: 13:39)

H: hour of the day on a 12-hour clock (example: 1:39)

mm: minute of the hour (example:05 for five minutes after the hour)

s: second

p: AM or PM

*: date/time in RFC 822 format (example: Thu, 18 Feb 2004 19:12:00 0500)

=: date in ISO 8601 format (example: 2004-02-18)

U: date as Unix epoch (seconds since 1 January 1970)

date(year,month,day,hour,min) constructs a date from individual numeric elements. This is useful, for example, if you need to assemble a date from separate attributes. year is the 4-digit year, month is a number from 1-12. The time arguments are optional, and are specified in a 24-hour clock.

> `date(2004,7,23,16,45)` is 23 July 2004 4:45pm

date("string") constructs a date from string which is a string literal or string expression. Usually, this is not necessary as Storyspace will coerce the string to a date type automatically. In some contexts, though, it may be more convenient or more clear to make the conversion explicit. (See format() to convert dates into strings)

#### Date/time comparison operators

days(date1,date2) returns the number of days that elapsed between date1 and date2, as a number. If date2 is the earlier date, the result is negative. The internal comparison includes the time portion of the date. thus if 2 dates are 1 day apart but the times are less than 24 hours aport, the result is 0 and not 1 as might be expected.

hours(date1,date2) returns the number of hours that elapsed between date1 and date2, as a number. If date2 is the earlier date, the result is negative.

minutes(date1,date2) returns the number of minutes that elapsed between date1 and date2, as a number. If date2 is the earlier date, the result is negative.

seconds(date1,date2) returns the number of seconds that elapsed between date1 and date2, as a number. If date2 is the earlier date, the result is negative.

months(date1,date2) returns the number of moths that elapsed between date1 and date2, as a number. If date2 is the earlier date, the result is negative.

years(date1,date2) returns the number of minutes that elapsed between date1 and date2, as a number. If date2 is the earlier date, the result is negotiatingative.

#### Locales

When converting between strings and dates, Storyspace uses a variety of formats including the date format used in your locale as specified in System Preferences:Language and Region.

When practical, you should adapt these preferences to your needs. In particular, if you frequently use historical dates, you should avoid formats with two-digit years.

The locale() action allows you to check your current locale setting and to change it. For example, if you are a Swedish historian working in Australia you might want the notes for your next article to use Swedish date formats with your task list might use Australian settings.

### Interval Operators

Two intervals may be combined with the + operator, and the difference between two intervals may be obtained using the - operator. Intervals may be multiplied or divided by numeric values as well. If $MyInterval is five minutes, `4*$MyInterval` is twenty minutes.

interval(start,end) returns the interval between two dates, start and end.

### List and Set Operators

A list is a list of strings or tags separated by semicolons.

`Arwen; Eowyn; Galadriel`

A set is a list where duplicate values are not allowed. A given element can appear in a set at most once; duplicates are automatically removed.

The order of elements in a set is not significant, and Storyspace controls the order of elements in a set. You determine the order of elements in a list.

Two lists or sets are equal if they contain the same elements.

Adding and Removing Items

The operators + and - add and remove items from lists and sets.

> `$MySet = $MySet + "important"`

adds the value “important” to $MySet. Since sets cannot contain duplicates, this will have no effect if $MySet already contains "important".

> `$MyList = $MyList + "important"`

adds "important" to the end of $MyList. Since lists can contain duplicate entries, this always changes $MyList.

You can add more than one tag at a time:

> `$MySet = $MySet+"important;overdue"`

You can also add a list or set to another list or set:

> `$MySet = $MySet + $UrgentTags`

Similarly, subtraction removes tags from a set or list:

> `$MySet = $MySet - "important"`

removes "important" from $MySet. If $MySet does not contain "important", this action will have no effect.

List/Set.contains("item") - true if any element of the List or Set matches the quoted string "item" exactly. Matches are case-sensitive. Match values must be enclosed in quotes. The returned value is the zero-based offset of the match +1.

"Arwen;Eowyn;Galadriel".contains("Eowyn") | 2
"Arwen;Eowyn;Galadriel".contains("Frodo") | 0

list.at(n) – returns the nth item in the list. If n is zero, returns the first item. If n is negative, returns the nth item from the end of the list. If the list does not contain n items, returns the empty string.

list.at("keyword") – extracts a value from a list, string, or set of keyword-value pairs in which the keyword and value are separated by colons. For example, suppose

`$MyString = "USA: North America; Canada: North America; France: Europe; Japan: Asia; default: unknown"`

Then

`$MyString.at("France") ==> "Europe"` `$MyString.at("Canada" => "North America"`

The special keyword "default" applies to any keyword not contained in the list. For convenience, when several keywords have the same value they may be separated by pipe characters “|”:

`"USA | Canada: North America; …"`

List/Set.each(n){...actions... } – performs an action for each element of the list or set. The local variable "n" is bound to each element in turn. For example:

> `$Result=0; $MyList.each(x){ $Result=$Result+x;}`

adds each element to $Result

List/Set.empty - true if the List or Set has no elements.

List/Set.format("delimiter") - converts a List or Set to String-type data, concatenating each value with the specified "delimiter" characters. thus if "delimiter" is ", " the source data becomes as comma+space delimited list as a single String.

List/Set.format("list-prefix", "item-prefix", "item-suffix", "list-suffix") - converts a List or Set to a String. The list begins with the "list-prefix" and ends with "list-suffix"; each item is preceded by "item-prefix" and followed by"item-suffix".

List/Set.icontains("item") - true if any element of the List or Set matches the quoted string "item" exactly; differences between upper and lower-case letters are ignored. Regular expressions are not supported (unlike with pure string operations). Matches are case-insensitive. Match values must be enclosed in quotes. The returned value is the zero-based offset of the match +1. The latter is to ensure that matches are always 1 or more and thus also coerce to 'true' for the true/false element of testing for match.

List/Set.intersect(list) - returns the intersection of two sets or lists — a set or list of the values shared by each.

List/Set.replace("item","replace") - replaces the designated item with a replacement value. Matches are only the whole list values; partial value matches are not supported. Match values must be enclosed in quotes.

List/Set.size - the number of values in the the list. Read-only property.

#### Sorting

Lists (but not sets) may be sorted. The following sort operations apply only to lists:

List.sort - case-sensitive sort

List.isort - case-insensitive sort().

List.nsort([expression]) - nsort() behaves exactly like sort(), but assumes that the list elements, are numbers.

List.sort([expression]) - if List is a list of note names or $Paths, returns a list sorted by the corresponding expression (or attribute value). If expression is a Number-type, a numeric sort is used; if Date-type, a date sort is used. Otherwise, the list is sorted lexically.

List.isort([expression]) - as above but case-insensitive.

List.nsort([expression]) - numeric sort. An nsort() behaves exactly like sort(), but assumes that the list elements, or the result of the optional expression, are numbers. Thus an nsort() always sorts numerically.

List.reverse - reverses the sequence of items in the list.

For example, suppose $Favorites is a list of favorite notes.

> `$Favorites.sort($Price)`

returns a list of notes sorted by price with the lowest price first, and

> `$Favorites.sort($Price).reverse`

is sorted by price with the highest price first.

List.unique() - returns a new list that contains each unique item found in the source list. Duplicate entries are not copied. Note that all items in a Set are, by definition, unique.

#### List Operations

Several functions are useful for extracting notable elements from sets and lists. In the following, the list argument implies set or list data.

count(list) returns the number of tags in list.

max(list) returns the largest tag in list

min(list) returns the smallest tag in list

If max(list) or min(list) is evaluated in a numerical context, numerical comparison is used. Otherwise, Storyspace uses lexical comparison.

The mathematical functions sum(), sum_if() and avg_if() take a group scope (i.e a list of $Paths) so can be used with lists - see Numeric Functions further above.

#### Building Lists

collect(group,expression) builds a list by visiting each note described by group and adding the value of the designated attribute to the list. For example,

> `collect(children,$Name)`

constructs a list with the name of each child of the note. group may be any group designator: {children,descendants,sibling,ancestor,all}. In addition, group may take a path modifier; for example

> `collect(children(/agents/books),$Name)`

expression can be any expression, but is typically an attribute.For example,

> `collect(children,$Name)`

> `collect(children,$Width*$Height)`

collect_if(group,condition,expression) constructs a list by collecting all the notes corresponding to group, testing each note to see if it meets condition, and adding the expression to the set for each such note. For example

> `collect_if(children,$Status="Important",$Name)`

will construct a set of the names of all of this note's important children.

Should a unique list of values be required, pass the output to a Set to remove duplicate values.

find(query) is equivalent to

> `collect_if( all, query, $Path)`

Note that `collect_if` is related to agents; many tasks you might perform with collect_if can be done as well, or better, with an agent. The results of an agent can be reused by other agents, while find() and collect_if() need to start from scratch each time they are run.

values("attribute_name") returns a set of unique values stored in that attribute throughout the document. If the attribute is a set or a list, values() returns a set of unique elements used throughout the document; if the attribute is a any other type, values() returns each of the distinct values in use.

### Logical Operators

Boolean operators & (and), | (or), and ! (not) operate as expected. Boolean assignment (and queries) coerce non-boolean attributes to either to or false.

number | zero is false and any non-zero is true.
string | "" and "false" are false, other values are true
set | empty sets are false, all others are true
date | "never" is false, all others are true
color | "black" (or RGB(0,0,0) or "#000" or "‹000000") is false, others are true

#### Logical equality tests

Use == to equality and != to test inequality. The older form of using a single equals sign (=) for an equality test is now deprecated.

A direct reference to an attribute of any data type can be be used as Boolean test for a (non-zero value):

> `$MyString` is the same as testing `$MyString!=""`

> `!$MyString` is the same as testing `$MyString==""`

> `$MyNumber` is the same as testing `$MyNumber!=0`

> `!$MyNumber` is the same as testing `$MyNumber==0`

> `$MyDate` is the same as testing `$MyDate!=date("never")`

> `!$MyDate` is the same as testing `$MyDate==date("never")`

Action, File, List, Set and URL data types conform to the String type test above as their data is just a particular form of string.

#### Logical Group Operators

Logical group operators examine a group of notes and determine whether every note in the group meets a criterion, or if any note does.

every(group,expression)

any(group,expression)

The designator group describes the notes to be examined. group may be any group designator {child,descendant,sibling,ancestor,all}. In addition, group may take a single argument that designates a particular group other than this; for example

> `collect(children(/agents/books),$Name)`

The expression may be any valid expression, but is most often a reference to an attribute.

> `any(children,$overdue)`

> `every(children,$status="important")`

### Link Operators

links[(item)].direction.linkType.attribute builds a list from a collection of links.

item selects which note's links should be collected. It may be a single item, a list of items, or a group.If item is omitted, "this" is implied; if item is omitted the enclosing parentheses may be omitted as well. item may be a designator (e.g. "parent") or a note path (/config/details).

The argument direction is either "inbound" or "outbound".

linkType collects only links of a specified link type. linkType is a regular expression: wild-card characters are permitted and have special meanings. If linkType contains white space or periods, enclose it in quotes:

> `links.outbound."responds to".$Name`

If 'linkType' is left empty, links of all types are collected with the exception of prototype links. Prototype links are always omitted. As a regular expression, linkType may match more than one link type:

> `links.outbound."agree|clarify".$Name`

attribute is the name of the attribute whose values are to be collected in the result.

For example

> `$MySet=links(/config).outbound.supports.$Name`

constructs a list of all the Names of notes that are linked to the top-level note named config via links of type "supports".

> `$MySet=links.inbound..$Name`

collects a set of all the names of notes that are linked to this note.

> `links[(note)].kind.linkType.attribute`

#### Making Links

Four actions create or remove links between notes.

linkTo(target [,linkType])

unlinkTo(target [,linkType])

linkFrom(target [,linkType])

unlinkFrom(target [,linkType])

The first argument to each of these actions, is the name or path of a note, or a list of paths. The optional second argument is the link’s type; if no argument is supplied, untitled links are used. Unlike links(), above, the linkType argument is not a regex and is a string literal.

linkTo and linkFrom will not create a new link if the link already exists. unlinkTo and unlinkFrom will do nothing if the described link does not exist. Thus, these actions may be used in agents:

`Query: Status(urgent)` `Action: linkFrom(/agenda/today/tasks,"urgent!")`

This action will insure that an "urgent!" link runs from the note "tasks" in today's agenda; if the link already exists, the action has no effect.

If linkType is not supplied, unlink actions will remove links of all link types.

### Eval() and Action()

The eval() function evaluates an string and returns the result. For example,

> `eval("$Price*1.05")`

returns the value of price augmented by 5%.

The eval() function performs an action stored in a string.

> `action("$Total=$Price*1.05")`

changes the value of `$Total`.

action() and eval() are most frequently used in export templates, but may occasionally prove useful when a note must assemble a rule on the fly.

### Notify, Twitter, Speak, and runCommand

#### Notify

notify(headline[,subtitle][,date] ) adds a notification to your computer’s notification center. Headline and an optional subtitle are displayed in the headline. If the optional date is supplied, the notification will be held until after that date and time; otherwise, the notification will appear immediately.

#### Twitter

####

twitter(screen name, status) will post a new status to your Twitter account. The screen name must have been registered in System Preferences:Internet Accounts.

#### Speak

.speak() will speak the value of any string value. For example:

> `$Text.speak()`

will speak the note’s text. An optional argument specifies the voice to use.

> `"Now is the winter of our discontent".speak("Tessa")`

will pronounce the string using the South African voice Tessa.

#### runCommand

The runCommand() function asks the operating system to start a new process and results the result of that process.

> `$Text = runCommand(command_line, input)`

runCommand() executes the specified command line in your default, passing it the the value input as its standard input. The standard output of the command, if any, is the value of the completed action. For example:

> `$Text = runCommand(ls ~/Documents)`

replaces the note’s text with a list of the files and folders in the user’s Documents folder, and

> `$Text |= runCommand("curl "+$URL)`

will – if the note has no text – ask curl to fetch whatever text is found at the url stored in the note’s $URL.

It is not necessary to use an attribute to hold the output from runCommand, allowing the operator to be used 'bare' in action code. If $CommandValue holds a valid command line string, this can be used in a rule or action:

`runCommand($CommandValue)`

### Locale()

### The function `locale()` lets you change the locale used to translate dates. For example, Americans write 12/1/2006 to denote December 1, while in England the same date is written 1/12/2006.

### The action

`locale(“en_GB”)`

### sets the current locale to “British English”. Locale codes begin with a two-letter language code, followed by and underscore and a two-letter region code. These are ISO standards ISO-639 and ISO-3166 respectively. Code combinations are available for any language supported by Mac OS X.

### To return to the user’s preferred locale, use

> `locale();`

### You may also save the old locale in an attribute for subsequent use. For example:

`$OldLocale=local(“en_GB”);`

### … do various things ...

`local($OldLocale);`

### Note that changing the locale() can be fairly time-consuming, as lots of machinery must be torn down and rebuilt for each change.

## Import

Storyspace provides many options for importing text from various sources.

### Copy and Paste

To move moderate amounts of text from another application to Storyspace, it may be easiest to copy and paste the text. This approach has the added benefit of giving you a chance to review your notes: arrange them, adjust their appearance, consolidate related notes, and prune notes that are out-of-date or irrelevant.

### Drag Data Into Views

Drag and drop can be the quickest way to add an entire text file to your Storyspace document.

You can drag and drop:

- text: drag a text selection into Storyspace and—
  - drop it into a text window to insert the dragged text at that point in the text
  - drop it into a view window to create a new note.
- a text file: drag a text file from the Finder. Drop it into a view window to create a new note containing the dragged text.
- Finder clipping files
  - drop into a text window to insert the text or image clipping at that point in the text (see notes on temporary suspension of the image feature)
  - drop into a view window to create a new note containing the text or image (see notes on temporary suspension of the image feature)
- Bookmarks from web browsers, Bookends, or Yojimbo create Storyspace notes; the URL of the note reflects the URL of the bookmark
- News items and subscriptions from news readers such as NetNewsWire
- OPML files
- tab-indented outlines
- vCards, dropped into Storyspace from the Address Book or other vCard-enabled programs

### Spreadsheets and Comma-Separated Value Files

Selecting a table in a spreadsheet and pasting it into Storyspace will create a useful set of notes.

- The first row is treated as a set of headings, which map to attributes. New user attributes will be created for attributes that do not already exist.
- A new container will be created for the table's rows.
- Each row of the table becomes a note. The table's fields become key attributes, and these attributes are populated from the table

Note that Storyspace is rather conservative in judging whether or not pasted text is actually a table. In particular, missing values in the rightmost column can lead Storyspace to conclude that your data is not, in fact, formatted as a table. Filling in the empty cells will help Storyspace import the information as you intend.

### Explode

The Explode command divides a long text note into several smaller notes, splitting the text at locations you have chosen.

To explode a note:

- Select the note you wish to explode.
- Choose Explode... from the Note menu
- Decide whether to end each note after a certain number of characters or after a delimiter such as a period, then click the radio button next to your choice
- Change the number of characters or the delimiter if necessary. To remove the delimiter from the new exploded notes, check the Delete delimiter box.
- Click Explode.

The new notes will appear as children of the original note, in a new container called Exploded Text.

Delimiters you can use to separate the source content include:

- \r (new exploded notes will begin with each Return)
- \n (new exploded notes will begin with each new line)
- \t (new exploded notes will begin with each tab)
- , (new exploded notes will begin with each comma - useful for CSV data)
- any custom string, e.g. #### or XYXYXY.

Explode can also optionally delete the delimiter character(s), making it easier to use custom string that would look odd if left in the output.

It is also possible to control what part of the exploded text is used as a new note's title. Options are:

- first sentence
- first two sentences
- first paragraph

## Release Notes

# 3.2.0

Storyspace Reader

This release now includes a copy of the Storyspace Reader, a free, redistributable application that reads (but doesn’t edit) Storyspace documents.

Find

Find dialog has a checkbox that allows you to search aliases as well as other notes, or to omit aliases from the search.

Links

You can now drag either the source or the end point of a link to lock it to a specific edge of the source or destination note. Dragging the source or end to the map background unlocks the link, in which case Tinderbox will select the starting and ending locations automatically.

The Link editor also lets you choose the start and end points for links. The default setting, automatic, continues to choose the start and end points as before.

Link labels may now be repositioned.

A new link style, broad, is available.

Text links now have their own link type and style.

When following links, if Tinderbox must choose among several equivalent links with satisfied guard fields, Tinderbox will choose the link of the current path— the link whose link type matches that of the link most recently followed. If the most recently followed link was untitled, the hightest priority link is selected.

The link creation dialog’s guard field text field now offers autocompletion.

The link view popover now lets you use broad links, and also lets you set the start and end points of a link if the automatic layout is not to your liking.

Links may be dragged in the map to lock their start and end points to specific edges of the note.

Link deletion and information widgets are hidden in Read mode.

Maps

Map guides are simpler and more effective. Guides now allow you to align notes on horizontal and vertical centers, as well as edges.

In map view, links with guard fields are distinguished by a small circle, about a quarter of the way along the link. If the guard field is satisfied, the circle is solid; if the guard field is not satisfied, the circle is hollow.

Link types (and the Link Type Inspector) now let you choose a connector type. New links of a given type adopt the type’s connector, and you can override the connector type for individual links as before.

Stretchtext and other Text Substitutions

The markup element now transcludes the text of the designated note when the note is read. Styles are respected.

The markup elements

> some text

and

> some text

allow conditional text when the note is read. condition may be any Boolean expression. For example

> You don’t have much money.

will insert a sentence if the reader’s $Cash is low.

The markup element

> expression

will insert, when the note is read, the value of the expression. For example

will be replaced by a the number stored in the attribute Cash for the note named “me”.

The markup element

anchor

will insert, when the note is read, the text “anchor” formatted as a link. When clicked, the enchor will be replaced by the dest for the note destination, provided that note’s requirements are met. If not, and if there are additional destinations, those destinations will be checked in turn and the first note whose requirements are satisfied will be used. If no destination is satisfied, anchor will not be linked.

Stretchtext links take precedence over default links; clicking a stretchtext link will not trigger a default link . (b006)

The construct now trims quotes from its arguments.

PRINTING

Text pane printing now respects the right edge of the paper, when the text pane is wider than the page.

Miscellaneous

In the Storyspace Reader, Browse Links no longer lets you change or delete links.

Added a symbol on links to indicate that a guard field is present, and whether that guard field is currently satisfied.

Updates for conformance with Tinderbox 6.6

Sculptural links now ignore aliases. If the alias is eligible, the original will be eligible as well, and we want probably want the original.

Document Inspector now ignores aliases when computing the word count.

Go Back appears on the Note menu.

Key attributes are hidden in Read mode.

visited() and unvisited() now work as expected if their path argument is not quoted. Quoting the path argument continues to be recommended.

KEY ATTRIBUTES

A new date picker is available in the key attribute table and in the Get Info attributes pane.

### KEY ATTRIBUTES

A new date picker is available in the key attribute table and in the Get Info attributes pane.

# 3.0.3

Text substitution allows you to modify and extend the text dynamically during a reading. You can include other notes, include the values of attributes, reveal or hide passages when arbitrary conditions are met, and create stretchtext links which, when clicked, modify and extend the text.

## License, Copyright and Colophon

© Copyright 1991-2015 by Eastgate Systems, Inc. All Rights Reserved.

Storyspace is © Copyright 1991-2015 by Riverrun, Ltd.. All Rights Reserved.

Tinderbox™ and Storyspace™ are trademarks of Eastgate Systems, Inc. Storyspace™ and CIVILIZED SOFTWARE™ are also trademarks of Eastgate Systems, Inc. All other trademarks are the property of their respective owners and are used for informational and illustrative purposes only.

This help document was created and edited with Tinderbox Six. Other especially helpful tools included BBedit, Acorn, Skitch, Xcode, AppCode, DropDMG, Transmit, and CSSEdit.

## Storyspace™ Software License Agreement

Eastgate Systems, Inc., grants you a non-exclusive license to use this copy of the program on the following terms:

YOU MAY:

I) Use the program on any one computer;

II) Install the program on a second computer you use provided all copies of the program are used directly and exclusively by yourself.

II) allow anyone else to use the program, so long as there is never more than one user per licensed program at any time;

III) make copies of the program in machine-readable form, but only for archival purposes, and only so long as all proprietary notices are reproduced on each copy.

YOU MAY NOT:

I) Modify, translate, reverse engineer, decompile, disassemble, create derivative works based upon, or copy (save for archival purposes) the program or the accompanying documentation;

II) rent, transfer or grant any rights in the program or accompanying documentation in any form to anyone else without the prior written consent of Eastgate Systems, Inc.;

III) remove any proprietary notices, labels, or marks on the program and accompanying documentation;

IV) use this program, or permit this program to be used, on more than one computer at any one time.

Non-compliance with any of the above restrictions will terminate this license.

This license is not a sale. Title and copyrights to the program and accompanying documentation and any copy remain with Eastgate Systems, Inc.

Household License:

You and up to four (4) other persons who occupy the same household may use the program on their respective computers. "Household" means a person or persons who share the same home, apartment, condominium or dormitory suite, but shall also extend to student household members who are primary residents of the household but who reside at a separate on-campus location.

## Limited Warranty and Disclaimer

This product and associated files are provided without warranty of any kind, express or implied, including without limitation the warranties that it is free of defects, virus free, able to operate on an uninterrupted basis, merchantable, fit for a particular purpose, or non-infringing. The entire risk as to the quality and performance of the product is borne by licensee. Should the product prove defective in any respect, licensee and not licensor assumes the entire cost of any service and repair.

This disclaimer of warranty constitutes an essential part of this agreement. No use of the product is authorized except under this disclaimer.

The liability of Eastgate Systems, Inc.,shall be limited to the replacement of the product or the refund of the purchase price. This is the entire liability of Eastgate Systems, Inc., and your exclusive remedy. Save for the above express limited warranty, Eastgate Systems, Inc., makes no warranties or conditions express, implied, statutory or in any communication with you.

This agreement is the entire agreement. If any provision of this agreement is held invalid, the remainder of this agreement shall continue in full force and effect.

Eastgate Systems Inc.
134 Main Street
WatertownMA 02472 USA

Tel: (800) 562-1638 (617) 924-9051

Fax: (617) 924-9051

Email: info@eastgate.com

Web: http://www.eastgate.com/