particle-academy/dark-slide
最新稳定版本:v0.7.0
Composer 安装命令:
composer require particle-academy/dark-slide
包简介
Standalone presentation read/write tool for agentic deck creation. Framework-agnostic PHP core that writes .pptx (Office Open XML) with inline markdown formatting + headings, real tables, gradient backgrounds, syntax-highlighted code, and embedded media — and reads them back with high fidelity. Opti
关键字:
README 文档
README
PHP package for reading and writing presentation files (.pptx) from a
JSON-friendly schema. Framework-agnostic core with an optional Laravel
adapter. Designed to round-trip with the
@particle-academy/fancy-slides
JS package's Deck schema — what the JS editor emits, DarkSlide writes
to a real Office Open XML file that opens in PowerPoint, Keynote,
Google Slides, and LibreOffice Impress.
Why
Sister project to holy-sheet
(XLSX writer). The two share an "agent emits JSON, PHP writes a real
document" pattern:
| Document type | JS authoring | PHP writing |
|---|---|---|
| Spreadsheets | fancy-sheets | holy-sheet |
| Presentations | fancy-slides | dark-slide |
Quickstart
use DarkSlide\Agent; $deck = [ 'id' => 'demo', 'title' => 'My deck', 'theme' => ['name' => 'default'], 'slides' => [ [ 'id' => 's1', 'layout' => 'title', 'elements' => [ [ 'id' => 'e1', 'type' => 'text', 'x' => 0.1, 'y' => 0.4, 'w' => 0.8, 'h' => 0.2, 'content' => 'Welcome to dark-slide', 'format' => 'plain', 'style' => ['fontSize' => 56, 'weight' => 'bold', 'align' => 'center'], ], ], ], ], ]; // Validate before writing — catches malformed agent output $errors = Agent::validate($deck); if (!empty($errors)) { foreach ($errors as $e) { echo "{$e['path']}: expected {$e['expected']}, got {$e['got']}\n"; } exit(1); } // Write to disk $result = Agent::write($deck, '/tmp/my-deck.pptx'); // $result === ['path' => '/tmp/my-deck.pptx', 'bytes' => 18432, 'slides' => 1] // Or get the bytes in memory (no temp file) $bytes = Agent::toBytes($deck);
Laravel
use DarkSlide\Laravel\Facades\DarkSlide; DarkSlide::write($deck, storage_path('app/decks/demo.pptx')); return response(DarkSlide::toBytes($deck), 200, [ 'Content-Type' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation', 'Content-Disposition' => 'attachment; filename="demo.pptx"', ]);
Schema
Mirrors @particle-academy/fancy-slides's Deck shape exactly. Coordinates
are 0..1 fractions; DarkSlide converts to PPTX EMU (914,400 per inch) on
write.
See docs/schema.md for the full reference.
Element coverage (v0.5)
| Element | Writer | Reader |
|---|---|---|
| text | ✅ markdown spans + headings (# / ## / ###) |
✅ markdown spans reconstructed |
| image | ✅ data URI + local path; fit (fill/cover/contain/scale-down) + crop; opt-in HTTP fetch |
✅ as data URI |
| shape | ✅ (rect, rounded-rect, ellipse, triangle, line, arrow) | ✅ |
| code | ✅ syntax-highlighted runs (JS/TS, PHP, JSON, bash, CSS, Python, HTML) | ✅ as text |
| table | ✅ real <a:tbl> (header + striped body rows) |
✅ round-trips columns + rows |
| background | ✅ solid color, gradient (linear-gradient(…)), image |
✅ solid, gradient, image-as-data-URI |
| chart | ✅ native OOXML chart parts (bar / line / area / pie / scatter) from an ECharts-style option; graceful image / placeholder fallback |
⚠ skipped |
| embed | not representable in pptx | n/a |
| transitions | ✅ per-slide transition (fade / slide / zoom) + deck defaultTransition |
⚠ skipped |
| animations | ✅ per-element animation (fade / fly-in / zoom / wipe) → <p:timing> build steps |
⚠ skipped |
What's new in v0.5
- Element entrance animations. Add
animation: { effect, trigger?, direction?, duration?, delay?, order? }to any element (effect:fade/fly-in/zoom/wipe). Slides with animations emit a real<p:timing>tree: builds are sorted by(order, index)and grouped into click steps (on-clickopens a step;with-prev/after-prevattach to it), mirroring fancy-slides' build sequencer. Each build targets its shape by the exact<p:cNvPr id>it was emitted with; animated shapes start hidden and reveal when their build fires. Elements withoutanimationare unaffected.
What's new in v0.4
- Slide transitions. Add
transition: { kind, duration?, direction? }to a slide (fade/slide/zoom), or a deck-widetheme.defaultTransition. - Image fit + crop.
fitis honoured (fill/covercentre-crop /contain&scale-downletterbox) and an explicitcrop: {x,y,w,h}maps to<a:srcRect>. Opt-in remote fetch viaAgent::write($deck, $path, ['allowHttpImages' => true])(off by default). - Native charts.
chartelements emit realppt/charts/chartN.xmlparts (no embedded workbook — literal caches) translated from an Apache ECharts-styleoption. Unsupported options fall back to a pre-rendered image or a titled placeholder. - Theme + layouts.
theme.colors/theme.fontsmap into the pptx clrScheme + fontScheme, and all 8 layouts ship as realslideLayoutN.xmlparts so PowerPoint recognises each slide's layout role.
What's new in v0.3
- Markdown headings.
# / ## / ###paragraph prefixes informat: "markdown"text elements emit larger bold runs in the pptx. - Syntax-highlighted code blocks. The
codeelement now ships one<a:r>per token, colored by kind (keyword / string / comment / number / builtin / punctuation). Pure-PHP tokenizer, zero third-party deps. Languages:javascript,typescript,jsx,tsx,php,json,bash,css,python,html. - Reader fidelity for v0.2 features. Tables, gradients, embedded images, and inline bold/italic/code spans now round-trip back to the Deck schema.
Agent tool-use surface
Agent::validateAndRepair($schema) returns ['ok' => bool, 'schema' => array, 'errors' => list] — wire it into your LLM tool to give the agent structured feedback on its emitted decks. Mirrors holy-sheet's pattern.
License
MIT
统计信息
- 总下载量: 100
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 2
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2026-05-26