hugoext/main.go

233 lines
4.8 KiB
Go
Raw Normal View History

2021-07-10 16:27:58 +03:00
package main
import (
"flag"
"fmt"
"log"
"os"
"path"
"path/filepath"
2021-07-10 17:44:25 +03:00
"strings"
2021-07-10 16:27:58 +03:00
"time"
"github.com/gohugoio/hugo/config"
"github.com/spf13/afero"
)
const (
defaultExt = "gmi"
defaultProcessor = "md2gmi"
defaultSource = "content"
defaultDestination = "public"
defaultConfigPath = "config.toml"
defaultUglyURLs = false
defaultPermalinkFormat = "/:year/:month/:title/"
)
func main() {
var ext, processor, source, destination, cfgpath string
var uglyurls bool
flag.StringVar(&ext, "ext", defaultExt, "ext to look for templates in ./layout")
flag.StringVar(&processor, "proc", defaultProcessor, "processor to pipe markdown content through")
flag.StringVar(&source, "source", defaultSource, "source directory")
flag.StringVar(&destination, "destination", defaultDestination, "output directory")
flag.StringVar(&cfgpath, "config", defaultConfigPath, "hugo config path")
flag.BoolVar(&uglyurls, "ugly-urls", defaultUglyURLs, "use directories with index or .ext files")
flag.Parse()
osfs := afero.NewOsFs()
cfg, err := config.FromFile(osfs, "config.toml")
if err != nil {
log.Fatal("config from file", err)
}
permalinks := cfg.GetStringMapString("permalinks")
2021-07-10 17:44:25 +03:00
//fmt.Println("permalinks", permalinks)
2021-07-10 16:27:58 +03:00
2021-07-10 17:44:25 +03:00
/*
fpath := "content/posts/first-post.md"
file, err := os.Open(fpath)
if err != nil {
log.Fatal("open", err)
}
2021-07-10 16:27:58 +03:00
2021-07-10 17:44:25 +03:00
page, err := ReadFrom(file)
if err != nil {
log.Fatal("read page", err)
}
2021-07-10 16:27:58 +03:00
2021-07-10 17:44:25 +03:00
fmt.Println(string(page.FrontMatter()))
fmt.Println(string(page.Content()))
meta, err := page.Metadata()
if err != nil {
log.Fatal("read meta", err)
}
c := NewContentFromMeta(meta)
fmt.Println(c)
link, err := pathPattern(permalinks["posts"]).Expand(c)
if err != nil {
log.Fatal("permalink expand", err)
}
fmt.Println(link)
*/
2021-07-10 16:27:58 +03:00
// test
linkcfg := func(subdir string) string {
format, ok := permalinks[subdir]
if ok {
return format
}
return defaultPermalinkFormat
}
2021-07-10 17:44:25 +03:00
files := make(chan File)
go collectFiles(source, files)
for file := range files {
pattern := linkcfg(file.Parent)
err := destinationPath(&file, pattern)
if err != nil {
fmt.Println(err, file)
continue
}
fmt.Printf("%s -> %s (%d)\n", file.Source, file.Destination, len(file.Body))
}
// iterate through file tree source
// for each file, get destination path, switch file extension, remove underscore for index
// call proc and pipe content through it, catch output of proc and write to destination
// replace links?
// write rss?
// write listings from template?
2021-07-10 16:27:58 +03:00
}
2021-07-10 17:44:25 +03:00
type FileTree struct {
Files map[string]*File
}
type File struct {
Root string
Source string
Destination string
Parent string
Name string
Extension string
Body []byte
}
func parse(fullpath string) ([]byte, *Content, error) {
2021-07-10 16:27:58 +03:00
file, err := os.Open(fullpath)
if err != nil {
2021-07-10 17:44:25 +03:00
return nil, nil, err
2021-07-10 16:27:58 +03:00
}
page, err := ReadFrom(file)
if err != nil {
2021-07-10 17:44:25 +03:00
return nil, nil, err
2021-07-10 16:27:58 +03:00
}
meta, err := page.Metadata()
if err != nil {
2021-07-10 17:44:25 +03:00
return nil, nil, err
2021-07-10 16:27:58 +03:00
}
c := NewContentFromMeta(meta)
2021-07-10 17:44:25 +03:00
return append(page.FrontMatter(), page.Content()...), c, nil
}
2021-07-10 16:27:58 +03:00
2021-07-10 17:44:25 +03:00
func destinationPath(file *File, pattern string) error {
body, c, err := parse(file.Source)
if err != nil {
return err
}
c.Filepath = file.Name
file.Body = body
if file.Parent != "." {
link, err := pathPattern(pattern).Expand(c)
if err != nil {
return err
}
file.Destination = link
} else {
file.Destination = strings.TrimLeft(file.Name, "_")
}
return nil
2021-07-10 16:27:58 +03:00
}
2021-07-10 17:44:25 +03:00
func collectFiles(fullpath string, filechan chan File) error {
defer close(filechan)
2021-07-10 16:27:58 +03:00
return filepath.Walk(fullpath,
func(p string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if info.IsDir() {
return nil
}
rel, err := filepath.Rel(fullpath, p)
if err != nil {
return err
}
filename := info.Name()
ext := path.Ext(filename)
name := filename[0 : len(filename)-len(ext)]
parent := filepath.Dir(rel)
2021-07-10 17:44:25 +03:00
filechan <- File{
Root: fullpath,
Source: p,
Name: name,
Extension: ext,
Parent: parent,
2021-07-10 16:27:58 +03:00
}
return nil
})
}
func NewContentFromMeta(meta map[string]interface{}) *Content {
return &Content{
Title: istring(meta["title"]),
Slug: istring(meta["slug"]),
Categories: istringArr(meta["categories"]),
Date: idate(meta["date"]),
}
}
func istring(input interface{}) string {
str, ok := input.(string)
if ok {
return str
}
return ""
}
func idate(input interface{}) time.Time {
str, ok := input.(string)
if !ok {
return time.Now()
}
t, err := time.Parse(time.RFC3339, str)
if err != nil {
// try just date, or give up
t, err := time.Parse("2006-01-02", str)
if err != nil {
return time.Now()
}
return t
}
return t
}
func istringArr(input interface{}) []string {
str, ok := input.([]string)
if ok {
return str
}
return nil
}