Added options to configure the site

This commit is contained in:
Leon Mika 2026-02-01 17:04:15 +11:00
parent 552b016719
commit 64e19d8700
7 changed files with 118 additions and 17 deletions

2
_site/another.md Normal file
View file

@ -0,0 +1,2 @@
This is some more content.

View file

@ -7,7 +7,11 @@ import (
)
func main() {
if err := progdoc.Site().Publish(); err != nil {
if err := progdoc.Site(
progdoc.Meta(progdoc.SiteMeta{Title: "Prog Doc"}),
progdoc.SourceFile("/", "README.md"),
progdoc.SourceDir("/", "_site"),
).Publish(); err != nil {
log.Fatal(err)
}
}

View file

@ -25,7 +25,7 @@ func (g generator) genSite(siteMap siteMap) (_ generation, err error) {
for _, page := range siteMap.Pages {
srcCtx := SourceCtx{Meta: siteMap.Meta}
targetPathDir := filepath.Join(g.outDir, page.Target)
targetPathDir := filepath.Join(outDir, page.Path)
err := os.MkdirAll(targetPathDir, os.ModePerm)
if err != nil {
return generation{}, err

View file

@ -6,20 +6,20 @@ type pageSource interface {
HTML(w io.Writer, srcCtx *SourceCtx) error
}
type siteMeta struct {
type SiteMeta struct {
Title string
}
type sitePage struct {
Target string
Path string
Source pageSource
}
type siteMap struct {
Meta *siteMeta
Meta *SiteMeta
Pages []sitePage
}
type SourceCtx struct {
Meta *siteMeta
Meta *SiteMeta
}

View file

@ -12,21 +12,26 @@ import (
)
type SiteBuilder struct {
opts []Option
}
func Site() *SiteBuilder {
return &SiteBuilder{}
func Site(opts ...Option) *SiteBuilder {
return &SiteBuilder{
opts: opts,
}
}
func (sb *SiteBuilder) Publish() error {
siteMap := siteMap{
Meta: &siteMeta{
Title: "Prog Doc",
},
Pages: []sitePage{
{Target: "/", Source: stdLayoutSource{MainSource: mdSource{MDFile: "README.md"}}},
{Target: "/more", Source: stdLayoutSource{MainSource: mdSource{MDFile: "_site/more.md"}}},
},
siteMap := siteMap{}
for _, opt := range sb.opts {
if err := opt.configSitemap(&siteMap); err != nil {
return err
}
}
if len(siteMap.Pages) == 0 {
return errors.New("No pages found")
}
gen := generator{}

90
siteopts.go Normal file
View file

@ -0,0 +1,90 @@
package progdoc
import (
"errors"
"log"
"os"
"path/filepath"
"strings"
)
type Option struct {
configSitemap func(sm *siteMap) error
}
func Meta(meta SiteMeta) Option {
return Option{
configSitemap: func(sm *siteMap) error {
sm.Meta = &meta
return nil
},
}
}
func SourceFile(path, file string) Option {
return Option{
configSitemap: func(sm *siteMap) error {
_, err := os.Stat(file)
if err != nil {
return err
}
// TODO: support things other than markdown
src, err := inferSourceFromFilename(file)
if err != nil {
return err
}
log.Printf("Page '%s' -> %s", path, file)
sm.Pages = append(sm.Pages, sitePage{
Path: path,
Source: stdLayoutSource{MainSource: src},
})
return nil
},
}
}
func SourceDir(basePath, dir string) Option {
return Option{
configSitemap: func(sm *siteMap) error {
return filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if !info.IsDir() && info.Mode().IsRegular() {
src, err := inferSourceFromFilename(path)
if err != nil {
return nil
}
relPath, err := filepath.Rel(dir, strings.TrimSuffix(path, filepath.Ext(path)))
if err != nil {
return nil
}
targetPath := filepath.Join(basePath, relPath)
log.Printf("Page '%s' -> %s", targetPath, path)
sm.Pages = append(sm.Pages, sitePage{
Path: relPath,
Source: stdLayoutSource{MainSource: src},
})
}
return nil
})
},
}
}
func inferSourceFromFilename(fname string) (pageSource, error) {
absName, err := filepath.Abs(fname)
if err != nil {
return nil, err
}
if strings.HasSuffix(absName, ".md") {
return mdSource{MDFile: absName}, nil
}
return nil, errors.New("unsupported file type")
}

View file

@ -12,7 +12,7 @@ type stdLayoutSource struct {
func (s stdLayoutSource) HTML(w io.Writer, srcCtx *SourceCtx) error {
var data struct {
Meta *siteMeta
Meta *SiteMeta
Content template.HTML
}