go-jack/models/models.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)
}