From bd8506d367ea223f2efbf354aac4929df7e25e1e Mon Sep 17 00:00:00 2001 From: celogeek <65178+celogeek@users.noreply.github.com> Date: Thu, 4 May 2023 19:36:26 +0200 Subject: [PATCH 1/2] add option to portrait only mode --- internal/converter/converter.go | 1 + .../converter/options/converter_options.go | 40 ++++++++----------- internal/epub/options/epub_options.go | 1 + main.go | 7 ++-- 4 files changed, 22 insertions(+), 27 deletions(-) diff --git a/internal/converter/converter.go b/internal/converter/converter.go index 3b47242..a45083d 100644 --- a/internal/converter/converter.go +++ b/internal/converter/converter.go @@ -128,6 +128,7 @@ func (c *Converter) InitParse() { c.AddBoolParam(&c.Options.NoResize, "noresize", c.Options.NoResize, "Do not reduce image size if exceed device size") c.AddStringParam(&c.Options.Format, "format", c.Options.Format, "Format of output images: jpeg (lossy), png (lossless)") c.AddFloatParam(&c.Options.AspectRatio, "aspect-ratio", c.Options.AspectRatio, "Aspect ratio (height/width) of the output\n -1 = same as device\n 0 = same as source\n1.6 = amazon advice for kindle") + c.AddBoolParam(&c.Options.PortraitOnly, "portrait-only", c.Options.PortraitOnly, "Portrait only: force orientation to portrait only.") c.AddSection("Default config") c.AddBoolParam(&c.Options.Show, "show", false, "Show your default parameters") diff --git a/internal/converter/options/converter_options.go b/internal/converter/options/converter_options.go index c685e6a..280e777 100644 --- a/internal/converter/options/converter_options.go +++ b/internal/converter/options/converter_options.go @@ -44,6 +44,7 @@ type Options struct { NoResize bool `yaml:"noresize"` Format string `yaml:"format"` AspectRatio float64 `yaml:"aspect_ratio"` + PortraitOnly bool `yaml:"portrait_only"` // Default Config Show bool `yaml:"-"` @@ -73,30 +74,20 @@ type Options struct { // Initialize default options. func New() *Options { return &Options{ - Profile: "", - Quality: 85, - Grayscale: true, - Crop: true, - CropRatioLeft: 1, - CropRatioUp: 1, - CropRatioRight: 1, - CropRatioBottom: 3, - Brightness: 0, - Contrast: 0, - AutoRotate: false, - AutoSplitDoublePage: false, - NoBlankImage: true, - Manga: false, - HasCover: true, - LimitMb: 0, - StripFirstDirectoryFromToc: false, - SortPathMode: 1, - ForegroundColor: "000", - BackgroundColor: "FFF", - NoResize: false, - Format: "jpeg", - AspectRatio: 0, - profiles: profiles.New(), + Quality: 85, + Grayscale: true, + Crop: true, + CropRatioLeft: 1, + CropRatioUp: 1, + CropRatioRight: 1, + CropRatioBottom: 3, + NoBlankImage: true, + HasCover: true, + SortPathMode: 1, + ForegroundColor: "000", + BackgroundColor: "FFF", + Format: "jpeg", + profiles: profiles.New(), } } @@ -202,6 +193,7 @@ func (o *Options) ShowConfig() string { {"Background Color", fmt.Sprintf("#%s", o.BackgroundColor), true}, {"Resize", !o.NoResize, true}, {"Aspect Ratio", aspectRatio, true}, + {"Portrait Only", o.PortraitOnly, true}, } { if v.Condition { b.WriteString(fmt.Sprintf("\n %-26s: %v", v.Key, v.Value)) diff --git a/internal/epub/options/epub_options.go b/internal/epub/options/epub_options.go index 7f6cc42..8976b10 100644 --- a/internal/epub/options/epub_options.go +++ b/internal/epub/options/epub_options.go @@ -17,6 +17,7 @@ type Color struct { type View struct { Width, Height int AspectRatio float64 + PortraitOnly bool Color Color } diff --git a/main.go b/main.go index 0db43e5..f6bec7b 100644 --- a/main.go +++ b/main.go @@ -130,9 +130,10 @@ $ go install github.com/celogeek/go-comic-converter/v%d@%s Manga: cmd.Options.Manga, HasCover: cmd.Options.HasCover, View: &epuboptions.View{ - Width: profile.Width, - Height: profile.Height, - AspectRatio: cmd.Options.AspectRatio, + Width: profile.Width, + Height: profile.Height, + AspectRatio: cmd.Options.AspectRatio, + PortraitOnly: cmd.Options.PortraitOnly, Color: epuboptions.Color{ Foreground: cmd.Options.ForegroundColor, Background: cmd.Options.BackgroundColor, From 5b301526e131aa85edf149bb4bd813ff4ee2953a Mon Sep 17 00:00:00 2001 From: celogeek <65178+celogeek@users.noreply.github.com> Date: Thu, 4 May 2023 22:18:36 +0200 Subject: [PATCH 2/2] mode portrait only --- internal/epub/epub.go | 24 ++++++---- .../epub/templates/epub_templates_content.go | 47 ++++++++++++++++--- 2 files changed, 56 insertions(+), 15 deletions(-) diff --git a/internal/epub/epub.go b/internal/epub/epub.go index 80b87b0..2918bec 100644 --- a/internal/epub/epub.go +++ b/internal/epub/epub.go @@ -299,9 +299,12 @@ func (e *ePub) Write() error { if totalParts > 1 { title = fmt.Sprintf("%s [%d/%d]", title, i+1, totalParts) } - titleAlign := "left:0" - if e.Image.Manga { - titleAlign = "right:0" + titleAlign := "" + if !e.Image.View.PortraitOnly { + titleAlign = "left:0" + if e.Image.Manga { + titleAlign = "right:0" + } } content := []zipContent{ @@ -323,10 +326,7 @@ func (e *ePub) Write() error { {"OEBPS/Text/style.css", e.render(epubtemplates.Style, map[string]any{ "View": e.Image.View, })}, - {"OEBPS/Text/space_title.xhtml", e.render(epubtemplates.Blank, map[string]any{ - "Title": "Blank Page Title", - "ViewPort": fmt.Sprintf("width=%d,height=%d", e.Image.View.Width, e.Image.View.Height), - })}, + {"OEBPS/Text/title.xhtml", e.render(epubtemplates.Text, map[string]any{ "Title": title, "ViewPort": fmt.Sprintf("width=%d,height=%d", e.Image.View.Width, e.Image.View.Height), @@ -334,6 +334,14 @@ func (e *ePub) Write() error { "ImageStyle": part.Cover.ImgStyle(e.Image.View.Width, e.Image.View.Height, titleAlign), })}, } + if !e.Image.View.PortraitOnly { + content = append(content, zipContent{ + "OEBPS/Text/space_title.xhtml", e.render(epubtemplates.Blank, map[string]any{ + "Title": "Blank Page Title", + "ViewPort": fmt.Sprintf("width=%d,height=%d", e.Image.View.Width, e.Image.View.Height), + }), + }) + } if err = wz.WriteMagic(); err != nil { return err @@ -367,7 +375,7 @@ func (e *ePub) Write() error { } // Double Page or Last Image that is not a double page - if img.DoublePage || (img.Part == 0 && img == lastImage) { + if !e.Image.View.PortraitOnly && (img.DoublePage || (img.Part == 0 && img == lastImage)) { if err := e.writeBlank(wz, img); err != nil { return err } diff --git a/internal/epub/templates/epub_templates_content.go b/internal/epub/templates/epub_templates_content.go index 835b887..8a1d938 100644 --- a/internal/epub/templates/epub_templates_content.go +++ b/internal/epub/templates/epub_templates_content.go @@ -67,7 +67,12 @@ func Content(o *ContentOptions) string { } else { spine.CreateAttr("page-progression-direction", "ltr") } - addToElement(spine, getSpine) + + if o.ImageOptions.View.PortraitOnly { + addToElement(spine, getSpinePortrait) + } else { + addToElement(spine, getSpineAuto) + } guide := pkg.CreateElement("guide") addToElement(guide, getGuide) @@ -82,9 +87,6 @@ func Content(o *ContentOptions) string { func getMeta(o *ContentOptions) []tag { metas := []tag{ {"meta", tagAttrs{"property": "dcterms:modified"}, o.UpdatedAt}, - {"meta", tagAttrs{"property": "rendition:layout"}, "pre-paginated"}, - {"meta", tagAttrs{"property": "rendition:spread"}, "auto"}, - {"meta", tagAttrs{"property": "rendition:orientation"}, "auto"}, {"meta", tagAttrs{"property": "schema:accessMode"}, "visual"}, {"meta", tagAttrs{"property": "schema:accessModeSufficient"}, "visual"}, {"meta", tagAttrs{"property": "schema:accessibilityHazard"}, "noFlashingHazard"}, @@ -102,6 +104,20 @@ func getMeta(o *ContentOptions) []tag { {"dc:date", tagAttrs{}, o.UpdatedAt}, } + if o.ImageOptions.View.PortraitOnly { + metas = append(metas, []tag{ + {"meta", tagAttrs{"property": "rendition:layout"}, "pre-paginated"}, + {"meta", tagAttrs{"property": "rendition:spread"}, "none"}, + {"meta", tagAttrs{"property": "rendition:orientation"}, "portrait"}, + }...) + } else { + metas = append(metas, []tag{ + {"meta", tagAttrs{"property": "rendition:layout"}, "pre-paginated"}, + {"meta", tagAttrs{"property": "rendition:spread"}, "auto"}, + {"meta", tagAttrs{"property": "rendition:orientation"}, "auto"}, + }...) + } + if o.ImageOptions.Manga { metas = append(metas, tag{"meta", tagAttrs{"name": "primary-writing-mode", "content": "horizontal-rl"}, ""}) } else { @@ -142,18 +158,21 @@ func getManifest(o *ContentOptions) []tag { items := []tag{ {"item", tagAttrs{"id": "toc", "href": "toc.xhtml", "properties": "nav", "media-type": "application/xhtml+xml"}, ""}, {"item", tagAttrs{"id": "css", "href": "Text/style.css", "media-type": "text/css"}, ""}, - {"item", tagAttrs{"id": "space_title", "href": "Text/space_title.xhtml", "media-type": "application/xhtml+xml"}, ""}, {"item", tagAttrs{"id": "page_title", "href": "Text/title.xhtml", "media-type": "application/xhtml+xml"}, ""}, {"item", tagAttrs{"id": "img_title", "href": fmt.Sprintf("Images/title.%s", o.ImageOptions.Format), "media-type": fmt.Sprintf("image/%s", o.ImageOptions.Format)}, ""}, } + if !o.ImageOptions.View.PortraitOnly { + items = append(items, tag{"item", tagAttrs{"id": "space_title", "href": "Text/space_title.xhtml", "media-type": "application/xhtml+xml"}, ""}) + } + if o.ImageOptions.HasCover || o.Current > 1 { addTag(o.Cover, false) } lastImage := o.Images[len(o.Images)-1] for _, img := range o.Images { - addTag(img, img.DoublePage || (img.Part == 0 && img == lastImage)) + addTag(img, !o.ImageOptions.View.PortraitOnly && (img.DoublePage || (img.Part == 0 && img == lastImage))) } items = append(items, imageTags...) @@ -164,7 +183,7 @@ func getManifest(o *ContentOptions) []tag { } // spine part of the content -func getSpine(o *ContentOptions) []tag { +func getSpineAuto(o *ContentOptions) []tag { isOnTheRight := !o.ImageOptions.Manga getSpread := func(isDoublePage bool) string { isOnTheRight = !isOnTheRight @@ -214,6 +233,20 @@ func getSpine(o *ContentOptions) []tag { return spine } +func getSpinePortrait(o *ContentOptions) []tag { + spine := []tag{ + {"itemref", tagAttrs{"idref": "page_title"}, ""}, + } + for _, img := range o.Images { + spine = append(spine, tag{ + "itemref", + tagAttrs{"idref": img.PageKey()}, + "", + }) + } + return spine +} + // guide part of the content func getGuide(o *ContentOptions) []tag { guide := []tag{}