Skip to content
This repository has been archived by the owner on Aug 29, 2023. It is now read-only.

Commit

Permalink
Merge c303c02 into 2a8f9fd
Browse files Browse the repository at this point in the history
  • Loading branch information
ystyle committed Nov 15, 2019
2 parents 2a8f9fd + c303c02 commit 9a32499
Show file tree
Hide file tree
Showing 5 changed files with 121 additions and 28 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
epubcheck*
.idea
*.epub
17 changes: 16 additions & 1 deletion epub.go
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ func (e *Epub) AddImage(source string, imageFilename string) (string, error) {
//
// The internal path to an already-added CSS file (as returned by AddCSS) to be
// used for the section is optional.
func (e *Epub) AddSection(body string, sectionTitle string, internalFilename string, internalCSSPath string) (string, error) {
func (e *Epub) addSection(body string, sectionTitle string, internalFilename string, internalCSSPath string, refInternalFilename string) (string, error) {
// Generate a filename if one isn't provided
if internalFilename == "" {
internalFilename = fmt.Sprintf(sectionFileFormat, len(e.sections)+1)
Expand All @@ -242,10 +242,25 @@ func (e *Epub) AddSection(body string, sectionTitle string, internalFilename str
xhtml: x,
}
e.sections = append(e.sections, s)
relativePath := filepath.Join(xhtmlFolderName, s.filename)
if refInternalFilename != "" {
refRelativePath := filepath.Join(xhtmlFolderName, refInternalFilename)
e.toc.addSubSection(refRelativePath, sectionTitle, relativePath)
} else {
e.toc.addSection(sectionTitle, relativePath)
}

return internalFilename, nil
}

func (e *Epub) AddSection(body string, sectionTitle string, internalFilename string, internalCSSPath string) (string, error) {
return e.addSection(body, sectionTitle, internalFilename, internalCSSPath, "")
}

func (e *Epub) AddSubSection(body string, sectionTitle string, internalFilename string, internalCSSPath string, refInternalFilename string) (string, error) {
return e.addSection(body, sectionTitle, internalFilename, internalCSSPath, refInternalFilename)
}

// Author returns the author of the EPUB.
func (e *Epub) Author() string {
return e.author
Expand Down
38 changes: 36 additions & 2 deletions example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@ package epub_test

import (
"fmt"
"log"

"github.com/bmaupin/go-epub"
"log"
)

func ExampleEpub_AddCSS() {
Expand Down Expand Up @@ -110,6 +109,41 @@ func ExampleEpub_AddSection() {
// section0002.xhtml
}

func ExampleEpub_AddSubSection() {
e := epub.NewEpub("My title")

// Add a section. The CSS path is optional
section1Body := ` <h1>Section 1</h1>
<p>This is a paragraph.</p>`
section1Path, err := e.AddSection(section1Body, "Section 1", "firstsection.xhtml", "")
if err != nil {
log.Fatal(err)
}

// Add a subsection.
section1_1Body := ` <h1>Section 1-1</h1>
<p>This is a paragraph.</p>`
section1_1Path, err := e.AddSubSection(section1_1Body, "Section 1-1", "", "", section1Path)

// Link to the first section
section2Body := fmt.Sprintf(` <h1>Section 2</h1>
<a href="%s">Link to section 1</a>`,
section1Path)
// The title and filename are also optional
section2Path, err := e.AddSection(section2Body, "", "", "")
if err != nil {
log.Fatal(err)
}
fmt.Println(section1Path)
fmt.Println(section1_1Path)
fmt.Println(section2Path)

// Output:
// firstsection.xhtml
// section0002.xhtml
// section0003.xhtml
}

func ExampleEpub_SetCover() {
e := epub.NewEpub("My title")

Expand Down
84 changes: 63 additions & 21 deletions toc.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ package epub
import (
"encoding/xml"
"fmt"
"github.com/gofrs/uuid"
"io/ioutil"
"path/filepath"
"strconv"
)

const (
Expand Down Expand Up @@ -54,18 +54,21 @@ type toc struct {
// Spec: http://www.idpf.org/epub/20/spec/OPF_2.0.1_draft.htm#Section2.4.1
ncxXML *tocNcxRoot

title string // EPUB title
title string // EPUB title
navTree map[string]*tocNavItem
NxcTree map[string]*tocNcxNavPoint
}

type tocNavBody struct {
XMLName xml.Name `xml:"nav"`
EpubType string `xml:"epub:type,attr"`
H1 string `xml:"h1"`
Links []tocNavItem `xml:"ol>li"`
XMLName xml.Name `xml:"nav"`
EpubType string `xml:"epub:type,attr"`
H1 string `xml:"h1"`
Links []*tocNavItem `xml:"ol>li"`
}

type tocNavItem struct {
A tocNavLink `xml:"a"`
A tocNavLink `xml:"a"`
Children []*tocNavItem `xml:"ol>li"`
}

type tocNavLink struct {
Expand All @@ -75,11 +78,11 @@ type tocNavLink struct {
}

type tocNcxRoot struct {
XMLName xml.Name `xml:"http://www.daisy.org/z3986/2005/ncx/ ncx"`
Version string `xml:"version,attr"`
Meta tocNcxMeta `xml:"head>meta"`
Title string `xml:"docTitle>text"`
NavMap []tocNcxNavPoint `xml:"navMap>navPoint"`
XMLName xml.Name `xml:"http://www.daisy.org/z3986/2005/ncx/ ncx"`
Version string `xml:"version,attr"`
Meta tocNcxMeta `xml:"head>meta"`
Title string `xml:"docTitle>text"`
NavMap []*tocNcxNavPoint `xml:"navMap>navPoint"`
}

type tocNcxContent struct {
Expand All @@ -92,10 +95,11 @@ type tocNcxMeta struct {
}

type tocNcxNavPoint struct {
XMLName xml.Name `xml:"navPoint"`
ID string `xml:"id,attr"`
Text string `xml:"navLabel>text"`
Content tocNcxContent `xml:"content"`
XMLName xml.Name `xml:"navPoint"`
ID string `xml:"id,attr"`
Text string `xml:"navLabel>text"`
Content tocNcxContent `xml:"content"`
Children []*tocNcxNavPoint `xml:"navMap>navPoint"`
}

// Constructor for toc
Expand All @@ -106,6 +110,8 @@ func newToc() *toc {

t.ncxXML = newTocNcxXML()

t.navTree = make(map[string]*tocNavItem)
t.NxcTree = make(map[string]*tocNcxNavPoint)
return t
}

Expand Down Expand Up @@ -147,24 +153,60 @@ func newTocNcxXML() *tocNcxRoot {
}

// Add a section to the TOC (navXML as well as ncxXML)
func (t *toc) addSection(index int, title string, relativePath string) {
func (t *toc) addSection(title string, relativePath string) {
relativePath = filepath.ToSlash(relativePath)
l := &tocNavItem{
A: tocNavLink{
Href: relativePath,
Data: title,
},
Children: []*tocNavItem{},
}
t.navXML.Links = append(t.navXML.Links, *l)

t.navTree[relativePath] = l
t.navXML.Links = append(t.navXML.Links, l)
uuid, _ := uuid.NewV4()
np := &tocNcxNavPoint{
ID: "navPoint-" + strconv.Itoa(index),
ID: "navPoint-" + uuid.String(),
Text: title,
Content: tocNcxContent{
Src: relativePath,
},
Children: []*tocNcxNavPoint{},
}
t.ncxXML.NavMap = append(t.ncxXML.NavMap, np)
t.NxcTree[relativePath] = np
}

// Add a section to the TOC (navXML as well as ncxXML)
func (t *toc) addSubSection(ref string, title string, relativePath string) {
refRelativePath := filepath.ToSlash(ref)
if link, ok := t.navTree[refRelativePath]; ok {
relativePath = filepath.ToSlash(relativePath)
l := &tocNavItem{
A: tocNavLink{
Href: relativePath,
Data: title,
},
Children: []*tocNavItem{},
}
link.Children = append(link.Children, l)
t.navTree[relativePath] = l

navMap, _ := t.NxcTree[refRelativePath]
uuid, _ := uuid.NewV4()
np := &tocNcxNavPoint{
ID: "navPoint-" + uuid.String(),
Text: title,
Content: tocNcxContent{
Src: relativePath,
},
Children: []*tocNcxNavPoint{},
}
navMap.Children = append(navMap.Children, np)
t.NxcTree[relativePath] = np
return
}
t.ncxXML.NavMap = append(t.ncxXML.NavMap, *np)
t.addSection(title, relativePath)
}

func (t *toc) setIdentifier(identifier string) {
Expand Down
8 changes: 4 additions & 4 deletions write.go
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,7 @@ func (e *Epub) writeSections(tempDir string) {
e.pkg.addToSpine(e.cover.xhtmlFilename)
}

for i, section := range e.sections {
for _, section := range e.sections {
// Set the title of the cover page XHTML to the title of the EPUB
if section.filename == e.cover.xhtmlFilename {
section.xhtml.setTitle(e.Title())
Expand All @@ -429,9 +429,9 @@ func (e *Epub) writeSections(tempDir string) {

relativePath := filepath.Join(xhtmlFolderName, section.filename)
// Don't add pages without titles or the cover to the TOC
if section.xhtml.Title() != "" && section.filename != e.cover.xhtmlFilename {
e.toc.addSection(i, section.xhtml.Title(), relativePath)
}
//if section.xhtml.Title() != "" && section.filename != e.cover.xhtmlFilename {
// e.toc.addSection(i, section.xhtml.Title(), relativePath)
//}
// The cover page should have already been added to the spine first
if section.filename != e.cover.xhtmlFilename {
e.pkg.addToSpine(section.filename)
Expand Down

0 comments on commit 9a32499

Please sign in to comment.