package main import ( "context" "flag" "fmt" "log" "os" "os/exec" "path/filepath" "smartbar/internal/config" "github.com/chromedp/cdproto/emulation" "github.com/chromedp/cdproto/page" "github.com/chromedp/chromedp" ) func findChromeExec() (string, error) { // Honor CHROME_PATH if set if v := os.Getenv("CHROME_PATH"); v != "" { return v, nil } candidates := []string{ "google-chrome-stable", "google-chrome", "chromium-browser", "chromium", "chrome", } for _, name := range candidates { if p, err := exec.LookPath(name); err == nil { return p, nil } } return "", fmt.Errorf("no Chrome/Chromium executable found; set CHROME_PATH or install chromium/google-chrome") } func main() { var ( input string output string width float64 height float64 ) flag.StringVar(&input, "in", "", "input HTML file path (required)") flag.StringVar(&output, "out", "", "output PDF path (required)") flag.Float64Var(&width, "w", config.PageWidthIn, "page width in inches") flag.Float64Var(&height, "h", config.PageHeightIn, "page height in inches") flag.Parse() if input == "" || output == "" { log.Fatal("--in and --out are required") } absInput, _ := filepath.Abs(input) url := "file://" + absInput execPath, err := findChromeExec() if err != nil { log.Fatal(err) } opts := append(chromedp.DefaultExecAllocatorOptions[:], chromedp.ExecPath(execPath), chromedp.Flag("headless", true), chromedp.Flag("disable-gpu", true), chromedp.Flag("hide-scrollbars", true)) allocCtx, cancel := chromedp.NewExecAllocator(context.Background(), opts...) defer cancel() ctx, cancel := chromedp.NewContext(allocCtx) defer cancel() if err := chromedp.Run(ctx, chromedp.Tasks{ chromedp.Navigate(url), chromedp.ActionFunc(func(ctx context.Context) error { // Ensure media is print for layout (API style for v0.9.x) if err := emulation.SetEmulatedMedia().WithMedia("print").Do(ctx); err != nil { return err } // Print to PDF with exact dimensions and zero margins wIn := width hIn := height params := page.PrintToPDF(). WithPaperWidth(wIn). WithPaperHeight(hIn). WithMarginTop(0).WithMarginBottom(0).WithMarginLeft(0).WithMarginRight(0). WithPrintBackground(true) buf, _, err := params.Do(ctx) if err != nil { return err } if err := os.WriteFile(output, buf, 0o644); err != nil { return err } fmt.Printf("Wrote %s\n", output) return nil }), }); err != nil { log.Fatal(err) } }