Metadata-Version: 2.4
Name: astro-slidev
Version: 0.2.0
Summary: Turn an Astro content-collection blog post into a Slidev presentation deck — deterministic, no LLM.
Project-URL: Homepage, https://github.com/stormsidali2001/astro-slidev
Project-URL: Repository, https://github.com/stormsidali2001/astro-slidev
Project-URL: Issues, https://github.com/stormsidali2001/astro-slidev/issues
Author: Sidali Assoul
License-Expression: MIT
License-File: LICENSE
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Documentation
Classifier: Topic :: Text Processing :: Markup :: Markdown
Requires-Python: >=3.10
Requires-Dist: markdown-it-py>=3.0.0
Requires-Dist: mdit-py-plugins>=0.4.0
Requires-Dist: pillow>=10.0.0
Requires-Dist: pyyaml>=6.0
Requires-Dist: questionary>=2.0.0
Provides-Extra: dev
Requires-Dist: pytest>=8.0.0; extra == 'dev'
Description-Content-Type: text/markdown

# astro-slidev

Turn an Astro content-collection blog post into a [Slidev](https://sli.dev) presentation deck — **deterministic, no LLM**. The same post always produces the same deck: a rule-based planner decides slide breaks, code grouping, table chunking, and layout, so you get a reproducible result you can tweak and re-run, not a one-off AI summary.

```bash
pip install astro-slidev
cd my-astro-project
astro-slidev build src/content/blog/my-post.md
# -> .astro-slidev-build/my-post/slide.md (+ assets/, layouts/, styles/)

npx @slidev/cli dev .astro-slidev-build/my-post/slide.md
```

## What it does

- Parses a post's Markdown (frontmatter + body) into an intermediate representation, never touching your live site's content.
- Plans a deck: groups short paragraphs and short code blocks onto shared slides instead of one-block-per-slide, isolates long code blocks, chunks oversized tables across continuation slides (so a 30-row table doesn't silently run off the bottom of a slide), and gives every code+list pairing a two-column "explanation" layout when it's a genuine line-by-line walkthrough.
- Renders real Slidev markdown: a cover slide (title/description/date/tags), a section-divider slide per H2/H3, and content slides — plus an agenda and summary slide built from your headings.
- Handles images (colocated with the post, downscaled if oversized), GFM tables, KaTeX math (`$...$` / `$$...$$`, passed through untouched), blockquote-style callouts (`> **Note:** ...`), and speaker notes (`<!-- note: ... -->`, invisible on your live site, shown in Slidev's presenter view).
- Ships a small, optional accent-color theme (kicker bars, tag pills, tinted table headers) that stays off by default — a fresh install produces a plain, unbranded deck using Slidev's own theme.

## Why not just ask an LLM to write the slides?

You can, and for a one-off talk that's often faster. This exists for the opposite case: you maintain a blog with dozens of posts and want a repeatable, reviewable way to turn any of them into a deck — one whose output you can diff, whose grouping rules you can tune once for your whole content style, and that never silently changes when you rerun it.

## Prerequisites

- **Python 3.10+** — `astro-slidev` itself is a pure-Python CLI (no Node dependency to install it or run `build`).
- **An existing Astro project with a [content collection](https://docs.astro.build/en/guides/content-collections/)** — e.g. posts as Markdown files under `src/content/blog/`, each with frontmatter. This is what you point `astro-slidev` at; it never modifies your project, only reads a post and writes its output to a separate directory.
- **Node.js + npx** (or your package manager's equivalent) — only needed for the *preview/export* step, since Slidev itself is a Node/Vite tool. Not required just to install or run `astro-slidev build`; you'll need it the moment you want to actually look at the deck.

## Installation

```bash
pip install astro-slidev
```

That's it — no Node packages to add to your Astro project's `package.json`, no config file required to get started.

## Quickstart: using it in an Astro project

Starting from an existing Astro project with a content collection (e.g. `src/content/blog/my-post.md`):

```bash
# 1. Install the CLI (once per machine/venv — not a project dependency)
pip install astro-slidev

# 2. From your Astro project's root, generate a deck for one post
cd my-astro-project
astro-slidev build src/content/blog/my-post.md
# -> .astro-slidev-build/my-post/slide.md (+ assets/, layouts/, styles/)

# 3. Preview it with Slidev (installs @slidev/cli on the fly via npx)
npx @slidev/cli dev .astro-slidev-build/my-post/slide.md
# opens a live-reloading preview at http://localhost:3030

# 4. When you're happy with it, export a static build to share/host
npx @slidev/cli build .astro-slidev-build/my-post/slide.md --out dist/slides
```

Don't know the exact path offhand? Run `astro-slidev build` with no post argument and it'll ask you interactively (series, then post) instead of making you type the path.

`.astro-slidev-build/` is a working directory, not something to commit — add it to your project's `.gitignore` (or point `--out` somewhere outside the repo entirely).

## Usage

```bash
# Build a specific post (path or bare slug, resolved against content_dirs)
astro-slidev build src/content/blog/my-post.md
astro-slidev build my-post

# No post given -> pick one interactively (series, then post)
astro-slidev build

# Override output directory / config file
astro-slidev build my-post --out dist/deck --config ./my-slides.yaml
```

`astro-slidev build` always runs from your project root (the directory you invoke it from) and writes exactly one line to stdout: the path to the generated deck directory. Everything else (progress, the follow-up Slidev commands) goes to stderr, so it composes cleanly with shell capture:

```bash
npx @slidev/cli dev "$(astro-slidev build my-post)/slide.md"
```

## Configuration

Drop a `slides.config.yaml` in your project root (picked up automatically) or pass `--config path/to/file.yaml`. You only need to list the keys you want to override — see [`src/astro_slidev/slides.config.yaml`](src/astro_slidev/slides.config.yaml) for the full set of defaults with comments.

| Key | Default | What it controls |
|---|---|---|
| `content_dirs` | *auto-detected* | Where the interactive picker looks, and where a bare slug resolves against. Unset by default: auto-detects `src/content/blog`, or every subdirectory of `src/content/` if that doesn't exist — most projects need zero config here. Set explicitly if discovery picks the wrong thing, or for a multi-locale project (e.g. `["src/content/blog", "src/content/blog-fr"]`). |
| `max_words_per_slide` | `90` | Budget for packing paragraphs/explanations onto one slide. |
| `max_bullets_per_slide` | `6` | Max bullets before a list splits into continuation slides. |
| `max_code_blocks_per_slide` | `3` | Max consecutive short code blocks grouped onto one slide. |
| `max_lines_per_code_block` | `25` | A code block longer than this always gets its own slide. |
| `max_rows_per_slide` | `5` | Max table rows before it splits into continuation slides (header repeated). |
| `code_layout` | `two-cols` | Layout for a code block with an attached line-by-line explanation list. |
| `max_image_dimension` | `2000` | Images wider/taller than this (px) get downscaled on copy. |
| `include_agenda` / `include_summary` | `true` | Whether to generate an agenda slide after the cover and a summary slide at the end. |
| `font_sans` / `font_mono` / `accent_color` | unset | Opt-in branding — set these to match your site's design system (e.g. `accent_color: "#2563EB"`). Unset means a plain Slidev deck with no custom theming. |

## Supported post conventions

- **Frontmatter**: only `title` is required. `description`, `pubDate`, `tags`, `series`, `seriesOrder` are all optional and degrade gracefully (no subtitle/date/pill row on the cover slide if absent).
- **Headings**: body content should use `##`/`###` (H2/H3) — H2 becomes a section divider, H3 a subsection. A post with no headings at all still works (everything lands on one section).
- **Images**: `![alt](./chart.png)`, resolved relative to the post's own file — the standard Astro content-collection colocated-image convention.
- **Callouts**: an informal blockquote with a bold lead-in, e.g. `> **Note:** ...` / `> **Warning:** ...` / `> **Tip:** ...`.
- **Speaker notes**: `<!-- note: mention the live demo -->` (single- or multi-line) anywhere in the body — invisible on your live site, shown in Slidev's presenter view on whichever slide the following content lands on.
- **Math**: `$...$` and `$$...$$`, passed through verbatim for Slidev's built-in KaTeX rendering.

## Development

```bash
git clone https://github.com/stormsidali2001/astro-slidev
cd astro-slidev
python3 -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
pytest
```

## License

MIT — see [LICENSE](LICENSE).
