diff --git a/README.md b/README.md
index bb6bfb8..537f7fd 100644
--- a/README.md
+++ b/README.md
@@ -18,10 +18,7 @@
```
3. 对自动生成的 epub 格式不满意可以自行修改后使用命令打包
+
```bash
bilinovel-downloader pack -d <目录路径>
```
-
-## 注意事项
-
-如果使用 [Kavita](https://github.com/Kareadita/Kavita) 阅读可能出现部分文字乱码问题,这是 Kavita 对 EPUB 格式支持不足导致的,目前在等待修复。
diff --git a/downloader/bilinovel/bilinovel.go b/downloader/bilinovel/bilinovel.go
index 7110829..ac0f777 100644
--- a/downloader/bilinovel/bilinovel.go
+++ b/downloader/bilinovel/bilinovel.go
@@ -260,7 +260,7 @@ func downloadVolume(volume *model.Volume, outputPath string) error {
return fmt.Errorf("failed to write volume: %v", err)
}
- coverPath := filepath.Join(outputPath, "OEBPS/Images/cover.jpg")
+ coverPath := filepath.Join(outputPath, "cover.jpeg")
err = os.MkdirAll(path.Dir(coverPath), 0755)
if err != nil {
return fmt.Errorf("failed to create cover directory: %v", err)
@@ -279,10 +279,7 @@ func downloadVolume(volume *model.Volume, outputPath string) error {
if err != nil {
return fmt.Errorf("failed to create cover file: %v", err)
}
- err = template.ContentXHTML(&model.Chapter{
- Title: "封面",
- Content: fmt.Sprintf(``, path.Ext(volume.Cover)),
- }).Render(context.Background(), file)
+ err = template.CoverXHTML(fmt.Sprintf(`../../cover%s`, strings.ReplaceAll(path.Ext(volume.Cover), "jpg", "jpeg"))).Render(context.Background(), file)
if err != nil {
return fmt.Errorf("failed to render cover: %v", err)
}
@@ -332,11 +329,6 @@ func downloadVolume(volume *model.Volume, outputPath string) error {
return fmt.Errorf("failed to create content opf: %v", err)
}
- err = CreateTocNCX(outputPath, u.String(), volume)
- if err != nil {
- return fmt.Errorf("failed to create toc ncx: %v", err)
- }
-
err = CreateEpub(outputPath)
if err != nil {
return fmt.Errorf("failed to create epub: %v", err)
@@ -530,7 +522,7 @@ func CreateContentOPF(dirPath string, uuid string, volume *model.Volume) error {
Metas: []model.DublinCoreMeta{
{
Name: "cover",
- Content: "images-cover" + path.Ext(volume.Cover),
+ Content: "cover",
},
{
Property: "dcterms:modified",
@@ -549,42 +541,38 @@ func CreateContentOPF(dirPath string, uuid string, volume *model.Volume) error {
manifest := &model.Manifest{
Items: make([]model.ManifestItem, 0),
}
- manifest.Items = append(manifest.Items, model.ManifestItem{
- ID: "ncx",
- Link: "toc.ncx",
- Media: "application/x-dtbncx+xml",
- })
manifest.Items = append(manifest.Items, model.ManifestItem{
ID: "cover.xhtml",
- Link: "Text/cover.xhtml",
+ Link: "OEBPS/Text/cover.xhtml",
Media: "application/xhtml+xml",
})
manifest.Items = append(manifest.Items, model.ManifestItem{
ID: "contents.xhtml",
- Link: "Text/contents.xhtml",
+ Link: "OEBPS/Text/contents.xhtml",
Media: "application/xhtml+xml",
Properties: "nav",
})
manifest.Items = append(manifest.Items, model.ManifestItem{
- ID: "images-cover" + path.Ext(volume.Cover),
- Link: fmt.Sprintf("Images/cover%s", path.Ext(volume.Cover)),
- Media: fmt.Sprintf("image/%s", strings.ReplaceAll(strings.TrimPrefix(path.Ext(volume.Cover), "."), "jpg", "jpeg")),
+ ID: "cover",
+ Link: fmt.Sprintf("cover%s", strings.ReplaceAll(path.Ext(volume.Cover), "jpg", "jpeg")),
+ Media: fmt.Sprintf("image/%s", strings.ReplaceAll(strings.TrimPrefix(path.Ext(volume.Cover), "."), "jpg", "jpeg")),
+ Properties: "cover-image",
})
manifest.Items = append(manifest.Items, model.ManifestItem{
ID: "read.ttf",
- Link: "Fonts/read.ttf",
+ Link: "OEBPS/Fonts/read.ttf",
Media: "application/vnd.ms-opentype",
})
for _, chapter := range volume.Chapters {
manifest.Items = append(manifest.Items, model.ManifestItem{
ID: path.Base(chapter.TextOEBPSPath),
- Link: chapter.TextOEBPSPath,
+ Link: "OEBPS/" + chapter.TextOEBPSPath,
Media: "application/xhtml+xml",
})
for _, image := range chapter.ImageOEBPSPaths {
item := model.ManifestItem{
ID: strings.Join(strings.Split(strings.ToLower(image), string(filepath.Separator)), "-"),
- Link: image,
+ Link: "OEBPS/" + image,
}
item.Media = fmt.Sprintf("image/%s", strings.ReplaceAll(strings.TrimPrefix(path.Ext(volume.Cover), "."), "jpg", "jpeg"))
manifest.Items = append(manifest.Items, item)
@@ -592,7 +580,7 @@ func CreateContentOPF(dirPath string, uuid string, volume *model.Volume) error {
}
manifest.Items = append(manifest.Items, model.ManifestItem{
ID: "style",
- Link: "Styles/style.css",
+ Link: "style.css",
Media: "text/css",
})
@@ -606,7 +594,7 @@ func CreateContentOPF(dirPath string, uuid string, volume *model.Volume) error {
})
}
}
- contentOPFPath := filepath.Join(dirPath, "OEBPS/content.opf")
+ contentOPFPath := filepath.Join(dirPath, "content.opf")
err := os.MkdirAll(path.Dir(contentOPFPath), 0755)
if err != nil {
return fmt.Errorf("failed to create content directory: %v", err)
@@ -622,51 +610,6 @@ func CreateContentOPF(dirPath string, uuid string, volume *model.Volume) error {
return nil
}
-func CreateTocNCX(dirPath string, uuid string, volume *model.Volume) error {
- navMap := &model.NavMap{Points: make([]*model.NavPoint, 0)}
- navMap.Points = append(navMap.Points, &model.NavPoint{
- Id: "cover",
- PlayOrder: 1,
- Label: "封面",
- Content: model.NavPointContent{Src: "Text/cover.xhtml"},
- })
- navMap.Points = append(navMap.Points, &model.NavPoint{
- Id: "contents",
- PlayOrder: 2,
- Label: "目录",
- Content: model.NavPointContent{Src: "Text/contents.xhtml"},
- })
- for idx, chapter := range volume.Chapters {
- navMap.Points = append(navMap.Points, &model.NavPoint{
- Id: fmt.Sprintf("chapter-%03v", idx+1),
- PlayOrder: len(navMap.Points) + 1,
- Label: chapter.Title,
- Content: model.NavPointContent{Src: chapter.TextOEBPSPath},
- })
- }
-
- head := &model.TocNCXHead{
- Meta: []model.TocNCXHeadMeta{
- {Name: "dtb:uid", Content: fmt.Sprintf("urn:uuid:%s", uuid)},
- },
- }
-
- ncxPath := filepath.Join(dirPath, "OEBPS/toc.ncx")
- err := os.MkdirAll(path.Dir(ncxPath), 0755)
- if err != nil {
- return fmt.Errorf("failed to create toc directory: %v", err)
- }
- file, err := os.Create(ncxPath)
- if err != nil {
- return fmt.Errorf("failed to create toc file: %v", err)
- }
- err = template.TocNCX(volume.Title, head, navMap).Render(context.Background(), file)
- if err != nil {
- return fmt.Errorf("failed to render toc: %v", err)
- }
- return nil
-}
-
//go:embed read.ttf
var readTTF []byte
diff --git a/downloader/bilinovel/epub.go b/downloader/bilinovel/epub.go
index 318c841..81846a8 100644
--- a/downloader/bilinovel/epub.go
+++ b/downloader/bilinovel/epub.go
@@ -31,7 +31,7 @@ func CreateEpub(path string) error {
return err
}
- err = addStringToZip(zipWriter, "OEBPS/Styles/style.css", StyleCSS, zip.Deflate)
+ err = addStringToZip(zipWriter, "style.css", StyleCSS, zip.Deflate)
if err != nil {
return err
}
diff --git a/downloader/bilinovel/style.css.go b/downloader/bilinovel/style.css.go
index 08c5ae9..3efa107 100644
--- a/downloader/bilinovel/style.css.go
+++ b/downloader/bilinovel/style.css.go
@@ -3,11 +3,15 @@ package bilinovel
const StyleCSS = `
@font-face {
font-family: "MI LANTING";
- src: url(../Fonts/read.ttf);
+ src: url(OEBPS/Fonts/read.ttf);
}
.read-font {
- font-family: "MI LANTING", serif !important;
+ display: block;
+ font-family: "MI LANTING", serif;
+ font-size: 1.33333em;
+ text-indent: 2em;
+ margin: 0.8em 0;
}
body > div {
diff --git a/model/container_opf.go b/model/container_opf.go
index c869ddb..965461d 100644
--- a/model/container_opf.go
+++ b/model/container_opf.go
@@ -158,7 +158,6 @@ type Spine struct {
}
func (s *Spine) Marshal() (string, error) {
- s.Toc = "ncx"
xmlBytes, err := xml.Marshal(s)
if err != nil {
return "", err
diff --git a/model/toc_ncx.go b/model/toc_ncx.go
deleted file mode 100644
index afa5512..0000000
--- a/model/toc_ncx.go
+++ /dev/null
@@ -1,47 +0,0 @@
-package model
-
-import "encoding/xml"
-
-type TocNCXHead struct {
- XMLName xml.Name `xml:"head"`
- Meta []TocNCXHeadMeta `xml:"meta"`
-}
-
-type TocNCXHeadMeta struct {
- XMLName xml.Name `xml:"meta"`
- Content string `xml:"content,attr"`
- Name string `xml:"name,attr"`
-}
-
-func (h *TocNCXHead) Marshal() (string, error) {
- xmlBytes, err := xml.Marshal(h)
- if err != nil {
- return "", err
- }
- return string(xmlBytes), nil
-}
-
-type NavPoint struct {
- Id string `xml:"id,attr"`
- PlayOrder int `xml:"playOrder,attr"`
- Label string `xml:"navLabel>text"`
- Content NavPointContent `xml:"content"`
- NavPoints []*NavPoint `xml:"navPoint"`
-}
-
-type NavPointContent struct {
- Src string `xml:"src,attr"`
-}
-
-type NavMap struct {
- XMLName xml.Name `xml:"navMap"`
- Points []*NavPoint `xml:"navPoint"`
-}
-
-func (n *NavMap) Marshal() (string, error) {
- xmlBytes, err := xml.Marshal(n)
- if err != nil {
- return "", err
- }
- return string(xmlBytes), nil
-}
diff --git a/template/container.xml.templ b/template/container.xml.templ
index 9796422..65ce672 100644
--- a/template/container.xml.templ
+++ b/template/container.xml.templ
@@ -4,7 +4,7 @@ templ ContainerXML() {
@templ.Raw(``)