Initial commit

This commit is contained in:
Leon Mika 2026-02-01 15:00:26 +11:00
commit 9e7950ddba
11 changed files with 200 additions and 0 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
.idea/

5
README.md Normal file
View file

@ -0,0 +1,5 @@
# projdoc - Project Documentation Generator
A Go package used for generating HTML documentation for Go projects. Modelled after 11ty.
To learn more, visit the [more](/more).

3
_site/more.md Normal file
View file

@ -0,0 +1,3 @@
# More
This is more information about this project and it's good.

13
cmd/doc/main.go Normal file
View file

@ -0,0 +1,13 @@
package main
import (
"log"
"lmika.dev/pkg/progdoc"
)
func main() {
if err := progdoc.Site().Build(); err != nil {
log.Fatal(err)
}
}

42
generator.go Normal file
View file

@ -0,0 +1,42 @@
package progdoc
import (
"os"
"path/filepath"
)
type generator struct {
outDir string
}
func (g generator) genSite(siteMap siteMap) (err error) {
outDir := g.outDir
if outDir == "" {
outDir, err = os.MkdirTemp("", "")
if err != nil {
return err
}
}
for _, page := range siteMap.Pages {
srcCtx := SourceCtx{Meta: siteMap.Meta}
targetPathDir := filepath.Join(g.outDir, page.Target)
err := os.MkdirAll(targetPathDir, os.ModePerm)
if err != nil {
return err
}
if err := (func(fileName string) error {
f, err := os.Create(fileName)
if err != nil {
return err
}
defer f.Close()
return page.Source.HTML(f, &srcCtx)
})(filepath.Join(targetPathDir, "index.html")); err != nil {
return err
}
}
return nil
}

5
go.mod Normal file
View file

@ -0,0 +1,5 @@
module lmika.dev/pkg/progdoc
go 1.24.3
require github.com/yuin/goldmark v1.7.16 // indirect

2
go.sum Normal file
View file

@ -0,0 +1,2 @@
github.com/yuin/goldmark v1.7.16 h1:n+CJdUxaFMiDUNnWC3dMWCIQJSkxH4uz3ZwQBkAlVNE=
github.com/yuin/goldmark v1.7.16/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg=

34
mdsource.go Normal file
View file

@ -0,0 +1,34 @@
package progdoc
import (
"io"
"os"
"github.com/yuin/goldmark"
"github.com/yuin/goldmark/extension"
"github.com/yuin/goldmark/parser"
"github.com/yuin/goldmark/renderer/html"
)
type mdSource struct {
MDFile string
}
func (m mdSource) HTML(w io.Writer, srcCtx *SourceCtx) error {
srcBytes, err := os.ReadFile(m.MDFile)
if err != nil {
return err
}
md := goldmark.New(
goldmark.WithExtensions(extension.GFM),
goldmark.WithParserOptions(
parser.WithAutoHeadingID(),
),
goldmark.WithRendererOptions(
html.WithUnsafe(),
),
)
return md.Convert(srcBytes, w)
}

25
models.go Normal file
View file

@ -0,0 +1,25 @@
package progdoc
import "io"
type pageSource interface {
HTML(w io.Writer, srcCtx *SourceCtx) error
}
type siteMeta struct {
Title string
}
type sitePage struct {
Target string
Source pageSource
}
type siteMap struct {
Meta *siteMeta
Pages []sitePage
}
type SourceCtx struct {
Meta *siteMeta
}

26
progdoc.go Normal file
View file

@ -0,0 +1,26 @@
package progdoc
type SiteBuilder struct {
}
func Site() *SiteBuilder {
return &SiteBuilder{}
}
func (sb *SiteBuilder) Build() 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"}}},
},
}
gen := generator{outDir: "out"}
if err := gen.genSite(siteMap); err != nil {
return err
}
return nil
}

44
stdlayout.go Normal file
View file

@ -0,0 +1,44 @@
package progdoc
import (
"bytes"
"html/template"
"io"
)
type stdLayoutSource struct {
MainSource pageSource
}
func (s stdLayoutSource) HTML(w io.Writer, srcCtx *SourceCtx) error {
var data struct {
Meta *siteMeta
Content template.HTML
}
var content bytes.Buffer
if err := s.MainSource.HTML(&content, srcCtx); err != nil {
return err
}
data.Meta = srcCtx.Meta
data.Content = template.HTML(content.String())
return stdLayoutTemplate.Execute(w, data)
}
var stdLayoutTemplate = template.Must(template.New("stdlayout").Parse(`<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{.Meta.Title}}</title>
<link rel="stylesheet" href="https://cdn.simplecss.org/simple.min.css">
</head>
<body>
<main>
{{.Content}}
</main>
</body>
</html>
`))