package render
import (
"fmt"
"html/template"
"io"
"slidewalk/internal/parser"
"slidewalk/web"
)
var pageTemplate = template.Must(template.ParseFS(web.Templates, "templates/page.html.tmpl"))
// Page is the data needed to render a full slide deck as one HTML page.
type Page struct {
// Title is used as the document's
.
Title string
// Slides are the deck's slides, in presentation order.
Slides []parser.Slide
// DevReload, when true, includes the dev-only live-reload client script
// that listens for change notifications from the dev server. It must
// stay false for static exports.
DevReload bool
}
// slideView is the per-slide data exposed to the page template. Index is
// the slide's 1-based position, used as the data-slide attribute.
type slideView struct {
Index int
Title string
Class string
Notes string
Incremental bool
HTML template.HTML
}
// pageView is the top-level data exposed to the page template.
type pageView struct {
Title string
Slides []slideView
DevReload bool
}
// Render writes page as a single self-contained HTML document to w, with
// one per slide in presentation order.
//
// Render is the shared assembly step behind both the dev server
// (internal/watch) and the static exporter (internal/export): both call it
// to turn parsed slides into the final page, so the markup is only ever
// built in one place.
func Render(w io.Writer, page Page) error {
views := make([]slideView, len(page.Slides))
for i, s := range page.Slides {
views[i] = slideView{
Index: i + 1,
Title: s.Title,
Class: s.Class,
Notes: s.Notes,
Incremental: s.Incremental,
HTML: s.HTML,
}
}
data := pageView{Title: page.Title, Slides: views, DevReload: page.DevReload}
if err := pageTemplate.Execute(w, data); err != nil {
return fmt.Errorf("rendering page: %w", err)
}
return nil
}