Skip to content
⚠️ This document is AI-translated. The Chinese version is the authoritative source.

Binary Protocol Quick Reference

Simple Explanation

Presto templates are not a bunch of files -- they are executable programs. You feed Markdown text in, and they produce typesetting code (Typst). It's that simple.

Imagine a black box: Markdown goes in on the left, Typst comes out on the right. This black box can also answer a few questions -- "Who are you?" (--manifest), "Got an example?" (--example), "What version?" (--version). The Presto application interacts with templates through these four methods and no others.

Template binaries run in a strict sandbox: 30-second timeout, no network access, no file writing, minimal environment variables. This means template code cannot steal data or cause damage.


Protocol Quick Reference

Four Invocation Methods

MethodCommandstdinstdoutPurpose
Convert./binaryMarkdown textTypst codeCore function: turn Markdown into typesetting code
Metadata./binary --manifestNonemanifest JSONExtract template info during installation
Example./binary --exampleNoneMarkdown textShowcase template output
Version./binary --versionNoneVersion stringVersion check and update detection

Security Constraints

ConstraintValueDescription
Execution timeout30 secondsMaximum time per invocation
Build timeout300 seconds (5 minutes)Maximum time for template build
Manifest size limit1 MB--manifest output limit
Example size limit1 MB--example output limit
Typst output limit10 MBConversion output limit
Build artifact limit50 MBCompiled binary size limit
Environment variablesOnly PATH=/usr/local/bin:/usr/bin:/binMinimal environment, no other variables
Network accessProhibitedmacOS sandbox-exec / Linux unshare --net
File writingProhibitedOutput only via stdout
CLI flagsOnly the four aboveNo additional flags beyond the protocol

Three Layers of Security

LayerMechanismPurpose
Static analysisImport blocklistBlock dangerous dependencies pre-build
Runtime sandboxmacOS sandbox-exec / Linux unshare --netIsolate network and filesystem
Output validationFormat checkingEnsure stdout contains only valid content

Interaction Sequence Diagram


Detailed Explanation

1. Convert: Core Function

This is the reason templates exist. Presto passes the user's Markdown to the template binary via stdin, and the binary processes it and returns Typst source code via stdout.

Internal processing flow:

  1. splitFrontmatter() -- Separate the YAML header (page configuration) from the body
  2. writePageSetup() -- Generate Typst page setup code based on frontmatter fields
  3. renderBody() -- Parse Markdown AST with goldmark, converting each node to Typst syntax

Key constraints:

  • stdin accepts only Markdown text
  • stdout must output only valid Typst source code
  • Cannot read or write any files, cannot access the network
  • Automatically terminated after 30 seconds

2. Metadata: --manifest

When installing a template, the first thing Presto does is call --manifest to get the template's self-description. This JSON tells Presto:

  • The template's name, author, and version
  • Which fonts are required
  • Which frontmatter fields are supported (types, defaults, formats)

Manifest data is embedded in the binary at compile time via Go's //go:embed -- it's not generated at runtime.

3. Example: --example

Returns a sample Markdown document, used for:

  • Preview display in the template store
  • A starter template when users first use it
  • Input data for automated testing

Also embedded via //go:embed.

4. Version: --version

Returns the version string, read from the version field of the embedded manifest.json. Used for:

  • Checking if the template has updates
  • Compatibility checks (in conjunction with minPrestoVersion)

5. Embedding Mechanism

Templates follow a "binary embedding model," not a "file copying model." All resources are packaged into the executable at compile time:

go
//go:embed manifest.json
var manifestData []byte

//go:embed example.md
var exampleData []byte

This means:

  • Distribution involves only a single file, with no additional resource directories needed
  • No external file dependencies at runtime, eliminating "config not found" issues
  • Sandbox restrictions are easier to enforce -- the binary doesn't need to read any external files

Complete manifest.json Example

json
{
  "name": "academic-paper",
  "displayName": "Academic Paper",
  "description": "A typesetting template for Chinese academic papers, supporting common structures such as abstract, keywords, and references",
  "version": "1.2.0",
  "author": "Zhang San <zhangsan@example.com>",
  "license": "MIT",
  "minPrestoVersion": "0.5.0",
  "keywords": ["academic", "paper", "Chinese", "LaTeX alternative"],
  "requiredFonts": [
    {
      "name": "NotoSerifCJKsc",
      "displayName": "Noto Serif CJK SC",
      "url": "https://github.com/notofonts/noto-cjk/releases"
    },
    {
      "name": "NotoSansCJKsc",
      "displayName": "Noto Sans CJK SC",
      "url": "https://github.com/notofonts/noto-cjk/releases"
    }
  ],
  "frontmatterSchema": {
    "title": {
      "type": "string",
      "default": "Untitled Paper"
    },
    "author": {
      "type": "string",
      "default": "Anonymous"
    },
    "date": {
      "type": "string",
      "format": "date"
    },
    "abstract": {
      "type": "string",
      "default": ""
    },
    "keywords": {
      "type": "string",
      "default": ""
    },
    "twocolumn": {
      "type": "boolean",
      "default": false
    },
    "fontsize": {
      "type": "string",
      "default": "12pt"
    },
    "papersize": {
      "type": "string",
      "default": "a4"
    },
    "margin": {
      "type": "string",
      "default": "2.5cm"
    },
    "linestretch": {
      "type": "number",
      "default": 1.5
    }
  }
}

Field descriptions:

FieldRequiredDescription
nameYesTemplate unique identifier, lowercase + hyphens
displayNameYesUser-visible template name
descriptionYesTemplate purpose description
versionYesSemantic version number (semver)
authorYesAuthor information
licenseYesOpen source license
minPrestoVersionYesMinimum compatible Presto version
keywordsNoSearch keywords
requiredFontsNoList of required fonts
frontmatterSchemaYesUser-configurable frontmatter field definitions

Supported type values in frontmatterSchema:

typeDescriptionExample default
"string"Text"Untitled Paper"
"number"Number1.5
"boolean"Booleanfalse

The optional format field hints at UI rendering (e.g., "date" will display a date picker).

Presto — Markdown to PDF