VML (VoxMark Language) is a declarative programming language for building interactive web applications and documents.
Project description
VML — VoxMark Language
Version: 1.0.0
VML (VoxMark Language) is a declarative programming language for building interactive web applications and documents. It combines component-based UI, data binding, conditional rendering, scoped styling, reusable object definitions, routing, and compilation to HTML, CSS, and WebAssembly through the VoxMark compiler.
Table of Contents
- Features
- Installation
- Quick Start
- Syntax Basics
- Variables
- Classes
- Widget Reference
- Multi-file Projects
- CLI Reference
- Quick Reference Table
- License
Features
- Component-based UI — 50+ built-in widgets covering content, layout, typography, navigation, media, forms, control flow, styling, and data visualisation.
- Data binding — reusable variables (
::var) and object-style classes (::class_def) referenced anywhere with@name/@Name.prop. - Conditional rendering — client-side
::if/::else/::ifelsewidgets evaluated from JavaScript expressions. - Scoped styling — inline styles, CSS classes, scoped
:::cssblocks, and CSS custom properties via::cssvar. - Routing — hash-based single-page router (
::router) with auto-generated navigation. - Compilation targets — HTML, CSS, and WebAssembly (WASM), produced by the VoxMark compiler.
- Multi-file projects — compose full sites from separate
.vmlfiles using::include.
Installation
Install VoxMark Language using the Python Package Manager (pip):
pip install voxmark
Quick Start
1. Create a project
voxmark init my-project
2. Change into the project directory
cd my-project
3. Build the project
voxmark compiler --build index.vml -o build/
Optionally set a title:
voxmark compiler --build index.vml -o build/ --title My-Project
4. Preview the build
Open build/index.html directly, or run the VoxMark server:
voxmark server build/
Choose a port:
voxmark server --port 7080 build/
Bind a host and port:
voxmark server --host 0.0.0.0 --port 7080 build/
Syntax Basics
Widget Anatomy
::cmd[args]{body} ← double colon — most widgets
:::cmd[args]{body} ← triple colon — block/layout/structural widgets
| Part | Required | Description |
|---|---|---|
:: or ::: |
yes | Widget opener. Triple-colon widgets are typically block-level layout containers. |
cmd |
yes | The widget name (case-insensitive). |
[args] |
depends | Pipe-separated arguments: [arg1|arg2|arg3]. Some widgets require them, some don't. |
{body} |
depends | Body content. Supports Markdown, nested ::widgets, and @var references. Omit for bodyless widgets. |
Argument Separator |
Multiple arguments inside [...] are separated by |:
::button[primary|https://example.com]{Visit}
::icon[github|1.2em|#7c6dff]{🐙}
::badge[stable|#22c55e]
Body Segment Separator ||
Some widgets accept multiple body segments separated by || — for example, tabs (one segment per tab panel), columns (one segment per column), and the router (one segment per page):
::tab[Python|Rust]{
python
||
rust
}
Bodyless Widgets
Some widgets take only [args] and no {body}. These never have curly braces:
::badge[v1.0|#7c6dff]
::progress[72/100|Completion]
::divider[]
::spacer[2em]
Nesting
VML widgets nest freely inside any {body}:
::card[Example]{
Status: ::badge[OK|#22c55e]
Press ::kbd{Ctrl+S} to save.
::alert[info]{Nested alert inside a card body.}
}
Markdown Inside Bodies
Widget bodies are fully Markdown-aware. Any Markdown that Mistune supports (CommonMark + GFM) works inside a body:
::callout[💡]{
**Bold**, *italic*, `inline code`, [links](https://example.com),
and even fenced code blocks all work here.
}
Exception: the body of
::var,:::css,:::cssplay,::math,::kbd,::chart,::embed,::svg,:::demo,::if,::else,::ifelse,::router,::footer,::input,::checkbox,::select, and::cssvaris treated as raw text (not Markdown) because those widgets need their body content unmodified.
Variables
Define a reusable text value once and reference it anywhere with @name.
::var[author]{Divyanshu Sinha}
::var[version]{2.0.0}
::var[repo]{https://github.com/DivyanshuSinha136}
Built by **@author** — VoxMark v@version.
[Source code](@repo)
Rules:
- Variable names are case-sensitive identifiers.
- Values can contain any text including spaces and special characters.
- Re-defining a variable replaces its previous value.
@namereferences are resolved after all widget rendering, so a variable defined anywhere in the document is available everywhere.
Classes
Define an object-style namespace of named properties and reference them with dot notation throughout the document.
::class_def[School]{
name:Springfield Elementary
||address:742 Evergreen Terrace, Springfield
||founded:1953
||principal:Principal Skinner
||website:https://springfield-elem.edu
}
The school is **@School.name**, founded in @School.founded.
Address: @School.address
Principal: @School.principal — [Website](@School.website)
Syntax rules:
| Rule | Detail |
|---|---|
| Body format | Each ||-separated segment is key:value |
| Key | Any word characters: [A-Za-z0-9_]+ |
| Value | Everything after the first : (may contain colons, spaces, URLs, etc.) |
| ClassName | Convention: start with a capital letter. re.sub(r'[^\w]', '', name) for safety. |
| Unknown ref | @School.unknown is left unchanged — safe to use conditionally |
| Re-definition | Replaces all properties of that class |
| Visibility | Emits an invisible <meta class="vml-class-def"> tag — no visible output |
Dot-ref vs plain-var:
| Syntax | Resolves |
|---|---|
@School.name |
Class property (resolved first) |
@author |
Simple var (no dot — resolved after class refs) |
Class properties work inside any widget body, argument, or plain text.
Widget Reference
Content Widgets
| Widget | Description |
|---|---|
| Card | A rounded content card with an optional title bar. ::card[title]{body} |
| Alert | A status alert box with four styles: success, info, warn, error. ::alert[type]{msg} |
| Callout | A highlighted callout / tip box with a leading emoji icon. ::callout[emoji]{body} |
| Tabs | A tabbed panel. Labels go in [args], content segments in {body} separated by ||. ::tab[A|B]{seg0||seg1} |
| Timeline | A vertical event timeline. Each item is Title::Description, segments separated by ||. ::timeline{...} |
| Progress Bar | An animated progress bar with an optional label. ::progress[value/max|label] (bodyless) |
| Badge | An inline pill badge. ::badge[label|colour] (bodyless) |
| Collapsible | A <details>/<summary> collapsible section. Uses triple-colon. :::fold[summary]{body} |
| Tooltip | An inline element with a hover tooltip. ::tooltip[tip]{anchor text} |
Layout Widgets
| Widget | Description |
|---|---|
| Columns | A responsive multi-column layout. ::columns[ratio]{col0||col1||...} |
| Grid | A CSS grid container. Uses triple-colon. :::grid[cols|gap]{cell0||cell1||...} |
| Flex | A CSS flex container. Uses triple-colon. :::flex[gap|align-items|justify-content|flex-wrap]{item0||item1} |
| Hero | A full-width hero section with configurable background and alignment. Uses triple-colon. :::hero[bg|align|min-height]{body} |
| Section | A full-width content section with optional title and subtitle. Uses triple-colon. :::section[title|subtitle|align]{body} |
| Box | A styled container box with configurable variant. Uses triple-colon. :::box[variant]{body} |
| Div | A generic <div> wrapper with custom class, id, or style. Uses triple-colon. :::div[class|id|style]{body} |
| Center / Right | Align block content. ::center{content} / ::right{content} |
| Spacer / Divider | Add whitespace or a horizontal rule. ::spacer[size] / ::divider[style] (both bodyless) |
Typography Widgets
| Widget | Description |
|---|---|
| Highlight | Highlighted / marked text with colour variants (yellow, green, pink, blue, orange, purple). ::hl[colour]{text} |
| Styled Bold | Bold text with special rendering styles: gradient, outline, shadow, neon, stamp, underline, mono. ::b[style]{text} |
| Color | Inline text with a custom colour. ::color[hex]{text} |
| Glow | Glowing text with a custom glow colour. ::glow[colour]{text} |
| Keyboard Key | Render keyboard shortcuts as styled <kbd> elements. ::kbd{key combo} |
| Math | Render a LaTeX / KaTeX expression. ::math{LaTeX} (KaTeX loaded automatically in --build output) |
Navigation Widgets
| Widget | Description |
|---|---|
| Sidebar | A slide-in navigation sidebar with a floating toggle button. Uses triple-colon. :::sidebar[Title|side|width]{nav segments} |
| Router | A hash-based single-page router with auto-generated tab navigation. ::router[default_page]{page_id:Title::body||...} |
| Footer | A site footer with an optional multi-column layout and copyright bar. ::footer[copyright|accent]{col0||col1||...} |
Media & Embed Widgets
| Widget | Description |
|---|---|
| Icon | An inline SVG icon from the built-in icon set (209 icons across brand, arrows, status, media, files, editing, social, coding, UI, communication, people, nature, and misc categories). ::icon[name|size|colour]{fallback} |
| Icon Card | A card with a large icon, title, and description text. ::iconcard[icon|title]{description} |
| Inline SVG | Render raw, sanitised SVG directly in the document. Uses triple-colon. :::svg{markup} |
| Embed | Embed external content: youtube, github, spotify, codepen, map, pdf, audio, image, site. ::embed[type]{src} |
Form Widgets
| Widget | Description |
|---|---|
| Input | A styled form input field. Supports text, email, password, number, url, tel, search, date, datetime-local, time, range, color, file. ::input[type|placeholder|id|default|min|max|step]{label} |
| Checkbox | A styled checkbox with a label. ::checkbox[id|value|checked]{label} |
| Select | A styled dropdown select. Options as Value:Label pairs. ::select[id|default|label]{opt0|opt1|...} |
| Button | A styled button / link with styles primary, secondary, ghost, outline, danger, success. ::button[style|action]{label} |
| Button Group | A group of buttons rendered inline. Uses triple-colon. :::btngroup{btn0||btn1||...} |
Control Flow Widgets
All control-flow widgets are client-side — the condition is evaluated in the browser using a sanitised JS expression, evaluated once at page load.
| Widget | Description |
|---|---|
| If | Show content when a JavaScript expression is truthy. ::if[condition]{body} |
| Else | Show content when the same expression is falsy. Pair with a preceding ::if. ::else[condition]{body} |
| If / Else (inline) | Compact inline branch showing one of two segments based on a condition. ::ifelse[condition]{then||else} |
CSS Widgets
| Widget | Description |
|---|---|
| Scoped CSS Block | Define raw CSS that applies to the current document scope. Uses triple-colon. :::css{raw CSS} |
| CSS Playground | A live split-editor showing CSS and HTML side-by-side with instant preview. Uses triple-colon. :::cssplay{css||html} |
| CSS Variable | Define a CSS custom property (--variable) for the document scope. ::cssvar[--name]{value} |
| Inline Style | Apply arbitrary inline CSS to a block of content. ::style[css-properties]{body} |
| CSS Class | Apply one or more CSS class names to a block of content. ::class[names]{body} |
Data Visualisation
| Widget | Description |
|---|---|
| Chart | A Chart.js chart powered by a JSON payload. Types: bar, line, pie, doughnut, radar, polarArea. ::chart[type]{json} (Chart.js loaded automatically in --build output) |
| Graph | A rich server-side data graph with built-in themes. ::graph[type|title|palette|height]{json} |
| Graph Playground | An interactive graph editor. Uses triple-colon. :::graphplay{json} |
| Demo Sandbox | A live, editable HTML/CSS sandbox rendered in a sandboxed iframe. Uses triple-colon. :::demo{html} |
Build-time Widgets
| Widget | Description |
|---|---|
| Include | Read another .vml, .md, or .txt file from disk and inline its fully-rendered output. Path is relative to the current source file. Processed at compile time by voxmark compiler --build. Circular includes are detected and skipped; missing files emit an HTML comment instead of an error; nesting is supported up to 16 levels deep. In the live editor (/api/render), includes render as empty placeholders since there is no filesystem context. |
Multi-file Projects
Combine ::include with ::router and :::sidebar to build multi-page sites from separate files:
my-site/
index.vml
sections/
home.vml
about.vml
contact.vml
index.vml:
:::sidebar[My Site]{Home::#home||About::#about||Contact::#contact}
::router[home]{
home:Home::
||about:About::
||contact:Contact::
}
::footer[© 2025]{Built with **VoxMark**}
Build with:
voxmark compiler --build index.vml -o build/
CLI Reference
voxmark compiler --build input -o build-dir
| Flag | Description |
|---|---|
--build |
Required. Compile to HTML + CSS + WASM + JS loader. |
input |
Source .vml / .md file or directory. |
-o, --output |
Output directory (default: build/). |
--title |
Override HTML title. |
--no-wasm |
Skip .wasm / loader.js output. |
--no-wat |
Skip debug .wat output. |
Additional commands:
voxmark server [--port PORT] [--host HOST] [--open]
voxmark lint [input]
voxmark format [input] [-o output] [-i]
voxmark ast [input] [--json]
voxmark init [directory]
voxmark watch [input] -o build-dir [--port PORT]
voxmark version
Global flags: --verbose / -v · --quiet / -q · --no-color
Quick Reference Table
| Widget | Syntax | Triple? | Bodyless? |
|---|---|---|---|
| Alert | ::alert[type]{msg} |
— | — |
| Badge | ::badge[label|colour] |
— | ✓ |
| Bold styled | ::b[style]{text} |
— | — |
| Box | :::box[variant]{content} |
✓ | — |
| Button | ::button[style|href]{label} |
— | — |
| Button group | :::btngroup{::button||…} |
✓ | — |
| Callout | ::callout[emoji]{text} |
— | — |
| Card | ::card[title]{body} |
— | — |
| Center | ::center{content} |
— | — |
| Chart | ::chart[type]{json} |
— | — |
| Checkbox | ::checkbox[id|val|checked]{label} |
— | — |
| Class (apply) | ::class[names]{body} |
— | — |
| Class (define) | ::class_def[Name]{k:v||k:v} |
— | — |
| Color | ::color[#hex]{text} |
— | — |
| Columns | ::columns[1:1]{col||col} |
— | — |
| CSS block | :::css{…} |
✓ | — |
| CSS class | ::class[names]{content} |
— | — |
| CSS playground | :::cssplay{css||html} |
✓ | — |
| CSS variable | ::cssvar[--name]{value} |
— | — |
| Demo sandbox | :::demo{html} |
✓ | — |
| Div | :::div[class|id|style]{content} |
✓ | — |
| Divider | ::divider[style] |
— | ✓ |
| Else | ::else[cond]{content} |
— | — |
| Embed | ::embed[type]{url} |
— | — |
| Flex | :::flex[gap|…]{item||item} |
✓ | — |
| Fold | :::fold[title]{body} |
✓ | — |
| Footer | ::footer[copy|accent]{col||col} |
— | — |
| Glow | ::glow[colour]{text} |
— | — |
| Graph | ::graph[type|title|palette|h]{json} |
— | — |
| Graph playground | :::graphplay{json} |
✓ | — |
| Grid | :::grid[cols|gap]{cell||cell} |
✓ | — |
| Hero | :::hero[bg|align|h]{content} |
✓ | — |
| Highlight | ::hl[colour]{text} |
— | — |
| Icon | ::icon[name|size|colour]{fallback} |
— | — |
| Icon card | ::iconcard[icon|title]{desc} |
— | — |
| If | ::if[cond]{content} |
— | — |
| If/else | ::ifelse[cond]{then||else} |
— | — |
| Include | `` | — | ✓ |
| Input | ::input[type|…]{label} |
— | — |
| Keyboard key | ::kbd{key combo} |
— | — |
| Math | ::math{LaTeX} |
— | — |
| Progress | ::progress[val/max|label] |
— | ✓ |
| Right-align | ::right{content} |
— | — |
| Router | ::router[default]{id:Title::body||…} |
— | — |
| Section | :::section[title|sub|align]{body} |
✓ | — |
| Select | ::select[id|default|label]{opts} |
— | — |
| Sidebar | :::sidebar[title|side|w]{nav} |
✓ | — |
| Spacer | ::spacer[size] |
— | ✓ |
| Style (inline) | ::style[css]{content} |
— | — |
| SVG | :::svg{} |
✓ | — |
| Tab | ::tab[A|B]{body||body} |
— | — |
| Timeline | ::timeline{Title::Desc||…} |
— | — |
| Tooltip | ::tooltip[tip text]{anchor} |
— | — |
| Variable | ::var[name]{value} |
— | — |
VoxMark Language View after compilation.
License
VoxMark Language (VML) — created and maintained by Divyanshu Sinha (@DivyanshuSinha136) and license under MIT.
Other Links
Homepage: https://github.com/DivyanshuSinha136/VoxMark-Language/ Repository: https://github.com/DivyanshuSinha136/VoxMark-Language Documentation: https://divyanshusinha136.github.io/VoxMark-Language/ Issues: https://github.com/DivyanshuSinha136/VoxMark-Language/issues/
Try Now VoxMark Language (VML).
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file voxmark-1.0.0.tar.gz.
File metadata
- Download URL: voxmark-1.0.0.tar.gz
- Upload date:
- Size: 111.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
48f04e9cebdd949db3544ff1399b9b3378b4b47be6fa3f76c7105e5225acc9c1
|
|
| MD5 |
839d9958b737746f647c2f3a08873597
|
|
| BLAKE2b-256 |
0424c42ce882168583b06517de6bd68d3cfdd214f832e93f56063b827887f25b
|
File details
Details for the file voxmark-1.0.0-py3-none-any.whl.
File metadata
- Download URL: voxmark-1.0.0-py3-none-any.whl
- Upload date:
- Size: 107.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f8c56b9e02cb70103eb52eb32b77e73ad26369ddcf26889df8404b3b807b0579
|
|
| MD5 |
742fdeb90b54c9dc790fb644042b69bc
|
|
| BLAKE2b-256 |
60b3ebae8975ffc081896068a60da44f95cd699071fc882a69695139d97fac41
|