commit 5c1a76f223b1e484b0a27bb7c9a085bcd74fcf16 Author: James Magahern Date: Sun Aug 10 17:17:01 2025 -0700 initial commit: vibe coded compiler diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..30b9507 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +dist/ + diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..be84654 --- /dev/null +++ b/Makefile @@ -0,0 +1,40 @@ +GO := $(shell which go) +ifeq (, $(GO)) + $(error "Required Go toolchain (go) not in $(PATH).") +endif + +PAGES := $(sort $(wildcard pages/*.html)) pages.yaml + +.PHONY: serve build clean + +build: dist/index.stamp + +dist/index.stamp: $(PAGES) templates/base.gohtml templates/index.gohtml templates/print.gohtml templates/print_2up.gohtml cmd/build/main.go + @$(GO) run ./cmd/build + @mkdir -p dist + @date +%s > dist/index.stamp + +serve: build + xdg-open "http://localhost:8000" || true + python -m http.server + +PDF := dist/output.pdf +PDF_2UP := dist/output-2up.pdf + +.PHONY: deps +deps: + @$(GO) mod tidy + +.PHONY: pdf +pdf: build deps + @echo "Generating PDF with headless Chrome..." + @$(GO) run ./cmd/pdf --in dist/print.html --out $(PDF) + +.PHONY: pdf-2up +pdf-2up: build deps + @echo "Generating 2-up PDF with headless Chrome..." + @$(GO) run ./cmd/pdf --in dist/print_2up.html --out $(PDF_2UP) --w 11 --h 8.5 + +clean: + rm -rf dist index.html + diff --git a/cmd/pdf/main.go b/cmd/pdf/main.go new file mode 100644 index 0000000..f7a2ec8 --- /dev/null +++ b/cmd/pdf/main.go @@ -0,0 +1,93 @@ +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", "dist/print.html", "input HTML file path") + flag.StringVar(&output, "out", "dist/output.pdf", "output PDF path") + flag.Float64Var(&width, "w", config.PageWidthIn, "page width in inches") + flag.Float64Var(&height, "h", config.PageHeightIn, "page height in inches") + flag.Parse() + + 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) + } +} diff --git a/css/style.css b/css/style.css new file mode 100644 index 0000000..7954087 --- /dev/null +++ b/css/style.css @@ -0,0 +1,69 @@ +@page { + /* Browsers may ignore CSS vars in @page; PDF size is controlled by generator */ + margin: 0; +} + +/* Base */ +html, body { + height: 100%; +} + +html, body { + margin: 0; + padding: 0; +} + +/* Use border-box sizing everywhere to keep dimensions predictable */ +html { box-sizing: border-box; } +*, *::before, *::after { box-sizing: inherit; } + +/* Screen preview: render a page at exact CSS inches and center it */ +@media screen { + body { + background: #eeeeee; + display: flex; + align-items: flex-start; + justify-content: center; + padding: 1rem; + box-sizing: border-box; + } + + #page { + width: var(--page-w, 5.5in); + height: var(--page-h, 8.5in); + background: white; + box-shadow: 0 0 0 1px rgba(0,0,0,0.08), 0 8px 24px rgba(0,0,0,0.18); + } +} + +/* Print-specific sizing to ensure exact physical dimensions */ +@media print { + html, body { + width: var(--page-w, 5.5in); + height: var(--page-h, 8.5in); + margin: 0; + padding: 0; + overflow: hidden; /* Never spill to a second page */ + } + + #page { + width: 100%; + height: 100%; + max-width: var(--page-w, 5.5in); + max-height: var(--page-h, 8.5in); + margin: 0; + padding: 0; + overflow: hidden; /* Clip any overflow just in case */ + page-break-inside: avoid; /* Legacy */ + break-inside: avoid-page; /* Modern */ + } + + /* Avoid browser-added headers/footers if possible (user may need to disable in print dialog) */ + body { + -webkit-print-color-adjust: exact; + print-color-adjust: exact; + box-sizing: border-box; + background: white; + } +} + diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..e1d0840 --- /dev/null +++ b/go.mod @@ -0,0 +1,18 @@ +module smartbar + +go 1.21 + +require ( + github.com/chromedp/cdproto v0.0.0-20240202021202-6d0b6a386732 + github.com/chromedp/chromedp v0.9.5 +) + +require ( + github.com/chromedp/sysutil v1.0.0 // indirect + github.com/gobwas/httphead v0.1.0 // indirect + github.com/gobwas/pool v0.2.1 // indirect + github.com/gobwas/ws v1.3.2 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/mailru/easyjson v0.7.7 // indirect + golang.org/x/sys v0.16.0 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..0744849 --- /dev/null +++ b/go.sum @@ -0,0 +1,23 @@ +github.com/chromedp/cdproto v0.0.0-20240202021202-6d0b6a386732 h1:XYUCaZrW8ckGWlCRJKCSoh/iFwlpX316a8yY9IFEzv8= +github.com/chromedp/cdproto v0.0.0-20240202021202-6d0b6a386732/go.mod h1:GKljq0VrfU4D5yc+2qA6OVr8pmO/MBbPEWqWQ/oqGEs= +github.com/chromedp/chromedp v0.9.5 h1:viASzruPJOiThk7c5bueOUY91jGLJVximoEMGoH93rg= +github.com/chromedp/chromedp v0.9.5/go.mod h1:D4I2qONslauw/C7INoCir1BJkSwBYMyZgx8X276z3+Y= +github.com/chromedp/sysutil v1.0.0 h1:+ZxhTpfpZlmchB58ih/LBHX52ky7w2VhQVKQMucy3Ic= +github.com/chromedp/sysutil v1.0.0/go.mod h1:kgWmDdq8fTzXYcKIBqIYvRRTnYb9aNS9moAV0xufSww= +github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU= +github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM= +github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og= +github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= +github.com/gobwas/ws v1.3.2 h1:zlnbNHxumkRvfPWgfXu8RBwyNR1x8wh9cf5PTOCqs9Q= +github.com/gobwas/ws v1.3.2/go.mod h1:hRKAFb8wOxFROYNsT1bqfWnhX+b5MFeJM9r2ZSwg/KY= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80 h1:6Yzfa6GP0rIo/kULo2bwGEkFvCePZ3qHDDTC3/J9Swo= +github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80/go.mod h1:imJHygn/1yfhB7XSJJKlFZKl/J+dCPAknuiaGOshXAs= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde h1:x0TT0RDC7UhAVbbWWBzr41ElhJx5tXPWkIHA2HWPRuw= +github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde/go.mod h1:nZgzbfBr3hhjoZnS66nKrHmduYNpc34ny7RK4z5/HM0= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= +golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= diff --git a/index.html b/index.html new file mode 100644 index 0000000..2116f1f --- /dev/null +++ b/index.html @@ -0,0 +1,34 @@ + + + + + + All Pages + + + + +
+ +
+
cover.html
+ +
+ +
+
bouba.html
+ +
+ +
+ + + + diff --git a/internal/config/config.go b/internal/config/config.go new file mode 100644 index 0000000..c62e1e2 --- /dev/null +++ b/internal/config/config.go @@ -0,0 +1,7 @@ +package config + +// Centralized physical page size in inches. Change here to retarget the whole system. +var ( + PageWidthIn = 5.5 + PageHeightIn = 8.5 +) diff --git a/pages.yaml b/pages.yaml new file mode 100644 index 0000000..eed6211 --- /dev/null +++ b/pages.yaml @@ -0,0 +1,5 @@ +# locations in pages/ + +- cover.html +- bouba.html + diff --git a/pages/bouba.html b/pages/bouba.html new file mode 100644 index 0000000..b49c822 --- /dev/null +++ b/pages/bouba.html @@ -0,0 +1,9 @@ + + +

bouba

+ +This is a test kiki. \ No newline at end of file diff --git a/pages/cover.html b/pages/cover.html new file mode 100644 index 0000000..bb62485 --- /dev/null +++ b/pages/cover.html @@ -0,0 +1,8 @@ + + +

Smart Bar

+welcome to smart bar \ No newline at end of file diff --git a/templates/base.gohtml b/templates/base.gohtml new file mode 100644 index 0000000..7fe5ab0 --- /dev/null +++ b/templates/base.gohtml @@ -0,0 +1,14 @@ + + + + + + {{ .Title }} + + + +
{{ .Content }}
+ + + + diff --git a/templates/index.gohtml b/templates/index.gohtml new file mode 100644 index 0000000..8ab4581 --- /dev/null +++ b/templates/index.gohtml @@ -0,0 +1,29 @@ + + + + + + All Pages + + + + +
+ {{ range .Pages }} +
+
{{ .Name }}
+ +
+ {{ end }} +
+ + + + diff --git a/templates/print.gohtml b/templates/print.gohtml new file mode 100644 index 0000000..de134e5 --- /dev/null +++ b/templates/print.gohtml @@ -0,0 +1,29 @@ + + + + + + Print + + + + + {{ range .Pages }} +
{{ .Content }}
+ {{ end }} + + + + diff --git a/templates/print_2up.gohtml b/templates/print_2up.gohtml new file mode 100644 index 0000000..a11d7c8 --- /dev/null +++ b/templates/print_2up.gohtml @@ -0,0 +1,32 @@ + + + + + + Print 2-Up + + + + + {{ range .Sheets }} +
+
{{ .Left.Content }}
+ {{ if .Right }}
{{ .Right.Content }}
{{ end }} +
+ {{ end }} + + + +