voxmark 1.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- voxmark-1.0.0/LICENSE.txt +21 -0
- voxmark-1.0.0/PKG-INFO +539 -0
- voxmark-1.0.0/README.md +506 -0
- voxmark-1.0.0/pyproject.toml +57 -0
- voxmark-1.0.0/setup.cfg +4 -0
- voxmark-1.0.0/voxmark/__init__.py +23 -0
- voxmark-1.0.0/voxmark/__main__.py +846 -0
- voxmark-1.0.0/voxmark/app.py +152 -0
- voxmark-1.0.0/voxmark/compiler.py +956 -0
- voxmark-1.0.0/voxmark/examples.py +450 -0
- voxmark-1.0.0/voxmark/firewall.py +291 -0
- voxmark-1.0.0/voxmark/language.py +2774 -0
- voxmark-1.0.0/voxmark/lexer.py +324 -0
- voxmark-1.0.0/voxmark/parser.py +363 -0
- voxmark-1.0.0/voxmark/renderer.py +482 -0
- voxmark-1.0.0/voxmark/style.css +2071 -0
- voxmark-1.0.0/voxmark/wasm_encoder.py +401 -0
- voxmark-1.0.0/voxmark.egg-info/PKG-INFO +539 -0
- voxmark-1.0.0/voxmark.egg-info/SOURCES.txt +21 -0
- voxmark-1.0.0/voxmark.egg-info/dependency_links.txt +1 -0
- voxmark-1.0.0/voxmark.egg-info/entry_points.txt +2 -0
- voxmark-1.0.0/voxmark.egg-info/requires.txt +9 -0
- voxmark-1.0.0/voxmark.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Divyanshu Sinha
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
voxmark-1.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,539 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: voxmark
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: VML (VoxMark Language) is a declarative programming language for building interactive web applications and documents.
|
|
5
|
+
Author-email: Divyanshu Sinha <divyanshu.sinha631@gmail.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/DivyanshuSinha136/VoxMark-Language/
|
|
8
|
+
Project-URL: Repository, https://github.com/DivyanshuSinha136/VoxMark-Language/
|
|
9
|
+
Project-URL: Documentation, https://divyanshusinha136.github.io/VoxMark-Language/
|
|
10
|
+
Project-URL: Issues, https://github.com/DivyanshuSinha136/VoxMark-Language/issues
|
|
11
|
+
Keywords: markdown,vml,document,engine,flask,interactive,web,webdevelopment,opensource
|
|
12
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Topic :: Text Processing :: Markup
|
|
20
|
+
Classifier: Framework :: Flask
|
|
21
|
+
Requires-Python: >=3.10
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
License-File: LICENSE.txt
|
|
24
|
+
Requires-Dist: flask>=3.0
|
|
25
|
+
Requires-Dist: mistune>=3.0
|
|
26
|
+
Requires-Dist: pygments>=2.17
|
|
27
|
+
Requires-Dist: waitress>=3.0
|
|
28
|
+
Provides-Extra: dev
|
|
29
|
+
Requires-Dist: pytest; extra == "dev"
|
|
30
|
+
Requires-Dist: black; extra == "dev"
|
|
31
|
+
Requires-Dist: ruff; extra == "dev"
|
|
32
|
+
Dynamic: license-file
|
|
33
|
+
|
|
34
|
+

