summaryrefslogtreecommitdiff
path: root/internal/config/config.go
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-04-23 09:06:37 +0300
committerPaul Buetow <paul@buetow.org>2026-04-23 09:06:37 +0300
commit1834c8886b15aa3b868e988c185ac5c344392886 (patch)
tree89bab79059910638b7f8b3f865e9feddf95f4b81 /internal/config/config.go
parent0ccc8073852895996ed70c4b2a86c460e3a3ddae (diff)
Add ISO A4 PDF print/book pipeline, page-frame prompts, and usage docs
Print and book PDF modes now letterbox each raster to A4 portrait at pdf.density; print uses the matte color for pads. CLI forces 3:4 generation for print|book unless --aspect-ratio is set. Cover, gallery, and back prompts gain DINA4PDF instructions when those modes are active. Introduce DescribePageFrame and PDF helpers with tests; add CLI tests for presentation and aspect precedence. Expand README and config example with A4 examples, language env vars, and page-format vs PDF behavior. Add sample Sumer vocabulary files. Made-with: Cursor
Diffstat (limited to 'internal/config/config.go')
-rw-r--r--internal/config/config.go40
1 files changed, 40 insertions, 0 deletions
diff --git a/internal/config/config.go b/internal/config/config.go
index 9286be3..a79c1ce 100644
--- a/internal/config/config.go
+++ b/internal/config/config.go
@@ -35,6 +35,7 @@ type Config struct {
Story StoryConfig `mapstructure:"story" yaml:"story"`
Styles StyleConfig `mapstructure:"styles" yaml:"styles"`
Narration NarrationConfig `mapstructure:"narration" yaml:"narration"`
+ PDF PDFConfig `mapstructure:"pdf" yaml:"pdf"`
PromptsDir string `mapstructure:"prompts_dir" yaml:"prompts_dir"`
}
@@ -110,6 +111,16 @@ type NarrationConfig struct {
ChunkWords int `mapstructure:"chunk_words" yaml:"chunk_words"`
}
+// PDFConfig controls final PDF assembly (ImageMagick).
+type PDFConfig struct {
+ // Density is the ImageMagick -density value (DPI hint for the PDF).
+ Density int `mapstructure:"density" yaml:"density"`
+ // JPEGQuality is 0 for default encoding, or 1–100 to JPEG-compress the PDF (smaller files).
+ JPEGQuality int `mapstructure:"jpeg_quality" yaml:"jpeg_quality"`
+ // Presentation is "none", "print" (matte + ISO A4 portrait pages), or "book" (aged tilt + ISO A4 portrait pages).
+ Presentation string `mapstructure:"presentation" yaml:"presentation"`
+}
+
// DefaultConfig returns a configuration populated with the initial Gemini-first defaults.
func DefaultConfig() *Config {
return &Config{
@@ -185,6 +196,11 @@ func DefaultConfig() *Config {
},
ChunkWords: 100,
},
+ PDF: PDFConfig{
+ Density: 150,
+ JPEGQuality: 0,
+ Presentation: "none",
+ },
PromptsDir: DefaultPromptsDir,
}
}
@@ -367,6 +383,20 @@ func (c *Config) normalize() {
if c.PromptsDir == "" {
c.PromptsDir = DefaultPromptsDir
}
+
+ if c.PDF.Density <= 0 {
+ c.PDF.Density = 150
+ }
+ if c.PDF.JPEGQuality < 0 {
+ c.PDF.JPEGQuality = 0
+ }
+ if c.PDF.JPEGQuality > 100 {
+ c.PDF.JPEGQuality = 100
+ }
+ c.PDF.Presentation = strings.ToLower(strings.TrimSpace(c.PDF.Presentation))
+ if c.PDF.Presentation == "" {
+ c.PDF.Presentation = "none"
+ }
}
func (c *Config) validate() error {
@@ -380,6 +410,12 @@ func (c *Config) validate() error {
return fmt.Errorf("unknown TTS provider: %s", c.Provider.TTS)
}
+ switch c.PDF.Presentation {
+ case "none", "print", "book":
+ default:
+ return fmt.Errorf("unknown pdf.presentation %q (use none, print, or book)", c.PDF.Presentation)
+ }
+
return nil
}
@@ -422,6 +458,10 @@ func setDefaults(v *viper.Viper, cfg *Config) {
v.SetDefault("narration.voices", cfg.Narration.Voices)
v.SetDefault("narration.chunk_words", cfg.Narration.ChunkWords)
+ v.SetDefault("pdf.density", cfg.PDF.Density)
+ v.SetDefault("pdf.jpeg_quality", cfg.PDF.JPEGQuality)
+ v.SetDefault("pdf.presentation", cfg.PDF.Presentation)
+
v.SetDefault("prompts_dir", cfg.PromptsDir)
}