package site import ( "bufio" "bytes" "fmt" "io/ioutil" "os" "path/filepath" "sort" "strings" "text/template" goutil "git.gutmet.org/goutil.git/misc" . "git.gutmet.org/wombat.git/templatestructures" ) 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) } } sort.Slice(ret, func(i, j int) bool { return strings.ToUpper(ret[i].Title) < strings.ToUpper(ret[j].Title) }) 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, script string) { md := getMetadata(path) emd := md.explicit content, _ := goutil.ReadFile(path) page := Page{} page.Title = emd.title page.Style = style page.Script = script 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, script string, path string, info os.FileInfo, err error) error { if !ignore(path) && isHTMLFile(path) && hasDescription(path) { completePage(path, t, style, script) } return nil } func Generate() { style, err := goutil.ReadFile("style.css") script, err2 := goutil.ReadFile("script.js") templateString, err3 := 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, script, path, info, err) } if err == nil && err2 == nil && err3 == nil { filepath.Walk("stage1", traverseFunc) } else { fmt.Println(err) fmt.Println(err2) fmt.Println(err3) } }