diff --git a/internal/converter/converter.go b/internal/converter/converter.go index a45083d..73d592e 100644 --- a/internal/converter/converter.go +++ b/internal/converter/converter.go @@ -129,6 +129,7 @@ func (c *Converter) InitParse() { 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.AddIntParam(&c.Options.TitlePage, "titlepage", c.Options.TitlePage, "Title page\n0 = never\n1 = always\n2 = only if epub is splitted") c.AddSection("Default config") c.AddBoolParam(&c.Options.Show, "show", false, "Show your default parameters") @@ -361,7 +362,12 @@ func (c *Converter) Validate() error { // Aspect Ratio if c.Options.AspectRatio < 0 && c.Options.AspectRatio != -1 { - return errors.New("aspect ratio should be: -1, 0, > 0") + return errors.New("aspect ratio should be -1, 0 or > 0") + } + + // Title Page + if c.Options.TitlePage < 0 || c.Options.TitlePage > 2 { + return errors.New("title page should be 0, 1 or 2") } return nil diff --git a/internal/converter/options/converter_options.go b/internal/converter/options/converter_options.go index 280e777..6362663 100644 --- a/internal/converter/options/converter_options.go +++ b/internal/converter/options/converter_options.go @@ -45,6 +45,7 @@ type Options struct { Format string `yaml:"format"` AspectRatio float64 `yaml:"aspect_ratio"` PortraitOnly bool `yaml:"portrait_only"` + TitlePage int `yaml:"title_page"` // Default Config Show bool `yaml:"-"` @@ -87,6 +88,7 @@ func New() *Options { ForegroundColor: "000", BackgroundColor: "FFF", Format: "jpeg", + TitlePage: 1, profiles: profiles.New(), } } @@ -167,6 +169,16 @@ func (o *Options) ShowConfig() string { aspectRatio = fmt.Sprintf("1:%0.2f (device)", float64(profile.Height)/float64(profile.Width)) } + titlePage := "" + switch o.TitlePage { + case 0: + titlePage = "never" + case 1: + titlePage = "always" + case 2: + titlePage = "when epub is splitted" + } + var b strings.Builder for _, v := range []struct { Key string @@ -194,6 +206,7 @@ func (o *Options) ShowConfig() string { {"Resize", !o.NoResize, true}, {"Aspect Ratio", aspectRatio, true}, {"Portrait Only", o.PortraitOnly, true}, + {"Title Page", titlePage, true}, } { if v.Condition { b.WriteString(fmt.Sprintf("\n %-26s: %v", v.Key, v.Value)) diff --git a/internal/epub/epub.go b/internal/epub/epub.go index ce13a96..4a170fd 100644 --- a/internal/epub/epub.go +++ b/internal/epub/epub.go @@ -372,6 +372,7 @@ func (e *ePub) Write() error { }) e.computeViewPort(epubParts) + hasTitlePage := e.TitlePage == 1 || (e.TitlePage == 2 && totalParts > 1) for i, part := range epubParts { ext := filepath.Ext(e.Output) suffix := "" @@ -398,6 +399,7 @@ func (e *ePub) Write() error { {"META-INF/com.apple.ibooks.display-options.xml", epubtemplates.AppleBooks}, {"OEBPS/content.opf", epubtemplates.Content(&epubtemplates.ContentOptions{ Title: title, + HasTitlePage: hasTitlePage, UID: e.UID, Author: e.Author, Publisher: e.Publisher, @@ -408,7 +410,7 @@ func (e *ePub) Write() error { Current: i + 1, Total: totalParts, })}, - {"OEBPS/toc.xhtml", epubtemplates.Toc(title, e.StripFirstDirectoryFromToc, part.Images)}, + {"OEBPS/toc.xhtml", epubtemplates.Toc(title, hasTitlePage, e.StripFirstDirectoryFromToc, part.Images)}, {"OEBPS/Text/style.css", e.render(epubtemplates.Style, map[string]any{ "View": e.Image.View, })}, @@ -427,8 +429,10 @@ func (e *ePub) Write() error { return err } - if err = e.writeTitleImage(wz, part.Cover, title); err != nil { - return err + if hasTitlePage { + if err = e.writeTitleImage(wz, part.Cover, title); err != nil { + return err + } } lastImage := part.Images[len(part.Images)-1] diff --git a/internal/epub/options/epub_options.go b/internal/epub/options/epub_options.go index 8976b10..83dedec 100644 --- a/internal/epub/options/epub_options.go +++ b/internal/epub/options/epub_options.go @@ -41,6 +41,7 @@ type Options struct { Input string Output string Title string + TitlePage int Author string LimitMb int StripFirstDirectoryFromToc bool diff --git a/internal/epub/templates/epub_templates_content.go b/internal/epub/templates/epub_templates_content.go index b851b62..46609a9 100644 --- a/internal/epub/templates/epub_templates_content.go +++ b/internal/epub/templates/epub_templates_content.go @@ -10,6 +10,7 @@ import ( type ContentOptions struct { Title string + HasTitlePage bool UID string Author string Publisher string @@ -156,14 +157,19 @@ 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": "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)}, ""}, {"item", tagAttrs{"id": "page_cover", "href": "Text/cover.xhtml", "media-type": "application/xhtml+xml"}, ""}, {"item", tagAttrs{"id": "img_cover", "href": fmt.Sprintf("Images/cover.%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.HasTitlePage { + items = append(items, + tag{"item", tagAttrs{"id": "page_title", "href": "Text/title.xhtml", "media-type": "application/xhtml+xml"}, ""}, + tag{"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"}, ""}) + } } lastImage := o.Images[len(o.Images)-1] @@ -198,9 +204,12 @@ func getSpineAuto(o *ContentOptions) []tag { return fmt.Sprintf("%s layout-blank", getSpread(false)) } - spine := []tag{ - {"itemref", tagAttrs{"idref": "space_title", "properties": getSpreadBlank()}, ""}, - {"itemref", tagAttrs{"idref": "page_title", "properties": getSpread(false)}, ""}, + spine := []tag{} + if o.HasTitlePage { + spine = append(spine, + tag{"itemref", tagAttrs{"idref": "space_title", "properties": getSpreadBlank()}, ""}, + tag{"itemref", tagAttrs{"idref": "page_title", "properties": getSpread(false)}, ""}, + ) } for _, img := range o.Images { if img.DoublePage && o.ImageOptions.Manga == isOnTheRight { @@ -230,8 +239,11 @@ func getSpineAuto(o *ContentOptions) []tag { } func getSpinePortrait(o *ContentOptions) []tag { - spine := []tag{ - {"itemref", tagAttrs{"idref": "page_title"}, ""}, + spine := []tag{} + if o.HasTitlePage { + spine = append(spine, + tag{"itemref", tagAttrs{"idref": "page_title"}, ""}, + ) } for _, img := range o.Images { spine = append(spine, tag{ diff --git a/internal/epub/templates/epub_templates_toc.go b/internal/epub/templates/epub_templates_toc.go index d7ea700..54966e2 100644 --- a/internal/epub/templates/epub_templates_toc.go +++ b/internal/epub/templates/epub_templates_toc.go @@ -9,7 +9,7 @@ import ( ) // create toc -func Toc(title string, stripFirstDirectoryFromToc bool, images []*epubimage.Image) string { +func Toc(title string, hasTitle bool, stripFirstDirectoryFromToc bool, images []*epubimage.Image) string { doc := etree.NewDocument() doc.CreateProcInst("xml", `version="1.0" encoding="UTF-8"`) doc.CreateDirective("DOCTYPE html") @@ -55,7 +55,11 @@ func Toc(title string, stripFirstDirectoryFromToc bool, images []*epubimage.Imag beginning := etree.NewElement("li") beginningLink := beginning.CreateElement("a") - beginningLink.CreateAttr("href", "Text/title.xhtml") + if hasTitle { + beginningLink.CreateAttr("href", "Text/title.xhtml") + } else { + beginningLink.CreateAttr("href", images[0].PagePath()) + } beginningLink.CreateText(title) ol.InsertChildAt(0, beginning) diff --git a/main.go b/main.go index f6bec7b..b8b72a1 100644 --- a/main.go +++ b/main.go @@ -105,6 +105,7 @@ $ go install github.com/celogeek/go-comic-converter/v%d@%s Output: cmd.Options.Output, LimitMb: cmd.Options.LimitMb, Title: cmd.Options.Title, + TitlePage: cmd.Options.TitlePage, Author: cmd.Options.Author, StripFirstDirectoryFromToc: cmd.Options.StripFirstDirectoryFromToc, SortPathMode: cmd.Options.SortPathMode,