package tequat import ( "bufio" "fmt" "html" "html/template" "mime" "net/http" "strings" "pkg.jfrech.com/brief/mailx" "pkg.jfrech.com/brief/tequat/internal/formathtml" ) // TODO export when an HTML frontend is sincerely considered func (tqa TQA) formatHTML(as *AttachmentStore, fields []mailx.Field, w http.ResponseWriter) error { w.Header().Set("Content-Type", "text/html; charset=utf-8") w.Header().Set("X-Content-Type-Options", "nosniff") var parts []template.HTML for _, atom := range []Atom(tqa) { switch a := atom.(type) { case Text: parts = append(parts, template.HTML(`
` + html.EscapeString(a.Raw) + `
`)) case Quote: parts = append(parts, template.HTML(`
` + html.EscapeString(addprefix(">", a.Raw)) + `
`)) case SignatureBlock: parts = append(parts, template.HTML(`
-- ` + "\n" + html.EscapeString(a.Raw) + `
`)) case Attachment: asi, err := as.Put(a) if err != nil { return err } webviewableimage := func(t string) bool { return t == "image/png" || t == "image/jpeg" || t == "image/gif" } // TODO extend if t, _, err := mime.ParseMediaType(a.ContentType()); err == nil && webviewableimage(t) { parts = append(parts, template.HTML(``)) } else { parts = append(parts, template.HTML(`
attached ` + html.EscapeString(fmt.Sprintf("%s (%dB)", a.ContentType(), len(a.Data))) + `
`)) } // TODO case DroppedAlternatives: default: parts = append(parts, template.HTML(`
` + html.EscapeString(fmt.Sprintf("unrecognised type: %T", a)) + `
`)) } } return formathtml.Templates.ExecuteTemplate(w, "mail.html", struct{ Fields []mailx.Field; Parts []template.HTML; }{ Fields: fields, Parts: parts, }) } func addprefix(prefix string, lines string) string { b := new(strings.Builder) scanner := bufio.NewScanner(strings.NewReader(lines)) for scanner.Scan() { b.WriteString(prefix) b.Write(scanner.Bytes()) b.WriteString("\n") } if scanner.Err() != nil { panic("unreachable") } return b.String() }