예제 #1
0
파일: template.go 프로젝트: kurrik/tmpl
// 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
}
예제 #2
0
// 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
}
예제 #3
0
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
}
예제 #4
0
// 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
}
예제 #5
0
// 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
}
예제 #6
0
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
}
예제 #7
0
파일: template.go 프로젝트: kurrik/tmpl
// 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
}
예제 #8
0
// 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
}
예제 #9
0
// 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
}