// Reads directory contents from the given path and returns file names. func (ts *Templates) readDir(path string) (names []string, err error) { var f fauxfile.File if f, err = ts.fs.Open(path); err != nil { return } defer f.Close() names, err = f.Readdirnames(-1) return }
// Reads directory contents from the given path and returns file names. func (gw *GhostWriter) readDir(path string) (names []string, err error) { var f fauxfile.File if f, err = gw.fs.Open(path); err != nil { return } defer f.Close() names, err = f.Readdirnames(-1) return }
func WriteFile(fs fauxfile.Filesystem, p string, data string) error { var ( f fauxfile.File err error ) fs.MkdirAll(path.Dir(p), 0755) if f, err = fs.Create(p); err != nil { return err } defer f.Close() if _, err = f.Write([]byte(data)); err != nil { return err } return nil }
// Renders all of the posts in the site. func (gw *GhostWriter) renderTags() (err error) { var ( posts Posts tag string dst string tagpath string writer *bufio.Writer fdst fauxfile.File str string ) if gw.tagsTemplate == "" { return } for tag, posts = range gw.site.Tags { tagpath = gw.site.TagPath(tag) dst = path.Join(gw.args.dst, tagpath, "index.html") gw.fs.MkdirAll(path.Dir(dst), 0755) if fdst, err = gw.fs.Create(dst); err != nil { return } defer fdst.Close() writer = bufio.NewWriter(fdst) sort.Sort(ByDateDesc{posts}) data := map[string]interface{}{ "Tag": tag, "Posts": posts, "Site": gw.site, } if str, err = gw.rootTemplate.RenderText(gw.tagsTemplate, data); err != nil { return } writer.Write([]byte(str)) writer.Flush() if err != nil { return } fdst.Close() } return }
// Copies the file at path src to path dst. // Returns the number of bytes written or an error if it occurred. func (gw *GhostWriter) copyFile(src string, dst string) (n int64, err error) { var ( fdst fauxfile.File fsrc fauxfile.File fi os.FileInfo ) if fsrc, err = gw.fs.Open(src); err != nil { return } defer func() { if err := fsrc.Close(); err != nil { gw.log.Printf("Problem closing %v: %v\n", src, err) } else { gw.log.Printf("Closed %v\n", src) } }() if fdst, err = gw.fs.Create(dst); err != nil { return } defer func() { if err := fdst.Close(); err != nil { gw.log.Printf("Problem closing %v: %v\n", dst, err) } else { gw.log.Printf("Closed %v\n", dst) } }() if fi, err = fsrc.Stat(); err != nil { return } fdst.Chmod(fi.Mode()) _, err = io.Copy(fdst, fsrc) return }
// Deserializes the yaml file at the given path to the supplied object. func (gw *GhostWriter) unyaml(path string, out interface{}) (err error) { var ( file fauxfile.File info os.FileInfo data []byte ) if file, err = gw.fs.Open(path); err != nil { return } defer file.Close() if info, err = file.Stat(); err != nil { return } data = make([]byte, info.Size()) if _, err = file.Read(data); err != nil { return } err = yaml.Unmarshal(data, out) return }
func ReadFile(fs fauxfile.Filesystem, path string) (data string, err error) { var ( f fauxfile.File fi os.FileInfo ) if f, err = fs.Open(path); err != nil { return } defer f.Close() if fi, err = f.Stat(); err != nil { return } buf := make([]byte, fi.Size()) if _, err = f.Read(buf); err != nil { if err != io.EOF { return } err = nil } data = string(buf) return }
// Reads a file from the given path and returns a string of the contents. func (ts *Templates) readFile(path string) (out string, err error) { var ( f fauxfile.File fi os.FileInfo buf []byte ) if f, err = ts.fs.Open(path); err != nil { return } defer f.Close() if fi, err = f.Stat(); err != nil { return } buf = make([]byte, fi.Size()) if _, err = f.Read(buf); err != nil { if err != io.EOF { return } err = nil } out = string(buf) return }
// Renders the initalized Post object into an HTML file in the destination. func (gw *GhostWriter) renderPost(post *Post) (err error) { var ( fdst fauxfile.File src string dst string postpath string postbody string body *bytes.Buffer writer *bufio.Writer tmpl *template.Template names []string fmap *template.FuncMap index int str string ) if postpath, err = post.Path(); err != nil { return } src = filepath.Join(post.SrcDir, "body.md") dst = path.Join(gw.args.dst, postpath, "index.html") if postbody, err = gw.readFile(src); err != nil { // A missing body is not an error, just assume a blank entry. postbody = "" err = nil } gw.fs.MkdirAll(path.Dir(dst), 0755) if fdst, err = gw.fs.Create(dst); err != nil { return } defer fdst.Close() if names, err = gw.readDir(post.SrcDir); err != nil { return } for _, name := range names { switch filepath.Ext(name) { case ".md": case ".yaml": default: // Copy other files into destination-they're content. s := filepath.Join(post.SrcDir, name) d := filepath.Join(gw.args.dst, postpath, name) gw.copyFile(s, d) } } fmap = gw.getFuncMap() (*fmap)["link"] = func(i string) string { var ( locali string link string ok bool ) locali = fmt.Sprintf("%v/%v", post.Id, i) if link, ok = gw.links[locali]; ok { return link } return gw.links[i] } (*fmap)["include"] = func(i string) (contents string) { var ( includeErr error fixedPath string ) fixedPath = filepath.Join(post.SrcDir, i) if contents, includeErr = gw.readFile(fixedPath); includeErr != nil { contents = fmt.Sprintf("[[ERROR: Could not read %v]]", fixedPath) } return } // Render post body against links map. tmpl, err = template.New("body").Funcs(*fmap).Parse(postbody) if err != nil { return } body = new(bytes.Buffer) if err = tmpl.Execute(body, nil); err != nil { return } // Render markdown post.Body = string(blackfriday.MarkdownCommon(body.Bytes())) // Check for snippet if index = strings.Index(post.Body, "<!--BREAK-->"); index != -1 { post.Snippet = post.Body[0:index] } // Render post into site template. writer = bufio.NewWriter(fdst) data := map[string]interface{}{ "Post": post, "Site": gw.site, } if str, err = gw.rootTemplate.RenderText(gw.postTemplate, data); err != nil { return } writer.Write([]byte(str)) writer.Flush() return }