Textulon

A transient floating editor for inspecting, transforming, previewing, and lightly reshaping text handed to it by another tool.
Powered by RoboCore • macOS 13+
One engine, three front-ends. The transform engine (RoboCore) and the Markdown / Mermaid / SVG renderer (TextulonRender) and the JSON/XML tree (TextulonTree) are shared modules, not reimplementations — a document transformed or rendered on one platform produces the same output on the others. What differs is the shell around them: a floating desktop window on macOS, a conventional desktop window on Windows, and a share-sheet viewer on iOS. The two sections at the bottom of this page — TextuLite for Windows and TextuLite for iOS — state exactly what each one does and does not have.

Intent

Textulon is the one-purpose macOS app at the end of the acquire → transform → return text pipeline. It does not select text on its own. Some other tool — a Stream Deck button, a robo keyboard shortcut, a Raycast script — supplies the input. Textulon shows it, lets you reshape it, and hands the result back via the clipboard or stdout.

That separation means the same transform engine works whether the front-end is a Stream Deck key, an editor menu, or just a piped CLI command.

Companion to Mac-A-Tron’s Keyboard Shortcut action. Where the Keyboard Shortcut action does inline buffer manipulation ({grab}{insert before …}{paste}), Textulon is for cases that need a glance, a tweak, or a preview before paste-back.

Quick Start

1) Install it

Textulon is distributed as a signed macOS app. Install Textulon.app in /Applications so it is available from Finder, Stream Deck actions, and command-line aliases.

2) Open it with something

Three ways to put text in front of you:

# From a file
Textulon --input-file ~/notes/messy.json --mode json

# From a pipe
pbpaste | Textulon --input-stdin

# From within the UI: ⌘O opens a file picker
#   (Textulon will ask before discarding non-empty editor contents)

Shell aliases. Open Settings (,), scroll to Command Line → Shell aliases at the bottom, and press Install. Textulon appends textulon and tx aliases to ~/.zshrc, pointing at the installed app. It is idempotent — aliases already present are left alone, and the status line tells you what it did. Open a new terminal (or source ~/.zshrc) and then:

tx ~/some-file.json              # autodetect mode by extension
cat foo.xml | tx --input-stdin   # pipe stdin
tx --help                        # full CLI surface

3) Look at the version

$ Textulon --version
Textulon v1.0.191 (built 2026-08-09)
Built against robo v1.1.125 (built 2026-02-04)
Copyright © 2025-2026 RoboMac

Textulon reports its signed-app build and the RoboCore version it was linked against.

Modes

The Mode dropdown determines how the editor and preview pane behave. In Auto, Textulon inspects the editor contents on every change and rotates the preview into the right shape.

