forked from ystyle/kaf-cli
-
Notifications
You must be signed in to change notification settings - Fork 0
/
azw3.go
104 lines (95 loc) · 2.71 KB
/
azw3.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
package kafcli
import (
"bytes"
"fmt"
"github.com/leotaku/mobi"
"golang.org/x/text/language"
"image"
"math/rand"
"os"
"time"
)
type Azw3Converter struct{}
func (convert Azw3Converter) Build(book Book) error {
fmt.Println("使用第三方库生成azw3, 不保证所有样式都能正常显示")
fmt.Println("正在生成azw3...")
start := time.Now()
chunks := SectionSliceChunk(book.SectionList, 2000)
for i, chunk := range chunks {
index := i + 1
title := fmt.Sprintf("%s_%d", book.Bookname, index)
filename := fmt.Sprintf("%s_%d.azw3", book.Out, index)
if len(chunks) == 1 {
title = fmt.Sprintf("%s", book.Bookname)
filename = fmt.Sprintf("%s.azw3", book.Out)
}
mb := mobi.Book{
Title: title,
Authors: []string{book.Author},
CreatedDate: time.Now(),
Chapters: []mobi.Chapter{},
Language: language.MustParse(book.Lang),
UniqueID: rand.Uint32(),
}
var excss string
if book.LineHeight != "" {
excss = fmt.Sprintf("line-height: %s;", book.LineHeight)
}
css := fmt.Sprintf(cssContent, book.Align, book.Bottom, book.Indent, excss)
for _, section := range chunk {
ch := mobi.Chapter{
Title: section.Title,
Chunks: mobi.Chunks(convert.wrapTitle(section.Title, section.Content, book.Align)),
}
mb.Chapters = append(mb.Chapters, ch)
if len(section.Sections) > 0 {
for _, subsection := range section.Sections {
ch := mobi.Chapter{
Title: subsection.Title,
Chunks: mobi.Chunks(convert.wrapTitle(subsection.Title, subsection.Content, book.Align)),
}
mb.Chapters = append(mb.Chapters, ch)
}
}
}
mb.CSSFlows = []string{css}
if book.Cover != "" {
f, err := os.Open(book.Cover)
if err != nil {
return fmt.Errorf("添加封面失败: %w", err)
}
img, _, err := image.Decode(f)
if err != nil {
return fmt.Errorf("添加封面失败: %w", err)
}
mb.CoverImage = img
}
// Convert book to PalmDB database
db := mb.Realize()
// Write database to file
f, _ := os.Create(filename)
err := db.Write(f)
if err != nil {
return fmt.Errorf("保存失败: %w", err)
}
}
fmt.Println("生成azw3电子书耗时:", time.Now().Sub(start))
return nil
}
func (convert Azw3Converter) wrapTitle(title, content, align string) string {
var buff bytes.Buffer
buff.WriteString(fmt.Sprintf(mobiTtmlTitleStart, align))
buff.WriteString(title)
buff.WriteString(htmlTitleEnd)
buff.WriteString(content)
return buff.String()
}
func SectionSliceChunk(s []Section, size int) [][]Section {
var ret [][]Section
for size < len(s) {
// s[:size:size] 表示 len 为 size,cap 也为 size,第二个冒号后的 size 表示 cap
s, ret = s[size:], append(ret, s[:size:size])
}
ret = append(ret, s)
return ret
}