GenerateHTML generates an HTML file for the given package and entities
{
// Create the output directory if it doesn't exist
if err := os.MkdirAll(outputDir, os.ModePerm); err != nil {
return fmt.Errorf("error creating output directory: %v", err)
}
tmpl, err := template.New("package").Parse(htmlTemplate)
if err != nil {
return err
}
// Extract the relative path of the package based on the project path
relativePackagePath, err := filepath.Rel(projectPath, packagePath)
if err != nil {
return err
}
// Replace slashes with hyphens to ensure unique filenames
safeFileName := strings.ReplaceAll(relativePackagePath, string(os.PathSeparator), "-")
// Generate the HTML file
filePath := filepath.Join(outputDir, fmt.Sprintf("%s.html", safeFileName))
file, err := os.Create(filePath)
if err != nil {
return err
}
defer file.Close()
// Determine if the package has functions, types, and structs
hasFunctions := false
hasTypes := false
hasStructs := false
hasInterfaces := false
hasImports := len(imports) > 0
for _, entity := range entities {
if entity.Type == "function" {
hasFunctions = true
} else if entity.Type == "type" {
hasTypes = true
} else if entity.Type == "struct" {
hasStructs = true
} else if entity.Type == "interface" {
hasInterfaces = true
}
}
data := struct {
PackageName string
Entities []parser.EntityInfo
Imports []parser.ImportInfo
Title string
HasFunctions bool
HasTypes bool
HasStructs bool
HasInterfaces bool
HasImports bool
}{
PackageName: relativePackagePath,
Entities: entities,
Imports: imports,
Title: docTitle,
HasFunctions: hasFunctions,
HasTypes: hasTypes,
HasStructs: hasStructs,
HasInterfaces: hasInterfaces,
HasImports: hasImports,
}
return tmpl.Execute(file, data)
}
GenerateIndex generates the index.html file listing all the documented packages
{
// Create the output directory if it doesn't exist
if err := os.MkdirAll(outputDir, os.ModePerm); err != nil {
return err
}
tmpl, err := template.New("index").Parse(indexTemplate)
if err != nil {
return err
}
file, err := os.Create(filepath.Join(outputDir, "index.html"))
if err != nil {
return err
}
defer file.Close()
// Group packages by their prefix
groupedPackages := make(map[string][]PackageLink)
var totalPackages int
for _, pkg := range packages {
parts := strings.Split(pkg, string(os.PathSeparator))
prefix := parts[0]
safeFileName := strings.ReplaceAll(pkg, string(os.PathSeparator), "-")
groupedPackages[prefix] = append(groupedPackages[prefix], PackageLink{
Name: pkg,
Link: safeFileName + ".html",
})
totalPackages++
}
// Sort packages within each group
for _, packages := range groupedPackages {
sort.Slice(packages, func(i, j int) bool {
return packages[i].Name < packages[j].Name
})
}
// Execute template with data
return tmpl.Execute(file, struct {
Title string
GroupedPackages map[string][]PackageLink
TotalPackages int
ReadmeContent string
}{
Title: docTitle,
GroupedPackages: groupedPackages,
TotalPackages: totalPackages,
ReadmeContent: readmeContent,
})
}
CopyStaticAssets copies the static folder itself to the output directory
{
if err := os.MkdirAll(outputDir, os.ModePerm); err != nil {
return fmt.Errorf("error creating output directory: %v", err)
}
// Create the 'static' directory in the output location
dstPath := filepath.Join(outputDir, "static")
if err := os.MkdirAll(dstPath, os.ModePerm); err != nil {
return fmt.Errorf("error creating static directory: %v", err)
}
assets, err := staticAssets.ReadDir("templates/static")
if err != nil {
return fmt.Errorf("error reading static assets: %v", err)
}
for _, asset := range assets {
srcPath := filepath.Join("templates/static", asset.Name())
dstAssetPath := filepath.Join(dstPath, asset.Name())
if asset.IsDir() {
// If it's a directory, recursively copy its contents
if err := CopyStaticAssets(filepath.Join(outputDir, "static", asset.Name())); err != nil {
return fmt.Errorf("error copying directory: %v", err)
}
} else {
// If it's a file, copy it
if err := copyFile(srcPath, dstAssetPath); err != nil {
return err
}
}
}
return nil
}
copyFile copies a single file from src to dst
{
src, err := staticAssets.Open(srcPath)
if err != nil {
return fmt.Errorf("error opening static asset: %v", err)
}
defer src.Close()
dst, err := os.Create(dstPath)
if err != nil {
return fmt.Errorf("error creating file: %v", err)
}
defer dst.Close()
if _, err := io.Copy(dst, src); err != nil {
return fmt.Errorf("error copying file: %v", err)
}
return nil
}
import "embed"
import "fmt"
import "os"
import "path/filepath"
import "strings"
import "text/template"
import "github.com/vanilla-os/pallas/pkg/parser"
import "embed"
Anonymous Import
import "os"
import "path/filepath"
import "sort"
import "strings"
import "text/template"
import "fmt"
import "io"
import "os"
import "path/filepath"