// Package html renders an internal.AggregatorWriter as a complete, // standalone HTML document: the report table fragment (built from the // shared table definition in internal/writing/internal/tabledef, so it can // never drift from the terminal layout) embedded in a Bootstrap-styled page // with a translated title and generation timestamp. package html import ( _ "embed" "fmt" "html/template" "io" "time" "github.com/nmoniz/any2anexoj/internal" "github.com/nmoniz/any2anexoj/internal/writing/internal/tabledef" ) // bootstrapCSSURL is the jsDelivr CDN URL for Bootstrap 5.3.3. const bootstrapCSSURL = "https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" // bootstrapIntegrity is the official SRI hash for Bootstrap 5.3.3 css. const bootstrapIntegrity = "sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" // Writer writes a complete HTML document for an AggregatorWriter. type Writer struct { output io.Writer translator tabledef.Translator lang string } // NewWriter builds a Writer that writes a complete HTML document to w. The // report table is rendered from the shared table definition via tr, and the // document title is looked up from the "report_title" translation via tr, // so callers never pass a pre-baked title. func NewWriter(w io.Writer, tr tabledef.Translator, lang string) *Writer { return &Writer{ output: w, translator: tr, lang: lang, } } //go:embed document.tmpl var documentTemplateBody string // documentTemplate renders the full HTML page from document.tmpl. The table // fragment is typed as template.HTML so the template engine emits it // verbatim without escaping the angle brackets in the