20. CLI
lini [options] <input.lini>
lini fmt [--check] [--stdout] <input.lini>
lini desugar <input.lini>
lini highlight <input.lini>
lini highlight --css
lini serve [--port N] [--static] [--theme NAME|FILE|A/B] [PATH]
lini theme [NAME]
| Flag | Meaning |
|---|---|
-o FILE | Output path (default stdout). |
--format svg|html | svg (default) or HTML wrapper. |
--check | The full compile, no artefact written — the same errors and warnings, the same exit code. (fmt --check is that subcommand’s own flag — below.) |
--port N | lini serve only — the preview port (default 7700). |
--json | Emit diagnostics as a JSON document (stable codes, severity, spans, related spans, machine-applicable fixes — SPEC 21) instead of SVG; the tooling/LSP form. Exit 1 if any error-level diagnostic fired. |
--theme NAME|FILE|A/B | A built-in theme (dark, high-contrast, …), a CSS file of --lini-* overrides, or a light/dark pair (light/dark). |
--no-warn / --strict | Silence warnings / treat them as errors — under every form (--check, --json, SVG) alike. |
--static | A self-contained SVG that renders identically anywhere (SPEC 10.6, SPEC 18). |
--embed-font | Embed the used bundled family × weights as base64 @font-face — browser-only (SPEC 18). Both font flags need the default-on font build feature; name-only output never does. |
--watch | Recompile on every input change (requires -o). |
-h, -V | Help / version. |
lini - reads stdin (filename <stdin> in errors). lini serve runs a local live
preview (default port 7700): a .lini file live-reloads that one file; a directory (or
no path → the current directory) opens the playground — pick, edit, and render any
.lini file beneath it in the browser. A served compile reads image assets
(SPEC 7) under the same boundary that confines the file list: the served
root — a file target’s root is its directory — and an asset path escaping it is a
compile error; a plain lini compile is unbounded (you compile your own file). lini theme lists the built-in themes;
lini theme NAME prints one as a --lini-* CSS file — a ready starting point for
your own (light-dark() colours, the font commented out).
lini fmt reformats to canonical style — 2-space indent, key: value;
declarations grouped on one line, a style-only node collapsed onto its head line when it
fits (|box#api| { fill: red }), a lone label trailing the head (|box#api| "API"),
children one per line in [ ], table cells padded into aligned columns — a styled
cell ("Apple" { color: --red-ink }) keeps its block and its row steps out of the
aligned grid; unstyled rows stay aligned — a draw:
value broken before each move() and wrapped between calls at the column limit
(continuations indented, so a profile reads as its subpaths), comments and
blank lines preserved — a comment opening its line stays leading, one
following code stays on that code’s line, since it annotates the statement it
trails. --check exits 1 if it would change anything; --stdout writes
instead of rewriting.
lini desugar prints the file fully lowered to primitives — the Desugar pass
(SPEC 19) that is the engine’s true input — so the lowered form
re-renders byte-identically. A chart’s or sequence’s type desugars here (a |chart|
is a |block| wearing .lini-chart); its geometric primitive subtree is a layout-phase
artefact (SPEC 19), like a routed link’s geometry. A
teaching/debugging view; prints to stdout, never rewrites, comments not preserved.
A |table|’s header band and its per-column alignment are likewise not
shown: both are decided from the resolved columns: (SPEC 8),
which any tier of the cascade can set, so they are a cascade-phase artefact —
the structure desugar does show (each cell in its |cell|, an entity’s label
as its title |header|) is the part that
needs no column count.
lini highlight prints the file as <span class="lini-tok-…"> HTML — the
one syntax highlighter, at a shell. It is lexical: it never parses, so a
file mid-edit still colours and the only failure left is I/O; and it is
byte-preserving — strip the tags, undo the four entity escapes, and the
source comes back exactly, which is what lets a host drop the output into a
<pre> and trust the listing. Newlines pass through as newlines (a caller that
cannot carry one rewrites them itself). The classes are the token kinds, under
the reserved prefix like every other name Lini writes into a host document
(SPEC 18, SPEC 23): lini-tok- +
comment · string · number · const · keyword · type · type-user ·
prop · prop-user · var · op · class · punct. The words behind them
come from the same source the editor grammars do (SPEC 22), so a
new type or property colours the moment it has a ledger row.
lini highlight --css prints the token palette those spans wear —
nine --lini-tok-* role variables as light-dark() pairs, then the rules that
paint the thirteen classes from them — so the markup and its colours come from
one place and a listing reads the same in a book, on a site, and in the
playground. The role defaults are layered (@layer lini.defaults), so a host
re-tints one by redeclaring its variable with no !important; the sheet sets no
color-scheme, leaving the light/dark choice to whatever the host has set on
the listing’s ancestors.
The same scanner is lini::highlight_html to a crate and highlight() to the
browser build; a host that can link Rust should, and this subcommand is for the
one that cannot.
Exit codes: 0 success · 1 parse/resolution error or --check reformat needed · 2 I/O ·
3 invalid CLI.