# Subtitle Editor — User Guide

`https://contexts.live/org/{slug}/tools/editor/`

---

## What is this?

The Subtitle Editor is a web page for creating and editing subtitle/caption data for contexts.live productions. It replaces the Google Sheets workflow, letting you build, edit, and export structured JSON files directly in the browser — and save them directly to the server.

No software to install. Open the page, do your work, save or download.

---

## Getting started

### Open a file from the server

Click **Open from server…** to browse JSON files already saved on the server. Files are listed most recently saved first. Each row shows the title, filename (without `.json`), and — if different from the filename — the id with a ⚠ indicator. Click a row to open the file. Version buttons (`-1`, `-2` …) on the right load older versions.

If a file is currently open in another editor window, a red **⚠ Also open by:** warning appears below the filename, showing the IP address and how long ago that window was opened. This is advisory only — you are not prevented from opening the file.

You can also open a file directly by adding `?file=FILENAME.json`, `?pack=PACKNAME`, or `?unit=UNITNAME` to the editor URL.

### Open a local file

Click **Open local file…** and select any of `.json`, `.tsv`, `.csv`, `.vtt`, `.srt`, `.pptx`, or `.pdf`. The format is detected automatically.

For `.pptx` files, each slide becomes one row: slides with text become `text` rows (paragraphs joined with `<br>`), empty slides become empty `text` rows. No timecodes are imported.

For `.pdf` files, the editor creates a score pack — one `text` row per page with `score.image` pre-populated (`page-000001.png` etc.). Meta rows for `id`, `version`, `scorePages`, `scoreFormat`, and `scorePrefix` are created automatically. The id is derived from the PDF filename. The PDF is uploaded and split into PNGs when you **Save to server**.

### Paste content

Click **Paste**, paste any supported content, and click **Parse**. Accepts TSV, CSV, VTT, SRT, or JSON.

### Start from scratch

Click **New**. Use the `+meta` and `+line` buttons in the table header to add rows.

> Any load or import will ask for confirmation if you have unsaved changes.

---

## JSON formats

The editor supports two JSON formats:

**v1 (legacy)** — the original format with a top-level metadata structure and a `cues` array separate from `lines`. Identified by the absence of `meta.cx`.

**v2 (current)** — the new format with a flat `meta` object at the top (identified by `meta.cx: "2.0"`), `cueIn`/`cueOut` on each line, and sources (`st`, `ad`, `sl` etc.) as fields on lines.

The editor detects the format automatically on import. **Save to server** always saves v2 JSON. The **JSON** download button lets you export v2 explicitly.

The **Save to server** button saves to `org/{slug}/packs/` on cx-server (port configured in `config.json`).

---

## The toolbar

| Button | What it does |
|---|---|
| **New** | Clear everything and start fresh |
| **Paste** | Show/hide the paste panel |
| **Open from server…** | Browse and load a JSON from the server |
| **Open local file…** | Load a file from your computer |
| **Save to server** | Save to server in the appropriate format |
| **JSON v1 / JSON v2 / TSV / VTT** | Download in the chosen format |
| **Undo** | Undo the last structural change (up to 5 levels) |
| **Find & Replace** | Show/hide the find, replace and transform panel |
| **Validate** | Check the data for errors and warnings |
| **Columns** | Show/hide the column manager |
| **Rows** | Show/hide the rows panel (combine, split) |
| **Options** | Show/hide the options panel |
| **Help** | Open this guide |

All panels have a ✕ close button. **Cmd+Z** / **Ctrl+Z** triggers undo. **Cmd+F** / **Ctrl+F** opens Find & Replace.

---

## The row grid

### Two sections

- **Meta rows** (above the divider): global information — title, composer, id, cx, etc. These become the `meta` object in v2 JSON, or top-level keys in v1.
- **Line rows** (below the divider): subtitle content — sung/spoken lines, character names, stage directions, etc.

### Row colours

| Colour | Row type |
|---|---|
| White | meta, text, note |
| Light blue | character |
| Light green | audible |
| Light orange | actSettingTitle |
| Light purple | pack, unit |

### Row types

**Meta types:** `cx`, `title`, `id`, `language`, `composer`, `writer`, `date`, `venue`, `subtitle`, `description`, `performers`, `version`, `scorePages`, `scoreFormat`, `scorePrefix`, `catalogue`, `source`, `site`, `url`, `index`, `style`, `region`, `note`

