156 lines
3.7 KiB
Go
156 lines
3.7 KiB
Go
package site
|
|
|
|
import (
|
|
"bufio"
|
|
"bytes"
|
|
"fmt"
|
|
"git.gutmet.org/goutil.git"
|
|
. "git.gutmet.org/wombat.git/templatestructures"
|
|
"io/ioutil"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"text/template"
|
|
)
|
|
|
|
type metadata struct {
|
|
explicit explicitMetadata
|
|
subpages []string
|
|
}
|
|
|
|
type explicitMetadata struct {
|
|
title string
|
|
description string
|
|
}
|
|
|
|
func (m *metadata) getSubpages() []Subpage {
|
|
if len(m.subpages) == 0 {
|
|
return nil
|
|
}
|
|
ret := make([]Subpage, 0)
|
|
for _, path := range m.subpages {
|
|
emd := getExplicitMetadata(path)
|
|
if len(emd.title) > 0 && len(emd.description) > 0 {
|
|
subpage := Subpage{emd.title, emd.description, path}
|
|
ret = append(ret, subpage)
|
|
}
|
|
}
|
|
return ret
|
|
}
|
|
|
|
func metapath(htmlfile string) string {
|
|
if !strings.HasPrefix(htmlfile, "stage1") {
|
|
htmlfile = filepath.Join("stage1", htmlfile)
|
|
}
|
|
return goutil.TrimExt(htmlfile) + ".desc"
|
|
}
|
|
|
|
func getExplicitMetadata(htmlfile string) explicitMetadata {
|
|
metapath := metapath(htmlfile)
|
|
ret := explicitMetadata{}
|
|
f, err := os.Open(metapath)
|
|
if err == nil {
|
|
defer f.Close()
|
|
scanner := bufio.NewScanner(f)
|
|
for scanner.Scan() {
|
|
text := scanner.Text()
|
|
if strings.HasPrefix(text, "title:") {
|
|
ret.title = strings.Trim(strings.TrimPrefix(text, "title:"), "\" ")
|
|
} else if strings.HasPrefix(text, "description:") {
|
|
ret.description = strings.TrimSpace(strings.TrimPrefix(text, "description:"))
|
|
}
|
|
}
|
|
} else {
|
|
fmt.Fprintln(os.Stderr, err)
|
|
}
|
|
return ret
|
|
}
|
|
|
|
func isHTML(file os.FileInfo) bool {
|
|
return isHTMLFile(file.Name())
|
|
}
|
|
|
|
func isHTMLFile(path string) bool {
|
|
return strings.HasSuffix(path, ".html")
|
|
}
|
|
|
|
func hasDescription(path string) bool {
|
|
metapath := metapath(path)
|
|
if _, err := os.Stat(metapath); os.IsNotExist(err) {
|
|
return false
|
|
} else {
|
|
return true
|
|
}
|
|
}
|
|
|
|
func getSubpages(filename string) []string {
|
|
ret := []string{}
|
|
dirpath := goutil.TrimExt(filename)
|
|
if files, err := ioutil.ReadDir(dirpath); err == nil {
|
|
for _, file := range files {
|
|
if isHTML(file) {
|
|
fullpath := strings.TrimPrefix(strings.TrimPrefix(dirpath, "stage1/"), "stage1\\")
|
|
ret = append(ret, filepath.Join(fullpath, file.Name()))
|
|
}
|
|
}
|
|
}
|
|
return ret
|
|
}
|
|
|
|
func getMetadata(path string) metadata {
|
|
ret := metadata{}
|
|
ret.explicit = getExplicitMetadata(path)
|
|
ret.subpages = getSubpages(path)
|
|
return ret
|
|
}
|
|
|
|
func completePage(path string, t *template.Template, style string) {
|
|
md := getMetadata(path)
|
|
emd := md.explicit
|
|
content, _ := goutil.ReadFile(path)
|
|
page := Page{}
|
|
page.Title = emd.title
|
|
page.Style = style
|
|
page.Subpages = md.getSubpages()
|
|
page.Description = emd.description
|
|
page.Content = content
|
|
buf := new(bytes.Buffer)
|
|
err := t.Execute(buf, page)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
}
|
|
destination := strings.Replace(path, "stage1", "stage2", 1)
|
|
os.Remove(destination) // remove hardlink before writing
|
|
goutil.WriteFile(destination, buf.String())
|
|
}
|
|
|
|
func ignore(path string) bool {
|
|
var ignorePaths = []string{filepath.Join("stage1", "blog") + string(os.PathSeparator)}
|
|
for _, prefix := range ignorePaths {
|
|
if strings.HasPrefix(path, prefix) {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func traverse(t *template.Template, style string, path string, info os.FileInfo, err error) error {
|
|
if !ignore(path) && isHTMLFile(path) && hasDescription(path) {
|
|
completePage(path, t, style)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func Generate() {
|
|
style, err := goutil.ReadFile("style.css")
|
|
templateString, err2 := goutil.ReadFile("template")
|
|
t := template.Must(template.New("page").Parse(templateString))
|
|
traverseFunc := func(path string, info os.FileInfo, err error) error { return traverse(t, style, path, info, err) }
|
|
if err == nil && err2 == nil {
|
|
filepath.Walk("stage1", traverseFunc)
|
|
} else {
|
|
fmt.Println(err)
|
|
fmt.Println(err2)
|
|
}
|
|
}
|