all repos — vite @ 02c90b752aeecafd7c76262990e3a5e4b08bb446

a fast (this time, actually) and minimal static site generator

markdown/markdown.go (view raw)

 1package markdown
 2
 3import (
 4	"fmt"
 5	"os"
 6	gotmpl "text/template"
 7	"time"
 8
 9	"git.icyphox.sh/vite/config"
10	"git.icyphox.sh/vite/markdown/template"
11
12	bfc "github.com/Depado/bfchroma"
13	"github.com/alecthomas/chroma/formatters/html"
14	bf "github.com/russross/blackfriday/v2"
15)
16
17var (
18	bfFlags = bf.UseXHTML | bf.Smartypants | bf.SmartypantsFractions |
19		bf.SmartypantsDashes | bf.NofollowLinks | bf.FootnoteReturnLinks
20	bfExts = bf.NoIntraEmphasis | bf.Tables | bf.FencedCode | bf.Autolink |
21		bf.Strikethrough | bf.SpaceHeadings | bf.BackslashLineBreak |
22		bf.HeadingIDs | bf.Footnotes | bf.NoEmptyLineBeforeBlock
23)
24
25type Output struct {
26	HTML []byte
27	Meta Matter
28}
29
30// Renders markdown to html, and fetches metadata.
31func (out *Output) RenderMarkdown(source []byte) error {
32	md := MarkdownDoc{}
33	if err := md.Extract(source); err != nil {
34		return fmt.Errorf("markdown: %w", err)
35	}
36
37	out.HTML = bf.Run(
38		md.Body,
39		bf.WithNoExtensions(),
40		bf.WithRenderer(
41			bfc.NewRenderer(
42				bfc.ChromaOptions(
43					html.TabWidth(4),
44					html.WithClasses(true),
45				),
46				bfc.Extend(
47					bf.NewHTMLRenderer(bf.HTMLRendererParameters{
48						Flags: bfFlags,
49					}),
50				),
51			),
52		),
53		bf.WithExtensions(bfExts),
54	)
55	out.Meta = md.Frontmatter
56	return nil
57}
58
59// Renders out.HTML into dst html file, using the template specified
60// in the frontmatter. data is the template struct.
61func (out *Output) RenderHTML(dst, tmplDir string, data interface{}) error {
62	metaTemplate := out.Meta["template"]
63	if metaTemplate == "" {
64		metaTemplate = config.Config.DefaultTemplate
65	}
66
67	tmpl := template.NewTmpl()
68	tmpl.SetFuncs(gotmpl.FuncMap{
69		"parsedate": func(s string) time.Time {
70			date, _ := time.Parse("2006-01-02", s)
71			return date
72		},
73	})
74	if err := tmpl.Load(tmplDir); err != nil {
75		return err
76	}
77
78	w, err := os.Create(dst)
79	if err != nil {
80		return err
81	}
82
83	if err = tmpl.ExecuteTemplate(w, metaTemplate, data); err != nil {
84		return err
85	}
86	return nil
87}