forked from mirror/cobra
genmarkdown: add optional frontmatter- and linkadjustment-funcs
The automatic Markdown generator works great! But to use it to render the documentation in Hugo, we need front matter and slightly different links. This commit adds optional callback funcs to add that.
This commit is contained in:
parent
be18870136
commit
1d99c8ff6d
23
md_docs.go
23
md_docs.go
|
@ -47,6 +47,10 @@ func (s byName) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
||||||
func (s byName) Less(i, j int) bool { return s[i].Name() < s[j].Name() }
|
func (s byName) Less(i, j int) bool { return s[i].Name() < s[j].Name() }
|
||||||
|
|
||||||
func GenMarkdown(cmd *Command, out *bytes.Buffer) {
|
func GenMarkdown(cmd *Command, out *bytes.Buffer) {
|
||||||
|
GenMarkdownCustom(cmd, out, func(s string) string { return s })
|
||||||
|
}
|
||||||
|
|
||||||
|
func GenMarkdownCustom(cmd *Command, out *bytes.Buffer, linkHandler func(string) string) {
|
||||||
name := cmd.CommandPath()
|
name := cmd.CommandPath()
|
||||||
|
|
||||||
short := cmd.Short
|
short := cmd.Short
|
||||||
|
@ -78,7 +82,7 @@ func GenMarkdown(cmd *Command, out *bytes.Buffer) {
|
||||||
pname := parent.CommandPath()
|
pname := parent.CommandPath()
|
||||||
link := pname + ".md"
|
link := pname + ".md"
|
||||||
link = strings.Replace(link, " ", "_", -1)
|
link = strings.Replace(link, " ", "_", -1)
|
||||||
fmt.Fprintf(out, "* [%s](%s)\t - %s\n", pname, link, parent.Short)
|
fmt.Fprintf(out, "* [%s](%s)\t - %s\n", pname, linkHandler(link), parent.Short)
|
||||||
}
|
}
|
||||||
|
|
||||||
children := cmd.Commands()
|
children := cmd.Commands()
|
||||||
|
@ -91,7 +95,7 @@ func GenMarkdown(cmd *Command, out *bytes.Buffer) {
|
||||||
cname := name + " " + child.Name()
|
cname := name + " " + child.Name()
|
||||||
link := cname + ".md"
|
link := cname + ".md"
|
||||||
link = strings.Replace(link, " ", "_", -1)
|
link = strings.Replace(link, " ", "_", -1)
|
||||||
fmt.Fprintf(out, "* [%s](%s)\t - %s\n", cname, link, child.Short)
|
fmt.Fprintf(out, "* [%s](%s)\t - %s\n", cname, linkHandler(link), child.Short)
|
||||||
}
|
}
|
||||||
fmt.Fprintf(out, "\n")
|
fmt.Fprintf(out, "\n")
|
||||||
}
|
}
|
||||||
|
@ -100,13 +104,17 @@ func GenMarkdown(cmd *Command, out *bytes.Buffer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func GenMarkdownTree(cmd *Command, dir string) {
|
func GenMarkdownTree(cmd *Command, dir string) {
|
||||||
for _, c := range cmd.Commands() {
|
noOp := func(s string) string { return s }
|
||||||
GenMarkdownTree(c, dir)
|
GenMarkdownTreeCustom(cmd, dir, noOp, noOp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GenMarkdownTreeCustom(cmd *Command, dir string, filePrepender func(string) string, linkHandler func(string) string) {
|
||||||
|
for _, c := range cmd.Commands() {
|
||||||
|
GenMarkdownTreeCustom(c, dir, filePrepender, linkHandler)
|
||||||
|
}
|
||||||
out := new(bytes.Buffer)
|
out := new(bytes.Buffer)
|
||||||
|
|
||||||
GenMarkdown(cmd, out)
|
GenMarkdownCustom(cmd, out, linkHandler)
|
||||||
|
|
||||||
filename := cmd.CommandPath()
|
filename := cmd.CommandPath()
|
||||||
filename = dir + strings.Replace(filename, " ", "_", -1) + ".md"
|
filename = dir + strings.Replace(filename, " ", "_", -1) + ".md"
|
||||||
|
@ -116,6 +124,11 @@ func GenMarkdownTree(cmd *Command, dir string) {
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
defer outFile.Close()
|
defer outFile.Close()
|
||||||
|
_, err = outFile.WriteString(filePrepender(filename))
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
_, err = outFile.Write(out.Bytes())
|
_, err = outFile.Write(out.Bytes())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
|
|
48
md_docs.md
48
md_docs.md
|
@ -25,7 +25,7 @@ This will generate a whole series of files, one for each command in the tree, in
|
||||||
|
|
||||||
## Generate markdown docs for a single command
|
## Generate markdown docs for a single command
|
||||||
|
|
||||||
You may wish to have more control over the output, or only generate for a single command, instead of the entire command tree. If this is the case you may prefer to `GenMarkdown()` instead of `GenMarkdownTree`
|
You may wish to have more control over the output, or only generate for a single command, instead of the entire command tree. If this is the case you may prefer to `GenMarkdown` instead of `GenMarkdownTree`
|
||||||
|
|
||||||
```go
|
```go
|
||||||
out := new(bytes.Buffer)
|
out := new(bytes.Buffer)
|
||||||
|
@ -33,3 +33,49 @@ You may wish to have more control over the output, or only generate for a single
|
||||||
```
|
```
|
||||||
|
|
||||||
This will write the markdown doc for ONLY "cmd" into the out, buffer.
|
This will write the markdown doc for ONLY "cmd" into the out, buffer.
|
||||||
|
|
||||||
|
## Customize the output
|
||||||
|
|
||||||
|
Both `GenMarkdown` and `GenMarkdownTree` has alternate versions with callbacks to get some control of the output:
|
||||||
|
|
||||||
|
```go
|
||||||
|
func GenMarkdownTreeCustom(cmd *Command, dir string, filePrepender func(string) string, linkHandler func(string) string) {
|
||||||
|
//...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```go
|
||||||
|
func GenMarkdownCustom(cmd *Command, out *bytes.Buffer, linkHandler func(string) string) {
|
||||||
|
//...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The `filePrepender` will prepend the return value given the full filepath to the rendered Markdown file. A common use case is to add front matter to use the generated documentation with [Hugo](http://gohugo.io/):
|
||||||
|
|
||||||
|
```go
|
||||||
|
const fmTemplate = `---
|
||||||
|
date: %s
|
||||||
|
title: "%s"
|
||||||
|
slug: %s
|
||||||
|
url: %s
|
||||||
|
---
|
||||||
|
`
|
||||||
|
|
||||||
|
filePrepender := func(filename string) string {
|
||||||
|
now := time.Now().Format(time.RFC3339)
|
||||||
|
name := filepath.Base(filename)
|
||||||
|
base := strings.TrimSuffix(name, path.Ext(name))
|
||||||
|
url := "/commands/" + strings.ToLower(base) + "/"
|
||||||
|
return fmt.Sprintf(fmTemplate, now, strings.Replace(base, "_", " ", -1), base, url)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The `linkHandler` can be used to customize the rendered internal links to the commands, given a filename:
|
||||||
|
|
||||||
|
```go
|
||||||
|
linkHandler := func(name string) string {
|
||||||
|
base := strings.TrimSuffix(name, path.Ext(name))
|
||||||
|
return "/commands/" + strings.ToLower(base) + "/"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
Loading…
Reference in New Issue