Skip to content

Commit

Permalink
refactor watcher, generator, tpldata into their own file
Browse files Browse the repository at this point in the history
  • Loading branch information
mna committed Jul 11, 2013
1 parent 5845dd8 commit 7a7dd3e
Show file tree
Hide file tree
Showing 4 changed files with 235 additions and 218 deletions.
133 changes: 133 additions & 0 deletions gen.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
package main

import (
"html/template"
"io"
"io/ioutil"
"log"
"os"
"path/filepath"
"sort"

"github.com/eknkc/amber"
)

const (
maxRecentPosts = 2
)

var (
postTpl *template.Template
postTplNm = "post.amber"
)

type sortableFileInfo []os.FileInfo

func (s sortableFileInfo) Len() int { return len(s) }
func (s sortableFileInfo) Less(i, j int) bool { return s[i].ModTime().Before(s[j].ModTime()) }
func (s sortableFileInfo) Swap(i, j int) { s[i], s[j] = s[j], s[i] }

func FilterDir(s sortableFileInfo) sortableFileInfo {
for i := 0; i < len(s); {
if s[i].IsDir() {
s[i], s = s[len(s)-1], s[:len(s)-1]
} else {
i++
}
}
return s
}

func compileTemplate() {
ap := filepath.Join(TemplatesDir, postTplNm)
if _, err := os.Stat(ap); os.IsNotExist(err) {
// Amber post template does not exist, compile the native Go templates
postTpl, err = template.ParseGlob(filepath.Join(TemplatesDir, "*.html"))
if err != nil {
log.Fatal("FATAL ", err)
}
postTplNm = "post" // TODO : Validate this...
} else {
c := amber.New()
if err := c.ParseFile(ap); err != nil {
log.Fatal("FATAL ", err)
}
if postTpl, err = c.Compile(); err != nil {
log.Fatal("FATAL ", err)
}
}
}

func generateSite() {
// First compile the template(s)
compileTemplate()
// Clear the public directory, except subdirs
fis, err := ioutil.ReadDir(PublicDir)
if err != nil {
log.Fatal("FATAL ", err)
}
for _, fi := range fis {
if !fi.IsDir() {
err = os.Remove(filepath.Join(PublicDir, fi.Name()))
if err != nil {
log.Println("DELETE ERROR ", err)
}
}
}
// Now read the posts
fis, err = ioutil.ReadDir(PostsDir)
if err != nil {
log.Fatal("FATAL ", err)
}
sfi := sortableFileInfo(fis)
sfi = FilterDir(sfi)
sort.Reverse(sfi)

recent := make([]*ShortPost, maxRecentPosts)
all := make([]*LongPost, len(sfi))
// First pass to get the recent posts (and others) so that
// they can be passed to all posts.
for i, fi := range sfi {
all[i] = newLongPost(fi)
if i < maxRecentPosts {
recent[i] = all[i].Short()
}
}

for i, p := range all {
td := newTemplateData(p, i, recent, all)
generateFile(td, i == 0)
}
}

// TODO : Should pass to the template:
// Title : The first heading in the file, or the file name, or front matter?
// Description : ?
// ModTime
// Parsed : The html-parsed markdown
// Recent : A slice of n recent posts
// Next : The next (more recent) post
// Previous : The previous (older) post

func generateFile(td *TemplateData, idx bool) {
var w io.Writer

fw, err := os.Create(filepath.Join(PublicDir, td.Post.Slug))
if err != nil {
log.Fatal("FATAL ", err)
}
defer fw.Close()
w = fw
if idx {
idxw, err := os.Create(filepath.Join(PublicDir, "index.html"))
if err != nil {
log.Fatal("FATAL ", err)
}
defer idxw.Close()
w = io.MultiWriter(fw, idxw)
}
err = postTpl.ExecuteTemplate(w, postTplNm, td)
if err != nil {
log.Fatal("FATAL ", err)
}
}
50 changes: 3 additions & 47 deletions main.go
Original file line number Diff line number Diff line change
@@ -1,61 +1,17 @@
package main

import (
"html/template"
"log"
"os"
"path/filepath"

"github.com/eknkc/amber"
"github.com/howeyc/fsnotify"
"github.com/jessevdk/go-flags"
)

var (
postTpl *template.Template
postTplNm = "post.amber"
)

func main() {
_, err := flags.Parse(&Options)
if err == nil { // err prints the usage automatically
// Compile the template(s)
compileTemplate()
if err == nil { // err != nil prints the usage automatically
// Generate the site
regeneratePosts()

generateSite()
// Start the watcher
w, err := fsnotify.NewWatcher()
if err != nil {
log.Fatal("FATAL ", err)
}
defer w.Close()
go watch(w)
if err = w.Watch(PostsDir); err != nil {
log.Fatal("FATAL ", err)
}

defer startWatcher().Close()
// Start the web server
run()
}
}

func compileTemplate() {
ap := filepath.Join(TemplatesDir, postTplNm)
if _, err := os.Stat(ap); os.IsNotExist(err) {
// Amber post template does not exist, compile the native Go templates
postTpl, err = template.ParseGlob(filepath.Join(TemplatesDir, "*.html"))
if err != nil {
log.Fatal("FATAL ", err)
}
postTplNm = "post" // TODO : Validate this...
} else {
c := amber.New()
if err := c.ParseFile(ap); err != nil {
log.Fatal("FATAL ", err)
}
if postTpl, err = c.Compile(); err != nil {
log.Fatal("FATAL ", err)
}
}
}
85 changes: 85 additions & 0 deletions tpldata.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package main

import (
"io/ioutil"
"log"
"os"
"path/filepath"
"regexp"
"strings"
"time"

"github.com/russross/blackfriday"
)

type TemplateData struct {
SiteName string
Post *LongPost
Recent []*ShortPost
Prev *ShortPost
Next *ShortPost
}

func newTemplateData(p *LongPost, i int, r []*ShortPost, all []*LongPost) *TemplateData {
td := &TemplateData{SiteName: SiteName, Post: p, Recent: r}

if i > 0 {
td.Prev = all[i-1].Short()
}
if i < len(all)-2 {
td.Next = all[i+1].Short()
}
return td
}

type ShortPost struct {
Slug string
Author string
Title string
Description string
PubTime time.Time
ModTime time.Time
}

type LongPost struct {
*ShortPost
Content string
}

var rxSlug = regexp.MustCompile(`[^a-zA-Z\-_0-9]`)

func getSlug(fnm string) string {
return rxSlug.ReplaceAllString(strings.Replace(fnm, filepath.Ext(fnm), "", 1), "-")
}

func newLongPost(fi os.FileInfo) *LongPost {
slug := getSlug(fi.Name())
sp := &ShortPost{
slug,
"author", // TODO : Complete...
slug, // TODO : Read first heading, or front matter
"description", // TODO : Read front matter
fi.ModTime(), // TODO : This is NOT the pub time...
fi.ModTime(),
}

f, err := os.Open(filepath.Join(PostsDir, fi.Name()))
if err != nil {
log.Fatal("FATAL ", err)
}
defer f.Close()
b, err := ioutil.ReadAll(f)
if err != nil {
log.Fatal("FATAL ", err)
}
res := blackfriday.MarkdownCommon(b)
lp := &LongPost{
sp,
string(res),
}
return lp
}

func (lp *LongPost) Short() *ShortPost {
return lp.ShortPost
}
Loading

0 comments on commit 7a7dd3e

Please sign in to comment.