-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy pathnavigation.go
116 lines (101 loc) · 2.97 KB
/
navigation.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
105
106
107
108
109
110
111
112
113
114
115
116
// Copyright 2012 Ruben Pollan <[email protected]>
// Use of this source code is governed by a LGPL licence
// version 3 or later that can be found in the LICENSE file.
package epubgo
import (
"errors"
)
// NavigationIterator is an iterator on the epub navigation index tree.
//
// With it is possible to navigate throw the sections, subsections, ...
// of the epub.
type NavigationIterator struct {
parents []navCursor
curr navCursor
}
type navCursor struct {
navMap []navpoint
index int
}
func newNavigationIterator(navMap []navpoint) (*NavigationIterator, error) {
if len(navMap) == 0 {
return nil, errors.New("Navigation is empty")
}
var nav NavigationIterator
nav.curr.navMap = navMap
nav.curr.index = 0
return &nav, nil
}
// Title returns the title of the item on the iterator
func (nav NavigationIterator) Title() string {
return nav.item().Title()
}
// URL returns the url of the item on the iterator
//
// It usually contains a path and a section link after a '#'.
// The path can be open with epub.OpenFile()
func (nav NavigationIterator) URL() string {
return nav.item().URL()
}
// HasChildren returns whether the item has any children sections
func (nav NavigationIterator) HasChildren() bool {
return nav.item().Children() != nil
}
// HasParents returns whether the item has any parent sections
func (nav NavigationIterator) HasParents() bool {
return nav.parents != nil
}
// IsFirst returns whether the item is the first of the sections on the same depth level
func (nav NavigationIterator) IsFirst() bool {
return nav.curr.index == 0
}
// IsLast returns whether the item is the last of the sections on the same depth level
func (nav NavigationIterator) IsLast() bool {
return nav.curr.index == len(nav.curr.navMap)-1
}
// Next advances the iterator to the next element on the same depth level
//
// Returns an error if is the last
func (nav *NavigationIterator) Next() error {
if nav.IsLast() {
return errors.New("It is the last entry")
}
nav.curr.index++
return nil
}
// Previous steps back the iterator to the previous element on the same depth level
//
// Returns an error if is the first
func (nav *NavigationIterator) Previous() error {
if nav.IsFirst() {
return errors.New("It is the first entry")
}
nav.curr.index--
return nil
}
// In moves the iterator one level in on depth
//
// Returns an error if it don't has children
func (nav *NavigationIterator) In() error {
if !nav.HasChildren() {
return errors.New("It has no children")
}
nav.parents = append(nav.parents, nav.curr)
nav.curr.navMap = nav.item().Children()
nav.curr.index = 0
return nil
}
// Out moves the iterator one level out on depth
//
// Returns an error if it don't has parents
func (nav *NavigationIterator) Out() error {
if !nav.HasParents() {
return errors.New("It has no parents")
}
nav.curr = nav.parents[len(nav.parents)-1]
nav.parents = nav.parents[:len(nav.parents)-1]
return nil
}
func (nav NavigationIterator) item() *navpoint {
return &nav.curr.navMap[nav.curr.index]
}