ModePreview paneWhat it’s for
AutoInferredPasted-in text of unknown shape.
PlainNoneJust the editor; transforms still available.
JSONTree (collapsible value tree), Query (JSONPath expression → matching nodes), or Pretty (via json.beautify)Validate & reformat, click through a parsed structure, or jump to nodes via path expressions. The status row shows the selected node's JSONPath (e.g. $.documents[0].title).
JSON LinesFull List readable record view with Previous/Next, Jump, stable per-record links, and record/source-line labels, plus an optional Single Record viewLog and export files where each line is its own JSON object. Textulon parses each non-empty line independently rather than building one giant tree, and decodes JSON string escapes in the preview so \n becomes a line break. The source is never rewritten. Used automatically for .jsonl and .ndjson.
XMLTree (element / attribute / text nodes with positional indexes), Query (XPath expression → matching nodes), or Pretty (via xml.beautify)Validate well-formed XML, navigate the parsed tree, or query with XPath. The status row shows positional XPath (e.g. /catalog/book[2]/title).
MarkdownRendered Markdown (HTML in a sandboxed WKWebView) with inline Mermaid fence supportSource on top, rendered preview below. Fenced mermaid / mmd blocks render as diagrams inside the Markdown document.
MermaidRendered Mermaid diagram (flowchart, sequence, ER, etc)Preview diagrams from .mmd or .mermaid files.
SVGRendered SVG preview with transparent-background controlsAuto mode recognises <svg. The preview bar offers System/Dark/Light backgrounds and a green 1 px frame around the SVG canvas.
HTMLRendered HTML in WKWebViewSource on top; rendered preview below. Network is blocked. The preview paints its own background (white by default) so unstyled HTML stays readable in dark mode. Opening an .mht / .mhtml archive imports it to standalone HTML — see below.
JavaScript / TypeScript / Shell / YAML / TOML / INI / Python / Go / SwiftSource syntax colouringLightweight source editing and inspection; Shell mode also provides rc/profile snippets.
RoboKeysScratch pane that receives live robo keys output.Test key chains before binding them to a Stream Deck button.
ASCIILive string-extraction results with inline filters.Extract readable ASCII / UTF-8 / UTF-16 BE strings from binary noise.
Hex (toggle)Byte grid above mode-native previewInspect/edit bytes for any file. .bin, .dat, .raw open with Hex view on by default.
Resizable split, in either direction. The editor and preview panes share the window through a draggable divider. \ switches the split between stacked (source above render) and side-by-side; \ toggles the split off entirely. The orientation is per-document and is carried through session restore. A Hide Raw toggle in the header collapses the source pane so the rendered view takes the full window; toggle off to bring source back. Settings let you choose separate Hide Raw-on-open defaults for Markdown, Mermaid, HTML, SVG, JSON, XML, Hex, and binary/ASCII-style previews.
Auto detection. File extension is checked first, then content. Auto recognises JSON, JSON Lines, XML/HTML, Markdown/Mermaid, SVG (<svg), code/settings files, RoboKeys-looking text, and Parseo-recognised binaries.
MHTML import. Opening a .mht or .mhtml web archive — the format Safari, Chrome, and Word use for "single file" page saves — unpacks the MIME parts and rewrites them into one standalone HTML document with the referenced images and stylesheets inlined as data: URIs. Textulon opens the converted document under the sibling .html name as an unsaved tab, so the original archive is never overwritten; press S to keep it. Resources the archive did not actually contain are reported as an unresolved-reference count rather than silently dropped.
Tree → source highlight. In JSON/XML Tree, clicking a row selects the corresponding source range in the editor. If the row is a container (object/array/element with children), the same click also toggles its expand/collapse state; the chevron toggles without moving the editor selection. Parse errors show a red chip with the failing offset.

Editor, Tabs, and Restore

FeatureDetails
TabsThe tab bar appears when more than one document is open. Use Tab and Tab to switch documents.
File breadcrumbClick the final file name to copy the full path. Click a folder segment for Open File, Reveal in Finder, and path-copy options including home-relative and current-directory-relative paths when available.
Session restoreTabs marked Keep restore after quit. Stream Deck-originated tabs default to Ephemeral and are not saved. Memory buffers marked Keep are stored as compressed session data.
Reopen closed tabT reopens the most recently closed file-backed tab and keeps walking back through the session's closed tabs — the inverse of W. Closed files are also promoted to the top of Open Recent, which remembers the last 10 files across runs.
Close policyClosing the last non-blank document replaces it with a blank one rather than leaving an empty window; closing that sole blank document quits Textulon.
Opening filesO, drag-and-drop onto the window, or a path on the command line. Multiple files open into multiple tabs. When Textulon is already running, a CLI open is forwarded into the existing instance.
Auto-saveThe editor checkpoints roughly once a minute so an unexpected quit does not lose work. This is crash insurance, not a substitute for S — auto-save does not write over your file.
Change detectionIf a file is modified by another program while it is open, Textulon offers to reload it. It compares contents rather than just the timestamp, so a touch that did not change anything does not prompt. Esc dismisses the prompt.
Spell checkStandard macOS continuous spell checking is available in the source editor, with the usual right-click correction menu.
Revert AllRestores the editor to the contents last opened or last saved, after a confirmation. Disabled when nothing has changed.
Window placementTextulon remembers the last window size, but launch placement prefers the screen holding the focused window, or the mouse's screen. The saved position is used as a fallback only when it is still fully visible.
Stay on TopP, or the titlebar pin glyph, floats the window above others. The preference persists across runs.
Find / ReplaceF opens Textulon's source find panel with literal or regex search, case and whole-word options, context rows, jump, replace current, and replace all.
Word wrap / line numbersW cycles wrap through three states — full width, column (wraps at the Wrap column set in Settings, for reading prose on a wide window), and off. The column state is skipped when no wrap column is configured. L toggles line numbers.
Get InfoI opens a panel with the file's size, dates, encoding, and line/word/character counts — plus an editable Document Properties section for formats that can carry them.
ZoomSource and render panes carry separate persisted zoom levels. + / - / 0 route to whichever pane has focus, so a dense Mermaid diagram and a comfortable source font can coexist.
Current lineThe cursor line can be highlighted with a configurable background from Settings.
Rectangular selection drag selects a source rectangle. Textulon-to-Textulon copy/cut/paste preserves columns by using a private pasteboard payload plus normal plain text.
Match actionsM jumps to the mate; M selects the block. Matching covers brackets, XML/HTML/SVG tags, Markdown heading sections, Mermaid subgraph/end, and settings sections, while skipping common strings/comments lexically.
Undo historyZ shows Textulon's visible edit history. Typing groups close after about four seconds of inactivity; transforms, snippets, paste, cut/delete, and line edits become separate records.
Snippets and colourMarkdown/HTML toolbar buttons wrap selected text. SVG snippets include document scaffolds, shapes, and transform stubs; Shell snippets cover common rc/profile patterns. The shared colour picker inserts colour text in HTML, Mermaid, and SVG.
Image data URIsHTML, Markdown, and Mermaid modes can import an image file as Base64 data:image/... source text. Select an HTML image tag, Markdown image, or selected URI text and choose Export Selected Data URI Image to write it back to a file. Mermaid support is source-level because diagram rendering of data-URI images depends on Mermaid syntax and settings.

