02. Styles And Text
VMPrint’s default authoring model is still simple document flow.
Styles
styles is a named table keyed by element type.
{
"styles": {
"headline": {
"fontFamily": "Tinos",
"fontSize": 30,
"fontWeight": "bold",
"lineHeight": 1.08,
"marginBottom": 8
},
"deck": {
"fontFamily": "Tinos",
"fontSize": 12,
"fontStyle": "italic",
"lineHeight": 1.4,
"marginBottom": 10
},
"body": {
"fontSize": 10,
"lineHeight": 1.45,
"textAlign": "justify",
"allowLineSplit": true,
"orphans": 2,
"widows": 2,
"marginBottom": 10
}
}
}
Then author elements against those style names:
[
{ "type": "headline", "content": "A Better Authored Surface" },
{ "type": "deck", "content": "Keep the source simple. Let the engine do the heavy spatial work." },
{ "type": "body", "content": "Paragraph one..." },
{ "type": "body", "content": "Paragraph two..." }
]
Rich text
Use nested children when you need inline emphasis or mixed inline objects.
{
"type": "body",
"children": [
{ "type": "text", "content": "VMPrint supports " },
{ "type": "text", "content": "rich inline text", "properties": { "style": { "fontWeight": "bold" } } },
{ "type": "text", "content": " without making the whole AST DOM-like." }
]
}
Lists
Use native list and list-item elements for bullets, numbering, and nested lists. Do not put authored marker text such as •, 1., or a. into list-item.content; VMPrint generates marker boxes during layout.
{
"type": "list",
"list": {
"kind": "ordered",
"markerStyle": "decimal",
"start": 3,
"indent": 30,
"markerWidth": 18,
"markerGap": 8,
"itemSpacing": 4,
"levels": [
{ "kind": "ordered", "markerStyle": "decimal", "indent": 30, "markerWidth": 18, "markerGap": 8 },
{ "kind": "unordered", "markerStyle": "circle", "indent": 24, "markerWidth": 12, "markerGap": 6 }
]
},
"children": [
{
"type": "list-item",
"content": "Third item owns a nested list.",
"children": [
{
"type": "list",
"children": [
{ "type": "list-item", "content": "Nested child inherits level-one marker defaults." }
]
}
]
},
{ "type": "list-item", "content": "Fourth item continues the ordered sequence." }
]
}
indent positions the item body, markerWidth reserves the generated marker column, and markerGap controls the space between marker and body. Wrapped item lines continue under the body, so list items use a hanging indent naturally.
For non-English numbering, choose a generated markerStyle such as cjk-ideographic, cjk-decimal, hiragana, katakana, arabic-indic, extended-arabic-indic, devanagari, or thai.
Use markerText only when the marker is a custom literal:
{
"type": "list",
"list": {
"kind": "unordered",
"markerText": "✓",
"indent": 26,
"markerWidth": 14,
"markerGap": 6
},
"children": [
{ "type": "list-item", "content": "The check mark is generated by the list actor." }
]
}
Marker styling is separate from item body styling. Use styles["list-marker"] for global marker paint or list.markerTextStyle / levels[].markerTextStyle for list-specific marker paint.
Drop caps
AST 1.1 promotes drop-cap structure to a first-class field.
{
"type": "body",
"content": "Every element in a VMPrint document is measured with sub-point precision...",
"dropCap": {
"enabled": true,
"lines": 3,
"gap": 8,
"characterStyle": {
"fontFamily": "Tinos",
"fontSize": 44,
"fontWeight": "bold"
}
}
}
Use plain flow as long as you can. Reach for spatial constructs only when flow stops matching the page’s intent.
Next: