cs-midi-docs/internal/render/pdf.go

71 lines
1.8 KiB
Go

package render
import (
"bytes"
"fmt"
"html/template"
"os/exec"
"git.else-if.org/jess/cs-midi-docs/internal/content"
)
var printTmpl = template.Must(template.New("print").Parse(`<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>{{.Title}}</title>
<style>
body { font-family: system-ui, sans-serif; max-width: 800px; margin: 0 auto; padding: 2em; color: #1a1a1a; line-height: 1.6; }
h1 { border-bottom: 2px solid #333; padding-bottom: 0.3em; }
h2 { border-bottom: 1px solid #ccc; padding-bottom: 0.2em; }
pre { background: #f5f5f5; padding: 1em; overflow-x: auto; border-radius: 4px; }
code { font-size: 0.9em; }
hr { margin: 3em 0; border: none; border-top: 1px solid #ccc; }
@media print { body { max-width: none; } pre { white-space: pre-wrap; } }
</style>
</head>
<body>{{.Body}}</body>
</html>`))
func GeneratePDF(tree *content.Node, title string) ([]byte, error) {
if _, err := exec.LookPath("weasyprint"); err != nil {
return nil, fmt.Errorf("weasyprint not found: install it for PDF generation")
}
htmlContent, err := BookHTML(tree)
if err != nil {
return nil, err
}
var page bytes.Buffer
printTmpl.Execute(&page, struct {
Title string
Body template.HTML
}{title, template.HTML(htmlContent)})
cmd := exec.Command("weasyprint", "-", "-")
cmd.Stdin = &page
var out bytes.Buffer
cmd.Stdout = &out
var stderr bytes.Buffer
cmd.Stderr = &stderr
if err := cmd.Run(); err != nil {
return nil, fmt.Errorf("weasyprint: %v: %s", err, stderr.String())
}
return out.Bytes(), nil
}
func PrintHTML(tree *content.Node, title string) ([]byte, error) {
htmlContent, err := BookHTML(tree)
if err != nil {
return nil, err
}
var page bytes.Buffer
printTmpl.Execute(&page, struct {
Title string
Body template.HTML
}{title, template.HTML(htmlContent)})
return page.Bytes(), nil
}