// Structs and functions for unmarshaling NCX files in e-pub archives
package main
import (
"fmt"
"encoding/xml"
"net/url"
"sort"
)
// A URI for content
type Content struct {
Src string `xml:"src,attr"`
}
// A content label and URI pair
type NavPoint struct {
Label string `xml:"navLabel>text"`
Content Content `xml:"content"`
Order int `xml:"playOrder,attr"`
}
// A series of navigation points
type Ncx struct {
XMLName xml.Name `xml:"ncx"`
Title string `xml:"docTitle>text"`
NavPoints []NavPoint `xml:"navMap>navPoint"`
}
// Parse an NCX file
func ParseNcx(content string) *Ncx {
dest := &Ncx{}
// Unmarshal XHTML
if err := xml.Unmarshal([]byte(content), &dest); err != nil {
fmt.Printf("error: %s\n", err)
}
// Sort navigation points
sort.Slice(dest.NavPoints, func(i, j int) bool {
return dest.NavPoints[i].Order < dest.NavPoints[j].Order
})
return dest
}
// Build a table of contents from an NCX file
func ReadTableOfContents(content string) []string {
ncx := ParseNcx(content)
var toc []string
for _, point := range ncx.NavPoints {
src, err := url.QueryUnescape(point.Content.Src)
if err != nil {
fmt.Printf("error: %s\n", err)
}
toc = append(toc, src)
}
return toc
}