Skip to content

Releases: GMfatcat/goslide

v1.5.0

22 Apr 10:47

Choose a tag to compare

πŸŽ‰ GoSlide v1.5.0

What's New

πŸ“„ PDF export

New goslide export-pdf <file.md> command renders your deck to a PDF
via headless Chrome. Whatever you see in goslide serve β€” fonts,
themes, Chart.js, Mermaid diagrams, LLM-baked API results β€” renders
in the PDF, because the renderer is literally a real browser.

goslide export-pdf talk.md
goslide export-pdf talk.md -o handout.pdf
goslide export-pdf talk.md --notes                 # include speaker notes
goslide export-pdf talk.md --paper-size a4-landscape

Paper sizes (default slide-16x9):

Preset Dimensions Intended use
slide-16x9 1920 Γ— 1080 px On-screen presentation look (default)
slide-4x3 1600 Γ— 1200 px Legacy projector aspect
a4-landscape 297 Γ— 210 mm Print-friendly handout
letter-landscape 11 Γ— 8.5 in US letter handout

Fragment animations are collapsed to their final state β€” one slide,
one PDF page.

🧭 Chrome discovery: install-once, no bundled chromium

GoSlide stays a single ~8MB binary. export-pdf locates Chrome in
this order:

  1. GOSLIDE_CHROME_PATH env var (explicit override)
  2. PATH β€” searches chrome, chromium, chromium-browser,
    google-chrome, microsoft-edge
  3. Platform-specific known install locations
    (C:\Program Files\Google\Chrome\Application\chrome.exe,
    /Applications/Google Chrome.app/..., etc.)

If nothing is found, the command exits non-zero with an actionable
message listing every location it checked. No auto-download.

🧩 How it works

Under the hood export-pdf is a thin wrapper:

  1. Runs the existing goslide build to produce static HTML with
    everything (LLM bakes included) already inlined.
  2. Launches Chrome headless against that HTML with reveal.js's
    ?print-pdf mode.
  3. Waits for window.__goslideReady (new front-end marker that fires
    once Mermaid promises settle β€” async-safe rendering).
  4. Calls Chrome DevTools Page.printToPDF with the resolved paper
    dimensions and writes the bytes to the output path.

The Launcher interface keeps unit tests deterministic (fake launcher
for orchestrator tests) and the real ChromedpLauncher only runs when
Chrome is actually present. The integration test auto-skips when
FindChrome() errors, so CI without Chrome stays green.

Compatibility

No breaking changes. v1.4.0 decks export unchanged; the new command is
additive. Existing goslide build / serve / generate / host are
untouched.

Go version: still 1.21.6. Chromedp is pinned to v0.10.0 β€” the last
release compatible with Go 1.21.

Requirements

  • Chrome / Edge / Chromium installed locally. Developers typically
    have one of these; if not, any distribution works. Set
    GOSLIDE_CHROME_PATH if you want to pick a specific binary.

Out of scope (future work)

  • Fragment-per-page mode.
  • Custom header/footer, page numbers, bookmarks.
  • Password-protected PDFs.
  • Auto-downloading or bundling Chromium.

Full Changelog

See v1.4.0...v1.5.0 for all changes.

v1.4.0

20 Apr 13:57

Choose a tag to compare

πŸŽ‰ GoSlide v1.4.0

What's New

🧠 LLM transformer inside api components (experimental)

The api component accepts a new render item of type llm. Fetched
JSON is substituted into a user-authored prompt via {{data}} and the
model's reply renders inline alongside the chart, table, or metric.

~~~api
endpoint: /api/sales
fixture: sales.json           # optional; used by goslide build
render:
  - type: chart:bar
    label-key: quarter
    data-key: revenue
  - type: llm
    prompt: |
      Write 2 analyst bullets on these numbers:
      {{data}}
~~~

