diff options
| author | Paul Buetow <paul@buetow.org> | 2026-04-23 09:06:37 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-04-23 09:06:37 +0300 |
| commit | 1834c8886b15aa3b868e988c185ac5c344392886 (patch) | |
| tree | 89bab79059910638b7f8b3f865e9feddf95f4b81 /internal/config/config.go | |
| parent | 0ccc8073852895996ed70c4b2a86c460e3a3ddae (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.go | 40 |
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) } |
