/
space.go
130 lines (110 loc) · 2.41 KB
/
space.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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
package space
import (
"path/filepath"
"regexp"
"github.com/codegangsta/inject"
mw "github.com/futurespace/ware"
)
var reHtml = regexp.MustCompile("(index)?.html$")
var cache map[string]string
type Space struct {
inject.Injector
Site *Site
Processor *Processor
fs Filesystem
dir string
}
func New() *Space {
s := &Space{inject.New(), &Site{}, NewProcessor(), NewFilesystem(), "."}
return s
}
// Sets a working directory.
func (s *Space) Dir(path string) (err error) {
path, err = filepath.Abs(path)
if err != nil {
return err
}
s.dir = path
return
}
// Joins the path and defaults path by key.
func (s *Space) joinPath(path string, defaults string) string {
if path == "" {
path = defaults
}
return s.Join(path)
}
func (s *Space) Source() string {
return s.joinPath(s.Site.Source, "src")
}
func (s *Space) Destination() string {
return s.joinPath(s.Site.Destination, "build")
}
func (s *Space) Join(path ...string) string {
p := make([]string, len(path)+1)
p[0] = s.dir
copy(p[1:], path)
return filepath.Join(p...)
}
func (s *Space) Paths(path string) FileInfos {
return s.fs.Walk(path)
}
type ClassicSpace struct {
*Space
*mw.Ware
}
func Classic() *ClassicSpace {
// Create a Ware.
w := mw.New()
s := New()
p := s.Processor
s.Map(w)
w.MapTo(s.fs, (*Filesystem)(nil))
w.Use(Logger())
w.Use(generate(s))
w.Use(build(s))
w.Action(p.Handle)
return &ClassicSpace{s, w}
}
func generate(s *Space) mw.Handler {
return func(c mw.Context) {
c.Next()
files := s.fs.Files()
pages := s.Site.Pages
posts := s.Site.Posts
for id, _ := range pages {
files[cache[id]].Write()
}
for id, _ := range posts {
files[cache[id]].Write()
}
}
}
func build(s *Space) mw.Handler {
return func(c mw.Context) {
source := s.Source()
fileInfos := s.Paths(source)
for path, fileInfo := range fileInfos {
s.fs.Add(fileInfo, path, source)
}
c.Next()
cache = make(map[string]string, 0)
pages := make(Pages, 0)
posts := make(Pages, 0)
s.Site.Pages = pages
s.Site.Posts = posts
for k, file := range s.fs.Files() {
page := file.Page
page.Url = page.Permalink
page.Id = filepath.FromSlash(reHtml.ReplaceAllString(page.Permalink, ""))
page.Target.Rel = page.Permalink
page.Target.Abs = filepath.Join(s.Destination(), page.Target.Rel)
if page.Type == "page" {
pages[page.Id] = page
} else {
posts[page.Id] = page
}
cache[page.Id] = k
}
}
}