fork of anirudh.fi/vite that uses chroma for hl
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Init vite v2

Doesn't fully work yet. Don't bother trying.

+455 -427
-206
build.go
··· 1 - package main 2 - 3 - import ( 4 - "fmt" 5 - "io/ioutil" 6 - "os" 7 - "os/exec" 8 - "path/filepath" 9 - "sort" 10 - "strings" 11 - "text/template" 12 - 13 - "github.com/cross-cpm/go-shutil" 14 - ) 15 - 16 - var cfg = parseConfig() 17 - 18 - type Post struct { 19 - Fm Matter 20 - } 21 - 22 - var posts []Post 23 - 24 - type NewFm struct { 25 - Template string 26 - URL string 27 - Title string 28 - Subtitle string 29 - Date string 30 - Body string 31 - } 32 - 33 - func execute(cmds []string) { 34 - for _, cmd := range cmds { 35 - out, err := exec.Command(cmd).Output() 36 - printMsg("running:", cmd) 37 - if err != nil { 38 - printErr(err) 39 - fmt.Println(string(out)) 40 - } 41 - } 42 - } 43 - 44 - func processTemplate(tmplPath string) *template.Template { 45 - tmplFile := filepath.Join("templates", tmplPath) 46 - tmpl, err := template.ParseFiles(tmplFile) 47 - if err != nil { 48 - printErr(err) 49 - } 50 - 51 - return tmpl 52 - } 53 - 54 - func handleMd(mdPath string) { 55 - content, err := ioutil.ReadFile(mdPath) 56 - if err != nil { 57 - printErr(err) 58 - } 59 - 60 - restContent, fm := parseFrontmatter(content) 61 - bodyHtml := mdRender(restContent, cfg) 62 - relPath, _ := filepath.Rel("pages/", mdPath) 63 - 64 - var buildPath string 65 - if strings.HasSuffix(relPath, "_index.md") { 66 - dir, _ := filepath.Split(relPath) 67 - buildPath = filepath.Join("build", dir) 68 - } else { 69 - buildPath = filepath.Join( 70 - "build", 71 - strings.TrimSuffix(relPath, filepath.Ext(relPath)), 72 - ) 73 - } 74 - 75 - os.MkdirAll(buildPath, 0755) 76 - 77 - fm.Body = string(bodyHtml) 78 - 79 - if strings.Contains(relPath, "blog/") { 80 - posts = append(posts, Post{fm}) 81 - } 82 - 83 - var newFm = NewFm{ 84 - fm.Template, 85 - fm.URL, 86 - fm.Title, 87 - fm.Subtitle, 88 - fm.Date.Time.Format(cfg.DateFmt), 89 - fm.Body, 90 - } 91 - // combine config and matter structs 92 - combined := struct { 93 - Cfg Config 94 - Fm NewFm 95 - }{cfg, newFm} 96 - 97 - htmlFile, err := os.Create(filepath.Join(buildPath, "index.html")) 98 - if err != nil { 99 - printErr(err) 100 - return 101 - } 102 - if fm.Template == "" { 103 - fm.Template = "text.html" 104 - } 105 - tmpl := processTemplate(fm.Template) 106 - err = tmpl.Execute(htmlFile, combined) 107 - if err != nil { 108 - printErr(err) 109 - return 110 - } 111 - htmlFile.Close() 112 - } 113 - 114 - func renderIndex(posts []Post) { 115 - indexTmpl := processTemplate("index.html") 116 - path := filepath.Join("pages", "_index.md") 117 - 118 - // Sort posts by date 119 - sort.Slice(posts, func(i, j int) bool { 120 - return posts[j].Fm.Date.Time.Before(posts[i].Fm.Date.Time) 121 - }) 122 - 123 - content, err := ioutil.ReadFile(path) 124 - if err != nil { 125 - printErr(err) 126 - } 127 - 128 - restContent, fm := parseFrontmatter(content) 129 - bodyHtml := mdRender(restContent, cfg) 130 - fm.Body = string(bodyHtml) 131 - 132 - var newFm = NewFm{ 133 - fm.Template, 134 - fm.URL, 135 - fm.Title, 136 - fm.Subtitle, 137 - fm.Date.Time.Format(cfg.DateFmt), 138 - fm.Body, 139 - } 140 - 141 - combined := struct { 142 - Fm NewFm 143 - Posts []Post 144 - Cfg Config 145 - }{newFm, posts, cfg} 146 - 147 - htmlFile, err := os.Create(filepath.Join("build", "index.html")) 148 - err = indexTmpl.Execute(htmlFile, combined) 149 - if err != nil { 150 - printErr(err) 151 - return 152 - } 153 - htmlFile.Close() 154 - } 155 - 156 - func viteBuild() { 157 - if len(cfg.Prebuild) != 0 { 158 - printMsg("executing pre-build actions...") 159 - execute(cfg.Prebuild) 160 - } 161 - err := filepath.Walk("./pages", func(path string, info os.FileInfo, err error) error { 162 - if err != nil { 163 - printErr(err) 164 - return err 165 - } 166 - if filepath.Ext(path) == ".md" && path != filepath.Join("pages", "_index.md") { 167 - handleMd(path) 168 - } else { 169 - f, err := os.Stat(path) 170 - if err != nil { 171 - printErr(err) 172 - } 173 - mode := f.Mode() 174 - if mode.IsRegular() { 175 - options := shutil.CopyOptions{} 176 - relPath, _ := filepath.Rel("pages/", path) 177 - options.FollowSymlinks = true 178 - shutil.CopyFile( 179 - path, 180 - filepath.Join("build", relPath), 181 - &options, 182 - ) 183 - } 184 - } 185 - return nil 186 - }) 187 - 188 - if err != nil { 189 - printErr(err) 190 - } 191 - 192 - // Deal with the special snowflake '_index.md' 193 - renderIndex(posts) 194 - 195 - _, err = shutil.CopyTree("static", filepath.Join("build", "static"), nil) 196 - if err != nil { 197 - printErr(err) 198 - } 199 - printMsg("site build complete") 200 - printMsg("generating feeds...") 201 - generateRSS(posts, cfg) 202 - if len(cfg.Postbuild) != 0 { 203 - printMsg("executing post-build actions...") 204 - execute(cfg.Postbuild) 205 - } 206 - }
+163
commands/build.go
··· 1 + package commands 2 + 3 + import ( 4 + "fmt" 5 + "os" 6 + "path/filepath" 7 + "sort" 8 + "strings" 9 + "time" 10 + 11 + "git.icyphox.sh/vite/config" 12 + "git.icyphox.sh/vite/markdown" 13 + "git.icyphox.sh/vite/util" 14 + ) 15 + 16 + const ( 17 + BUILD = "build" 18 + PAGES = "pages" 19 + TEMPLATES = "templates" 20 + ) 21 + 22 + type Pages struct { 23 + Dirs []string 24 + Files []string 25 + } 26 + 27 + // Populates a Pages object with dirs and files 28 + // found in 'pages/'. 29 + func (pgs *Pages) initPages() error { 30 + files, err := os.ReadDir("./pages") 31 + if err != nil { 32 + return err 33 + } 34 + 35 + for _, f := range files { 36 + if f.IsDir() { 37 + pgs.Dirs = append(pgs.Dirs, f.Name()) 38 + } else { 39 + pgs.Files = append(pgs.Files, f.Name()) 40 + } 41 + } 42 + 43 + return nil 44 + } 45 + 46 + // Core builder function. Converts markdown to html, 47 + // copies over non .md files, etc. 48 + func Build() error { 49 + pages := Pages{} 50 + err := pages.initPages() 51 + if err != nil { 52 + return err 53 + } 54 + 55 + // Deal with files. 56 + // ex: pages/{_index,about,etc}.md 57 + err = func() error { 58 + for _, f := range pages.Files { 59 + if filepath.Ext(f) == ".md" { 60 + // ex: pages/about.md 61 + mdFile := filepath.Join(PAGES, f) 62 + var htmlDir string 63 + if f == "_index.md" { 64 + htmlDir = BUILD 65 + } else { 66 + htmlDir = filepath.Join( 67 + BUILD, 68 + strings.TrimSuffix(f, ".md"), 69 + ) 70 + } 71 + os.Mkdir(htmlDir, 0755) 72 + // ex: build/about/index.html 73 + htmlFile := filepath.Join(htmlDir, "index.html") 74 + 75 + fb, err := os.ReadFile(mdFile) 76 + if err != nil { 77 + return err 78 + } 79 + 80 + out := markdown.Output{} 81 + out.RenderMarkdown(fb) 82 + if err = out.RenderHTML( 83 + htmlFile, 84 + TEMPLATES, 85 + struct { 86 + Cfg config.ConfigYaml 87 + Fm markdown.Matter 88 + Body string 89 + }{config.Config, out.Meta, string(out.HTML)}, 90 + ); err != nil { 91 + return err 92 + } 93 + } else { 94 + src := filepath.Join(PAGES, f) 95 + util.CopyFile(src, BUILD) 96 + } 97 + } 98 + return nil 99 + }() 100 + if err != nil { 101 + return err 102 + } 103 + 104 + // Deal with dirs -- i.e. of markdown files. 105 + // ex: pages/{blog,travel}/*.md 106 + err = func() error { 107 + for _, d := range pages.Dirs { 108 + // ex: build/blog 109 + dstDir := filepath.Join(BUILD, d) 110 + // ex: pages/blog 111 + srcDir := filepath.Join(PAGES, d) 112 + os.Mkdir(dstDir, 0755) 113 + 114 + entries, err := os.ReadDir(srcDir) 115 + if err != nil { 116 + return err 117 + } 118 + 119 + posts := []markdown.Output{} 120 + // Collect all posts 121 + for _, e := range entries { 122 + ePath := filepath.Join(srcDir, e.Name()) 123 + fb, err := os.ReadFile(ePath) 124 + if err != nil { 125 + return err 126 + } 127 + 128 + out := markdown.Output{} 129 + out.RenderMarkdown(fb) 130 + 131 + slug := strings.TrimSuffix(filepath.Ext(e.Name()), ".md") 132 + 133 + htmlFile := filepath.Join(dstDir, slug) 134 + out.RenderHTML( 135 + htmlFile, 136 + TEMPLATES, 137 + struct { 138 + Cfg config.ConfigYaml 139 + Fm markdown.Matter 140 + Body string 141 + }{config.Config, out.Meta, string(out.HTML)}) 142 + posts = append(posts, out) 143 + } 144 + 145 + // Sort posts slice by date 146 + sort.Slice(posts, func(i, j int) bool { 147 + date1 := posts[j].Meta["date"].(time.Time) 148 + date2 := posts[i].Meta["date"].(time.Time) 149 + return date1.Before(date2) 150 + }) 151 + 152 + for _, p := range posts { 153 + fmt.Println(p.Meta["date"]) 154 + } 155 + } 156 + return nil 157 + }() 158 + if err != nil { 159 + return err 160 + } 161 + 162 + return nil 163 + }
-34
config.go
··· 1 - package main 2 - 3 - import ( 4 - "gopkg.in/yaml.v2" 5 - "io/ioutil" 6 - ) 7 - 8 - type Config struct { 9 - Title string `yaml:"title"` 10 - Header string `yaml:"header"` 11 - DateFmt string `yaml:"datefmt"` 12 - SiteURL string `yaml:"siteurl"` 13 - Description string `yaml:"description"` 14 - Author map[string]string `yaml:"author"` 15 - Footer string `yaml:"footer"` 16 - Prebuild []string `yaml:"prebuild"` 17 - Postbuild []string `yaml:"postbuild"` 18 - RSSPrefixURL string `yaml:"rssprefixurl"` 19 - } 20 - 21 - func parseConfig() Config { 22 - var config Config 23 - cf, err := ioutil.ReadFile("config.yaml") 24 - if err != nil { 25 - printErr(err) 26 - } 27 - 28 - err = yaml.Unmarshal(cf, &config) 29 - if err != nil { 30 - printErr(err) 31 - } 32 - 33 - return config 34 - }
+38
config/config.go
··· 1 + package config 2 + 3 + import ( 4 + "fmt" 5 + "os" 6 + 7 + "gopkg.in/yaml.v3" 8 + ) 9 + 10 + type ConfigYaml struct { 11 + Title string `yaml:"title"` 12 + Desc string `yaml:"description"` 13 + Author struct { 14 + Name string `yaml:"name"` 15 + Email string `yaml:"email"` 16 + } `yaml:"author"` 17 + URL string `yaml:"url"` 18 + Prebuild []string `yaml:"prebuild"` 19 + Postbuild []string `yaml:"postbuild"` 20 + } 21 + 22 + var Config ConfigYaml 23 + 24 + func init() { 25 + cf, err := os.ReadFile("config.yaml") 26 + if err != nil { 27 + fmt.Errorf("error: %+v\n", err) 28 + os.Exit(1) 29 + } 30 + if err = Config.ParseConfig(cf); err != nil { 31 + fmt.Errorf("error: %+v\n", err) 32 + } 33 + } 34 + 35 + func (c *ConfigYaml) ParseConfig(cf []byte) error { 36 + err := yaml.Unmarshal(cf, c) 37 + return err 38 + }
-45
frontmatter.go
··· 1 - package main 2 - 3 - import ( 4 - "bytes" 5 - "github.com/adrg/frontmatter" 6 - "time" 7 - ) 8 - 9 - type Date8601 struct { 10 - time.Time 11 - } 12 - 13 - func (d *Date8601) UnmarshalYAML(unmarshal func(interface{}) error) error { 14 - var date string 15 - 16 - err := unmarshal(&date) 17 - if err != nil { 18 - return err 19 - } 20 - 21 - d.Time, err = time.Parse("2006-01-02", date) 22 - return err 23 - } 24 - 25 - type Matter struct { 26 - Template string `yaml:"template"` 27 - URL string `yaml:"url"` 28 - Title string `yaml:"title"` 29 - Subtitle string `yaml:"subtitle"` 30 - Date Date8601 `yaml:"date"` 31 - Body string 32 - } 33 - 34 - // Parses frontmatter, populates the `matter` struct and 35 - // returns the rest 36 - func parseFrontmatter(inputBytes []byte) ([]byte, Matter) { 37 - m := Matter{} 38 - input := bytes.NewReader(inputBytes) 39 - rest, err := frontmatter.Parse(input, &m) 40 - 41 - if err != nil { 42 - printErr(err) 43 - } 44 - return rest, m 45 - }
+3 -7
go.mod
··· 1 - module github.com/icyphox/go-vite 1 + module git.icyphox.sh/vite 2 2 3 3 go 1.13 4 4 5 5 require ( 6 6 github.com/Depado/bfchroma v1.3.0 7 - github.com/adrg/frontmatter v0.2.0 8 - github.com/alecthomas/chroma v0.9.2 // indirect 9 - github.com/cross-cpm/go-shutil v0.0.0-20190908093542-3fcbb1a2151e 10 - github.com/gorilla/feeds v1.1.1 11 - github.com/kr/pretty v0.2.1 // indirect 7 + github.com/alecthomas/chroma v0.9.2 12 8 github.com/russross/blackfriday/v2 v2.1.0 13 - gopkg.in/yaml.v2 v2.4.0 9 + gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b 14 10 )
+2 -24
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 1 github.com/Depado/bfchroma v1.3.0 h1:zz14vpvySU6S0CL6yGPr1vkFevQecIt8dJdCsMS2JpM= 4 2 github.com/Depado/bfchroma v1.3.0/go.mod h1:c0bFk0tFmT+clD3TIGurjWCfD/QV8/EebfM3JGr+98M= 5 - github.com/adrg/frontmatter v0.1.0 h1:8gYVjU1CRsoc6in25uKQVpcQpR9cYz2BD0NQk6JepyU= 6 - github.com/adrg/frontmatter v0.1.0/go.mod h1:93rQCj3z3ZlwyxxpQioRKC1wDLto4aXHrbqIsnH9wmE= 7 - github.com/adrg/frontmatter v0.2.0 h1:/DgnNe82o03riBd1S+ZDjd43wAmC6W35q67NHeLkPd4= 8 - github.com/adrg/frontmatter v0.2.0/go.mod h1:93rQCj3z3ZlwyxxpQioRKC1wDLto4aXHrbqIsnH9wmE= 9 3 github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38 h1:smF2tmSOzy2Mm+0dGI2AIUHY+w0BUc+4tn40djz7+6U= 10 4 github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38/go.mod h1:r7bzyVFMNntcxPZXK3/+KdruV1H5KSlyVY0gc+NgInI= 11 - github.com/alecthomas/chroma v0.7.3 h1:NfdAERMy+esYQs8OXk0I868/qDxxCEo7FMz1WIqMAeI= 12 5 github.com/alecthomas/chroma v0.7.3/go.mod h1:sko8vR34/90zvl5QdcUdvzL3J8NKjAUx9va9jPuFNoM= 13 6 github.com/alecthomas/chroma v0.9.2 h1:yU1sE2+TZbLIQPMk30SolL2Hn53SR/Pv750f7qZ/XMs= 14 7 github.com/alecthomas/chroma v0.9.2/go.mod h1:eMuEnpA18XbG/WhOWtCzJHS7WqEtDAI+HxdwoW0nVSk= ··· 18 11 github.com/alecthomas/repr v0.0.0-20180818092828-117648cd9897/go.mod h1:xTS7Pm1pD1mvyM075QCDSRqH6qRLXylzS24ZTpRiSzQ= 19 12 github.com/alecthomas/repr v0.0.0-20200325044227-4184120f674c h1:MVVbswUlqicyj8P/JljoocA7AyCo62gzD0O7jfvrhtE= 20 13 github.com/alecthomas/repr v0.0.0-20200325044227-4184120f674c/go.mod h1:xTS7Pm1pD1mvyM075QCDSRqH6qRLXylzS24ZTpRiSzQ= 21 - github.com/cross-cpm/go-shutil v0.0.0-20190908093542-3fcbb1a2151e h1:x8RmdI3kIwKOGLb/SaraDgArPZ0Kb+0WmkM0K2P1CZk= 22 - github.com/cross-cpm/go-shutil v0.0.0-20190908093542-3fcbb1a2151e/go.mod h1:VPohcIQ6FLWAgzOT7enwtRTAvwfQBDD1v4c7mvY2s2c= 23 14 github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964 h1:y5HC9v93H5EPKqaS1UYVg1uYah5Xf51mBfIoWehClUQ= 24 15 github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964/go.mod h1:Xd9hchkHSWYkEqJwUGisez3G1QY8Ryz0sdWrLPMGjLk= 25 16 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 26 17 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 27 18 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 28 - github.com/dlclark/regexp2 v1.2.0 h1:8sAhBGEM0dRWogWqWyQeIJnxjWO6oIjl8FKqREDsGfk= 29 19 github.com/dlclark/regexp2 v1.2.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= 30 20 github.com/dlclark/regexp2 v1.4.0 h1:F1rxgk7p4uKjwIQxBs9oAXe5CqrXlCduYEJvrF4u93E= 31 21 github.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= 32 - github.com/gorilla/feeds v1.1.1 h1:HwKXxqzcRNg9to+BbvJog4+f3s/xzvtZXICcQGutYfY= 33 - github.com/gorilla/feeds v1.1.1/go.mod h1:Nk0jZrvPFZX1OBe5NPiddPw7CfwF6Q9eqzaBbaightA= 34 - github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= 35 - github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= 36 - github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= 37 - github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= 38 - github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= 39 22 github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= 40 23 github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= 41 24 github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= ··· 43 26 github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 44 27 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 45 28 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 46 - github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= 47 29 github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= 48 30 github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= 49 31 github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= 50 32 github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= 51 33 github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= 52 - github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= 53 34 github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= 54 35 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 55 36 github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= ··· 62 43 golang.org/x/sys v0.0.0-20200413165638-669c56c373c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 63 44 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= 64 45 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 65 - gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= 66 - gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 67 - gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= 68 - gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= 69 - gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= 70 46 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 47 + gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= 48 + gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+7 -5
init.go commands/init.go
··· 1 - package main 1 + package commands 2 2 3 3 import ( 4 + "fmt" 4 5 "os" 5 6 "path/filepath" 6 7 ) 7 8 8 - func viteInit(path string) { 9 + func Init(path string) error { 9 10 paths := []string{"build", "pages", "static", "templates"} 10 11 var dirPath string 12 + 11 13 for _, p := range paths { 12 14 dirPath = filepath.Join(path, p) 13 15 err := os.MkdirAll(dirPath, 0755) 14 16 if err != nil { 15 - printErr(err) 16 - return 17 + return err 17 18 } 18 19 } 19 20 fp, _ := filepath.Abs(path) 20 - printMsg("created project:", fp) 21 + fmt.Printf("vite: created project at %q\n", fp) 22 + return nil 21 23 }
+14 -7
main.go
··· 3 3 import ( 4 4 "fmt" 5 5 "os" 6 + 7 + "git.icyphox.sh/vite/commands" 6 8 ) 7 9 8 10 func main() { ··· 18 20 new PATH create a new markdown post 19 21 ` 20 22 21 - // TODO: make arg parsing less shit 22 - 23 23 if len(args) <= 1 { 24 24 fmt.Println(helpStr) 25 25 return ··· 32 32 return 33 33 } 34 34 initPath := args[2] 35 - viteInit(initPath) 35 + err := commands.Init(initPath) 36 + if err != nil { 37 + fmt.Errorf("error: init: %+v\n", err) 38 + } 39 + 36 40 case "build": 37 - _, err := os.Stat("config.yaml") 41 + err := commands.Build() 38 42 if err != nil { 39 - return 43 + fmt.Errorf("error: build: %+v\n", err) 40 44 } 41 - viteBuild() 45 + 42 46 case "new": 43 47 if len(args) <= 2 { 44 48 fmt.Println(helpStr) 45 49 return 46 50 } 47 51 newPath := args[2] 48 - viteNew(newPath) 52 + err := commands.New(newPath) 53 + if err != nil { 54 + fmt.Errorf("error: new: %+v\n", err) 55 + } 49 56 } 50 57 51 58 }
-29
markdown.go
··· 1 - package main 2 - 3 - import ( 4 - bfc "github.com/Depado/bfchroma" 5 - bf "github.com/russross/blackfriday/v2" 6 - ) 7 - 8 - var bfFlags = bf.UseXHTML | bf.Smartypants | bf.SmartypantsFractions | 9 - bf.SmartypantsDashes | bf.NofollowLinks 10 - var bfExts = bf.NoIntraEmphasis | bf.Tables | bf.FencedCode | bf.Autolink | 11 - bf.Strikethrough | bf.SpaceHeadings | bf.BackslashLineBreak | 12 - bf.HeadingIDs | bf.Footnotes | bf.NoEmptyLineBeforeBlock 13 - 14 - func mdRender(input []byte, cfg Config) []byte { 15 - return bf.Run( 16 - input, 17 - bf.WithRenderer( 18 - bfc.NewRenderer( 19 - bfc.ChromaStyle(Icy), 20 - bfc.Extend( 21 - bf.NewHTMLRenderer(bf.HTMLRendererParameters{ 22 - Flags: bfFlags, 23 - }), 24 - ), 25 - ), 26 - ), 27 - bf.WithExtensions(bfExts), 28 - ) 29 - }
+82
markdown/frontmatter.go
··· 1 + package markdown 2 + 3 + import ( 4 + "bufio" 5 + "bytes" 6 + "errors" 7 + "fmt" 8 + 9 + "gopkg.in/yaml.v3" 10 + ) 11 + 12 + type Matter map[string]interface{} 13 + 14 + type MarkdownDoc struct { 15 + Frontmatter Matter 16 + Body []byte 17 + } 18 + 19 + const ( 20 + yamlDelim = "---" 21 + ) 22 + 23 + func (md *MarkdownDoc) Extract(source []byte) error { 24 + bufsize := 1024 * 1024 25 + buf := make([]byte, bufsize) 26 + 27 + input := bytes.NewReader(source) 28 + s := bufio.NewScanner(input) 29 + s.Buffer(buf, bufsize) 30 + 31 + matter := []byte{} 32 + body := []byte{} 33 + 34 + s.Split(splitFunc) 35 + n := 0 36 + for s.Scan() { 37 + if n == 0 { 38 + matter = s.Bytes() 39 + } else if n == 1 { 40 + body = s.Bytes() 41 + } 42 + n++ 43 + } 44 + if err := s.Err(); err != nil { 45 + return fmt.Errorf("error: failed to scan text") 46 + } 47 + if err := yaml.Unmarshal(matter, &md.Frontmatter); err != nil { 48 + return fmt.Errorf("error: failed to parse yaml") 49 + } 50 + md.Body = body 51 + return nil 52 + } 53 + 54 + func splitFunc(data []byte, atEOF bool) (advance int, token []byte, err error) { 55 + if atEOF && len(data) == 0 { 56 + return 0, nil, nil 57 + } 58 + delim, err := sniffDelim(data) 59 + if err != nil { 60 + return 0, nil, err 61 + } 62 + if delim != yamlDelim { 63 + return 0, nil, fmt.Errorf("error: %s is not a supported delimiter", delim) 64 + } 65 + if x := bytes.Index(data, []byte(delim)); x >= 0 { 66 + if next := bytes.Index(data[x+len(delim):], []byte(delim)); next > 0 { 67 + return next + len(delim), bytes.TrimSpace(data[:next+len(delim)]), nil 68 + } 69 + return len(data), bytes.TrimSpace(data[x+len(delim):]), nil 70 + } 71 + if atEOF { 72 + return len(data), data, nil 73 + } 74 + return 0, nil, nil 75 + } 76 + 77 + func sniffDelim(input []byte) (string, error) { 78 + if len(input) < 4 { 79 + return "", errors.New("error: input is empty") 80 + } 81 + return string(input[:3]), nil 82 + }
+67
markdown/markdown.go
··· 1 + package markdown 2 + 3 + import ( 4 + "os" 5 + "path/filepath" 6 + "text/template" 7 + 8 + bfc "github.com/Depado/bfchroma" 9 + bf "github.com/russross/blackfriday/v2" 10 + ) 11 + 12 + var bfFlags = bf.UseXHTML | bf.Smartypants | bf.SmartypantsFractions | 13 + bf.SmartypantsDashes | bf.NofollowLinks 14 + var bfExts = bf.NoIntraEmphasis | bf.Tables | bf.FencedCode | bf.Autolink | 15 + bf.Strikethrough | bf.SpaceHeadings | bf.BackslashLineBreak | 16 + bf.HeadingIDs | bf.Footnotes | bf.NoEmptyLineBeforeBlock 17 + 18 + type Output struct { 19 + HTML []byte 20 + Meta Matter 21 + } 22 + 23 + // Renders markdown to html, and fetches metadata. 24 + func (out *Output) RenderMarkdown(source []byte) { 25 + md := MarkdownDoc{} 26 + md.Extract(source) 27 + 28 + out.HTML = bf.Run( 29 + md.Body, 30 + bf.WithRenderer( 31 + bfc.NewRenderer( 32 + bfc.ChromaStyle(Icy), 33 + bfc.Extend( 34 + bf.NewHTMLRenderer(bf.HTMLRendererParameters{ 35 + Flags: bfFlags, 36 + }), 37 + ), 38 + ), 39 + ), 40 + bf.WithExtensions(bfExts), 41 + ) 42 + out.Meta = md.Frontmatter 43 + } 44 + 45 + // Renders out.HTML into dst html file, using the template specified 46 + // in the frontmatter. data is the template struct. 47 + func (out *Output) RenderHTML(dst, tmplDir string, data interface{}) error { 48 + metaTemplate := out.Meta["template"].(string) 49 + if metaTemplate == "" { 50 + metaTemplate = "text.html" 51 + } 52 + 53 + t, err := template.ParseGlob(filepath.Join(tmplDir, "*.html")) 54 + if err != nil { 55 + return err 56 + } 57 + 58 + w, err := os.Create(dst) 59 + if err != nil { 60 + return err 61 + } 62 + 63 + if err = t.ExecuteTemplate(w, metaTemplate, data); err != nil { 64 + return err 65 + } 66 + return nil 67 + }
+5 -7
new.go commands/new.go
··· 1 - package main 1 + package commands 2 2 3 3 import ( 4 4 "fmt" 5 - "io/ioutil" 6 5 "os" 7 6 "path/filepath" 8 7 "strings" 9 8 "time" 10 9 ) 11 10 12 - func viteNew(path string) { 11 + func New(path string) error { 13 12 _, file := filepath.Split(path) 14 13 url := strings.TrimSuffix(file, filepath.Ext(file)) 15 14 ··· 23 22 24 23 _, err := os.Create(path) 25 24 if err != nil { 26 - printErr(err) 27 - return 25 + return err 28 26 } 29 - ioutil.WriteFile(path, []byte(content), 0644) 30 - printMsg("created:", path) 27 + os.WriteFile(path, []byte(content), 0644) 28 + return nil 31 29 }
-47
rss.go
··· 1 - package main 2 - 3 - import ( 4 - "os" 5 - "path/filepath" 6 - "sort" 7 - "time" 8 - 9 - . "github.com/gorilla/feeds" 10 - ) 11 - 12 - func generateRSS(posts []Post, cfg Config) { 13 - now := time.Now() 14 - feed := &Feed{ 15 - Title: cfg.Title, 16 - Link: &Link{Href: cfg.SiteURL}, 17 - Description: cfg.Description, 18 - Author: &Author{ 19 - Name: cfg.Author["name"], 20 - Email: cfg.Author["email"], 21 - }, 22 - Created: now, 23 - } 24 - 25 - // Sort posts by date 26 - sort.Slice(posts, func(i, j int) bool { 27 - return posts[j].Fm.Date.Time.Before(posts[i].Fm.Date.Time) 28 - }) 29 - 30 - atomfile, err := os.Create(filepath.Join("build", "blog", "feed.xml")) 31 - if err != nil { 32 - printErr(err) 33 - } 34 - for _, p := range posts { 35 - feed.Items = append(feed.Items, &Item{ 36 - Title: p.Fm.Title, 37 - Link: &Link{Href: cfg.RSSPrefixURL + p.Fm.URL}, 38 - Description: string(p.Fm.Body), 39 - Created: p.Fm.Date.Time, 40 - }) 41 - } 42 - 43 - err = feed.WriteAtom(atomfile) 44 - if err != nil { 45 - printErr(err) 46 - } 47 - }
+1 -1
style.go markdown/style.go
··· 1 - package main 1 + package markdown 2 2 3 3 import ( 4 4 "github.com/alecthomas/chroma"
+73
util/copy.go
··· 1 + package util 2 + 3 + import ( 4 + "fmt" 5 + "io" 6 + "os" 7 + "path/filepath" 8 + ) 9 + 10 + // CopyFile copies a file from src to dst. 11 + func CopyFile(src, dst string) error { 12 + in, err := os.Open(src) 13 + if err != nil { 14 + return err 15 + } 16 + defer in.Close() 17 + 18 + out, err := os.Create(dst) 19 + if err != nil { 20 + return err 21 + } 22 + defer out.Close() 23 + 24 + _, err = io.Copy(out, in) 25 + if err != nil { 26 + return err 27 + } 28 + 29 + // Copy modes. 30 + f, err := os.Stat(src) 31 + if err == nil { 32 + err = os.Chmod(dst, f.Mode()) 33 + if err != nil { 34 + return err 35 + } 36 + } 37 + 38 + return out.Close() 39 + } 40 + 41 + // CopyDir copies an entire directory tree from 42 + // src to dst. 43 + func CopyDir(src, dst string) error { 44 + fi, err := os.Stat(src) 45 + if err != nil { 46 + return err 47 + } 48 + 49 + if !fi.IsDir() { 50 + return fmt.Errorf("error: %q is not a directory", fi) 51 + } 52 + 53 + if err = os.MkdirAll(dst, 0755); err != nil { 54 + return err 55 + } 56 + 57 + items, _ := os.ReadDir(src) 58 + for _, item := range items { 59 + srcFilename := filepath.Join(src, item.Name()) 60 + dstFilename := filepath.Join(dst, item.Name()) 61 + if item.IsDir() { 62 + if err := CopyDir(srcFilename, dstFilename); err != nil { 63 + return err 64 + } 65 + } else { 66 + if err := CopyFile(srcFilename, dstFilename); err != nil { 67 + return err 68 + } 69 + } 70 + } 71 + 72 + return nil 73 + }
-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 - }