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 bf "git.icyphox.sh/grayfriday"
13)
14
15var (
16 bfFlags = bf.UseXHTML | bf.Smartypants | bf.SmartypantsFractions |
17 bf.SmartypantsDashes | bf.NofollowLinks | bf.FootnoteReturnLinks
18 bfExts = bf.NoIntraEmphasis | bf.Tables | bf.FencedCode | bf.Autolink |
19 bf.Strikethrough | bf.SpaceHeadings | bf.BackslashLineBreak |
20 bf.HeadingIDs | bf.Footnotes | bf.NoEmptyLineBeforeBlock
21)
22
23type Output struct {
24 HTML []byte
25 Meta Matter
26}
27
28// Renders markdown to html, and fetches metadata.
29func (out *Output) RenderMarkdown(source []byte) error {
30 md := MarkdownDoc{}
31 if err := md.Extract(source); err != nil {
32 return fmt.Errorf("markdown: %w", err)
33 }
34
35 out.HTML = bf.Run(
36 md.Body,
37 bf.WithNoExtensions(),
38 bf.WithRenderer(bf.NewHTMLRenderer(bf.HTMLRendererParameters{Flags: bfFlags})),
39 bf.WithExtensions(bfExts),
40 )
41 out.Meta = md.Frontmatter
42 return nil
43}
44
45// Renders out.HTML into dst html file, using the template specified
46// in the frontmatter. data is the template struct.
47func (out *Output) RenderHTML(dst, tmplDir string, data interface{}) error {
48 metaTemplate := out.Meta["template"]
49 if metaTemplate == "" {
50 metaTemplate = config.Config.DefaultTemplate
51 }
52
53 tmpl := template.NewTmpl()
54 tmpl.SetFuncs(gotmpl.FuncMap{
55 "parsedate": func(s string) time.Time {
56 date, _ := time.Parse("2006-01-02", s)
57 return date
58 },
59 })
60 if err := tmpl.Load(tmplDir); err != nil {
61 return err
62 }
63
64 w, err := os.Create(dst)
65 if err != nil {
66 return err
67 }
68
69 if err = tmpl.ExecuteTemplate(w, metaTemplate, data); err != nil {
70 return err
71 }
72 return nil
73}