PML (Picture Markup Language) — A Lisp-style language for sprite asset generation
Project description
PML — Picture Markup Language
A Lisp-style DSL for sprite asset generation. Describe game sprites in S-expressions, compile to PNG/GIF via Pillow.
(sprite-canvas 128 256 :bg "transparent")
(add (character :expression "happy" :style 'cel))
(render "hero.png")
Quick Start
# Install
uv sync
# Run a file
uv run pml examples/hello.pml
# Start REPL
uv run pml
# Render a sprite (see examples/sprite.pml)
uv run pml examples/sprite.pml -o examples_output
# Render animation as GIF
uv run pml examples/animation.pml -o examples_output
# CLI options
uv run pml file.pml --json # Structured JSON output
uv run pml file.pml -o ./output # Set output directory
uv run pml file.pml --watch # Auto-re-run on file change
uv run pml --help # All options
Examples
Basic Graphics
(canvas 300 200 :bg "#f5f5f5")
(add (rect 20 20 80 60 :fill "#3498db" :stroke "#2c3e50" :stroke-width 2))
(add (circle 180 60 35 :fill "#e74c3c"))
(add (ellipse 260 100 25 40 :fill "#2ecc71"))
(render "shapes.png")
Character Sprite
(sprite-canvas 128 256 :bg "transparent" :anchor 'center-bottom)
(define hero
(character
:outfit (outfit :top 'armor :bottom 'armor :shoes 'boots)
:weapon (weapon :type 'sword :material 'crystal :element 'holy)
:expression "happy"
:style 'cel))
(add hero)
(render "hero.png")
Animation → GIF
(canvas 200 200 :bg "#1a1a2e")
(define ball (circle 30 30 20 :fill "#e74c3c"))
(animate ball 'x 30 170 1.0 :ease 'sine-in-out)
(animate ball 'y 30 170 0.4 :ease 'bounce-out)
(play)
(render "bounce.gif" :fps 30)
Skeleton & IK
(defskeleton arm (x y)
(joint shoulder :pos (0 0) :length 40.0 :angle 0.0 :min -120 :max 120)
(joint elbow :pos (0 40) :length 35.0 :angle 0.0 :min -150 :max 0)
(joint wrist :pos (0 35) :length 0.0 :angle 0.0))
(define arm-inst (instantiate-skeleton arm 50 180))
(ik-solve arm-inst 'wrist 95 125 :method 'fabrik :iterations 30)
(joint-position arm-inst 'elbow) ; → (x y)
Spritesheet
(render-spritesheet "sprites.png"
(character :expression "happy") (character :expression "angry")
:cols 2 :cell-width 64 :cell-height 64)
; → spritesheet.png + spritesheet.spritesheet.json
UI Widgets
(sprite-canvas 256 192)
(define btn (button :label "Start" :width 100 :height 32 :style 'rounded))
(add (group :transform (translate 0 10) btn))
(render "ui.png")
More examples in examples/.
Features
- Full Lisp dialect: S-expressions, closures, macros, lexical scoping
- Graphics pipeline: primitives, transforms, canvas compositing
- Sprite system: style engine, palette management, semantic components (character, body, eyes, hair, outfit, items, UI, scene elements)
- Animation engine: property tweening, timeline, easing functions, GIF export
- Inverse Kinematics: FABRIK and CCD solvers with angle constraints and skin binding
- Module system: import/provide with caching and circular dependency detection
- Standard library: math, color, easing, shapes
- MCP server: expose as tools for AI agents (Claude, Cursor)
- CLI: file execution, REPL, watch mode, JSON output, output directory control
- Pillow backend: PNG, JPG, GIF output
- LLM-friendly API: structured error hints for AI repair
Project Structure
pml/ # Core interpreter
├── lexer.py → parser.py → expander.py → evaluator.py # Pipeline
├── environment.py # Lexical scoping
├── module_loader.py # import/provide system
├── errors.py # Error types with repair hints
├── types.py # Symbol, Keyword, Procedure, Macro
├── repl.py # CLI + REPL entry
├── api.py # PMLRuntime — LLM-facing API
├── mcp_server.py # MCP server for AI agents
├── transform.py # AffineTransform
├── builtins/ # Arithmetic, comparison, IO, list/string ops
├── graphics/ # Primitives, canvas, render
├── sprites/ # Style, palette, components
├── animation/ # Timeline, easing, interpolation
├── skeleton/ # SkeletonTemplate, FABRIK/CCD IK
└── backend/ # Pillow render backend
stdlib/ # Standard library (.pml files)
├── math.pml, color.pml, easing.pml, shapes.pml
└── sprites/ # Component API docs
examples/ # Runnable .pml demos
tests/ # pytest test suite (389 tests)
docs/
├── language.md # Full language reference
└── README.zh.md # Chinese guide
Documentation
| Resource | Link |
|---|---|
| Language Reference | docs/language.md |
| Chinese Guide | docs/README.zh.md |
| Examples | examples/ |
| API Reference | pml/api.py |
MCP Server
For AI agents (Claude Desktop, Cursor, etc.):
uv run pml-mcp
Exposes 5 tools: execute_pml, render_sprite, validate, list_components, preview_params.
Add to Claude Desktop config:
{
"mcpServers": {
"pml": {
"command": "uv",
"args": ["run", "pml-mcp"],
"cwd": "/path/to/PML"
}
}
}
Requirements
- Python ≥ 3.10
- Pillow ≥ 12.2.0
uvpackage manager (install guide)
License
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file picmarkup-0.1.0.tar.gz.
File metadata
- Download URL: picmarkup-0.1.0.tar.gz
- Upload date:
- Size: 165.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.21 {"installer":{"name":"uv","version":"0.11.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dce7a465543d8d9765245ee07d5901d824fa29904e586172f112fae82d8fdedd
|
|
| MD5 |
7f3ee375fbdcf5a09ce25f444961fd65
|
|
| BLAKE2b-256 |
e4bd3823c8c3878a7737ac5d764b47120d75d5202ea0651af45582c62c6e0cfd
|
File details
Details for the file picmarkup-0.1.0-py3-none-any.whl.
File metadata
- Download URL: picmarkup-0.1.0-py3-none-any.whl
- Upload date:
- Size: 101.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.21 {"installer":{"name":"uv","version":"0.11.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e3b08c95484b10db9ac587eb9fed89aeea8b569b4d7e90017e069d9a6813c9ae
|
|
| MD5 |
d3b0279f371cb248a2cd6ed8c3676520
|
|
| BLAKE2b-256 |
5130935ea996d2edf60fb52318fb6fada7a7baa7ce673959bf798e558b6e5224
|