Skip to content

Markdown editing

lukataylor-pixel edited this page May 3, 2026 · 2 revisions

Markdown editing

Click any .md, .markdown, or .mdx file. It opens as a tab. Above the tab content sits the toolbar pill — mode toggle on the left, formatting tools that scroll horizontally if needed.

Four modes

Mode Surface Use it for
Preview Real GFM render via MarkdownUI Reading. Reviewing. Sharing your screen.
Source Raw markdown, monospace, paragraph-scoped syntax highlighting Heavy editing. Find/replace. Pasting tables.
Split Source on the left, rendered on the right Drafting + checking layout simultaneously.
Math KaTeX-rendered preview via WKWebView Anything with $…$ or $$…$$ — academic, technical, anything where math beats prose.

Single-click a file card opens in Preview by default. Double-click opens in Split. The mode is per-panel and persists across relaunch.

Preview supports

  • Headings (1–6)
  • Paragraphs, line breaks
  • Bold, italic, inline code
  • Bulleted, numbered, and task lists (with checkboxes)
  • Block quotes
  • Fenced code blocks with syntax highlighting (via MarkdownUI's GitHub theme)
  • Tables (GFM pipe syntax)
  • Links and images
  • Wiki-links ([[Note Name]] — see Search and navigation)
  • Horizontal rules
  • Inline HTML (limited)
  • A frontmatter card at the top (when a YAML --- block is present)

If you want to edit, switch to Source or Split.

Source supports

The Source view is an NSTextView. Standard Mac text editing: find via the system find bar (⌘F within the editor), undo/redo, multi-select, drag-select, font scaling.

Syntax highlighting runs against the edit range only — not the full file — so editing line 4000 of a long PRD doesn't re-scan the other 3,999 lines. The fallback to a full re-scan kicks in when an edit straddles a code-fence boundary; otherwise it stays incremental.

-click on a wiki-link or markdown link opens it. Plain mouse clicks place the caret normally.

Math mode

Open any file in Math mode to see math expressions rendered:

The familiar identity:

$$
e^{i\pi} + 1 = 0
$$

Inline: $\sigma^2 = \mathbb{E}[(X - \mu)^2]$.

The renderer is a WKWebView running marked.js + KaTeX (vendored to the resource bundle by scripts/vendor-katex.sh). If you build from source, run that script once; pre-built DMG releases include the libraries.

Math mode is read-only. To edit, flip back to Source or Split.

Snippets

Type a trigger followed by space or newline to expand:

Trigger Expansion
,date 2026-05-03 (today, ISO)
,time 14:23 (now, HH:MM)
,now 2026-05-03T14:23:11Z (full ISO-8601)
,today [[2026-05-03]] (wiki-link to today's daily note)

Define your own at ~/.soffit/snippets.json:

{
  ",sig":  "— Luka",
  ",todo": "- [ ] ",
  ",ymd":  "{{date}}"
}

The file is watched; new snippets activate without a relaunch. {{date}}, {{time}}, {{now}}, and {{long_date}} substitute live.

The toolbar pill

In order, left-to-right:

  1. Mode segment — Preview / Source / Split / Math
  2. Headings menu — H1 through H4
  3. Bold — wraps in **…**
  4. Italic — wraps in *…*
  5. Inline code — wraps in `…`
  6. Bulleted list — prefixes selected lines with -
  7. Numbered list — prefixes with 1.
  8. Task list — prefixes with - [ ]
  9. Quote — prefixes with >
  10. Link — wraps in [text](https://)
  11. Table — popover, hover-pick rows × columns

If a button is hidden behind the pane edge, scroll the pill horizontally.

Status bar

Below the editor:

  • Outline toggle — TOC of the current file's headings (click to scroll)
  • Backlinks toggle — files that wiki-link here
  • Spell-check toggle — system spell-check on/off (persisted)
  • Word count · char count — running counts at the right edge

Image paste

Copy an image (screenshot, file, anything NSPasteboard recognises). ⌘V in the Source/Split editor saves it to <workspace>/attachments/paste-<timestamp>.png and inserts ![](attachments/paste-…png) at the cursor.

The attachments folder gets created on first paste. You can move/rename pasted files freely; the markdown will stay in sync as long as you update the path.

Autosave

A 500ms debounce. Type a burst, pause, file lands on disk. Atomic write, off the main thread, so even big files don't hitch the editor.

Closing the tab (or quitting the app) flushes the pending edit synchronously — you won't lose what you just typed.

Caveats

  • External edits while open will be overwritten by the next save. Soffit doesn't yet detect file mtime conflicts. If you vim a file in another window while it's open in Soffit, save in Soffit last.
  • The Source highlighter uses regex, not tree-sitter. Some pathological edge cases (deeply nested fences, inline HTML containing markdown) may temporarily look wrong until the next edit re-scans.

Clone this wiki locally