-
Miek Gieben authored
Link to commands in the header. Signed-off-by:
Miek Gieben <miek.gieben@ru.nl>
Miek Gieben authoredLink to commands in the header. Signed-off-by:
Miek Gieben <miek.gieben@ru.nl>
main.go 4.32 KiB
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// doc2hugo converts godoc formatted package documentation into Markdown format with a hugo header.
package main
import (
"bytes"
"flag"
"fmt"
"log"
"os"
"path"
"path/filepath"
"strings"
"time"
"go.science.ru.nl/doc2md"
)
var (
verbose = flag.Bool("v", false, "verbose mode")
outdir = flag.String("o", ".", "directory where to output generated files")
// layout control
showTimestamps = flag.Bool("timestamps", false, "show timestamps with directory listings")
declLinks = flag.Bool("links", true, "link identifiers to their declarations")
// The hash format for Github is the default `#L%d`; but other source control platforms do not
// use the same format. For example Bitbucket Enterprise uses `#%d`. This option provides the
// user the option to switch the format as needed and still remain backwards compatible.
srcLinkHashFormat = flag.String("hashformat", "#L%d", "source link URL hash format")
flgImport = flag.String("import", "", "import path for the package")
)
func usage() {
fmt.Fprintf(os.Stderr, "usage: doc2hugo [options] package\n")
flag.PrintDefaults()
os.Exit(2)
}
func main() {
flag.Usage = usage
flag.Parse()
if flag.NArg() != 1 {
usage()
}
pkgName := flag.Arg(0) // actually path
config := &doc2md.Config{
ShowTimestamps: *showTimestamps,
DeclLinks: *declLinks,
SrcLinkHashFormat: *srcLinkHashFormat,
Verbose: *verbose,
Import: *flgImport,
GitRef: "main",
}
doc2md.Funcs["subdir_format"] = func(s string) string {
// up to first slash is domain, chop off to get relative link
sl := strings.Index(s, "/")
return `[` + s[sl+1:] + `](` + path.Base(s) + `)`
}
err := filepath.Walk(pkgName,
func(p string, info os.FileInfo, err error) error {
if !info.IsDir() {
return nil
}
rel, _ := filepath.Rel(pkgName, p)
if len(rel) > 2 && strings.HasPrefix(rel, ".") {
return nil
}
imp := config.Import
defer func() { config.Import = imp; config.SubPackage = "" }()
if rel != "" && rel != "." {
// chekc for dir
config.Import += "/" + rel
config.SubPackage = rel
}
out := path.Join(*outdir, pkgName)
if config.SubPackage != "" {
out = path.Join(out, config.SubPackage)
}
if err := os.MkdirAll(out, 0777); err != nil {
return err
}
outfile := path.Join(out, "index.md")
if err != nil {
return err
}
buf := &bytes.Buffer{}
if err := doc2md.Transform(buf, p, config); err != nil {
return err
}
log.Printf("Writing %s", outfile)
if rbuf, err := readme(pkgName, rel, buf); err == nil {
rbuf = hugo(pkgName, rel, rbuf)
if err := os.WriteFile(outfile, rbuf, 0666); err != nil {
return err
}
} else {
rbuf := hugo(pkgName, rel, buf.Bytes())
if err = os.WriteFile(outfile, rbuf, 0666); err != nil {
return err
}
}
return nil
})
if err != nil {
log.Fatal(err)
}
}
// if there is a README return the contents.
func readme(p, rel string, godoc *bytes.Buffer) ([]byte, error) {
if rel != "." {
p = path.Join(p, rel)
}
buf, err := os.ReadFile(path.Join(p, "README.md"))
if err != nil {
return nil, err
}
rbuf := &bytes.Buffer{}
rbuf.WriteString("# README\n\n")
rbuf.Write(buf)
if godoc.Len() > 10 { // there is go code docs, link to that.
rbuf.WriteString("\n---------------------\n")
rbuf.WriteString("# Package documentation {#documentation}\n\n")
rbuf.Write(godoc.Bytes())
}
return rbuf.Bytes(), nil
}
// add hugo meta data.
func hugo(p, rel string, buf []byte) []byte {
p = path.Clean(p)
if rel != "." {
p = path.Join(p, rel)
}
now := time.Now().UTC()
header := &bytes.Buffer{}
header.WriteString("+++\ntitle = \"")
header.WriteString(p)
header.WriteString("\"\n")
header.WriteString(fmt.Sprintf("%s = \"Package %s.\"\n", "description", p))
header.WriteString(fmt.Sprintf("%s = \"Package %s.\"\n", "summary", p))
header.WriteString(fmt.Sprintf("%s = \"/%s\"\n", "url", p))
header.WriteString(fmt.Sprintf("%s = %s\n", "date", now.Format("2006-01-02")))
header.WriteString(fmt.Sprintf("%s = \"%s\"\n", "repo", "https://gitlab.science.ru.nl/cncz/go/-/tree/main/"+p))
// date??
header.WriteString("+++\n\n")
header.Write(buf)
return header.Bytes()
}