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 <section data-slide="n"> 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 }