fast and minimal static site generator
ssg

Init

+1
.gitignore
··· 1 + vite
+98
build.go
··· 1 + package main 2 + 3 + import ( 4 + "io/ioutil" 5 + "os" 6 + "path/filepath" 7 + "strings" 8 + "text/template" 9 + "github.com/cross-cpm/go-shutil" 10 + ) 11 + 12 + func processTemplate(tmplPath string) *template.Template { 13 + tmplFile := filepath.Join("templates", tmplPath) 14 + tmpl, err := template.ParseFiles(tmplFile) 15 + if err != nil { 16 + printErr(err) 17 + } 18 + 19 + return tmpl 20 + } 21 + 22 + func handleMd(mdPath string) { 23 + content, err := ioutil.ReadFile(mdPath) 24 + if err != nil { 25 + printErr(err) 26 + } 27 + 28 + restContent, fm := parseFrontmatter(content) 29 + bodyHtml := mdRender(restContent) 30 + relPath, _ := filepath.Rel("pages/", mdPath) 31 + 32 + var buildPath string 33 + if strings.HasSuffix(relPath, "_index.md") { 34 + dir, _ := filepath.Split(relPath) 35 + buildPath = filepath.Join("build", dir) 36 + } else { 37 + buildPath = filepath.Join( 38 + "build", 39 + strings.TrimSuffix(relPath, filepath.Ext(relPath)), 40 + ) 41 + } 42 + 43 + os.MkdirAll(buildPath, 0755) 44 + fm.Body = string(bodyHtml) 45 + 46 + htmlFile, err := os.Create(filepath.Join(buildPath, "index.html")) 47 + if err != nil { 48 + printErr(err) 49 + return 50 + } 51 + if fm.Template == "" { 52 + fm.Template = "text.html" 53 + } 54 + tmpl := processTemplate(fm.Template) 55 + err = tmpl.Execute(htmlFile, fm) 56 + if err != nil { 57 + printErr(err) 58 + return 59 + } 60 + htmlFile.Close() 61 + } 62 + 63 + func viteBuild() { 64 + err := filepath.Walk("./pages", func(path string, info os.FileInfo, err error) error { 65 + if err != nil { 66 + printErr(err) 67 + return err 68 + } 69 + if filepath.Ext(path) == ".md" { 70 + handleMd(path) 71 + } else { 72 + f, err := os.Stat(path) 73 + if err != nil { 74 + printErr(err) 75 + } 76 + mode := f.Mode() 77 + if mode.IsRegular() { 78 + options := shutil.CopyOptions{} 79 + relPath, _ := filepath.Rel("pages/", path) 80 + options.FollowSymlinks = true 81 + shutil.CopyFile( 82 + path, 83 + filepath.Join("build", relPath), 84 + &options, 85 + ) 86 + } 87 + } 88 + return nil 89 + }) 90 + if err != nil { 91 + printErr(err) 92 + } 93 + 94 + _, err = shutil.CopyTree("static", filepath.Join("build", "static"), nil) 95 + if err != nil { 96 + printErr(err) 97 + } 98 + }
+28
frontmatter.go
··· 1 + package main 2 + 3 + import ( 4 + "bytes" 5 + "github.com/adrg/frontmatter" 6 + ) 7 + 8 + type matter struct { 9 + Template string `yaml:"template"` 10 + URL string `yaml:"url"` 11 + Title string `yaml:"title"` 12 + Subtitle string `yaml:"subtitle"` 13 + Date string `yaml:"date"` 14 + Body string 15 + } 16 + 17 + // Parses frontmatter, populates the `matter` struct and 18 + // returns the rest 19 + func parseFrontmatter(inputBytes []byte) ([]byte, matter) { 20 + m := matter{} 21 + input := bytes.NewReader(inputBytes) 22 + rest, err := frontmatter.Parse(input, &m) 23 + 24 + if err != nil { 25 + printErr(err) 26 + } 27 + return rest, m 28 + }
+11
go.mod
··· 1 + module github.com/icyphox/go-vite 2 + 3 + go 1.13 4 + 5 + require ( 6 + github.com/adrg/frontmatter v0.1.0 7 + github.com/cross-cpm/go-shutil v0.0.0-20190908093542-3fcbb1a2151e 8 + github.com/pmezard/go-difflib v1.0.0 // indirect 9 + github.com/russross/blackfriday/v2 v2.0.1 10 + github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect 11 + )
+16
go.sum
··· 1 + github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= 2 + github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= 3 + github.com/adrg/frontmatter v0.1.0 h1:8gYVjU1CRsoc6in25uKQVpcQpR9cYz2BD0NQk6JepyU= 4 + github.com/adrg/frontmatter v0.1.0/go.mod h1:93rQCj3z3ZlwyxxpQioRKC1wDLto4aXHrbqIsnH9wmE= 5 + github.com/cross-cpm/go-shutil v0.0.0-20190908093542-3fcbb1a2151e h1:x8RmdI3kIwKOGLb/SaraDgArPZ0Kb+0WmkM0K2P1CZk= 6 + github.com/cross-cpm/go-shutil v0.0.0-20190908093542-3fcbb1a2151e/go.mod h1:VPohcIQ6FLWAgzOT7enwtRTAvwfQBDD1v4c7mvY2s2c= 7 + github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 8 + github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 9 + github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= 10 + github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= 11 + github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= 12 + github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= 13 + gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= 14 + gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 15 + gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= 16 + gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+21
init.go
··· 1 + package main 2 + 3 + import ( 4 + "os" 5 + "path/filepath" 6 + ) 7 + 8 + func viteInit(path string) { 9 + paths := []string{"build", "pages", "static", "templates"} 10 + var dirPath string 11 + for _, p := range paths { 12 + dirPath = filepath.Join(path, p) 13 + err := os.MkdirAll(dirPath, 0755) 14 + if err != nil { 15 + printErr(err) 16 + return 17 + } 18 + } 19 + fp, _ := filepath.Abs(path) 20 + printMsg("created project:", fp) 21 + }
+37
main.go
··· 1 + package main 2 + 3 + import ( 4 + "fmt" 5 + "os" 6 + ) 7 + 8 + func main() { 9 + args := os.Args 10 + 11 + helpStr := `usage: vite [options] 12 + 13 + A simple and minimal static site generator. 14 + 15 + options: 16 + init PATH create vite project at PATH 17 + build builds the current project 18 + new PATH create a new markdown post 19 + ` 20 + 21 + if len(args) <= 2 { 22 + fmt.Println(helpStr) 23 + return 24 + } 25 + 26 + switch args[1] { 27 + case "init": 28 + initPath := args[2] 29 + viteInit(initPath) 30 + case "build": 31 + viteBuild() 32 + case "new": 33 + // newPath := args[2] 34 + // viteNew(newPath) 35 + } 36 + 37 + }
+8
makefile
··· 1 + default: 2 + go build -o vite 3 + 4 + install: 5 + install -Dm755 vite $(DESTDIR)$(PREFIX)/bin/vite 6 + 7 + uninstall: 8 + @rm -f $(DESTDIR)$(PREFIX)/bin/vite
+18
markdown.go
··· 1 + package main 2 + 3 + import ( 4 + bf "github.com/russross/blackfriday/v2" 5 + ) 6 + 7 + var bfFlags = bf.UseXHTML | bf.Smartypants | bf.SmartypantsFractions | 8 + bf.SmartypantsDashes | bf.SmartypantsAngledQuotes | bf.NofollowLinks | 9 + bf.FootnoteReturnLinks 10 + 11 + func mdRender(input []byte) []byte { 12 + return bf.Run( 13 + input, 14 + bf.WithRenderer(bf.NewHTMLRenderer(bf.HTMLRendererParameters{ 15 + Flags: bfFlags, 16 + })), 17 + ) 18 + }
+15
utils.go
··· 1 + package main 2 + 3 + import ( 4 + "fmt" 5 + "os" 6 + "strings" 7 + ) 8 + 9 + func printMsg(s ...string) { 10 + fmt.Println("vite:", strings.Join(s, " ")) 11 + } 12 + 13 + func printErr(e error) { 14 + fmt.Fprintln(os.Stderr, "error:", e) 15 + }