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
| Method | Command | stdin | stdout | Purpose |
|---|---|---|---|---|
| Convert | ./binary | Markdown text | Typst code | Core function: turn Markdown into typesetting code |
| Metadata | ./binary --manifest | None | manifest JSON | Extract template info during installation |
| Example | ./binary --example | None | Markdown text | Showcase template output |
| Version | ./binary --version | None | Version string | Version check and update detection |
Security Constraints
| Constraint | Value | Description |
|---|---|---|
| Execution timeout | 30 seconds | Maximum time per invocation |
| Build timeout | 300 seconds (5 minutes) | Maximum time for template build |
| Manifest size limit | 1 MB | --manifest output limit |
| Example size limit | 1 MB | --example output limit |
| Typst output limit | 10 MB | Conversion output limit |
| Build artifact limit | 50 MB | Compiled binary size limit |
| Environment variables | Only PATH=/usr/local/bin:/usr/bin:/bin | Minimal environment, no other variables |
| Network access | Prohibited | macOS sandbox-exec / Linux unshare --net |
| File writing | Prohibited | Output only via stdout |
| CLI flags | Only the four above | No additional flags beyond the protocol |
Three Layers of Security
| Layer | Mechanism | Purpose |
|---|---|---|
| Static analysis | Import blocklist | Block dangerous dependencies pre-build |
| Runtime sandbox | macOS sandbox-exec / Linux unshare --net | Isolate network and filesystem |
| Output validation | Format checking | Ensure 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:
splitFrontmatter()-- Separate the YAML header (page configuration) from the bodywritePageSetup()-- Generate Typst page setup code based on frontmatter fieldsrenderBody()-- 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:embed manifest.json
var manifestData []byte
//go:embed example.md
var exampleData []byteThis 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
{
"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:
| Field | Required | Description |
|---|---|---|
name | Yes | Template unique identifier, lowercase + hyphens |
displayName | Yes | User-visible template name |
description | Yes | Template purpose description |
version | Yes | Semantic version number (semver) |
author | Yes | Author information |
license | Yes | Open source license |
minPrestoVersion | Yes | Minimum compatible Presto version |
keywords | No | Search keywords |
requiredFonts | No | List of required fonts |
frontmatterSchema | Yes | User-configurable frontmatter field definitions |
Supported type values in frontmatterSchema:
| type | Description | Example default |
|---|---|---|
"string" | Text | "Untitled Paper" |
"number" | Number | 1.5 |
"boolean" | Boolean | false |
The optional format field hints at UI rendering (e.g., "date" will display a date picker).
