summaryrefslogtreecommitdiff
path: root/internal/build/build.go
diff options
context:
space:
mode:
authorHimanshu Sardana <himanshusardana2005@gmail.com>2026-03-26 21:26:35 +0000
committerHimanshu Sardana <himanshusardana2005@gmail.com>2026-03-26 21:26:35 +0000
commit103e84d847262830bbaa550b37218e9ca8b317d3 (patch)
treee19d3bfd6594600fb28be1ccac1a3869207bc49c /internal/build/build.go
parent5c631f0cdb8ee3238ff054d171dd8babd158047b (diff)
refactor: split into cmd, pkg
Diffstat (limited to 'internal/build/build.go')
-rw-r--r--internal/build/build.go290
1 files changed, 73 insertions, 217 deletions
diff --git a/internal/build/build.go b/internal/build/build.go
index 4511745..aadae66 100644
--- a/internal/build/build.go
+++ b/internal/build/build.go
@@ -3,260 +3,116 @@ package build
import (
"fmt"
"html/template"
- "io/fs"
"log"
- "os"
- "path/filepath"
- "sort"
- "strings"
- "time"
- "gopkg.in/yaml.v2"
-
- "github.com/adrg/frontmatter"
- "github.com/gomarkdown/markdown"
- "github.com/gomarkdown/markdown/ast"
- "github.com/gomarkdown/markdown/html"
- "github.com/gomarkdown/markdown/parser"
+ "github.com/HimanshuSardana/kite/pkg/content"
+ "github.com/HimanshuSardana/kite/pkg/themes"
)
-var (
- themeName = "gruvbox"
- contentDir = "./content"
- outputDir = "./output"
+const (
+ DefaultContentDir = "./content"
+ DefaultOutputDir = "./output"
+ DefaultThemesDir = "./themes"
+ DefaultConfigPath = "./config.yaml"
+ DefaultThemeName = "modern-light"
)
-type Frontmatter struct {
- Title string `yaml:"title"`
- Date string `yaml:"date"`
- Tags []string `yaml:"tags"`
-}
-
-type Page struct {
- Title string
- Content template.HTML
- TOC []TOCItem
-}
-
-type TOCItem struct {
- Level int
- Text string
- ID string
-}
-
-type PostSummary struct {
- Title string
- Slug string
- Date string
- Tags []string
-}
-
-type HomePage struct {
- SiteTitle string `yaml:"siteTitle"`
- AuthorName string `yaml:"authorName"`
- AuthorRole string `yaml:"authorRole"`
- AuthorBio string `yaml:"authorBio"`
- Year int
- Posts []PostSummary
-}
-
-var posts = make([]Post, 0)
-
-type Post struct {
- Title string
+type BuildOptions struct {
+ ThemeName string
+ ContentDir string
+ OutputDir string
+ ThemesDir string
+ ConfigPath string
}
-func Build(themeName string) {
- if themeName == "" {
- themeName = "modern-light"
+func Build(opts BuildOptions) error {
+ if opts.ThemeName == "" {
+ opts.ThemeName = DefaultThemeName
}
-
- summaries := make([]PostSummary, 0)
-
- err := filepath.WalkDir(contentDir, func(path string, d fs.DirEntry, err error) error {
- if err != nil {
- return err
- }
-
- if d.IsDir() {
- return nil
- }
-
- if strings.HasSuffix(d.Name(), ".md") {
- fmt.Println("Processing:", path)
-
- matter, htmlContent, toc := convertToHtml(path)
- slug := strings.TrimSuffix(d.Name(), ".md")
- summaries = append(summaries, PostSummary{
- Title: matter.Title,
- Slug: slug,
- Date: matter.Date,
- Tags: matter.Tags,
- })
-
- posts = append(posts, Post{Title: matter.Title})
- // fmt.Println("Appended post", posts)
- newPage := Page{
- Title: matter.Title,
- Content: template.HTML(htmlContent),
- TOC: toc,
- }
-
- tmpl, err := template.ParseFiles("./themes/" + themeName + "/layout.html")
- if err != nil {
- log.Fatalf("Error parsing template: %s", err)
- }
-
- relPath, err := filepath.Rel(contentDir, path)
- if err != nil {
- log.Fatalf("Error computing relative path: %s", err)
- }
- // test.md -> test.html
- // test.md -> test/index.html
- outputFilePath := filepath.Join(outputDir, strings.Replace(relPath, ".md", "/index.html", 1))
-
- err = os.MkdirAll(filepath.Dir(outputFilePath), 0o755)
- if err != nil {
- log.Fatalf("Error creating directories: %s", err)
- }
-
- outputFile, err := os.Create(outputFilePath)
- if err != nil {
- log.Fatalf("Error creating output file: %s", err)
- }
- defer outputFile.Close()
-
- err = tmpl.Execute(outputFile, newPage)
- if err != nil {
- log.Fatalf("Error generating output content: %s", err)
- }
- }
-
- return nil
- })
- if err != nil {
- log.Fatalf("Error walking directory: %s", err)
+ if opts.ContentDir == "" {
+ opts.ContentDir = DefaultContentDir
}
-
- fmt.Println("All files processed!")
-
- fmt.Println(posts)
- fmt.Println(themeName)
-
- renderHomePage(themeName, summaries, outputDir)
-}
-
-func convertToHtml(path string) (Frontmatter, []byte, []TOCItem) {
- md, err := os.ReadFile(path)
- if err != nil {
- log.Fatalf("Error reading %s: %s", path, err)
+ if opts.OutputDir == "" {
+ opts.OutputDir = DefaultOutputDir
}
-
- var matter Frontmatter
- rest, err := frontmatter.Parse(strings.NewReader(string(md)), &matter)
- if err != nil {
- log.Fatalf("Error parsing frontmatter: %s", err)
+ if opts.ThemesDir == "" {
+ opts.ThemesDir = DefaultThemesDir
+ }
+ if opts.ConfigPath == "" {
+ opts.ConfigPath = DefaultConfigPath
}
- extensions := parser.CommonExtensions | parser.AutoHeadingIDs
- p := parser.NewWithExtensions(extensions)
+ themePath := themes.GetThemePath(opts.ThemesDir, opts.ThemeName)
- doc := p.Parse(rest)
+ files, err := content.ListContentFiles(opts.ContentDir)
+ if err != nil {
+ return fmt.Errorf("listing content files: %w", err)
+ }
- var toc []TOCItem
+ summaries := make([]content.PostSummary, 0, len(files))
- ast.WalkFunc(doc, func(node ast.Node, entering bool) ast.WalkStatus {
- if heading, ok := node.(*ast.Heading); ok && entering {
- text := extractText(heading)
- id := string(heading.HeadingID)
+ for _, file := range files {
+ fmt.Println("Processing:", file.Path)
- toc = append(toc, TOCItem{
- Level: heading.Level,
- Text: text,
- ID: id,
- })
+ parsed, err := ParseMarkdown(file.Path)
+ if err != nil {
+ log.Printf("Error parsing %s: %v", file.Path, err)
+ continue
}
- return ast.GoToNext
- })
-
- renderer := html.NewRenderer(html.RendererOptions{
- Flags: html.CommonFlags,
- })
-
- output := markdown.Render(doc, renderer)
- return matter, output, toc
-}
+ summaries = append(summaries, content.PostSummary{
+ Title: parsed.Frontmatter.Title,
+ Slug: file.Slug,
+ Date: parsed.Frontmatter.Date,
+ Tags: parsed.Frontmatter.Tags,
+ })
-func extractText(h *ast.Heading) string {
- var text string
- ast.WalkFunc(h, func(node ast.Node, entering bool) ast.WalkStatus {
- if leaf, ok := node.(*ast.Text); ok && entering {
- text += string(leaf.Literal)
+ outputPath, err := content.GetOutputPath(opts.ContentDir, file.Path, opts.OutputDir)
+ if err != nil {
+ log.Printf("Error computing output path: %v", err)
+ continue
}
- return ast.GoToNext
- })
- return text
-}
-func renderHomePage(themeName string, summaries []PostSummary, outputDir string) {
- sort.Slice(summaries, func(i, j int) bool {
- return summaries[i].Date > summaries[j].Date
- })
+ tmpl, err := LoadTemplate(themePath, "layout.html")
+ if err != nil {
+ log.Fatalf("Error loading template: %v", err)
+ }
- for i, p := range summaries {
- if t, err := time.Parse("2006-01-02", p.Date); err == nil {
- summaries[i].Date = t.Format("Jan 2006")
+ page := Page{
+ Title: parsed.Frontmatter.Title,
+ Content: template.HTML(parsed.Content),
+ TOC: parsed.TOC,
}
- }
- config, err := os.ReadFile("config.yaml")
- if err != nil {
- panic(err)
+ if err := RenderPage(tmpl, outputPath, page); err != nil {
+ log.Printf("Error rendering page: %v", err)
+ }
}
- var data HomePage
- err = yaml.Unmarshal(config, &data)
- data.Posts = summaries
- data.Year = time.Now().Year()
- if err != nil {
- panic(err)
- }
+ fmt.Println("All files processed!")
- tmpl, err := template.ParseFiles("./themes/" + themeName + "/home.html")
- if err != nil {
- log.Fatalf("Error parsing home template: %s", err)
+ if err := RenderHomePage(themePath, opts.OutputDir, opts.ConfigPath, summaries); err != nil {
+ log.Printf("Error rendering home page: %v", err)
}
- outPath := filepath.Join(outputDir, "index.html")
- if err := os.MkdirAll(filepath.Dir(outPath), 0o755); err != nil {
- log.Fatalf("Error creating output dir: %s", err)
- }
- f, err := os.Create(outPath)
- if err != nil {
- log.Fatalf("Error creating index.html: %s", err)
- }
- defer f.Close()
+ return nil
+}
- if err := tmpl.Execute(f, data); err != nil {
- log.Fatalf("Error rendering home page: %s", err)
+func ListThemes(themesDir string) []string {
+ if themesDir == "" {
+ themesDir = DefaultThemesDir
}
- fmt.Println("Home page written to", outPath)
-}
-func ListThemes() []string {
- themeList := make([]string, 0)
- themes, err := os.ReadDir("./themes")
+ themeList, err := themes.List(themesDir)
if err != nil {
log.Fatal("Error:", err)
}
- for _, theme := range themes {
- if theme.IsDir() {
- themeList = append(themeList, string(theme.Name()))
- }
- }
- return themeList
+ result := make([]string, len(themeList))
+ for i, t := range themeList {
+ result[i] = t.Name
+ }
+ return result
}
func ShowHelpMessage() {