140 lines
2.6 KiB
Go
140 lines
2.6 KiB
Go
package models
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"html/template"
|
|
"io/ioutil"
|
|
"log"
|
|
"os"
|
|
"path"
|
|
"strings"
|
|
|
|
"github.com/yuin/goldmark"
|
|
meta "github.com/yuin/goldmark-meta"
|
|
"github.com/yuin/goldmark/extension"
|
|
"github.com/yuin/goldmark/parser"
|
|
"github.com/yuin/goldmark/renderer/html"
|
|
)
|
|
|
|
type Category struct {
|
|
Name string
|
|
Parent *Category
|
|
Children []*Category
|
|
Articles []*Article
|
|
}
|
|
|
|
type Site struct {
|
|
Name string
|
|
OutputDir string
|
|
Articles []*Article
|
|
Categories map[string]*Category
|
|
}
|
|
|
|
func (s *Site) Append(a *Article) {
|
|
s.Articles = append(s.Articles, a)
|
|
fmt.Println(a)
|
|
|
|
category_path := strings.Replace(a.File, s.OutputDir, "", -1)
|
|
|
|
categories := strings.Split(category_path, "/")
|
|
|
|
for index, category := range categories {
|
|
_, ok := s.Categories[category]
|
|
|
|
if category == "" {
|
|
continue
|
|
}
|
|
|
|
if !ok {
|
|
s.Categories[category] = &Category{Name: category}
|
|
}
|
|
|
|
s.Categories[category].Articles = append(s.Categories[category].Articles, a)
|
|
a.Categories = append(a.Categories, s.Categories[category])
|
|
|
|
if index > len(categories)-4 {
|
|
break
|
|
}
|
|
}
|
|
|
|
fmt.Println(categories)
|
|
}
|
|
|
|
func (s *Site) WriteRootPage() {
|
|
t, err := template.ParseFiles("templates/index.gohtml")
|
|
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
file, err := os.Create(path.Join(s.OutputDir, "index.html"))
|
|
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
err = t.Execute(file, s)
|
|
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
|
|
func (s *Site) Build() {
|
|
for _, article := range s.Articles {
|
|
article.Convert()
|
|
}
|
|
}
|
|
|
|
type Article struct {
|
|
Title string
|
|
HtmlContent string
|
|
publishedDate string
|
|
Url string
|
|
File string
|
|
RelativeFilePath string
|
|
Categories []*Category
|
|
}
|
|
|
|
func (a *Article) FromFile() {
|
|
// Build an Article based on a file path
|
|
|
|
content, err := os.ReadFile(a.File)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
a.FromContent(content)
|
|
}
|
|
|
|
func (a *Article) FromContent(content []byte) {
|
|
// Build an Article instance from a byte[] content
|
|
|
|
md := goldmark.New(
|
|
goldmark.WithExtensions(extension.GFM, meta.Meta),
|
|
goldmark.WithParserOptions(
|
|
parser.WithAutoHeadingID(),
|
|
),
|
|
goldmark.WithRendererOptions(
|
|
html.WithHardWraps(),
|
|
html.WithXHTML(),
|
|
),
|
|
)
|
|
|
|
var buf bytes.Buffer
|
|
context := parser.NewContext()
|
|
if err := md.Convert(content, &buf, parser.WithContext(context)); err != nil {
|
|
panic(err)
|
|
}
|
|
a.HtmlContent = buf.String()
|
|
metadata := meta.Get(context)
|
|
a.Title, _ = metadata["Title"].(string)
|
|
}
|
|
|
|
func (a Article) Convert() {
|
|
outputFilePath := strings.Replace(a.File, ".md", ".html", -1)
|
|
ioutil.WriteFile(outputFilePath, []byte(a.HtmlContent), 0644)
|
|
os.Remove(a.File)
|
|
}
|