|
|
35
|
+
|
|
36
|
+
# VML — VoxMark Language
|
|
37
|
+
|
|
38
|
+
**Version:** 1.0.0
|
|
39
|
+
|
|
40
|
+
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**.
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## Table of Contents
|
|
45
|
+
|
|
46
|
+
- [Features](#features)
|
|
47
|
+
- [Installation](#installation)
|
|
48
|
+
- [Quick Start](#quick-start)
|
|
49
|
+
- [Syntax Basics](#syntax-basics)
|
|
50
|
+
- [Widget Anatomy](#widget-anatomy)
|
|
51
|
+
- [Argument Separator `|`](#argument-separator-)
|
|
52
|
+
- [Body Segment Separator `||`](#body-segment-separator-)
|
|
53
|
+
- [Bodyless Widgets](#bodyless-widgets)
|
|
54
|
+
- [Nesting](#nesting)
|
|
55
|
+
- [Markdown Inside Bodies](#markdown-inside-bodies)
|
|
56
|
+
- [Variables](#variables)
|
|
57
|
+
- [Classes](#classes)
|
|
58
|
+
- [Widget Reference](#widget-reference)
|
|
59
|
+
- [Content Widgets](#content-widgets)
|
|
60
|
+
- [Layout Widgets](#layout-widgets)
|
|
61
|
+
- [Typography Widgets](#typography-widgets)
|
|
62
|
+
- [Navigation Widgets](#navigation-widgets)
|
|
63
|
+
- [Media & Embed Widgets](#media--embed-widgets)
|
|
64
|
+
- [Form Widgets](#form-widgets)
|
|
65
|
+
- [Control Flow Widgets](#control-flow-widgets)
|
|
66
|
+
- [CSS Widgets](#css-widgets)
|
|
67
|
+
- [Data Visualisation](#data-visualisation)
|
|
68
|
+
- [Build-time Widgets](#build-time-widgets)
|
|
69
|
+
- [Multi-file Projects](#multi-file-projects)
|
|
70
|
+
- [CLI Reference](#cli-reference)
|
|
71
|
+
- [Quick Reference Table](#quick-reference-table)
|
|
72
|
+
- [License](#license)
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## Features
|
|
77
|
+
|
|
78
|
+
- **Component-based UI** — 50+ built-in widgets covering content, layout, typography, navigation, media, forms, control flow, styling, and data visualisation.
|
|
79
|
+
- **Data binding** — reusable variables (`::var`) and object-style classes (`::class_def`) referenced anywhere with `@name` / `@Name.prop`.
|
|
80
|
+
- **Conditional rendering** — client-side `::if` / `::else` / `::ifelse` widgets evaluated from JavaScript expressions.
|
|
81
|
+
- **Scoped styling** — inline styles, CSS classes, scoped `:::css` blocks, and CSS custom properties via `::cssvar`.
|
|
82
|
+
- **Routing** — hash-based single-page router (`::router`) with auto-generated navigation.
|
|
83
|
+
- **Compilation targets** — HTML, CSS, and WebAssembly (WASM), produced by the VoxMark compiler.
|
|
84
|
+
- **Multi-file projects** — compose full sites from separate `.vml` files using `::include`.
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## Installation
|
|
89
|
+
|
|
90
|
+
Install VoxMark Language using the Python Package Manager (pip):
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
pip install voxmark
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## Quick Start
|
|
99
|
+
|
|
100
|
+
**1. Create a project**
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
voxmark init my-project
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
**2. Change into the project directory**
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
cd my-project
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
**3. Build the project**
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
voxmark compiler --build index.vml -o build/
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Optionally set a title:
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
voxmark compiler --build index.vml -o build/ --title My-Project
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
**4. Preview the build**
|
|
125
|
+
|
|
126
|
+
Open `build/index.html` directly, or run the VoxMark server:
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
voxmark server build/
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Choose a port:
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
voxmark server --port 7080 build/
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Bind a host and port:
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
voxmark server --host 0.0.0.0 --port 7080 build/
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## Syntax Basics
|
|
147
|
+
|
|
148
|
+
### Widget Anatomy
|
|
149
|
+
|
|
150
|
+
```
|
|
151
|
+
::cmd[args]{body} ← double colon — most widgets
|
|
152
|
+
:::cmd[args]{body} ← triple colon — block/layout/structural widgets
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
| Part | Required | Description |
|
|
156
|
+
|---|---|---|
|
|
157
|
+
| `::` or `:::` | yes | Widget opener. Triple-colon widgets are typically block-level layout containers. |
|
|
158
|
+
| `cmd` | yes | The widget name (case-insensitive). |
|
|
159
|
+
| `[args]` | depends | Pipe-separated arguments: `[arg1\|arg2\|arg3]`. Some widgets require them, some don't. |
|
|
160
|
+
| `{body}` | depends | Body content. Supports Markdown, nested `::widgets`, and `@var` references. Omit for bodyless widgets. |
|
|
161
|
+
|
|
162
|
+
### Argument Separator `|`
|
|
163
|
+
|
|
164
|
+
Multiple arguments inside `[...]` are separated by `|`:
|
|
165
|
+
|
|
166
|
+
```
|
|
167
|
+
::button[primary|https://example.com]{Visit}
|
|
168
|
+
::icon[github|1.2em|#7c6dff]{🐙}
|
|
169
|
+
::badge[stable|#22c55e]
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### Body Segment Separator `||`
|
|
173
|
+
|
|
174
|
+
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):
|
|
175
|
+
|
|
176
|
+
```
|
|
177
|
+
::tab[Python|Rust]{
|
|
178
|
+
python
|
|
179
|
+
||
|
|
180
|
+
rust
|
|
181
|
+
}
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### Bodyless Widgets
|
|
185
|
+
|
|
186
|
+
Some widgets take only `[args]` and no `{body}`. These never have curly braces:
|
|
187
|
+
|
|
188
|
+
```
|
|
189
|
+
::badge[v1.0|#7c6dff]
|
|
190
|
+
::progress[72/100|Completion]
|
|
191
|
+
::divider[]
|
|
192
|
+
::spacer[2em]
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### Nesting
|
|
196
|
+
|
|
197
|
+
VML widgets nest freely inside any `{body}`:
|
|
198
|
+
|
|
199
|
+
```
|
|
200
|
+
::card[Example]{
|
|
201
|
+
Status: ::badge[OK|#22c55e]
|
|
202
|
+
Press ::kbd{Ctrl+S} to save.
|
|
203
|
+
::alert[info]{Nested alert inside a card body.}
|
|
204
|
+
}
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### Markdown Inside Bodies
|
|
208
|
+
|
|
209
|
+
Widget bodies are fully Markdown-aware. Any Markdown that Mistune supports (CommonMark + GFM) works inside a body:
|
|
210
|
+
|
|
211
|
+
```
|
|
212
|
+
::callout[💡]{
|
|
213
|
+
**Bold**, *italic*, `inline code`, [links](https://example.com),
|
|
214
|
+
and even fenced code blocks all work here.
|
|
215
|
+
}
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
> **Exception:** the body of `::var`, `:::css`, `:::cssplay`, `::math`, `::kbd`, `::chart`, `::embed`, `::svg`, `:::demo`, `::if`, `::else`, `::ifelse`, `::router`, `::footer`, `::input`, `::checkbox`, `::select`, and `::cssvar` is treated as raw text (not Markdown) because those widgets need their body content unmodified.
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
222
|
+
## Variables
|
|
223
|
+
|
|
224
|
+
Define a reusable text value once and reference it anywhere with `@name`.
|
|
225
|
+
|
|
226
|
+
```
|
|
227
|
+
::var[author]{Divyanshu Sinha}
|
|
228
|
+
::var[version]{2.0.0}
|
|
229
|
+
::var[repo]{https://github.com/DivyanshuSinha136}
|
|
230
|
+
|
|
231
|
+
Built by **@author** — VoxMark v@version.
|
|
232
|
+
[Source code](@repo)
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
**Rules:**
|
|
236
|
+
- Variable names are case-sensitive identifiers.
|
|
237
|
+
- Values can contain any text including spaces and special characters.
|
|
238
|
+
- Re-defining a variable replaces its previous value.
|
|
239
|
+
- `@name` references are resolved after all widget rendering, so a variable defined anywhere in the document is available everywhere.
|
|
240
|
+
|
|
241
|
+
---
|
|
242
|
+
|
|
243
|
+
## Classes
|
|
244
|
+
|
|
245
|
+
Define an object-style namespace of named properties and reference them with dot notation throughout the document.
|
|
246
|
+
|
|
247
|
+
```
|
|
248
|
+
::class_def[School]{
|
|
249
|
+
name:Springfield Elementary
|
|
250
|
+
||address:742 Evergreen Terrace, Springfield
|
|
251
|
+
||founded:1953
|
|
252
|
+
||principal:Principal Skinner
|
|
253
|
+
||website:https://springfield-elem.edu
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
The school is **@School.name**, founded in @School.founded.
|
|
257
|
+
Address: @School.address
|
|
258
|
+
Principal: @School.principal — [Website](@School.website)
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
**Syntax rules:**
|
|
262
|
+
|
|
263
|
+
| Rule | Detail |
|
|
264
|
+
|---|---|
|
|
265
|
+
| Body format | Each `\|\|`-separated segment is `key:value` |
|
|
266
|
+
| Key | Any word characters: `[A-Za-z0-9_]+` |
|
|
267
|
+
| Value | Everything after the first `:` (may contain colons, spaces, URLs, etc.) |
|
|
268
|
+
| ClassName | Convention: start with a capital letter. `re.sub(r'[^\w]', '', name)` for safety. |
|
|
269
|
+
| Unknown ref | `@School.unknown` is left unchanged — safe to use conditionally |
|
|
270
|
+
| Re-definition | Replaces all properties of that class |
|
|
271
|
+
| Visibility | Emits an invisible `<meta class="vml-class-def">` tag — no visible output |
|
|
272
|
+
|
|
273
|
+
**Dot-ref vs plain-var:**
|
|
274
|
+
|
|
275
|
+
| Syntax | Resolves |
|
|
276
|
+
|---|---|
|
|
277
|
+
| `@School.name` | Class property (resolved first) |
|
|
278
|
+
| `@author` | Simple var (no dot — resolved after class refs) |
|
|
279
|
+
|
|
280
|
+
Class properties work inside any widget body, argument, or plain text.
|
|
281
|
+
|
|
282
|
+
---
|
|
283
|
+
|
|
284
|
+
## Widget Reference
|
|
285
|
+
|
|
286
|
+
### Content Widgets
|
|
287
|
+
|
|
288
|
+
| Widget | Description |
|
|
289
|
+
|---|---|
|
|
290
|
+
| **Card** | A rounded content card with an optional title bar. `::card[title]{body}` |
|
|
291
|
+
| **Alert** | A status alert box with four styles: `success`, `info`, `warn`, `error`. `::alert[type]{msg}` |
|
|
292
|
+
| **Callout** | A highlighted callout / tip box with a leading emoji icon. `::callout[emoji]{body}` |
|
|
293
|
+
| **Tabs** | A tabbed panel. Labels go in `[args]`, content segments in `{body}` separated by `\|\|`. `::tab[A\|B]{seg0\|\|seg1}` |
|
|
294
|
+
| **Timeline** | A vertical event timeline. Each item is `Title::Description`, segments separated by `\|\|`. `::timeline{...}` |
|
|
295
|
+
| **Progress Bar** | An animated progress bar with an optional label. `::progress[value/max\|label]` (bodyless) |
|
|
296
|
+
| **Badge** | An inline pill badge. `::badge[label\|colour]` (bodyless) |
|
|
297
|
+
| **Collapsible** | A `<details>`/`<summary>` collapsible section. Uses triple-colon. `:::fold[summary]{body}` |
|
|
298
|
+
| **Tooltip** | An inline element with a hover tooltip. `::tooltip[tip]{anchor text}` |
|
|
299
|
+
|
|
300
|
+
### Layout Widgets
|
|
301
|
+
|
|
302
|
+
| Widget | Description |
|
|
303
|
+
|---|---|
|
|
304
|
+
| **Columns** | A responsive multi-column layout. `::columns[ratio]{col0\|\|col1\|\|...}` |
|
|
305
|
+
| **Grid** | A CSS grid container. Uses triple-colon. `:::grid[cols\|gap]{cell0\|\|cell1\|\|...}` |
|
|
306
|
+
| **Flex** | A CSS flex container. Uses triple-colon. `:::flex[gap\|align-items\|justify-content\|flex-wrap]{item0\|\|item1}` |
|
|
307
|
+
| **Hero** | A full-width hero section with configurable background and alignment. Uses triple-colon. `:::hero[bg\|align\|min-height]{body}` |
|
|
308
|
+
| **Section** | A full-width content section with optional title and subtitle. Uses triple-colon. `:::section[title\|subtitle\|align]{body}` |
|
|
309
|
+
| **Box** | A styled container box with configurable variant. Uses triple-colon. `:::box[variant]{body}` |
|
|
310
|
+
| **Div** | A generic `<div>` wrapper with custom class, id, or style. Uses triple-colon. `:::div[class\|id\|style]{body}` |
|
|
311
|
+
| **Center / Right** | Align block content. `::center{content}` / `::right{content}` |
|
|
312
|
+
| **Spacer / Divider** | Add whitespace or a horizontal rule. `::spacer[size]` / `::divider[style]` (both bodyless) |
|
|
313
|
+
|
|
314
|
+
### Typography Widgets
|
|
315
|
+
|
|
316
|
+
| Widget | Description |
|
|
317
|
+
|---|---|
|
|
318
|
+
| **Highlight** | Highlighted / marked text with colour variants (`yellow`, `green`, `pink`, `blue`, `orange`, `purple`). `::hl[colour]{text}` |
|
|
319
|
+
| **Styled Bold** | Bold text with special rendering styles: `gradient`, `outline`, `shadow`, `neon`, `stamp`, `underline`, `mono`. `::b[style]{text}` |
|
|
320
|
+
| **Color** | Inline text with a custom colour. `::color[hex]{text}` |
|
|
321
|
+
| **Glow** | Glowing text with a custom glow colour. `::glow[colour]{text}` |
|
|
322
|
+
| **Keyboard Key** | Render keyboard shortcuts as styled `<kbd>` elements. `::kbd{key combo}` |
|
|
323
|
+
| **Math** | Render a LaTeX / KaTeX expression. `::math{LaTeX}` (KaTeX loaded automatically in `--build` output) |
|
|
324
|
+
|
|
325
|
+
### Navigation Widgets
|
|
326
|
+
|
|
327
|
+
| Widget | Description |
|
|
328
|
+
|---|---|
|
|
329
|
+
| **Sidebar** | A slide-in navigation sidebar with a floating toggle button. Uses triple-colon. `:::sidebar[Title\|side\|width]{nav segments}` |
|
|
330
|
+
| **Router** | A hash-based single-page router with auto-generated tab navigation. `::router[default_page]{page_id:Title::body\|\|...}` |
|
|
331
|
+
| **Footer** | A site footer with an optional multi-column layout and copyright bar. `::footer[copyright\|accent]{col0\|\|col1\|\|...}` |
|
|
332
|
+
|
|
333
|
+
### Media & Embed Widgets
|
|
334
|
+
|
|
335
|
+
| Widget | Description |
|
|
336
|
+
|---|---|
|
|
337
|
+
| **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}` |
|
|
338
|
+
| **Icon Card** | A card with a large icon, title, and description text. `::iconcard[icon\|title]{description}` |
|
|
339
|
+
| **Inline SVG** | Render raw, sanitised SVG directly in the document. Uses triple-colon. `:::svg{markup}` |
|
|
340
|
+
| **Embed** | Embed external content: `youtube`, `github`, `spotify`, `codepen`, `map`, `pdf`, `audio`, `image`, `site`. `::embed[type]{src}` |
|
|
341
|
+
|
|
342
|
+
### Form Widgets
|
|
343
|
+
|
|
344
|
+
| Widget | Description |
|
|
345
|
+
|---|---|
|
|
346
|
+
| **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}` |
|
|
347
|
+
| **Checkbox** | A styled checkbox with a label. `::checkbox[id\|value\|checked]{label}` |
|
|
348
|
+
| **Select** | A styled dropdown select. Options as `Value:Label` pairs. `::select[id\|default\|label]{opt0\|opt1\|...}` |
|
|
349
|
+
| **Button** | A styled button / link with styles `primary`, `secondary`, `ghost`, `outline`, `danger`, `success`. `::button[style\|action]{label}` |
|
|
350
|
+
| **Button Group** | A group of buttons rendered inline. Uses triple-colon. `:::btngroup{btn0\|\|btn1\|\|...}` |
|
|
351
|
+
|
|
352
|
+
### Control Flow Widgets
|
|
353
|
+
|
|
354
|
+
> All control-flow widgets are client-side — the condition is evaluated in the browser using a sanitised JS expression, evaluated once at page load.
|
|
355
|
+
|
|
356
|
+
| Widget | Description |
|
|
357
|
+
|---|---|
|
|
358
|
+
| **If** | Show content when a JavaScript expression is truthy. `::if[condition]{body}` |
|
|
359
|
+
| **Else** | Show content when the same expression is falsy. Pair with a preceding `::if`. `::else[condition]{body}` |
|
|
360
|
+
| **If / Else (inline)** | Compact inline branch showing one of two segments based on a condition. `::ifelse[condition]{then\|\|else}` |
|
|
361
|
+
|
|
362
|
+
### CSS Widgets
|
|
363
|
+
|
|
364
|
+
| Widget | Description |
|
|
365
|
+
|---|---|
|
|
366
|
+
| **Scoped CSS Block** | Define raw CSS that applies to the current document scope. Uses triple-colon. `:::css{raw CSS}` |
|
|
367
|
+
| **CSS Playground** | A live split-editor showing CSS and HTML side-by-side with instant preview. Uses triple-colon. `:::cssplay{css\|\|html}` |
|
|
368
|
+
| **CSS Variable** | Define a CSS custom property (`--variable`) for the document scope. `::cssvar[--name]{value}` |
|
|
369
|
+
| **Inline Style** | Apply arbitrary inline CSS to a block of content. `::style[css-properties]{body}` |
|
|
370
|
+
| **CSS Class** | Apply one or more CSS class names to a block of content. `::class[names]{body}` |
|
|
371
|
+
|
|
372
|
+
### Data Visualisation
|
|
373
|
+
|
|
374
|
+
| Widget | Description |
|
|
375
|
+
|---|---|
|
|
376
|
+
| **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) |
|
|
377
|
+
| **Graph** | A rich server-side data graph with built-in themes. `::graph[type\|title\|palette\|height]{json}` |
|
|
378
|
+
| **Graph Playground** | An interactive graph editor. Uses triple-colon. `:::graphplay{json}` |
|
|
379
|
+
| **Demo Sandbox** | A live, editable HTML/CSS sandbox rendered in a sandboxed iframe. Uses triple-colon. `:::demo{html}` |
|
|
380
|
+
|
|
381
|
+
### Build-time Widgets
|
|
382
|
+
|
|
383
|
+
| Widget | Description |
|
|
384
|
+
|---|---|
|
|
385
|
+
| **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. |
|
|
386
|
+
|
|
387
|
+
---
|
|
388
|
+
|
|
389
|
+
## Multi-file Projects
|
|
390
|
+
|
|
391
|
+
Combine `::include` with `::router` and `:::sidebar` to build multi-page sites from separate files:
|
|
392
|
+
|
|
393
|
+
```
|
|
394
|
+
my-site/
|
|
395
|
+
index.vml
|
|
396
|
+
sections/
|
|
397
|
+
home.vml
|
|
398
|
+
about.vml
|
|
399
|
+
contact.vml
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
`index.vml`:
|
|
403
|
+
|
|
404
|
+
```
|
|
405
|
+
:::sidebar[My Site]{Home::#home||About::#about||Contact::#contact}
|
|
406
|
+
|
|
407
|
+
::router[home]{
|
|
408
|
+
home:Home::
|
|
409
|
+
||about:About::
|
|
410
|
+
||contact:Contact::
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
::footer[© 2025]{Built with **VoxMark**}
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
Build with:
|
|
417
|
+
|
|
418
|
+
```bash
|
|
419
|
+
voxmark compiler --build index.vml -o build/
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
---
|
|
423
|
+
|
|
424
|
+
## CLI Reference
|
|
425
|
+
|
|
426
|
+
```bash
|
|
427
|
+
voxmark compiler --build input -o build-dir
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
| Flag | Description |
|
|
431
|
+
|---|---|
|
|
432
|
+
| `--build` | Required. Compile to HTML + CSS + WASM + JS loader. |
|
|
433
|
+
| `input` | Source `.vml` / `.md` file or directory. |
|
|
434
|
+
| `-o`, `--output` | Output directory (default: `build/`). |
|
|
435
|
+
| `--title` | Override HTML title. |
|
|
436
|
+
| `--no-wasm` | Skip `.wasm` / `loader.js` output. |
|
|
437
|
+
| `--no-wat` | Skip debug `.wat` output. |
|
|
438
|
+
|
|
439
|
+
Additional commands:
|
|
440
|
+
|
|
441
|
+
```bash
|
|
442
|
+
voxmark server [--port PORT] [--host HOST] [--open]
|
|
443
|
+
voxmark lint [input]
|
|
444
|
+
voxmark format [input] [-o output] [-i]
|
|
445
|
+
voxmark ast [input] [--json]
|
|
446
|
+
voxmark init [directory]
|
|
447
|
+
voxmark watch [input] -o build-dir [--port PORT]
|
|
448
|
+
voxmark version
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
**Global flags:** `--verbose` / `-v` · `--quiet` / `-q` · `--no-color`
|
|
452
|
+
|
|
453
|
+
---
|
|
454
|
+
|
|
455
|
+
## Quick Reference Table
|
|
456
|
+
|
|
457
|
+
| Widget | Syntax | Triple? | Bodyless? |
|
|
458
|
+
|---|---|:---:|:---:|
|
|
459
|
+
| Alert | `::alert[type]{msg}` | — | — |
|
|
460
|
+
| Badge | `::badge[label\|colour]` | — | ✓ |
|
|
461
|
+
| Bold styled | `::b[style]{text}` | — | — |
|
|
462
|
+
| Box | `:::box[variant]{content}` | ✓ | — |
|
|
463
|
+
| Button | `::button[style\|href]{label}` | — | — |
|
|
464
|
+
| Button group | `:::btngroup{::button\|\|…}` | ✓ | — |
|
|
465
|
+
| Callout | `::callout[emoji]{text}` | — | — |
|
|
466
|
+
| Card | `::card[title]{body}` | — | — |
|
|
467
|
+
| Center | `::center{content}` | — | — |
|
|
468
|
+
| Chart | `::chart[type]{json}` | — | — |
|
|
469
|
+
| Checkbox | `::checkbox[id\|val\|checked]{label}` | — | — |
|
|
470
|
+
| Class (apply) | `::class[names]{body}` | — | — |
|
|
471
|
+
| Class (define) | `::class_def[Name]{k:v\|\|k:v}` | — | — |
|
|
472
|
+
| Color | `::color[#hex]{text}` | — | — |
|
|
473
|
+
| Columns | `::columns[1:1]{col\|\|col}` | — | — |
|
|
474
|
+
| CSS block | `:::css{…}` | ✓ | — |
|
|
475
|
+
| CSS class | `::class[names]{content}` | — | — |
|
|
476
|
+
| CSS playground | `:::cssplay{css\|\|html}` | ✓ | — |
|
|
477
|
+
| CSS variable | `::cssvar[--name]{value}` | — | — |
|
|
478
|
+
| Demo sandbox | `:::demo{html}` | ✓ | — |
|
|
479
|
+
| Div | `:::div[class\|id\|style]{content}` | ✓ | — |
|
|
480
|
+
| Divider | `::divider[style]` | — | ✓ |
|
|
481
|
+
| Else | `::else[cond]{content}` | — | — |
|
|
482
|
+
| Embed | `::embed[type]{url}` | — | — |
|
|
483
|
+
| Flex | `:::flex[gap\|…]{item\|\|item}` | ✓ | — |
|
|
484
|
+
| Fold | `:::fold[title]{body}` | ✓ | — |
|
|
485
|
+
| Footer | `::footer[copy\|accent]{col\|\|col}` | — | — |
|
|
486
|
+
| Glow | `::glow[colour]{text}` | — | — |
|
|
487
|
+
| Graph | `::graph[type\|title\|palette\|h]{json}` | — | — |
|
|
488
|
+
| Graph playground | `:::graphplay{json}` | ✓ | — |
|
|
489
|
+
| Grid | `:::grid[cols\|gap]{cell\|\|cell}` | ✓ | — |
|
|
490
|
+
| Hero | `:::hero[bg\|align\|h]{content}` | ✓ | — |
|
|
491
|
+
| Highlight | `::hl[colour]{text}` | — | — |
|
|
492
|
+
| Icon | `::icon[name\|size\|colour]{fallback}` | — | — |
|
|
493
|
+
| Icon card | `::iconcard[icon\|title]{desc}` | — | — |
|
|
494
|
+
| If | `::if[cond]{content}` | — | — |
|
|
495
|
+
| If/else | `::ifelse[cond]{then\|\|else}` | — | — |
|
|
496
|
+
| Include | `` | — | ✓ |
|
|
497
|
+
| Input | `::input[type\|…]{label}` | — | — |
|
|
498
|
+
| Keyboard key | `::kbd{key combo}` | — | — |
|
|
499
|
+
| Math | `::math{LaTeX}` | — | — |
|
|
500
|
+
| Progress | `::progress[val/max\|label]` | — | ✓ |
|
|
501
|
+
| Right-align | `::right{content}` | — | — |
|
|
502
|
+
| Router | `::router[default]{id:Title::body\|\|…}` | — | — |
|
|
503
|
+
| Section | `:::section[title\|sub\|align]{body}` | ✓ | — |
|
|
504
|
+
| Select | `::select[id\|default\|label]{opts}` | — | — |
|
|
505
|
+
| Sidebar | `:::sidebar[title\|side\|w]{nav}` | ✓ | — |
|
|
506
|
+
| Spacer | `::spacer[size]` | — | ✓ |
|
|
507
|
+
| Style (inline) | `::style[css]{content}` | — | — |
|
|
508
|
+
| SVG | `:::svg{}` | ✓ | — |
|
|
509
|
+
| Tab | `::tab[A\|B]{body\|\|body}` | — | — |
|
|
510
|
+
| Timeline | `::timeline{Title::Desc\|\|…}` | — | — |
|
|
511
|
+
| Tooltip | `::tooltip[tip text]{anchor}` | — | — |
|
|
512
|
+
| Variable | `::var[name]{value}` | — | — |
|
|
513
|
+
|
|
514
|
+
## VoxMark Language View after compilation.
|
|
515
|
+
|
|
516
|
+

|
|
517
|
+

|
|
518
|
+

|
|
519
|
+

|
|
520
|
+

|
|
521
|
+

|
|
522
|
+
|
|
523
|
+
---
|
|
524
|
+
|
|
525
|
+
## License
|
|
526
|
+
|
|
527
|
+
VoxMark Language (VML) — created and maintained by **Divyanshu Sinha** ([@DivyanshuSinha136](https://github.com/DivyanshuSinha136)) and license under MIT.
|
|
528
|
+
|
|
529
|
+
---
|
|
530
|
+
|
|
531
|
+
## Other Links
|
|
532
|
+
Homepage: https://github.com/DivyanshuSinha136/VoxMark-Language/
|
|
533
|
+
Repository: https://github.com/DivyanshuSinha136/VoxMark-Language
|
|
534
|
+
Documentation: https://divyanshusinha136.github.io/VoxMark-Language/
|
|
535
|
+
Issues: https://github.com/DivyanshuSinha136/VoxMark-Language/issues/
|
|
536
|
+
|
|
537
|
+
---
|
|
538
|
+
|
|
539
|
+
Try Now VoxMark Language (`VML`).
|