posts-go/main.go

145 lines
3.4 KiB
Go
Raw Normal View History

2021-11-30 15:17:09 +00:00
package main
import (
2022-07-11 04:26:24 +00:00
"bytes"
"io"
2021-11-30 15:17:09 +00:00
"log"
"os"
"path/filepath"
"strings"
2022-07-11 04:26:24 +00:00
"text/template"
2021-11-30 15:17:09 +00:00
2022-07-11 04:26:24 +00:00
"github.com/tdewolff/minify/v2"
minify_css "github.com/tdewolff/minify/v2/css"
minify_html "github.com/tdewolff/minify/v2/html"
"github.com/yuin/goldmark"
gm_extension "github.com/yuin/goldmark/extension"
gm_html "github.com/yuin/goldmark/renderer/html"
2021-11-30 15:17:09 +00:00
)
const (
2022-07-11 04:26:24 +00:00
postFilesPath = "posts"
templatePostPath = "templates/post.html"
templateCSSPath = "templates/styles.css"
cssFilename = "styles.css"
2022-07-10 11:09:42 +00:00
generatedPath = "docs"
2022-07-11 04:26:24 +00:00
extHTML = ".html"
mimeTypeHTML = "text/html"
mimeTypeCSS = "text/css"
2021-11-30 15:17:09 +00:00
)
2022-07-11 04:26:24 +00:00
type templatePostData struct {
Body string
}
2021-11-30 15:17:09 +00:00
func main() {
2022-07-10 11:32:01 +00:00
// Cleanup generated path
if err := os.RemoveAll(generatedPath); err != nil {
log.Fatalln("Failed to remove all", generatedPath, err)
}
if err := os.MkdirAll(generatedPath, 0o777); err != nil {
log.Fatalln("Failed to mkdir all", generatedPath)
}
2022-07-11 04:26:24 +00:00
// Read post files directory
postFiles, err := os.ReadDir(postFilesPath)
2021-11-30 15:17:09 +00:00
if err != nil {
2022-07-11 04:26:24 +00:00
log.Fatalln("Failed to read dir", postFilesPath)
2021-11-30 15:17:09 +00:00
}
2022-07-11 04:26:24 +00:00
// Prepare template
templatePostBytes, err := os.ReadFile(templatePostPath)
2021-11-30 15:17:09 +00:00
if err != nil {
2022-07-11 04:26:24 +00:00
log.Fatalln("Failed to read file", templatePostPath, err)
2021-11-30 15:17:09 +00:00
}
2022-07-11 04:26:24 +00:00
templatePost, err := template.New("post").Parse(string(templatePostBytes))
if err != nil {
log.Fatalln("Failed to parse template", err)
}
// Prepare parse markdown
gm := goldmark.New(
goldmark.WithExtensions(
gm_extension.GFM,
),
goldmark.WithRendererOptions(
gm_html.WithHardWraps(),
),
)
// Prepare minify
m := minify.New()
m.AddFunc(mimeTypeHTML, minify_html.Minify)
m.AddFunc(mimeTypeCSS, minify_css.Minify)
// Generate post files
for _, postFile := range postFiles {
if postFile.IsDir() {
2021-11-30 15:17:09 +00:00
continue
}
2022-07-11 04:26:24 +00:00
// Prepare post file
mdFilename := filepath.Join(postFilesPath, postFile.Name())
mdFileBytes, err := os.ReadFile(mdFilename)
2021-11-30 15:17:09 +00:00
if err != nil {
2022-07-11 04:26:24 +00:00
log.Fatalln("Failed to read file", mdFilename, err)
2021-11-30 15:17:09 +00:00
}
2022-07-11 04:26:24 +00:00
// Prepare html file
htmlFilename := strings.TrimSuffix(postFile.Name(), filepath.Ext(postFile.Name())) + extHTML
htmlFilepath := filepath.Join(generatedPath, htmlFilename)
htmlFile, err := os.OpenFile(htmlFilepath, os.O_RDWR|os.O_CREATE, 0o600)
if err != nil {
log.Fatalln("Failed to open file", htmlFilepath, err)
}
// Parse markdown
var markdownBuf bytes.Buffer
if err := gm.Convert(mdFileBytes, &markdownBuf); err != nil {
log.Fatalln("Failed to convert markdown", err)
2021-11-30 15:17:09 +00:00
}
2022-07-11 04:26:24 +00:00
tmpReader, tmpWriter := io.Pipe()
2021-11-30 15:17:09 +00:00
2022-07-11 04:26:24 +00:00
// Template
go func() {
if err := templatePost.Execute(tmpWriter, templatePostData{
Body: markdownBuf.String(),
}); err != nil {
log.Fatalln("Failed to execute html template", err)
}
tmpWriter.Close()
}()
2021-11-30 15:17:09 +00:00
2022-07-11 04:26:24 +00:00
// Minify
if err := m.Minify(mimeTypeHTML, htmlFile, tmpReader); err != nil {
log.Fatalln("Failed to minify html", err)
2021-11-30 15:17:09 +00:00
}
2022-07-11 04:26:24 +00:00
tmpReader.Close()
htmlFile.Close()
}
// Copy css file
templateCSSFile, err := os.OpenFile(templateCSSPath, os.O_RDONLY, 0o600)
if err != nil {
log.Fatalln("Failed to open file", templateCSSPath, err)
}
cssFilename := filepath.Join(generatedPath, cssFilename)
cssFile, err := os.OpenFile(cssFilename, os.O_RDWR|os.O_CREATE, 0o600)
if err != nil {
log.Fatalln("Failed to open file", cssFilename, err)
}
if err := m.Minify(mimeTypeCSS, cssFile, templateCSSFile); err != nil {
log.Fatalln("Failed to minify css", err)
2021-11-30 15:17:09 +00:00
}
}