/** * Rewriting a `[NOTES]` or `[TODO]` block in `.sdoc` source. * * The dev server lets a reader add notes and tick todos from the Explorer, * which means editing the file they are reading. The edit is deliberately the * smallest one that can be made: a note edit replaces the block's own span and * a tick rewrites one character, so a document keeps its formatting, its * comments, and every byte the author put there. * * Kept apart from the middleware that calls it so the interesting half — find * the block, splice the text — is a pure function of source text. */ import type { DocNote, TodoItem } from '../types.js'; export interface NoteTarget { /** Slug of the entity to edit, as the Explorer knows it. */ entitySlug: string; /** Title of an `[example]` inside that entity, to edit its notes instead * of the entity's own. */ exampleTitle?: string | null; } export declare class NoteTargetError extends Error { } /** * A `[NOTES]` block, or '' when there is nothing to write. * * `base` is the indentation the block sits at — one level inside its entity or * example. A note's text is written verbatim on one line: the block's grammar * is one note per line, so a newline inside a note would split it in two. */ export declare function serializeNotes(notes: DocNote[], base: string): string; /** * Return `source` with the target opener's `notes` carrying exactly `notes`. * * Replaces the attribute where one is already written, removes it when the * list is emptied, and otherwise adds it just inside the opener's closing * bracket. Throws `NoteTargetError` when the target names nothing. */ export declare function writeNotes(source: string, target: NoteTarget, notes: DocNote[]): string; /** * Return `source` with the todo at `path` ticked or unticked. * * `path` addresses the item by position at each level — `[1, 0]` is the first * child of the second root item — which is what the rendered checklist knows * about itself. Only the mark between the brackets is rewritten: one character * in, one character out, so a tick never reflows the author's text. */ export declare function toggleTodo(source: string, target: NoteTarget, path: number[], done: boolean): string; /** * A `[TODO]` block, or '' when the list is empty. * * `base` is the indentation the block sits at; each level of nesting adds one * tab inside it, because indentation is what nests one item under another. */ export declare function serializeTodos(items: TodoItem[], base: string): string; /** * Return `source` with the target's `[TODO]` carrying exactly `items`. * * The whole block is re-serialized, unlike `toggleTodo` — this is the path for * edits that change the list's shape (text, an added item, a removed one), * where there is nothing smaller to rewrite. Emptying the list removes the * block rather than leaving an empty one behind. */ export declare function writeTodos(source: string, target: NoteTarget, items: TodoItem[]): string; /** Which `[COMPONENT]` to edit: the entity it lives in, and the component it * documents (the `component={X}` identifier, or the `title="…"` tab label when * one entity previews the same component twice). */ export interface ComponentTarget { entitySlug: string; component: string; } /** * Return `source` with the target `[COMPONENT]`'s `status` set to `status`, or * with the attribute removed when it is null. * * The one attribute writer left in this module. Notes and todos became blocks * in 0.0.139; a status is genuinely an attribute — a single word about the * component rather than something written *inside* it — so it is spliced the * way the notes attribute used to be: the attribute's own span and nothing * else, or just inside the opener's closing bracket when there is none yet. */ export declare function writeStatus(source: string, target: ComponentTarget, status: string | null): string;