Generate HTML documentation for a Go package.
Create the necessary directories,
parses template files and write HTML output for
the specified package entities and imports.
{
// 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)
}
Generate the index page for the documentation and
group packages by their directory prefix.
Create the output directory if it doesn't exist,
parse the index template and writes the generated HTML.
{
// 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,
})
}
Copy static assets (such as CSS, JS, images) from the "templates/static" directory
to the output directory.
Create the required directories and copy files recursively.
{
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
}
Copy a file from the source path to the destination path.
Handle opening, creating, and copying the file contents.
{
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"