**Line types:** `text`, `audible`, `character`, `actSettingTitle`, `pack`, `unit`, `note`

The `cx` meta row controls the save format — set to `2.0` for v2. Changing a type to a meta type moves the row to the meta section, and vice versa.

### Column headers for v2

In v2 files, source fields on lines use triple dot-notation: `st.text.en`, `ad.text.en`, `ad.audio.en`, `sp.en` etc. The editor accepts both `.` and `:` as separators on import and normalises to `.` internally.

---

## Editing cells

Click any cell to activate it — a textarea appears. Click elsewhere or Tab to move on.

### Keyboard navigation

| Key | Action |
|---|---|
| **Tab** | Move right; wraps to the next row |
| **Shift+Tab** | Move left |
| **Enter** | Move down one row |

**Enter on the last row of a section** adds a new row.

---

## Selection

**Cell range** — click a cell, then **Shift+click** or drag to extend.

**Row selection** — click a row number to select the whole row.

**Column selection** — click a column header to select the whole column.

Copy with **Cmd/Ctrl+C**, cut with **Cmd/Ctrl+X**, clear with **Escape**.

---

## Language columns

Language columns appear with an **amber header**. A column is treated as a language column if its name is a 2-letter ISO code, `ens`, or `ipa` — or if it is a triple column with `text` as the render segment (e.g. `st.text.en`, `ad.text.en`).

RTL languages (`ar`, `he`, `fa`, `ur`, `yi`) are detected automatically by column name.

### Triple columns (v2)

Column names use `.` (or `:` on import) to denote nested JSON structure up to three levels:

- `st.text.en` — subtitle text, English
- `ad.audio.en` — audio description audio file, English
- `sp.en` — speaker name, English

A triple column is treated as a **language column** if any segment is `text`. Otherwise it is a plain column.

---

## Column manager

Click **Columns** to open. Reorder by dragging, rename by double-clicking, hide/show with the 👁 eye icon, remove with `×`.

---

## Computed columns

Computed columns derive their value automatically (teal header).

| Function | What it shows |
|---|---|
| Length / Word count / Byte count | Character, word, or byte count |
| Convert to seconds | Timecode to decimal seconds |
| Format as H:MM:SS | Decimal seconds to timecode |
| Row number (all/text/audible) | Ordinal position |
| Gap to next start | Seconds to next content row's start |
| Duration (in → out) | Out minus in |
| Silence (out → next in) | This row's out to next row's in |
| Auto timecodeOut | Next content row's timecodeIn minus offset |
| Translate | Translation via MyMemory API |

---

## Find & Replace

Click **Find & Replace** (or **Cmd+F**) to open.

- **Replace mode** — find text and replace with new text
- **Transform mode** — apply a function to matched cells (strip formatting, smart quotes, wrap italic, offset timecodes etc.)
- **Quick transform buttons** — one-click transforms for common operations

---

## Rows panel

**Combine with next** — merges the current row with the one below.

**Split row** — splits at the first `<br>` in each lang cell.

Both operations are undoable.

---

## Validation

Click **Validate** to check the data.

- 🔴 **Fatal** — structural problems that will break export or playback
- 🟡 **Warning** — likely mistakes worth reviewing
- 🔵 **Note** — informational

---

## Saving & exporting

### Save to server

Click **Save to server**. The filename comes from the `id` meta row. Each save keeps the previous version as `name.-1.json`.

If a PDF score was opened locally, it is uploaded and split into PNGs on save. If you change the `id` before saving, the images are written to the new folder. The original `source.pdf` is kept alongside the PNGs.

If the file on the server has been modified since you opened it (by another window or another user), you will be asked: *"This file was modified by someone else since you opened it. Save anyway and overwrite their changes?"* — Yes overwrites, No cancels without saving.

### Download as JSON

Explicit download in v2 JSON format.

### Download as TSV

All visible columns as tab-separated values.

### Download as VTT

WebVTT subtitle file. Only available when the data contains timecode information.

---

## Undo

Up to 5 levels with **Cmd+Z** / **Ctrl+Z** or the **Undo** button.

---

## Status bar

Green = success · Amber = warning · Red = error · Grey pulsing = in progress.
