-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
128 lines (111 loc) · 3.6 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package main
import (
"fmt"
"io/fs"
"log"
"os"
"strings"
"text/template"
"time"
"github.com/adrg/frontmatter"
"github.com/gomarkdown/markdown"
"github.com/gomarkdown/markdown/parser"
)
// struct for data object including content and global config
type data struct {
Body string
SiteTitle string
Year string
Author string
Pagematter struct {
PageTitle string
}
}
var matter = data{}.Pagematter
// get files in directory
func GetFilesFromDirectory(path string) []fs.DirEntry {
files, readDirErr := os.ReadDir(path)
if readDirErr != nil {
log.Fatalf("Error getting files: %s", readDirErr)
}
return files
}
// read markdown file from directory
func ReadMarkdownFileFromDirectory(path string, filename string) []byte {
md, readErr := os.ReadFile(path + filename)
if readErr != nil {
log.Fatalf("Error reading markdown file: %s", readErr)
}
return md
}
// split body and frontmatter
func SplitBodyAndFrontmatter(md []byte) []byte {
bodyOnly, err := frontmatter.Parse(strings.NewReader(string(md)), &matter)
if err != nil {
log.Fatalf("Error parsing frontmatter: %s", err)
}
return bodyOnly
}
// insert body in template
func BuildTemplate(data data, templates ...string) string {
var t = template.Must(template.ParseFiles(templates...))
build := new(strings.Builder)
templateErr := t.ExecuteTemplate(build, "Page", data)
if templateErr != nil {
log.Fatalf("Error building the template %s", templateErr)
}
return build.String()
}
// write html file
func WriteHTMLFile(fileName string, outpath string, page string) {
outPath := outpath + strings.TrimSuffix(fileName, ".md") + ".html"
writeErr := os.WriteFile(outPath, []byte(page), 0644)
if writeErr != nil {
log.Fatalf("Error writing file: %s", writeErr)
}
fmt.Printf("\n" + fileName + " written to " + outPath + "\n" + "------------------------")
}
func BuildPage(fileName string, dir string, outpath string, templates ...string) {
// global config
author := os.Getenv("AUTHOR")
sitetitle := os.Getenv("SITETITLE")
currentyear := time.Now().Format("2006")
// get markdown body
md := ReadMarkdownFileFromDirectory(dir, fileName)
bodyOnly := SplitBodyAndFrontmatter(md)
// convert markdown to html body
extensions := parser.CommonExtensions | parser.Footnotes
parser := parser.NewWithExtensions(extensions)
body := markdown.ToHTML(bodyOnly, parser, nil)
// build page object with html body and frontmatter
page := data{string(body), sitetitle, currentyear, author, matter}
fmt.Printf("\nBuilding page %s:", page.Pagematter.PageTitle)
// build page with template and write to file
build := BuildTemplate(page, templates...)
WriteHTMLFile(fileName, outpath, build)
}
func BuildPages(dir string, outpath string, templates ...string) {
files := GetFilesFromDirectory(dir)
// build pages from files in directory
for _, file := range files {
fileName := file.Name()
BuildPage(fileName, dir, outpath, templates...)
}
}
func main() {
if len(os.Args) < 2 {
fmt.Println("Usage: go run main.go <input_type> <input_path> [output_path]")
fmt.Println("input_type: 'page' for single page or 'dir' for directory")
return
}
inputType := os.Args[1]
inputPath := os.Args[2]
outputPath := "./public/"
if inputType == "page" {
BuildPage(inputPath+".md", "./markdown/", outputPath, "./templates/page.tmpl", "./templates/header.tmpl", "./templates/footer.tmpl", "./templates/body.tmpl")
} else if inputType == "dir" {
BuildPages("markdown/"+inputPath+"/", outputPath, "./templates/page.tmpl", "./templates/header.tmpl", "./templates/footer.tmpl", "./templates/body.tmpl")
} else {
fmt.Println("Invalid input type. Use 'page' or 'dir'.")
}
}