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{}