Control model (three layers, not configurable β€” that's the point):

  • Cache-first β€” identical (model, prompt, data) triples call the
    LLM at most once. Results land in .goslide-cache/<sha256>.json
    (human-readable, commit-safe). Canonical JSON keying means logically
    equal data (different key order, whitespace) hits the same entry.
  • Click-to-call β€” goslide serve shows a Generate ✨ button on
    cache miss. Page load never triggers an LLM call automatically.
    Localstorage caches per-browser.
  • Build-lock β€” goslide build inlines cached results as a
    data-llm-bakes attribute on the api component. The exported HTML
    never contacts an LLM at view time.
# Warm cache via the dev loop:
goslide serve talk.md        # click Generate to populate .goslide-cache/

# Export to static HTML (reads cache only, zero network):
goslide build talk.md

# Or refresh cache during build (the one place we call LLM non-interactively):
goslide build talk.md --llm-refresh

Cache miss during goslide build is a hard error by default, listing
every affected slide / component / render-item. Pass --llm-refresh
to opt in to filling the cache during the build.

Offline build with a fixture file β€” fixture: ./sales.json on the
api component lets goslide build read static data instead of calling
a live endpoint. Great for committing a reproducible snapshot.

Reuses existing generate: config β€” no new YAML keys; the same
OpenAI-compatible endpoint that powers goslide generate powers the
LLM transformer. Works with any compatible provider (OpenAI,
OpenRouter, Ollama, vllm, sglang, etc.).

βœ… Validation

The IR validator rejects llm render items missing prompt with code
llm-missing-prompt β€” goslide build / goslide serve won't start
against a broken deck.

πŸ“¦ Validated example

examples/ai-generated/api-llm-sales/
is a fully self-contained directory. Clone this repo, cd into the
directory, run goslide build demo.md, and you'll see an LLM-written
analyst summary render in the output HTML without ever touching an LLM
β€” the committed .goslide-cache/ entry satisfies the bake. Real-LLM
regeneration requires OPENROUTER_API_KEY and --llm-refresh.

Compatibility

No breaking changes. v1.3.0 decks build unchanged; the new llm render
type is additive and only exercises the new code path when present.
The internal change to builder.Build (moving config.Load earlier so
the bake can mutate the IR before render) is invisible to callers.

Out of scope (future work)

  • Streaming LLM responses (SSE). Current MVP buffers the full reply.
  • JSONPath-style {{field.x}} expressions in the prompt. Current MVP
    injects the whole response as {{data}}.
  • goslide generate emitting llm render items. Manual-author-only in
    v1.4.0.

Full Changelog

See v1.3.0...v1.4.0 for all changes.

v1.3.0

19 Apr 12:34

Choose a tag to compare

πŸŽ‰ GoSlide v1.3.0

What's New

πŸ–ΌοΈ Image Placeholder Component

A new placeholder component β€” a styled dashed-rectangle "image
stand-in" with an icon, title, and optional description. Drop one
wherever a real image will eventually go, then replace it with the
actual asset when ready.

~~~placeholder
hint: K8s cluster architecture
icon: πŸ—ΊοΈ
aspect: 16:9
---
Control plane + worker node interaction
~~~
  • hint (required) β€” title text describing what the image will show
  • icon (optional) β€” single emoji cue (πŸ“Š charts, πŸ—ΊοΈ diagrams, πŸ“· photos, πŸ“ˆ trends, πŸ–ΌοΈ generic)
  • aspect (optional) β€” 16:9 (default), 4:3, 1:1, 3:4, or 9:16
  • Body (between --- and closing fence) β€” optional subtitle

Placeholders work in any layout: as a full-slide cover diagram, inside
an image-left/image-right region, or combined with the new
image-grid below.

🧩 image-grid Layout

A new CSS-grid slide layout that packs multiple cells (placeholders,
real images, charts, or any other component) into 2, 3, or 4 columns.

<!-- layout: image-grid -->
<!-- columns: 2 -->

<!-- cell -->
~~~placeholder
hint: Architecture
icon: πŸ—ΊοΈ
~~~

<!-- cell -->
![Dashboard](./dashboard.png)

<!-- cell -->
~~~chart
type: bar
title: Sales
data:
  labels: [Q1, Q2, Q3]
  values: [10, 12, 15]
~~~

<!-- cell -->
~~~placeholder
hint: Trends
icon: πŸ“ˆ
~~~

<!-- cell --> before each item marks a new grid cell; cells can hold
any content.

πŸ€– Smarter goslide generate

The AI-generation command (Phase 6a) now knows about the new features.
The system prompt has been tightened so LLM output consistently uses the
correct fence and comment syntax:

  • All component fences are ~~~ (triple tilde). Triple-backtick blocks
    are plain code and will not render as components.
  • Per-slide layout settings use HTML comments
    (<!-- layout: image-grid -->, <!-- columns: 2 -->), never a
    YAML --- block mid-document.
  • Explicit "wrong vs right" examples and a new image-grid example in
    the prompt.

On OpenRouter free tier, 5 of 6 models tested after this iteration
produce valid, first-pass-parseable output. See
examples/ai-generated/k8s-visual.md
for a real generation (openai/gpt-oss-20b:free, 13 placeholders + one
4-cell image-grid slide).

βœ… Validation

goslide validate / goslide build emit:

  • Error placeholder-missing-hint when a placeholder lacks hint
  • Warning unknown-aspect when aspect isn't on the whitelist (falls back to 16:9)
  • Warning columns-out-of-range when image-grid columns fall outside 2-4
  • Warning image-grid-empty when an image-grid layout contains no cells

Compatibility

No breaking changes. v1.2.0 decks work unchanged. The internal region
parser was refactored from a name-keyed map to an ordered slice so that
repeatable markers (<!-- cell -->) produce distinct regions β€”
transparent to existing layouts (two-column, three-column, etc.) since
none of them used repeated markers.

Full Changelog

See v1.2.0...v1.3.0 for all changes.

v1.2.0

19 Apr 08:40

Choose a tag to compare

πŸŽ‰ GoSlide v1.2.0

What's New

πŸ€– AI Slide Generation (experimental)

New goslide generate command produces a full GoSlide presentation by
calling any OpenAI-compatible LLM endpoint β€” OpenAI, OpenRouter, Ollama,
vllm, sglang, and others.

export OPENAI_API_KEY=sk-...
goslide generate "Introduction to Kubernetes"            # simple mode
goslide generate my-prompt.md -o talk.md                 # advanced mode
goslide generate --dump-prompt > system.txt              # inspect prompt

Highlights

  • Two modes. Single-topic strings for quick drafts; prompt.md files
    with YAML frontmatter (topic / audience / slides / theme /
    language) plus free-text body for controlled generation.
  • Embedded system prompt. Ships inside the binary, describes the
    AI-facing GoSlide subset (frontmatter, layouts, card/chart components).
    Dump it with --dump-prompt to feed any chat UI manually.
  • Heuristic auto-fix. Four local rules recover the most common LLM
    syntax slips (unclosed code fences, missing frontmatter terminator,
    unquoted YAML values with colons, missing trailing newline). Fixes are
    reported transparently on stderr.
  • Safe defaults. Refuses to overwrite existing output unless --force
    is passed. On unrecoverable parse failure, writes <output>.raw.md and
    <output>.fixed.md next to the target for diagnosis instead of
    clobbering your work.
  • API keys never touch disk. Read from an environment variable named
    by generate.api_key_env.

Configuration (goslide.yaml):

generate:
  base_url: https://api.openai.com/v1   # or https://openrouter.ai/api/v1, http://localhost:11434/v1, etc.
  model: gpt-4o
  api_key_env: OPENAI_API_KEY
  timeout: 120s

Experimental notice. Output quality depends on the chosen model and
prompt wording; semantic quality (flow, accuracy, style) is not guaranteed.
CLI flags and API may change. Review generated slides before presenting.

βœ… Validated Examples

See examples/ai-generated/ for real outputs
produced by openai/gpt-oss-120b:free on OpenRouter β€” English simple mode
and 繁體中文 advanced mode (high-school audience, 快逐廚房 metaphor). Both
parsed on first pass with no fixup needed. scripts/test-generate-llm.ps1
reproduces the test interactively.

πŸ“ Documentation

  • PRD.md Β§13 reflects the implemented state
  • Both English and 繁體中文 READMEs get a new AI slide generation
    section with an experimental warning

No Breaking Changes

v1.1.0 projects work unchanged. The generate: config section is optional
β€” absent when not using goslide generate.

Full Changelog

See v1.1.0...v1.2.0 for all changes.

v1.1.0

18 Apr 10:25

Choose a tag to compare

πŸŽ‰ GoSlide v1.1.0

What's New

🎨 22 Themes (8 new)

Added 8 community-favorite themes, bringing the total to 22 themes Γ— 8 accent colors = 176 visual combinations:

New Theme Style Default Accent
nord-light Arctic cool blue-grays teal
catppuccin-latte Soft warm pastels pink
paper Warm off-white, editorial amber
chalk Cool blue-grey, educational purple
synthwave Neon pink/cyan on deep purple pink
forest Deep forest greens, earthy green
rose Warm blush pink pink
amoled True black OLED, max contrast blue

πŸƒ Card Overlay Polish

  • Larger emoji icons (2em) for better visibility
  • Proper table spacing with accent-colored borders
  • Improved heading, paragraph, and list margins
  • Inline code gets background + border-radius styling

🎬 3D Transitions

  • perspective β€” Y-axis 3D rotation
  • flip β€” X-axis 3D rotation
  • cube β€” cube-face rotation (experimental)

πŸ“ Documentation

  • Mock API testing workflow documented in README
  • goslide.yaml vs goslide.yaml.example usage clarified
  • Theme catalog updated with all 22 themes

Full Changelog

See v1.0.0...v1.1.0 for all changes.

v1.0.0

18 Apr 06:11

Choose a tag to compare

πŸŽ‰ GoSlide v1.0.0

Markdown-driven interactive presentations β€” single binary, offline-first.

✨ Highlights

  • 14 themes β€” default, dark, corporate, minimal, hacker, dracula, midnight, gruvbox, solarized, catppuccin-mocha, ink-wash, instagram, western, pixel
  • 8 accent colors β€” 112 visual combinations out of the box
  • 12 slide layouts β€” from simple title slides to multi-column and grid-cards
  • Interactive components β€” charts, diagrams, sortable tables, tabs, sliders, toggles, expandable cards
  • API dashboards β€” live data from backend APIs with auto-refresh and proxy support
  • Static export β€” goslide build produces a single self-contained HTML (~7MB), works offline
  • Host mode β€” serve a directory as a presentation library with index page
  • Speaker view β€” press S for timer, notes, and next slide preview
  • Live reload β€” edit your .md, browser auto-refreshes and keeps your slide position

πŸ“¦ Downloads

Platform File
Windows (x64) goslide-windows-amd64.exe
macOS (Intel) goslide-darwin-amd64
macOS (Apple Silicon) goslide-darwin-arm64
Linux (x64) goslide-linux-amd64
Linux (ARM64) goslide-linux-arm64

πŸš€ Quick Start

# Create a presentation
goslide init

# Serve with live reload
goslide serve talk.md

# Export as standalone HTML
goslide build talk.md

# Host multiple presentations
goslide host ./slides

πŸ“‹ Full Feature List

Rendering

  • Markdown β†’ Reveal.js slides with --- separators
  • YAML frontmatter for presentation config
  • 14 themes Γ— 8 accent colors
  • 12 layout templates (two-column, code-preview, grid-cards, etc.)
  • Fragment animations (fade-in, fade-up, highlight-current)
  • Custom slide transitions (slide, fade, perspective, flip, convex, concave, zoom)
  • CJK support with bundled Noto Sans TC font

Components

  • Charts: bar, line, pie, radar, sparkline (Chart.js)
  • Diagrams: Mermaid.js (flowcharts, sequence, ERD)
  • Tables: sortable with click-to-sort headers
  • Tabs + Panels: tabbed content switching
  • Slider: range input with live value display
  • Toggle: switch control with panel visibility binding
  • Expandable Cards: grid layout with click-to-expand detail overlay
  • API Component: fetch from proxied APIs with 7 render types (metric, chart, table, json, log, image, markdown)
  • Embed HTML: raw HTML/CSS/JS execution
  • Embed Iframe: embedded external pages

Infrastructure

  • Single binary with all assets embedded (~8MB)
  • Live reload via WebSocket with slide position preservation
  • API reverse proxy with header injection and env var expansion
  • Custom theme overrides via goslide.yaml
  • Static HTML export (single file, works offline)
  • Host mode with index page and directory watching
  • Speaker view with notes, timer, next slide preview
  • Lightweight presenter sync (viewers see presenter's slide + jump button)
  • Progress bar with click-to-jump

CLI

  • goslide serve β€” single file with live reload
  • goslide host β€” directory with index page
  • goslide build β€” static HTML export
  • goslide init β€” scaffold from templates (basic, demo, corporate)
  • goslide list β€” list presentations with metadata