Receber por email
← Voltar para o catálogo

vmprint-ast-layout

Um guia prático para a construção de documentos VMPrint JSON AST 1.1, abordando geometria da página, tipos de elementos, flutuantes, abrangência de colunas, cabeçalhos/rodapés, texto multilíngue, controle de paginação e o sistema de script do documento.

657estrelas
Atualizado há 4 meses

Ver no GitHub ↗ Licença: Apache-2.0

Como adicionar

/plugin marketplace add cosmiciron/vmprint

O comando exato pode variar conforme o repositório. Confira o README no GitHub.

Para o autor da skill

Cole no README do seu repo

Mostra que sua skill está catalogada na Skillteca, gera backlink e tráfego rastreável.

[![Skillteca](https://www.skillteca.com.br/api/badge/vmprint-ast-layout/svg)](https://www.skillteca.com.br/skills/vmprint-ast-layout)

Alerta por categoria

Receba novas skills de Design e Frontend toda segunda

1 email curto, só com as skills novas de Design e Frontend. 4 minutos de leitura, sem spam, cancela com 1 clique.

Você confirma o email no primeiro envio. Sem spam. Cancela com 1 clique.

Ler descrição completa

VMPrint AST Layout Skill

A practitioner's guide to constructing sophisticated layouts with the VMPrint JSON AST version 1.1. Use this alongside the regression fixtures in engine/tests/fixtures/regression/ and engine/tests/fixtures/scripting/ (working examples for every feature).

Schema authority: The interfaces embedded in this skill (§ "Exact … interface" blocks) are the canonical contracts for allowed keys. Do not guess at key names — if a key is not listed in one of those interface blocks, it does not exist. The pitfalls section documents keys that have been hallucinated in the past.
AST 1.1 breaking changes from 1.0: placement replaces properties.layout; image, dropCap, columnSpan, table are now top-level element keys instead of nested inside properties.

1. Root Structure

Every document is a single JSON object:

{
  "documentVersion": "1.1",
  "layout": { ... },
  "fonts":  { ... },
  "styles": { "myType": { ... } },
  "elements": [ ... ],
  "header": { ... },
  "footer": { ... }
}
  • documentVersion — always "1.1"
  • layout — page geometry and typographic defaults
  • fonts — optional; only needed for custom font files
  • styles — maps element type strings to base styles; anything not here defaults to layout values
  • elements — the content tree
  • header / footer — optional running regions

Optional scripting keys at root level: methods, scriptVars, onBeforeLayout, onAfterSettle.

2. Page Geometry

"layout": {
  "pageSize": { "width": 720, "height": 405 },
  "orientation": "landscape",
  "margins": { "top": 34, "right": 50, "bottom": 34, "left": 50 },
  "pageTemplates": [
    {
      "pageIndex": 1,
      "pageSize": { "width": 280, "height": 420 },
      "margins": { "top": 34, "right": 22, "bottom": 34, "left": 22 }
    }
  ],
  "fontFamily": "Arimo",
  "fontSize": 10,
  "lineHeight": 1.35,
  "pageBackground": "#fdf6e3"
}

pageSize accepts "A4", "LETTER", or { "width": N, "height": N } in points. Standard sizes:

| Name | Points | |------|--------| | A4 portrait | 595 × 842 | | LETTER portrait | 612 × 792 | | 16:9 landscape | 720 × 405 |

pageTemplates can override pageSize, orientation, and/or margins for matching pages. pageIndex is zero-based; selectors such as "first", "odd", "even", and "all" are also supported. The engine resolves the active page geometry before measuring that page, so odd-sized pages change real flow space and render as matching PDF media boxes.

Content area math (critical for fitting content on page):

contentWidth  = pageWidth  - marginLeft - marginRight
contentHeight = pageHeight - marginTop  - marginBottom

For a 720 × 405 page with margins {top:34, right:50, bottom:34, left:50}:

  • contentWidth = 720 - 50 - 50 = 620 pt
  • contentHeight = 405 - 34 - 34 = 337 pt

In a 3-column story with gutter 12:

  • columnWidth = (620 - 12 × 2) / 3 = 198.67 pt

Line height in points = fontSize × lineHeight. For 10pt / 1.35: 13.5 pt per line.

Lines per column = floor(contentHeight / lineHeightPt).

3. Fonts

Built-in font families available without registration: Arimo, Tinos, Cousine, Caladea, Carlito, Noto Sans JP (CJK), Noto Sans Arabic, Noto Sans Thai, Noto Sans Devanagari.

Reference a built-in family by name in fontFamily; no fonts block needed:

"fonts": { "regular": "Arimo" }

For custom font files, register by role:

"fonts": {
  "regular":    "path/to/font.ttf",
  "bold":       "path/to/font-bold.ttf",
  "italic":     "path/to/font-italic.ttf",
  "bolditalic": "path/to/font-bolditalic.ttf"
}

The engine maps fontWeight/fontStyle to these slots at render time. For named non-system fonts in inline spans use fontFamily on properties.style of a "text" child.

Standard PDF 1.4 built-in fonts (zero-embed, Latin-only docs via StandardFontManager): Helvetica, Times New Roman, Courier — common aliases like Arial → Helvetica resolve automatically.

4. Styles Table

Every type string is a key into styles. Style resolution: styles[element.type] (base) merged with properties.style (override).

"styles": {
  "heading": {
    "fontSize": 22, "fontWeight": "bold",
    "marginBottom": 14, "keepWithNext": true,
    "hyphenation": "off"
  },
  "body": {
    "fontSize": 10, "marginBottom": 10,
    "allowLineSplit": true, "orphans": 2, "widows": 2,
    "textAlign": "justify"
  },
  "kicker": {
    "fontSize": 6.5, "letterSpacing": 1.2, "fontFamily": "Cousine",
    "textAlign": "center", "marginBottom": 9, "keepWithNext": true
  },
  "table-cell": {
    "fontFamily": "Cousine", "fontSize": 7,
    "paddingTop": 3, "paddingBottom": 3, "paddingLeft": 4, "paddingRight": 4
  }
}

Any element type you invent is valid — just add it to styles.

5. Block Element Types

{ "type": "heading", "content": "My Title" }
{ "type": "body", "content": "Plain paragraph." }
{ "type": "body", "content": "", "children": [ ... ] }

Special structural types handled by the engine:

| type | Role | |--------|------| | "story" | Multi-column DTP zone; carries columns, gutter, balance as top-level keys | | "table" | Table container; optional table top-level key for config | | "table-row" | Row inside a table | | "table-cell" | Cell inside a row; supports colSpan, rowSpan in properties | | "zone-map" | Independent-region layout; zoneLayout + zones[] at top level | | "strip" | Horizontal slot layout; stripLayout + slots[] at top level | | "image" | Block or inline image; image data at top level |

All other type strings are user-defined and look up styles only.

Use "content": "" (empty string) on container elements (table, story, zone-map, strip). Container elements and image elements do not require content but it's harmless to include it.

6. Top-Level Element Keys (AST 1.1)

In AST 1.1, several configuration objects moved out of properties and became top-level keys on the element. This is the most important change from 1.0.

| Key | Element type(s) | Purpose | |-----|-----------------|---------| | content | all | Text content string | | children | all block | Inline runs or child block elements | | name | any | Scripting target name | | type | all | Element type string | | image | "image" | Image data (data, mimeType, fit) | | table | "table" | Table config (headerRows, repeatHeader, columns, etc.) | | dropCap | any block | Drop cap config | | columnSpan | story children | "all" or number | | placement | story children | Float/absolute placement directive | | columns | "story" | Column count | | gutter | "story" | Inter-column gap | | balance | "story" | Equal-height column balancing | | zones | "zone-map" | Array of zone definitions | | zoneLayout | "zone-map" | Column sizing + gap config | | slots | "strip" | Array of slot definitions | | stripLayout | "strip" | Track sizing + gap config | | properties | all | style, sourceId, colSpan, rowSpan, semanticRole, etc. |

Exact ElementProperties interface (no other keys are valid):

interface ElementProperties {
    style?: Partial<ElementStyle>;   // inline style overrides
    colSpan?: number;                // table-cell only
    rowSpan?: number;                // table-cell only
    sourceId?: string;
    linkTarget?: string;             // inline text/inline elements
    semanticRole?: string;           // "header" on table-row
    reflowKey?: string;
    keepWithNext?: boolean;
    marginTop?: number;
    marginBottom?: number;
    pageOverrides?: {
        header?: PageRegionContent | null;
        footer?: PageRegionContent | null;
    };
    language?: string;               // code blocks
}

colSpan and rowSpan remain inside properties (not top-level).

7. Inline Runs (Rich

Compartilhar X LinkedIn