README file from
GithubScribe of Lagash - Visualization
An Obsidian plugin that helps writers visualize their chapters and scenes. It is part of the Scribe of Lagash series, a set of independent, focused tools for planning and writing stories in Obsidian.
This plugin doesn't own your prose: chapters and scenes are just regular notes
in your vault. Point the plugin at the folder that holds a story and it
recognizes chapters and scenes from their titles ("Chapter 1", "Scene II",
"Prologue", …); a little scribe-note-* frontmatter is optional and
only needed to override the title or add detail. You can see the story in three
views: StoryLines, where you arrange the cards on your own lines, and the
read-only Characters and Locations views, which group the same chapters
and scenes by who appears and where they happen. The only file the plugin ever
writes is a per-story StoryLines file that stores the lines and card
positions of the StoryLines view; the Characters and Locations views are derived
from your notes and save nothing.
Installation
Requires Obsidian ≥1.10.0.
You can install it from the
community plugins page,
or download main.js, manifest.json, and styles.css from the
latest release
and copy them into <vault>/.obsidian/plugins/scribe-of-lagash-visualization/.
Scribe of Lagash Plugins
Scribe of Lagash is a series of independent, single-concern Obsidian plugins for planning and writing stories:
- Scribe of Lagash - Visualization (github repository) — helps writers visualize their chapters and scenes.
- Scribe of Lagash - Goals and Stats (github repository) — helps writers set goals and see detailed statistics for their story.
About the name
"Scribe" is the writer at the center of every plugin in the series, and "Lagash" nods to Nippur de Lagash, the classic Argentine comic.
Current features
StoryLines view
The story's default view (ribbon icon / "Open StoryLines" command).
Horizontal, colored lines for a story, with each chapter/scene as a card
sitting on a line. Pick "Create lines" the first time to seed a "Main line",
then drag cards between lines or along the shared column grid — columns line
up across every line by reading order, and you can leave deliberate gaps
between cards. Dropping a card onto an occupied column nudges the others
right. When a Story Outline is set up, an Align cards to Story Outline
toolbar button snaps every card — real or planned — back to the outline's
reading order and onto the line its row names. Add /
rename / recolor / reorder / delete lines from the line headers. Changes save
to the StoryLines file (StoryLines.md) automatically; Mod+Z undoes.
Characters view
The combo box at the top right of the StoryLines tab
switches between the different views. Characters keeps the same
look but is read-only: one line per character (alphabetical), each showing
the chapters/scenes that name them in reading order, so a scene with two
characters appears on both lines. Names come from the notes'
scribe-note-characters frontmatter and the Story Outline's Characters
column, merged; if a note and its outline row list different characters a ⚠
explains the difference. Planned (not yet written) rows show as dashed,
non-clickable cards, and notes with no characters sit in a "No characters
listed" strip. Nothing is moved, created or saved in this view, and each tab
remembers its own view.
Locations view
The same read-only view, with one line per location.
Names come from the notes' scribe-note-locations frontmatter and the Story
Outline's Locations column, merged the same way (⚠ when they differ; a
"No locations listed" strip for the rest).
Story Outline file (optional)
Name a file under Story Outline file
name in settings and click Create; it's written as an empty
Markdown table (Act / Chapter / Scene / Line / Synopsis/Characters). The .md extension
is optional — Outline and Outline.md both create (SL) Outline.md. Fill
it in to plan the story before the
notes exist: rows with no matching note appear as dashed placeholder cards
on the StoryLines view, and clicking one creates the note (title, Synopsis,
frontmatter) on that line. Once a note exists its Synopsis shows on the
card; a row that disagrees with the real note/folder gets a ⚠ marker — the
files always win.
The optional Characters and Locations columns (comma-separated names)
feed the Characters and Locations views, including for notes not written yet. See
docs/feature-plans/outline-file-plan.md.
Planned next
- a chronological view ordering chapters/scenes by their
scribe-note-date. See docs/feature-plans/line-view-plan.md.
Setting up a story
In the plugin settings, add the vault-relative folder that holds your story's notes under Story folder. The plugin scans that folder and classifies each note by its title:
| Title looks like | Recognized as |
|---|---|
Chapter 1, Chapter IV, Ch. 12 — The Fall |
chapter (number 1, 4, 12) |
Scene 2, Scene IX |
scene |
Prologue, Epilogue, Interlude |
chapter (no number) |
| anything else | ignored |
Leave Story folder empty to scan the whole vault instead.
Recognized title words
The Title language setting picks which language's words the plugin looks for
at the start of a note's title. The number may be digits or a roman numeral
(IV), an optional . can follow the keyword, and matching is
case-insensitive. English (en) and Spanish (es) ship today:
| Meaning | English | Español |
|---|---|---|
| Chapter N | Chapter N, Chap N, Ch N |
Capítulo N, Capitulo N, Cap N |
| Scene N | Scene N, Sc N |
Escena N, Esc N |
| Chapter, no number | Prologue, Epilogue, Interlude, Foreword, Afterword, Preface |
Prólogo, Epílogo, Interludio, Prefacio, Epígrafe |
Act folder — the word the Story Outline file prepends to an Act cell when it builds a path |
Act |
Acto |
So with Title language set to Español, Cap. 3 — La caída is chapter 3 and
Escena II is scene 2. Adding a language is one more pattern table in
src/data/titleParser.ts — nothing else changes.
Story structure
A note's place in the manuscript comes from where it sits in folders, not from frontmatter. Any of these layouts works — but pick one per story:
| Layout | On disk (under the story folder) |
|---|---|
| Chapters as files | Chapter 1.md, Chapter 2.md, … |
| …grouped in acts | Act I/Chapter 1.md, Act II/Chapter 5.md, … |
| Chapters as folders of scenes | Chapter 1/Scene 1.md, Chapter 1/Scene 2.md, … |
| …grouped in acts | Act I/Chapter 1/Scene 1.md, … |
| Scenes with no chapter | Scene 1.md, or Act I/Scene 1.md |
| Deeper nesting | Act I/Part 2/Chapter 3.md — every folder just adds to the breadcrumb |
A scene's chapter is simply its containing folder — there is no parent key.
Prologue.md / Epilogue.md / Interlude.md can go anywhere; having no number,
they sort after the numbered notes in the same folder.
Don't mix "chapter as a file" and "chapter as a folder" in the same story. If you do, every file-chapter sorts before any folder-chapter's scenes. Pick one style and convert the whole story to it.
Manuscript order is then: folder path first (all of Act I/… before Act II/…;
a numbered folder sorts by its number, so Chapter 2/ comes before
Chapter 10/), then the number in the title, then the title text. Sub-folders
also show as a breadcrumb under each card — a note at
My Story/Act I/Chapter I/Scene 1.md (story folder My Story) shows "Scene 1"
with "Act I - Chapter I" underneath.
Planning ahead with the Story Outline file
Set Story Outline file name in settings (the .md is optional — Outline
and Outline.md both mean (SL) Outline.md) and click Create. The
plugin writes one (SL) <name>.md per story folder with an empty table and a
column guide, and never touches it again.
When you plan a story in the Story Outline file table before writing the notes, fill the columns that match your layout:
| Layout | Columns to fill | The row's note |
|---|---|---|
| Chapters as files | Chapter |
Chapter 1.md |
| …grouped in acts | Act + Chapter |
Act I/Chapter 1.md |
| Scenes in chapter folders | Chapter + Scene |
Chapter 1/Scene 2.md |
| …grouped in acts | Act + Chapter + Scene |
Act I/Chapter 1/Scene 2.md |
| Scenes with no chapter | Scene (+ optional Act) |
Scene 2.md |
| Custom folder | Folder (overrides Act) |
<Folder>/Chapter 1.md |
Numbers may be digits or roman numerals, optionally followed by free text —
e.g. a Chapter cell of 1 - The beginning plans Chapter 1 - The beginning.md,
the same as if you'd typed that title directly. The Act / Chapter / Scene
words and folder names follow the Title language setting. Line is a line
name or id from the StoryLines file; Synopsis shows on the card and becomes
the note body when you create it.
List the people in a chapters/scenes under Characters
(comma-separated, e.g. Harry, Ron, Hermione) to enable the Characters view:
each name becomes a line showing the chapters/scenes it appears in. Locations
does the same for the Locations view.
A row with neither a Chapter nor a Scene
value is ignored, and un-numbered units (Prologue, …) can't be planned here —
create those notes directly. The Story Outline file created for you repeats
this guide below the table.
Optional frontmatter
None of this is required — it only adds detail the cards can show:
---
scribe-note-date: 1901-03-04 # in-story date, any free-form string
scribe-note-characters: [Alice, Bob]
scribe-note-locations: [Riverside Tavern]
scribe-note-status: draft
---
Development
npm install
npm run dev # watch build, outputs main.js
npm run build # type-check + production build
npm test # unit tests (Node's built-in runner; no test framework dependency)
Supply-chain safety
- Every dependency in
package.jsonis pinned to an exact version — no^/~ranges and nolatest..npmrcsetssave-exact=trueso futurenpm install <pkg>additions stay pinned by default. .npmrcalso setsignore-scripts=true, sonpm install/npm cinever runs a dependency'spreinstall/install/postinstallscript automatically. The only dependency that ships one isesbuild, and its script just optimizes linking its already-installed platform binary — the build works fine without it. On the rare platform where it doesn't (e.g. an environment without a matching prebuilt@esbuild/*package), runnpm run rebuild:esbuildto explicitly and visibly opt that one script back in for that single command.
To try the plugin in a vault, copy (or symlink) manifest.json, main.js,
and styles.css into <vault>/.obsidian/plugins/scribe-of-lagash-visualization/,
then enable it from Obsidian's Community Plugins settings.
Contributing
Found a bug, or have a feature request? Open one on the GitHub Issues page — there's a template for each.
Contributions are welcome — see CONTRIBUTING.md for dev setup, code conventions, and the PR process. This project follows a Code of Conduct.
Found a security issue? See SECURITY.md instead of opening a public issue.
See CHANGELOG.md for release history.
License
MIT.