Scripting API
Automate the live project with JavaScript macros in the Script Console. The world global reads and changes the project through the undo stack, so a whole macro is one undo step.
Getting started
Write and run your first macro in the Script Console.
Built-in macros
The macro library that ships with the app, and how to save your own.
The world object
Every method below is a member of the world global. Reads return plain JavaScript values (strings, arrays, and {…} objects); writes each apply as one undoable step and return whether they succeeded.
Reading the project
world.entityIds() → string[]
The ids of every codex entity, in project order.
world.entityIds().forEach(function(id){ console.log(world.entityName(id)); });
world.entities() → object[]
Every codex entity as a plain object {id, name, category} (category is the category's display name, or "" when uncategorized).
world.entities().filter(function(e){ return e.category === 'Characters'; });
world.entityName(id) → string
The display name of the entity with that id, or "" if there is no such entity.
world.findEntity(name) → string
The id of the first entity whose name equals name exactly, or "" if none matches.
var id = world.findEntity('Aria'); if (id) console.log(world.field(id, 'Role'));
world.field(id, key) → string
The value of field key on entity id, or "" when the entity or the field is absent.
world.documentIds() → string[]
The ids of every document (prose, screenplay, or note), in project order.
world.documents() → object[]
Every document as {id, title, kind} (kind is "prose", "screenplay", or "note").
world.documents().forEach(function(d){ console.log(d.kind + ': ' + d.title); });
world.documentTitle(id) → string
The title of the document with that id, or "" if there is no such document.
world.documentBody(id) → string
The Markdown body of the document with that id, or "" when the document is absent.
world.categoryIds() → string[]
The ids of every codex category, in stable order.
world.categories() → object[]
Every codex category as {id, name}.
world.categoryName(id) → string
The display name of the category with that id, or "" if it is unknown.
world.findCategory(name) → string
The id of the first category whose name equals name exactly, or "" if none matches.
world.objects() → object[]
Every content object in the project as {id, title, type} -- where type is the stable token ("entity", "document", "timeline_event", "task", "map", ...) -- so a macro can enumerate the WHOLE model, not only entities and documents.
world.objects().filter(function(o){ return o.type === 'task'; })
.forEach(function(o){ console.log(o.title); });
world.objectIds(typeToken) → string[]
The ids of every content object of a given type token (e.g. "task", "timeline_event"); an empty token returns every id, an unknown token returns none.
var mapIds = world.objectIds('map');
world.objectTitle(id) → string
The display title (or name) of any object, whatever its type, or "" if none.
world.objectType(id) → string
The stable content-type token of an object (e.g. "entity", "map"), or "" if none.
Changing the project
world.createEntity(name) → string
Creates an uncategorized entity and returns its new id ("" for an empty name).
world.setField(id, key, value) → boolean
Sets field key to value on an entity. Returns true when the entity exists and the change was applied.
var id = world.createEntity('Mara');
world.setField(id, 'Role', 'Smuggler');
world.renameEntity(id, name) → boolean
Renames an entity. Returns true when the entity exists and name is non-empty.
world.createEntityInCategory(name, categoryId) → string
Creates an entity in a category and returns its new id. An empty or unknown categoryId leaves it uncategorized.
var cat = world.findCategory('Places');
world.createEntityInCategory('Harbor', cat);
world.createDocument(title) → string
Creates a top-level prose document and returns its new id ("" for an empty title).
world.setDocumentBody(id, body) → boolean
Sets a document's Markdown body. Returns true when the document exists.
world.setDocumentTitle(id, title) → boolean
Sets a document's title. Returns true when the document exists and title is non-empty.
world.createCategory(name) → string
Creates a root category and returns its new id ("" for an empty name).
The app object — reusable workflows
Where world reads and changes data, the app global extends the application. app.registerCommand(name, fn) registers a named command that appears in the Script Console's Commands menu and runs fn on demand — so a macro becomes a reusable workflow the user invokes whenever they like, not just a one-shot. Registering the same name again replaces it.
app.registerCommand("Draft missing summaries", function () {
world.entityIds().forEach(function (id) {
if (world.field(id, "Summary") === "")
world.setField(id, "Summary", "(to be written)");
});
console.log("Done.");
});
Now “Draft missing summaries” is in the Commands menu; each run is one undo step, exactly like an edit made in the UI. (Custom windows are a plugin capability — see the C++ plugin API — while scripts get data access and commands.)
Console output
console.log, console.warn, and console.error write to the Script Console's output area — the sandbox exposes no other I/O.
console.log("Entities: " + world.entityIds().length);