Files
epuppy/pkg/epub/open.go

113 lines
1.9 KiB
Go
Raw Normal View History

2025-10-15 00:54:19 +02:00
package epub
import (
"archive/zip"
"fmt"
"log"
"os"
"strings"
"github.com/alecthomas/repr"
2025-10-15 00:54:19 +02:00
)
// Open open a epub file
func Open(fn string, dumpxml bool) (*Book, error) {
2025-10-15 00:54:19 +02:00
fd, err := zip.OpenReader(fn)
if err != nil {
return nil, err
}
defer func() {
if err := fd.Close(); err != nil {
log.Fatal(err)
}
}()
2025-10-15 00:54:19 +02:00
bk := Book{fd: fd}
mt, err := bk.readBytes("mimetype")
if err != nil {
return &bk, err
}
bk.Mimetype = string(mt)
err = bk.readXML("META-INF/container.xml", &bk.Container)
if err != nil {
return &bk, err
}
err = bk.readXML(bk.Container.Rootfile.Path, &bk.Opf)
if err != nil {
return &bk, err
}
for _, mf := range bk.Opf.Manifest {
if mf.ID == bk.Opf.Spine.Toc {
err = bk.readXML(bk.filename(mf.Href), &bk.Ncx)
if err != nil {
return &bk, err
}
2025-10-19 20:39:04 +02:00
}
2025-10-19 20:39:04 +02:00
if mf.ID == "cover-image" {
bk.CoverFile = mf.Href
bk.CoverMediaType = mf.MediaType
2025-10-15 00:54:19 +02:00
}
}
type section struct {
file, title string
}
sections := []section{}
if len(bk.Ncx.Points) > 0 {
for _, block := range bk.Ncx.Points {
sections = append(sections,
section{
file: "OEBPS/" + block.Content.Src,
title: block.Text,
})
}
} else {
for _, file := range bk.Files() {
sections = append(sections,
section{
file: file,
})
}
}
for _, section := range sections {
content, err := bk.readBytes(section.file)
2025-10-15 00:54:19 +02:00
if err != nil {
return &bk, err
}
if strings.Contains(section.file, bk.CoverFile) {
bk.CoverImage = content
}
ct := Content{Src: section.file, Title: section.title}
2025-10-19 20:39:04 +02:00
if strings.Contains(string(content), "<?xml") || strings.Contains(string(content), "<!DOCTYPE") {
if err := ct.String(content); err != nil {
return &bk, err
2025-10-19 20:39:04 +02:00
}
}
if dumpxml {
fmt.Println(string(ct.XML))
}
2025-10-19 20:39:04 +02:00
bk.Content = append(bk.Content, ct)
}
if dumpxml {
repr.Println(sections)
os.Exit(0)
2025-10-15 00:54:19 +02:00
}
return &bk, nil
}