on v2026.4.26151538 help sign in
htmlang/README.md
215 lines 7.5 kB history raw
1# htmlang
3A minimalist layout language inspired by [elm-ui](https://package.elm-lang.org/packages/mdgriffith/elm-ui/latest/) that compiles to static HTML.
5`@` means structure. Bare lines mean content. No CSS required.
7## Example
9```
10@page My Site
11@let primary #3b82f6
13@fn card $title
14 @el [padding 20, background white, rounded 8, border 1 #e5e7eb, hover:border 1 $primary, transition all 0.15s ease]
15 @text [bold] $title
16 @children
18@column [max-width 800, center-x, padding 40, spacing 20]
19 @text [bold, size 32] Hello
21 @paragraph
22 Built with {@text [bold, color $primary] htmlang}.
24 @row [wrap, spacing 10]
25 @card [title Simple]
26 Write layouts without CSS
27 @card [title Fast]
28 Compiles to a single HTML file
29```
31Compiles to a self-contained `.html` file with flexbox layout and generated CSS classes. No JavaScript, no external dependencies.
33## Install
35```
36cargo install --path .
37```
39## Usage
41Everyday workflow:
43```
44htmlang init # scaffold a new project
45htmlang page.hl # compile page.hl -> page.html
46htmlang --watch page.hl # recompile on change
47htmlang serve . # dev server with live reload
48htmlang serve --https --cert cert.pem --key key.pem .
49htmlang fmt page.hl # format a file in place
50htmlang check page.hl # parse only, report diagnostics
51```
53More commands (run with `--help` for flags):
55| Command | Purpose |
56|--------------------|------------------------------------------------|
57| `build [dir]` | Compile every `.hl` under a directory |
58| `watch [path]` | Watch mode without a server |
59| `serve [path]` | Dev server with live reload (`--https` ready) |
60| `convert file.html`| Convert HTML back to htmlang |
61| `new name` | Scaffold a new page from a template |
62| `components` | List `@fn` / `@component` definitions |
63| `deps file.hl` | Print the include / import graph |
64| `dead-code [dir]` | Report unused `@fn` / `@let` / `@define` |
65| `feed [dir]` | Generate an Atom feed from `@article` pages |
66| `sitemap [dir]` | Generate `sitemap.xml` |
67| `lint [path]` | Run warnings-only checks, optional JSON output |
68| `stats file.hl` | Compile-time statistics |
69| `preview file.hl` | Open a one-off preview |
70| `diff a.hl b.hl` | Diff two files at the AST level |
71| `export file.hl` | Export to plain HTML (`--format pdf` planned) |
72| `repl` | Interactive REPL for expressions |
73| `deploy` | Preset-driven deploy helper |
74| `playground` | Write a self-contained playground HTML |
75| `clean [dir]` | Remove generated `.html` files |
76| `upgrade` | Apply mechanical migrations to out-of-date `.hl` |
77| `outline file.hl` | Print the document tree |
78| `explain CODE` | Longer explanation of a diagnostic code |
79| `lsp` | Launch the language server (stdio) |
80| `benchmark [dir]` | Measure parse / codegen timing |
82## Editor support
84A VS Code extension with syntax highlighting and LSP integration is available in [`editors/vscode`](editors/vscode). The language server (`htmlang-lsp`) provides diagnostics, completions, and hover documentation.
86## Language overview
88### Elements
90| Element | Purpose |
91|--------------|------------------------------|
92| `@row` | Horizontal flex layout |
93| `@column` | Vertical flex layout |
94| `@el` | Generic container |
95| `@text` | Styled inline text |
96| `@paragraph` | Flowing text with inline elements |
97| `@image` | Image |
98| `@link` | Anchor |
99| `@raw` | Verbatim HTML escape hatch |
100| `@form` | Form container |
101| `@details` | Disclosure widget |
102| `@summary` | Summary for `@details` |
103| `@blockquote`| Block quotation |
104| `@cite` | Citation reference |
105| `@code` | Inline code (monospace) |
106| `@pre` | Preformatted text |
107| `@hr` | Horizontal rule / divider |
108| `@figure` | Figure with caption |
109| `@figcaption`| Caption for `@figure` |
110| `@progress` | Progress bar |
111| `@meter` | Meter/gauge |
113### Layout attributes
115```
116@row [spacing 20] -- gap between children
117@row [gap-x 10, gap-y 20] -- separate horizontal/vertical gaps
118@el [padding 20] -- uniform padding (also padding-x, padding-y)
119@el [width fill] -- take remaining space (also width 200, width shrink)
120@el [center-x] -- center horizontally (also align-left, align-right)
121@el [overflow hidden] -- overflow behavior (hidden, scroll, auto)
122```
124### Style attributes
126```
127@el [background #3b82f6, color white, rounded 8, border 1 #e5e7eb]
128@text [bold, italic, underline, size 18, font Inter]
129@el [opacity 0.5, cursor pointer, transition all 0.15s ease]
130@el [shadow 0 2px 4px rgba(0,0,0,0.1)]
131@paragraph [text-align center, line-height 1.5]
132```
134### Positioning
136```
137@el [position relative]
138 @el [position absolute, z-index 10]
139 Overlay content
140```
142### Pseudo-states and media prefixes
144Prefix any style attribute with `hover:`, `active:`, or `focus:`:
146```
147@el [background #3b82f6, hover:background #2563eb, active:background #1d4ed8]
148```
150Use `dark:` for dark mode and `print:` for print styles:
152```
153@el [background white, dark:background #1a1a2e, print:display none]
154```
156### Variables and defines
158```
159@let primary #3b82f6 -- simple variable, used as $primary
160@let greeting "Hello $name" -- quoted string interpolation
161@define card [padding 20, rounded 8] -- attribute bundle, used as [$card]
162```
164### Functions
166```
167@fn button $label
168 @el [padding 12, background $primary, rounded 8]
169 @text [color white, bold] $label
170 @children -- slot for caller's children
172@button [label Click me]
173```
175### File includes
177```
178@include header.hl -- inline another .hl file
179```
181### Multi-line attributes
183Attribute lists can span multiple lines:
185```
186@el [
187 padding 20,
188 background white,
189 rounded 8,
190 shadow 0 2px 4px rgba(0,0,0,0.1)
192 Content here
193```
195### Other features
197- `--` comments
198- `{@text [bold] inline}` elements in text
199- `@el [attrs] > @link url` single-child chaining
200- `[padding 20]` bare attributes as implicit `@el`
201- `@raw """..."""` for embedding arbitrary HTML/CSS/JS
202- `@image [inline] logo.svg` inlines SVG content
203- `@each $name, $url in Home /, About /about` destructuring
204- `@let large = $base * 2` computed variables
205- `[grid-template-areas "header main", grid-area header]` named grid areas
206- `[animate fade-in 0.3s ease]` animation shorthand
207- `[view-transition-name hero]` View Transitions API
208- `[has(.active):background blue]` `:has()` pseudo-selector
209- `@slot header` / `@slot content` named slots in `@fn`
210- `@theme` design tokens as runtime CSS custom properties
211- VS Code snippets for common patterns
213## Documentation
215See [DESIGN.md](DESIGN.md) for the full language specification.