limit usage of Sprint

This commit is contained in:
Celogeek 2024-05-13 13:27:34 +02:00
parent 93294ba1f9
commit 0c8e54f0c4
Signed by: celogeek
SSH Key Fingerprint: SHA256:njNJLzoLQdbV9PC6ehcruRb0QnEgxABoCYZ+0+aUIYc
14 changed files with 190 additions and 66 deletions

View File

@ -104,7 +104,7 @@ func (c *Converter) InitParse() {
c.AddStringParam(&c.Options.Title, "title", "", "Title of the EPUB")
c.AddSection("Config")
c.AddStringParam(&c.Options.Profile, "profile", c.Options.Profile, fmt.Sprintf("Profile to use: \n%s", c.Options.AvailableProfiles()))
c.AddStringParam(&c.Options.Profile, "profile", c.Options.Profile, "Profile to use: \n"+c.Options.AvailableProfiles())
c.AddIntParam(&c.Options.Quality, "quality", c.Options.Quality, "Quality of the image")
c.AddBoolParam(&c.Options.Grayscale, "grayscale", c.Options.Grayscale, "Grayscale image. Ideal for eInk devices.")
c.AddIntParam(&c.Options.GrayscaleMode, "grayscale-mode", c.Options.GrayscaleMode, "Grayscale Mode\n0 = normal\n1 = average\n2 = luminance")
@ -298,10 +298,10 @@ func (c *Converter) Validate() error {
var defaultOutput string
inputBase := filepath.Clean(c.Options.Input)
if fi.IsDir() {
defaultOutput = fmt.Sprintf("%s.epub", inputBase)
defaultOutput = inputBase + ".epub"
} else {
ext := filepath.Ext(inputBase)
defaultOutput = fmt.Sprintf("%s.epub", inputBase[0:len(inputBase)-len(ext)])
defaultOutput = inputBase[0:len(inputBase)-len(ext)] + ".epub"
}
if c.Options.Output == "" {

View File

@ -9,6 +9,8 @@ import (
"strings"
"gopkg.in/yaml.v3"
"github.com/celogeek/go-comic-converter/v2/internal/pkg/utils"
)
type Options struct {
@ -217,13 +219,7 @@ func (o *Options) ShowConfig() string {
var profileDesc string
profile := o.GetProfile()
if profile != nil {
profileDesc = fmt.Sprintf(
"%s - %s - %dx%d",
o.Profile,
profile.Description,
profile.Width,
profile.Height,
)
profileDesc = profile.String()
}
sortpathmode := ""
@ -238,10 +234,10 @@ func (o *Options) ShowConfig() string {
aspectRatio := "auto"
if o.AspectRatio > 0 {
aspectRatio = fmt.Sprintf("1:%.02f", o.AspectRatio)
aspectRatio = "1:" + utils.FloatToString(o.AspectRatio, 2)
} else if o.AspectRatio < 0 {
if profile != nil {
aspectRatio = fmt.Sprintf("1:%0.2f (device)", float64(profile.Height)/float64(profile.Width))
aspectRatio = "1:" + utils.FloatToString(float64(profile.Height)/float64(profile.Width), 2) + " (device)"
} else {
aspectRatio = "1:?? (device)"
}
@ -277,7 +273,14 @@ func (o *Options) ShowConfig() string {
{"Grayscale", o.Grayscale, true},
{"Grayscale mode", grayscaleMode, o.Grayscale},
{"Crop", o.Crop, true},
{"Crop ratio", fmt.Sprintf("%d Left - %d Up - %d Right - %d Bottom - Limit %d%% - Skip %v", o.CropRatioLeft, o.CropRatioUp, o.CropRatioRight, o.CropRatioBottom, o.CropLimit, o.CropSkipIfLimitReached), o.Crop},
{"Crop ratio",
utils.IntToString(o.CropRatioLeft) + " Left - " +
utils.IntToString(o.CropRatioUp) + " Up - " +
utils.IntToString(o.CropRatioRight) + " Right - " +
utils.IntToString(o.CropRatioBottom) + " Bottom - " +
"Limit " + utils.IntToString(o.CropLimit) + "% - " +
"Skip " + utils.BoolToString(o.CropSkipIfLimitReached),
o.Crop},
{"Brightness", o.Brightness, o.Brightness != 0},
{"Contrast", o.Contrast, o.Contrast != 0},
{"Auto contrast", o.AutoContrast, true},
@ -288,11 +291,11 @@ func (o *Options) ShowConfig() string {
{"No blank image", o.NoBlankImage, true},
{"Manga", o.Manga, true},
{"Has cover", o.HasCover, true},
{"Limit", fmt.Sprintf("%d Mb", o.LimitMb), o.LimitMb != 0},
{"Limit", utils.IntToString(o.LimitMb) + " Mb", o.LimitMb != 0},
{"Strip first directory from toc", o.StripFirstDirectoryFromToc, true},
{"Sort path mode", sortpathmode, true},
{"Foreground color", fmt.Sprintf("#%s", o.ForegroundColor), true},
{"Background color", fmt.Sprintf("#%s", o.BackgroundColor), true},
{"Foreground color", "#" + o.ForegroundColor, true},
{"Background color", "#" + o.BackgroundColor, true},
{"Resize", !o.NoResize, true},
{"Aspect ratio", aspectRatio, true},
{"Portrait only", o.PortraitOnly, true},

View File

@ -4,6 +4,8 @@ package converter
import (
"fmt"
"strings"
"github.com/celogeek/go-comic-converter/v2/internal/pkg/utils"
)
type Profile struct {
@ -13,6 +15,10 @@ type Profile struct {
Height int `json:"height"`
}
func (p Profile) String() string {
return p.Code + " - " + p.Description + " - " + utils.IntToString(p.Width) + "x" + utils.IntToString(p.Height)
}
type Profiles map[string]Profile
// NewProfiles Initialize list of all supported profiles.
@ -61,9 +67,9 @@ func (p Profiles) String() string {
s := make([]string, 0)
for _, v := range p {
s = append(s, fmt.Sprintf(
" - %-7s ( %9s ) - %s",
" - %-7s - %4d x %-4d - %s",
v.Code,
fmt.Sprintf("%dx%d", v.Width, v.Height),
v.Width, v.Height,
v.Description,
))
}

View File

@ -73,8 +73,8 @@ func (e EPUB) writeImage(wz epubzip.EPUBZip, img epubimage.EPUBImage, zipImg *zi
err := wz.WriteContent(
img.EPUBPagePath(),
[]byte(e.render(epubtemplates.Text, map[string]any{
"Title": fmt.Sprintf("Image %d Part %d", img.Id, img.Part),
"ViewPort": fmt.Sprintf("width=%d,height=%d", e.Image.View.Width, e.Image.View.Height),
"Title": "Image " + utils.IntToString(img.Id) + " Part " + utils.IntToString(img.Part),
"ViewPort": e.Image.View.Port(),
"ImagePath": img.ImgPath(),
"ImageStyle": img.ImgStyle(e.Image.View.Width, e.Image.View.Height, ""),
})),
@ -91,8 +91,8 @@ func (e EPUB) writeBlank(wz epubzip.EPUBZip, img epubimage.EPUBImage) error {
return wz.WriteContent(
img.EPUBSpacePath(),
[]byte(e.render(epubtemplates.Blank, map[string]any{
"Title": fmt.Sprintf("Blank Page %d", img.Id),
"ViewPort": fmt.Sprintf("width=%d,height=%d", e.Image.View.Width, e.Image.View.Height),
"Title": "Blank Page " + utils.IntToString(img.Id),
"ViewPort": e.Image.View.Port(),
})),
)
}
@ -102,16 +102,16 @@ func (e EPUB) writeCoverImage(wz epubzip.EPUBZip, img epubimage.EPUBImage, part,
title := "Cover"
text := ""
if totalParts > 1 {
text = fmt.Sprintf("%d / %d", part, totalParts)
title = fmt.Sprintf("%s %s", title, text)
text = utils.IntToString(part) + " / " + utils.IntToString(totalParts)
title = title + " " + text
}
if err := wz.WriteContent(
"OEBPS/Text/cover.xhtml",
[]byte(e.render(epubtemplates.Text, map[string]any{
"Title": title,
"ViewPort": fmt.Sprintf("width=%d,height=%d", e.Image.View.Width, e.Image.View.Height),
"ImagePath": fmt.Sprintf("Images/cover.%s", e.Image.Format),
"ViewPort": e.Image.View.Port(),
"ImagePath": "Images/cover." + e.Image.Format,
"ImageStyle": img.ImgStyle(e.Image.View.Width, e.Image.View.Height, ""),
})),
); err != nil {
@ -156,7 +156,7 @@ func (e EPUB) writeTitleImage(wz epubzip.EPUBZip, img epubimage.EPUBImage, title
"OEBPS/Text/space_title.xhtml",
[]byte(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),
"ViewPort": e.Image.View.Port(),
})),
); err != nil {
return err
@ -167,8 +167,8 @@ func (e EPUB) writeTitleImage(wz epubzip.EPUBZip, img epubimage.EPUBImage, title
"OEBPS/Text/title.xhtml",
[]byte(e.render(epubtemplates.Text, map[string]any{
"Title": title,
"ViewPort": fmt.Sprintf("width=%d,height=%d", e.Image.View.Width, e.Image.View.Height),
"ImagePath": fmt.Sprintf("Images/title.%s", e.Image.Format),
"ViewPort": e.Image.View.Port(),
"ImagePath": "Images/title." + e.Image.Format,
"ImageStyle": img.ImgStyle(e.Image.View.Width, e.Image.View.Height, titleAlign),
})),
); err != nil {
@ -344,7 +344,7 @@ func (e EPUB) writePart(path string, currentPart, totalParts int, part epubPart,
title := e.Title
if totalParts > 1 {
title = fmt.Sprintf("%s [%d/%d]", title, currentPart, totalParts)
title = title + " [" + utils.IntToString(currentPart) + "/" + utils.IntToString(totalParts) + "]"
}
type zipContent struct {
@ -450,12 +450,12 @@ func (e EPUB) Write() error {
ext := filepath.Ext(e.Output)
suffix := ""
if totalParts > 1 {
fmtLen := len(fmt.Sprint(totalParts))
fmtPart := fmt.Sprintf(" Part %%0%dd of %%0%dd", fmtLen, fmtLen)
fmtLen := utils.FormatNumberOfDigits(totalParts)
fmtPart := "Part " + fmtLen + " of " + fmtLen
suffix = fmt.Sprintf(fmtPart, i+1, totalParts)
}
path := fmt.Sprintf("%s%s%s", e.Output[0:len(e.Output)-len(ext)], suffix, ext)
path := e.Output[0:len(e.Output)-len(ext)] + suffix + ext
if err := e.writePart(
path,

View File

@ -2,9 +2,10 @@
package epubimage
import (
"fmt"
"image"
"strings"
"github.com/celogeek/go-comic-converter/v2/internal/pkg/utils"
)
type EPUBImage struct {
@ -25,47 +26,51 @@ type EPUBImage struct {
// SpaceKey key name of the blank page after the image
func (i EPUBImage) SpaceKey() string {
return fmt.Sprintf("space_%d", i.Id)
return "space_" + utils.IntToString(i.Id)
}
// SpacePath path of the blank page
func (i EPUBImage) SpacePath() string {
return fmt.Sprintf("Text/%s.xhtml", i.SpaceKey())
return "Text/" + i.SpaceKey() + ".xhtml"
}
// EPUBSpacePath path of the blank page into the EPUB
func (i EPUBImage) EPUBSpacePath() string {
return fmt.Sprintf("OEBPS/%s", i.SpacePath())
return "OEBPS/" + i.SpacePath()
}
func (i EPUBImage) PartKey() string {
return utils.IntToString(i.Id) + "_p" + utils.IntToString(i.Part)
}
// PageKey key for page
func (i EPUBImage) PageKey() string {
return fmt.Sprintf("page_%d_p%d", i.Id, i.Part)
return "page_" + i.PartKey()
}
// PagePath page path linked to the image
func (i EPUBImage) PagePath() string {
return fmt.Sprintf("Text/%s.xhtml", i.PageKey())
return "Text/" + i.PageKey() + ".xhtml"
}
// EPUBPagePath page path into the EPUB
func (i EPUBImage) EPUBPagePath() string {
return fmt.Sprintf("OEBPS/%s", i.PagePath())
return "OEBPS/" + i.PagePath()
}
// ImgKey key for image
func (i EPUBImage) ImgKey() string {
return fmt.Sprintf("img_%d_p%d", i.Id, i.Part)
return "img_" + i.PartKey()
}
// ImgPath image path
func (i EPUBImage) ImgPath() string {
return fmt.Sprintf("Images/%s.%s", i.ImgKey(), i.Format)
return "Images/" + i.ImgKey() + "." + i.Format
}
// EPUBImgPath image path into the EPUB
func (i EPUBImage) EPUBImgPath() string {
return fmt.Sprintf("OEBPS/%s", i.ImgPath())
return "OEBPS/" + i.ImgPath()
}
// ImgStyle style to apply to the image.
@ -76,11 +81,11 @@ func (i EPUBImage) ImgStyle(viewWidth, viewHeight int, align string) string {
relWidth, relHeight := i.RelSize(viewWidth, viewHeight)
marginW, marginH := float64(viewWidth-relWidth)/2, float64(viewHeight-relHeight)/2
var style []string
style := make([]string, 0, 4)
style = append(style, fmt.Sprintf("width:%dpx", relWidth))
style = append(style, fmt.Sprintf("height:%dpx", relHeight))
style = append(style, fmt.Sprintf("top:%.2f%%", marginH*100/float64(viewHeight)))
style = append(style, "width:"+utils.IntToString(relWidth)+"px")
style = append(style, "height:"+utils.IntToString(relHeight)+"px")
style = append(style, "top:"+utils.FloatToString(marginH*100/float64(viewHeight), 2)+"%")
if align == "" {
switch i.Position {
case "rendition:page-spread-left":
@ -88,7 +93,7 @@ func (i EPUBImage) ImgStyle(viewWidth, viewHeight int, align string) string {
case "rendition:page-spread-right":
style = append(style, "left:0")
default:
style = append(style, fmt.Sprintf("left:%.2f%%", marginW*100/float64(viewWidth)))
style = append(style, "left:"+utils.FloatToString(marginW*100/float64(viewWidth), 2)+"%")
}
} else {
style = append(style, align)

View File

@ -404,7 +404,7 @@ func (e EPUBImageProcessor) loadPdf() (totalImages int, output chan task, err er
}
totalImages = len(pdf.Pages())
pageFmt := fmt.Sprintf("page %%0%dd", len(fmt.Sprintf("%d", totalImages)))
pageFmt := "page " + utils.FormatNumberOfDigits(totalImages)
output = make(chan task)
go func() {
defer close(output)

View File

@ -2,7 +2,6 @@
package epubimageprocessor
import (
"fmt"
"image"
"image/color"
"image/draw"
@ -324,7 +323,7 @@ func (e EPUBImageProcessor) CoverTitleData(o CoverTitleDataOptions) (epubzip.Ima
g.Draw(dst, o.Src)
return epubzip.CompressImage(
fmt.Sprintf("OEBPS/Images/%s.%s", o.Name, e.Image.Format),
"OEBPS/Images/"+o.Name+"."+e.Image.Format,
e.Image.Format,
dst,
e.Image.Quality,

View File

@ -1,8 +1,6 @@
// Package epuboptions EPUBOptions for EPUB creation.
package epuboptions
import "fmt"
type EPUBOptions struct {
Input string
Output string
@ -29,5 +27,5 @@ func (o EPUBOptions) WorkersRatio(pct int) (nbWorkers int) {
}
func (o EPUBOptions) ImgStorage() string {
return fmt.Sprintf("%s.tmp", o.Output)
return o.Output + ".tmp"
}

View File

@ -20,3 +20,7 @@ type Image struct {
Format string
AppleBookCompatibility bool
}
func (i Image) MediaType() string {
return "image/" + i.Format
}

View File

@ -1,8 +1,20 @@
package epuboptions
import (
"github.com/celogeek/go-comic-converter/v2/internal/pkg/utils"
)
type View struct {
Width, Height int
AspectRatio float64
PortraitOnly bool
Color Color
}
func (v View) Dimension() string {
return utils.IntToString(v.Width) + "x" + utils.IntToString(v.Height)
}
func (v View) Port() string {
return "width=" + utils.IntToString(v.Width) + ",height=" + utils.IntToString(v.Height)
}

View File

@ -38,15 +38,19 @@ func New(o Options) EPUBProgress {
}
}
fmtJob := fmt.Sprintf("%%0%dd", len(fmt.Sprint(o.TotalJob)))
fmtDesc := fmt.Sprintf("[%s/%s] %%-15s", fmtJob, fmtJob)
fmtJob := utils.FormatNumberOfDigits(o.TotalJob)
return progressbar.NewOptions(o.Max,
progressbar.OptionSetWriter(os.Stderr),
progressbar.OptionThrottle(65*time.Millisecond),
progressbar.OptionOnCompletion(func() {
utils.Println()
}),
progressbar.OptionSetDescription(fmt.Sprintf(fmtDesc, o.CurrentJob, o.TotalJob, o.Description)),
progressbar.OptionSetDescription(fmt.Sprintf(
"["+fmtJob+"/"+fmtJob+"] %-15s",
o.CurrentJob,
o.TotalJob,
o.Description,
)),
progressbar.OptionSetWidth(60),
progressbar.OptionShowCount(),
progressbar.OptionSetRenderBlankState(true),

View File

@ -1,12 +1,11 @@
package epubtemplates
import (
"fmt"
"github.com/beevik/etree"
"github.com/celogeek/go-comic-converter/v2/internal/pkg/epubimage"
"github.com/celogeek/go-comic-converter/v2/internal/pkg/epuboptions"
"github.com/celogeek/go-comic-converter/v2/internal/pkg/utils"
)
type Content struct {
@ -98,9 +97,9 @@ func (o Content) getMeta() []tag {
{"meta", tagAttrs{"property": "schema:accessibilityHazard"}, "noSoundHazard"},
{"meta", tagAttrs{"name": "book-type", "content": "comic"}, ""},
{"opf:meta", tagAttrs{"name": "fixed-layout", "content": "true"}, ""},
{"opf:meta", tagAttrs{"name": "original-resolution", "content": fmt.Sprintf("%dx%d", o.ImageOptions.View.Width, o.ImageOptions.View.Height)}, ""},
{"opf:meta", tagAttrs{"name": "original-resolution", "content": o.ImageOptions.View.Dimension()}, ""},
{"dc:title", tagAttrs{}, o.Title},
{"dc:identifier", tagAttrs{"id": "ean"}, fmt.Sprintf("urn:uuid:%s", o.UID)},
{"dc:identifier", tagAttrs{"id": "ean"}, "urn:uuid:" + o.UID},
{"dc:language", tagAttrs{}, "en"},
{"dc:creator", tagAttrs{}, o.Author},
{"dc:publisher", tagAttrs{}, o.Publisher},
@ -134,7 +133,7 @@ func (o Content) getMeta() []tag {
metas = append(
metas,
tag{"meta", tagAttrs{"name": "calibre:series", "content": o.Title}, ""},
tag{"meta", tagAttrs{"name": "calibre:series_index", "content": fmt.Sprint(o.Current)}, ""},
tag{"meta", tagAttrs{"name": "calibre:series_index", "content": utils.IntToString(o.Current)}, ""},
)
}
@ -145,7 +144,7 @@ func (o Content) getManifest() []tag {
var imageTags, pageTags, spaceTags []tag
addTag := func(img epubimage.EPUBImage, withSpace bool) {
imageTags = append(imageTags,
tag{"item", tagAttrs{"id": img.ImgKey(), "href": img.ImgPath(), "media-type": fmt.Sprintf("image/%s", o.ImageOptions.Format)}, ""},
tag{"item", tagAttrs{"id": img.ImgKey(), "href": img.ImgPath(), "media-type": o.ImageOptions.MediaType()}, ""},
)
pageTags = append(pageTags,
tag{"item", tagAttrs{"id": img.PageKey(), "href": img.PagePath(), "media-type": "application/xhtml+xml"}, ""},
@ -161,13 +160,13 @@ func (o Content) getManifest() []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_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)}, ""},
{"item", tagAttrs{"id": "img_cover", "href": "Images/cover." + o.ImageOptions.Format, "media-type": o.ImageOptions.MediaType()}, ""},
}
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)}, ""},
tag{"item", tagAttrs{"id": "img_title", "href": "Images/title." + o.ImageOptions.Format, "media-type": o.ImageOptions.MediaType()}, ""},
)
if !o.ImageOptions.View.PortraitOnly {
@ -212,7 +211,7 @@ func (o Content) getSpineAuto() []tag {
}
}
getSpreadBlank := func() string {
return fmt.Sprintf("%s layout-blank", getSpread(false))
return getSpread(false) + " layout-blank"
}
var spine []tag

View File

@ -3,6 +3,7 @@ package utils
import (
"fmt"
"os"
"strconv"
)
func Printf(format string, a ...interface{}) {
@ -12,3 +13,34 @@ func Printf(format string, a ...interface{}) {
func Println(a ...interface{}) {
_, _ = fmt.Fprintln(os.Stderr, a...)
}
func IntToString(i int) string {
return strconv.FormatInt(int64(i), 10)
}
func FloatToString(f float64, precision int) string {
return strconv.FormatFloat(f, 'f', precision, 64)
}
func BoolToString(b bool) string {
if b {
return "true"
}
return "false"
}
func NumberOfDigits(i int) int {
x, count := 10, 1
if i < 0 {
i = -i
count++
}
for ; x <= i; count++ {
x *= 10
}
return count
}
func FormatNumberOfDigits(i int) string {
return "%0" + IntToString(NumberOfDigits(i)) + "d"
}

View File

@ -0,0 +1,62 @@
package utils
import "fmt"
func ExampleFloatToString() {
fmt.Println("test=" + FloatToString(3.14151617, 0) + "=")
fmt.Println("test=" + FloatToString(3.14151617, 1) + "=")
fmt.Println("test=" + FloatToString(3.14151617, 2) + "=")
fmt.Println("test=" + FloatToString(3.14151617, 4) + "=")
// Output: test=3=
// test=3.1=
// test=3.14=
// test=3.1415=
}
func ExampleIntToString() {
fmt.Println("test=" + IntToString(159) + "=")
// Output: test=159=
}
func ExampleNumberOfDigits() {
fmt.Println(NumberOfDigits(0))
fmt.Println(NumberOfDigits(4))
fmt.Println(NumberOfDigits(10))
fmt.Println(NumberOfDigits(14))
fmt.Println(NumberOfDigits(256))
fmt.Println(NumberOfDigits(2004))
fmt.Println(NumberOfDigits(-5))
fmt.Println(NumberOfDigits(-10))
fmt.Println(NumberOfDigits(-12))
// Output: 1
// 1
// 2
// 2
// 3
// 4
// 2
// 3
// 3
}
func ExampleFormatNumberOfDigits() {
fmt.Println(FormatNumberOfDigits(0))
fmt.Println(FormatNumberOfDigits(4))
fmt.Println(FormatNumberOfDigits(10))
fmt.Println(FormatNumberOfDigits(14))
fmt.Println(FormatNumberOfDigits(256))
fmt.Println(FormatNumberOfDigits(2004))
fmt.Println(FormatNumberOfDigits(-5))
fmt.Println(FormatNumberOfDigits(-10))
fmt.Println(FormatNumberOfDigits(-12))
// Output: %01d
// %01d
// %02d
// %02d
// %03d
// %04d
// %02d
// %03d
// %03d
}