Structured Navigation

JSON and XML modes are not just pretty-printers. Textulon parses the source into a tree whose rows map back to source ranges. Click a node to select the matching text in the editor, or use the Query tab to run a JSONPath / XPath expression.

FeatureDetails
TreeCollapsible JSON objects/arrays and XML elements/text nodes. Parse errors show the failing offset.
QueryJSONPath supports exact paths, quoted keys, array indexes, wildcards, and descendant searches. XPath supports absolute paths, positional predicates, attribute equality, and namespace-prefixed names.
Path rowThe source header shows a clickable Path: chain. Click Path: or press F to jump by expression; click a segment to jump to that ancestor.
Titlebar shortcutThe fx glyph opens the same JSONPath / XPath prompt without leaving the mouse on the editor.

Document Properties

Markdown, Mermaid, HTML, and SVG documents can carry six document-level properties — Title, Author, Date, Description, Keywords, and Copyright. Textulon reads them from the file itself and writes them back to it. There is no sidecar database and no hidden index: the document is the storage.

FormatWhere the properties live
Markdown, Mermaid YAML front matter — a ------ block at the very top of the file. This is the Jekyll / Hugo / Pandoc convention rather than part of CommonMark, so Textulon hides the block in the Markdown preview instead of drawing a horizontal rule and dumping the raw keys. Mermaid parses the same block natively, and a title: there is drawn as the diagram's title.
HTML <title> plus <meta name="author">, date, description, keywords, and copyright inside <head>. A <head> is created if the document has none.
SVG <title> (which doubles as the graphic's accessible name) and <desc> as direct children of the root <svg>. SVG defines no element for author, date, keywords, or rights, so those go into a <metadata> block as Dublin Core inside RDF — the form Inkscape and the SVG spec's own examples use. A <title> nested inside a <g> is that group's tooltip, not the document's title, and is left alone.
Everything else JSON, XML, plain text, the source-language modes, hex/binary, and Parseo-backed documents have nowhere to put properties, so the section is hidden for them. Properties can still be typed directly into an exported PDF.

Three places use them:

Round-trips conservatively. Rewriting a properties block preserves unknown keys, comments, and blank lines, and clearing a field removes only that field rather than rewriting the whole block. Textulon will not reformat metadata you did not ask it to touch.

Properties survive conversion

Because all four formats hold the same six fields, converting between them carries the properties across instead of dropping them:

Writing macOS metadata

Both Get Info and the PDF export sheet offer Write macOS metadata, which sets the file's Spotlight extended attributes — Title, Authors, Description, Finder comment, Keywords, Copyright, and Creation date — so the values are findable with Spotlight and mdls. The Description is also written to the Finder comment, the one field macOS's own Get Info window will display for a plain text file.

This is one-way, deliberately. Textulon writes these attributes but never reads them back; the document text stays the source of truth. Extended attributes survive a Finder copy, cp -p, and Time Machine, but are lost through git, zip, email attachments, and most non-Apple filesystems — which is exactly why the file's own front matter or <head> is the durable copy.

Mermaid → SVG

A Mermaid diagram is a rendering instruction, not a picture — it needs a Mermaid runtime to become one. Converting to SVG turns it into a plain vector image that any browser, editor, or design tool can open on its own.

CommandScopeResult
Convert Mermaid to SVG
File menu, or the preview context menu
A whole standalone .mmd / .mermaid document. Opens the rendered diagram as a new, unsaved <basename>.svg tab. The original file is untouched until you save the new one.
Convert Mermaid Selection to SVG
Editor context menu
One embedded diagram inside a Markdown or HTML document. Replaces that block in place with the rendered SVG, leaving the rest of the document alone.
The selection command only appears when it will work. Textulon validates the exact selected text by rendering it off-screen first; if the selection is not a complete, valid Mermaid block, the menu item is hidden rather than offered and then failing. Select the block exactly — fence to fence.

Front matter properties on the Mermaid source are carried into the generated SVG — see Properties survive conversion.

Rendered HTML Export

Textulon can export rendered views as standalone HTML. The commands live in the File menu and are intentionally limited to modes where the rendered output adds something beyond saving source text.

CommandUseOutput
Export Rendered HTML (SVG)… Preferred for Markdown and Mermaid portability. Textulon renders the preview, waits for Mermaid, strips renderer scripts, and saves HTML with Mermaid diagrams embedded as inline SVG.
Export Rendered HTML (PNG Images)… Compatibility path for apps that do not import inline SVG reliably, such as Microsoft Word's HTML importer. Rendered Mermaid SVGs are rasterized to 3x PNG data-URI images while keeping their normal display size.
JSON / XML tree export Share a navigable structured view instead of just pretty source. A standalone collapsible HTML tree with Expand All / Collapse All controls.
Export Pageless PDF… Save rendered output without artificial page cuts. One continuous PDF page for Markdown, Mermaid, HTML, JSON tree, or XML tree output — no page breaks driven through text lines, tables, or diagrams. Meant for screen and PDF reading rather than paper pagination.

The Pageless PDF options sheet

Export Pageless PDF opens a real options sheet rather than a single width prompt:

OptionWhat it does
Export widthThe page width the renderer lays out against. Use a wider value for large Mermaid diagrams. Remembered between exports.
Document propertiesTitle, Author, Date, Description, Keywords, and Copyright, pre-filled from the document. These are written into the PDF's /Info dictionary — the fields Preview's Tools → Show Inspector shows. The author value is remembered as a default for later exports.
Save properties back to the documentWrites any edits you made in the sheet back into the source document's front matter or <head>, so the PDF and the source do not drift apart.
Write macOS metadataOptional, one-way Spotlight write. See Writing macOS metadata.
Why two HTML exports? Inline SVG is scalable and faithful, so it is the default for Markdown and Mermaid. PNG data URI export is larger and less editable, but it is useful when another application cannot import inline SVG.

Textulon does not export Pretty JSON/XML as HTML; use the json.beautify or xml.beautify transforms when you want formatted source text.

Copying Rendered Content

Copying rendered Markdown or HTML is not one operation, because receiving apps disagree about what a rich-text clipboard should contain. Textulon offers both behaviours instead of picking one and losing the other:

Copy modeWhat lands on the clipboardWhen to use it
HTML Only (default) Only public.html, in OneNote-compatible Office HTML. RTF, plain text, and WebKit extras are deliberately omitted. OneNote for Mac. It accepts rich content only when this is the sole type on the clipboard — any additional type makes it fall back to plain text.
Multi-Variant WebKit's native copy: HTML, RTF, plain text, and a web archive. Most other applications. Broader compatibility, but breaks OneNote paste.

C (or Edit → Copy Special…) shows the picker on each copy so you can choose per-copy. It opens focused on the other mode — press Space to switch and Enter to confirm, or just Enter to keep the current default. A "Save to Settings" checkbox (on by default) updates the persistent default, which can also be set in Settings → Default Copy Mode.

The source pane always copies plain text. C from the editor gives you the raw source regardless of copy mode; copy from the render pane when you want rich output.
Large saved HTML files copy whole. When a saved HTML file is loaded directly from disk and has not been edited, a render-pane copy takes the entire document regardless of what is selected in the preview. Mapping a preview selection back to source requires the full source text in memory, which is skipped for large files. To copy one region out of a large HTML file, select it in the source editor instead.

Hex View

Hex view is a source-pane toggle, not a mode. Turn it on with H or the header switch to inspect bytes while the Render pane stays mode-native. A JSON file can show raw bytes on top and the JSON tree underneath.

Hex capabilityDetails
Byte grid8-digit address column, grouped hex bytes, printable ASCII column, and 0x10 / 0x20 / 0x30 / 0x40 byte row widths.
EditingE edits a byte at an offset, I inserts a 0x00 byte, and deletes the selected byte.
FindF accepts addresses (0x100), hex patterns (48 65 6C), quoted text, or plain UTF-8 text.
Binary files.bin, .dat, and .raw open as bytes. Files above 32 MiB warn before loading; files above 256 MiB are refused.
SavingWhen Hex view is active, Save writes bytes verbatim instead of round-tripping through UTF-8.

Binary Metadata (Parseo)

Textulon embeds Parseo to inspect binary file metadata — MP3/ID3 tags, MP4 atoms, PNG chunks, PDF info, MPEG-TS packets, OneNote sections, and other bundled formats. Open a supported file from Finder or O; Parseo auto-detects the format when possible.

ASCII Mode

ASCII mode runs RoboCore's string extractor against the current source. For binary files it scans the loaded bytes; for normal text it scans the editor's UTF-8 bytes. The same engine powers the ascii transform, the Stream Deck action, and the {ascii} robo keys token.

ControlUse
Min lengthDrop strings shorter than the chosen length. Default is 6.
Alpha %Require a percentage of letters, digits, and common punctuation. Set to 0 to disable.
UTF-8 / UTF-16Accept multi-byte UTF-8 and ASCII-range UTF-16 BE pairs.
OffsetsPrefix each result with the starting byte offset.
Suppress / Ignore / SearchStrip matching tokens, reject chosen characters as ASCII, or keep only strings containing a case-insensitive search term.

Transforms

Every transform is implemented once, in RoboCore’s TransformEngine, and exposed via the shared TransformRegistry. The Transform dropdown is ranked: in Auto mode, the most applicable transform is offered first.

idWhat it does
rot13ROT-13 — reciprocal letter substitution.
rot18ROT-13 for letters + ROT-5 for digits (reciprocal).
json.beautifyJSON beautify (sorted keys).
json.minifyJSON minify.
xml.beautifyXML beautify via XMLDocument.
html.escapeEncode &, <, >, ", '.
html.unescapeDecode named & numeric HTML entities.
url.encodeRFC 3986 percent-encoding.
url.decodePercent-decoding.
base64.encodeBase64 encode (UTF-8 input).
base64.decodeBase64 decode → UTF-8.
lines.trimTrim each line.
lines.sortSort lines (localized standard compare).
lines.uniqueUnique lines, preserving first-seen order.
lines.sortUniqueSort + unique.
lines.toLFConvert line endings to LF (Unix).
lines.toCRLFConvert line endings to CRLF (Windows).
text.uppercaseUppercase the whole text.
text.lowercaseLowercase the whole text.
text.trimTrim leading/trailing whitespace from the whole text.
url.removeQueryStrip everything from ? onward (URL host+path).
asciiExtract ASCII / UTF-8 / UTF-16 BE strings from binary noise.
autoDetect the content kind and apply the best-fit transform.
Ranked, and filtered to what can actually run. The Transform dropdown only offers transforms applicable to the current contents or selection: JSON Beautify requires valid JSON/JSONC, XML Beautify requires well-formed XML, and the line-sorting transforms require more than one line. applies the selected transform to the selection if there is one — the button relabels itself Apply to Selection — otherwise to the whole editor.
Line endings. Textulon's editors never introduce CRLF on their own; a file keeps the line endings it arrived with. Use lines.toLF / lines.toCRLF when you deliberately want to change them — for example, normalising a file that came off a Windows share before committing it.
Curly-brace forms. Every transform above is also addressable from robo keys and the Keyboard Shortcut action by its {token} form — for example {json beautify}, {url decode}, {uppercase}, {remove query}, and {ascii}. Run robo keys --help for the complete token list.

Invocation

Textulon accepts a small CLI surface so that any front-end can launch it. The simplest form:

Textulon [<path> | --file <path> | -i <path>]     # autodetect mode by extension+contents
        [--input-file <path>  | --input-stdin]   # plain text in, --mode controls mode
        [--payload-file <path>| --payload-stdin] # full JSON payload (§5)
        [--mode auto|plain|json|jsonl|xml|markdown|mermaid|svg|html|robokeys|hex|ascii]
        [--output-behavior copyOnly|pasteBack|viewOnly]
        [--preferred-transform <id>]
        [--on-top yes|no]
        [--ephemeral-session | -es]              # separate throwaway instance
        [--version | -v]
        [--help | -h]

Already running? A CLI file open is forwarded into the existing Textulon instance instead of launching a second one. Use --ephemeral-session (or -es) when you deliberately want a separate, temporary instance whose tabs are neither restored nor saved.

Input vs. payload. The --input-* flags pass just the text; everything else (mode, output behaviour, etc.) comes from other CLI flags. The --payload-* flags pass an entire §5 JSON document — with sourceText, mode, outputBehavior, originatingAppBundleId, originFrame, etc. — which is what an automation front-end (Stream Deck, Raycast, robo) sends when it wants to carry origin metadata. A bare <path>, --file, and -i are the friendly forms: load a file and let Textulon pick the mode.

In the running app:

ShortcutAction
OOpen File — asks before discarding unsaved changes.
SSave back to the originating file (Save As if none).
SSave As — extension defaults from the current Mode.
NNew untitled tab.
IGet Info — file details plus editable Document Properties.
Tab / TabSwitch to next / previous document tab.
TReopen the most recently closed tab, walking back through the session's closed tabs.
P / PPrint rendered/default view / Print Source. The standard macOS print dialog includes PDF export.
WIn the editor: dismiss the find panel or Query tab first; close the window only when no overlay is up. In Help/Settings: close that window.
EscCloses the Help window. In the editor: dismisses the find panel or Query tab; otherwise no-op.
QQuit Textulon, regardless of which overlay is up.
FFind / Replace. In source text: literal or regex search with context rows, jump, replace current, and replace all. In Hex view: byte-aware find.
GFind next in the active find target.
JJump to line.
FJSONPath / XPath jump prompt in JSON or XML mode.
M / MJump to match / select matching block.
Apply Transform — operates on the selection if any; in RoboKeys mode, runs the keys command into the scratch pane.
B / IIn Markdown and HTML modes, insert Bold / Italic at the cursor (or wrap the selection).
] / [Indent / outdent selected or current source lines.
ZShow visible undo history and roll back to a selected record.
dragRectangular source selection; copy/cut/paste preserves columns inside Textulon.
? / F1 / ?Open the Help window.
PToggle Stay on Top (Pin).
MFocus the Mode picker (then Space / arrows to change).
TFocus the Transform picker (then Space / arrows to change).
IOpen the Snippets menu (Markdown, HTML, and other snippet-capable modes only); then to insert, or for a sub-group item.
H / TEnter Hex view / return to Text view.
EHex: Edit Byte at Offset.
I / Hex: Insert Byte / Delete Byte.
R / 0Toggle Hide Raw / force-show the source pane.
RImmersive Preview — drop the preview chrome as well as the source pane.
\ / \Toggle the split view off / switch the split between stacked and side-by-side.
W / LCycle source word wrap (full width → column → off) / toggle line numbers.
CCopy Special — choose HTML Only or Multi-Variant for this copy. See Copying Rendered Content.
+ / = / - / 0Zoom in, zoom out, or reset to actual size. Source and render panes hold separate persisted zoom levels; the shortcut routes to the focused pane.

A richer JSON payload mirrors §5 of the original spec:

{
  "sourceText": "<p>Hi</p>",
  "mode": "html",
  "preferredTransform": "html.escape",
  "outputBehavior": "copyOnly",
  "originatingAppBundleId": "com.apple.Safari",
  "originatingWindowTitle": "Some tab",
  "originFrame": { "x": 100, "y": 200, "width": 500, "height": 30 }
}

On Copy or Paste Back, the final text is placed on the system pasteboard and printed to stdout (newline-terminated). On Cancel, Textulon exits with code 1 and leaves the clipboard alone.

Screenshots

Main window — JSON beautify

Textulon showing JSON beautify on messy.json

Markdown — rendered preview

Textulon rendering Markdown

HTML — rendered preview

Textulon rendering HTML in preview

Structured JSON — tree, path row, and query

Textulon showing JSON tree, path row, and query results

XML — XPath navigation

Textulon showing XML tree and XPath navigation

Hex view — byte grid and byte-aware find

Textulon showing Hex view with byte grid and find

Privacy

Textulon is designed to handle secrets safely:

Command API

When Textulon is running it exposes a small newline-delimited JSON API over a Unix-domain socket. Mac-A-Tron’s Textulon Context Button action uses this to read state and run direct Textulon commands without relying on keyboard focus.

ItemValue
Socket~/Library/Application Support/Textulon/textulon.sock
TransportUnix-domain socket, request/response JSON, one JSON object per line.
State keysmode, effectiveMode, dirty, diskStored, hasSelection, selectionLength, supportsPreview, hideRaw, splitOrientation, hexView, parseoFile, file name/path.
{"type":"getState","id":"1"}
{"type":"getCommands","id":"2"}
{"type":"runCommand","id":"3","command":"toggleHideRaw"}
{"type":"runCommand","id":"4","command":"insertSnippet","args":{"name":"Bold","mode":"markdown"}}
If Textulon is not running, the socket is absent. Stream Deck context buttons show a red warning badge rather than trying to send stale keyboard shortcuts.

Textulon Context Button setup

Install or update the Mac-A-Tron Stream Deck plug-in, then add Textulon Context Button from the Mac-A-Tron category. Each key holds ordered rules keyed on mode, dirty state, disk-backed state, and selection state; the first matching rule supplies the button title and command.

For example, one key can show Save when the active Textulon document is dirty, Reload when it is clean and disk-backed, and Apply otherwise. Commands go through the local socket above; keyboard shortcuts remain available as a fallback rule type.

The starter profile intentionally leaves Textulon Context action images unset — Stream Deck only lets the plug-in draw dynamic mode, dirty, and disconnected states when the profile has not supplied a custom key image.

TextuLite for Windows

TextuLite for Windows is the Windows edition of the same tool. It is a .NET application that ships the Swift RoboCore engine and the shared renderers beside it, so users install neither .NET nor Swift separately. Native builds exist for x64 and ARM64, as an installer or a portable ZIP, with in-app updates. Downloads →

The engine is genuinely the same code, not a port. Transforms, the Markdown / Mermaid / SVG renderer, the JSON/XML tree, the document-properties codec, and the Mermaid-to-SVG extraction are shared modules compiled for Windows. A document rendered or transformed here matches the macOS result rather than approximating it.

What it has

AreaOn Windows
EditingTabs with session restore (including persistent untitled-document names), Find/Replace with regex, case, and whole-word, Go to Line, word wrap, line numbers, current-line highlighting, zoom, and drag-and-drop open. CtrlShiftT reopens the last closed file. The close-disposition policy matches macOS.
Modes and previewsAuto-detected or forced: Markdown, Mermaid, SVG, HTML, JSON, JSON Lines, XML, and the source-language modes, with the structured tree and its Expand All / Collapse All controls.
Document propertiesFull parity — a Document Properties… editor plus the Insert Document Properties command, across Markdown, Mermaid, HTML, and SVG, with the same conservative round-trip behaviour and the same PDF /Info stamping.
Mermaid → SVGBoth forms — whole document from the Export menu, and Convert Mermaid Selection to SVG from the editor context menu, with the same off-screen validation that hides the command when the selection is not valid Mermaid.
ExportRendered HTML, PDF, Pageless PDF at a chosen width with the document's properties, and Print.
MHTML importOpens .mht / .mhtml archives into standalone HTML with resources inlined, the same as macOS.
ThemeFollows the Windows theme, or force light/dark.
TransformsThe complete RoboCore set, ranked for the current content, including lines.toLF / lines.toCRLF.

What it does not have

These are macOS-only, either because they depend on macOS frameworks or because they exist to serve the Stream Deck pipeline:

Missing on WindowsWhy
Hex viewNot implemented on Windows.
Binary metadata (Parseo)Parseo is embedded in the macOS app only.
ASCII modeThe ascii transform still exists; the dedicated live-filter mode does not.
RoboKeys modeDepends on the macOS robo keystroke pipeline and Accessibility permission.
Command API socket and Stream Deck context buttonsThe socket API exists to drive Textulon from Mac-A-Tron. Windows Stream Deck automation is WinTronic's job.
Stay on Top, rectangular selection, the full snippet library, Copy SpecialNot ported. The Insert Document Properties command is the one snippet that crossed over.

TextuLite for iOS

TextuLite on iPhone and iPad is not a smaller Textulon window — it is a different shape of the same tool. On the desktop, text arrives from a Stream Deck key or a pipe. On iOS it arrives from the share sheet, so the app is built around receiving a document, showing it usefully, and handing something back — not around a long-lived editing session with tabs and a split window.

The share extension is the front door. Share from any app and pick TextuLite, and the extension opens with the content already loaded — no round trip through Files or the clipboard. Close dismisses it without touching the clipboard; Copy, Save, and Share are always explicit actions you take, never side effects of viewing something.

The distinct viewer

In place of the desktop's source/render split, TextuLite has a three-way segmented view. Only the segments that make sense for the current content appear:

ViewWhat it shows
EditThe source, plus the transform picker ranked for the current content — the same engine and the same ranking as the desktop.
RenderedMarkdown, HTML, SVG, or Mermaid, via the shared TextulonRender module. When a transform has produced a result, the preview shows that result rather than the original.
TreeAn expandable JSON or XML structure, via the shared TextulonTree module. This segment appears only while the content actually parses, and clamps back to Edit when it stops being structured.

Safari shares import the live page

Sharing from Safari imports what is on screen: the selected text when there is a selection, otherwise the displayed page's live HTML or visible text, handed over by Safari itself. TextuLite does not re-download the page from its URL. That means a page behind a login, a form you have filled in, or content rendered by script comes across as you actually see it — and it means no network request leaves the device.

Getting text in and results out

InOut
Share from another app · Open File from Files · Paste the clipboard, which opens a new document in its most useful view Copy source or result to the clipboard · Save a named file to Files · Share a named file onward · Replace Source to feed the result back into the editor and apply another transform

Rendered exports and Mermaid

The Rendered view can save or share a standalone HTML document or a PDF. Mermaid diagrams are completed as inline SVG before the HTML is written, so the recipient does not need TextuLite — or any Mermaid runtime — to see them.

Mermaid conversion works the same way it does on the desktop: Convert to SVG opens a standalone Mermaid document as a new unsaved <basename>.svg document, and selecting one exact Mermaid block in Source offers Convert Mermaid Selection to SVG, which replaces that block in place. The command appears only once the selection has been validated by an off-screen render.

What it opens

Plain text, Markdown, HTML, JSON, JSON Lines, XML, SVG, Mermaid, YAML, TOML, CSV/TSV, logs, configuration files, scripts, style sheets, and common programming-language source files. Text encodings: UTF-8, UTF-16, UTF-32, Windows-1252, ISO Latin-1, and Mac OS Roman. Binary files are rejected — there is no Hex view, no ASCII extraction mode, and no Parseo on iOS.

What it deliberately does not have

No tabs or session restore, no split window, no Hex or Parseo or ASCII or RoboKeys modes, no command socket, and no Stream Deck integration. These are desktop concerns; porting them would make a worse phone app, not a more capable one.

Privacy. Transformation and rendering run entirely on the device. TextuLite collects no analytics and uploads no document contents. Privacy policy →