github.com/abdfnx/gh-api@v0.0.0-20210414084727-f5432eec23b8/internal/docs/markdown.go (about)

     1  package docs
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"io"
     7  	"os"
     8  	"path/filepath"
     9  	"strings"
    10  
    11  	"github.com/spf13/cobra"
    12  )
    13  
    14  func printOptions(buf *bytes.Buffer, cmd *cobra.Command, name string) error {
    15  	flags := cmd.NonInheritedFlags()
    16  	flags.SetOutput(buf)
    17  	if flags.HasAvailableFlags() {
    18  		buf.WriteString("### Options\n\n```\n")
    19  		flags.PrintDefaults()
    20  		buf.WriteString("```\n\n")
    21  	}
    22  
    23  	parentFlags := cmd.InheritedFlags()
    24  	parentFlags.SetOutput(buf)
    25  	if parentFlags.HasAvailableFlags() {
    26  		buf.WriteString("### Options inherited from parent commands\n\n```\n")
    27  		parentFlags.PrintDefaults()
    28  		buf.WriteString("```\n\n")
    29  	}
    30  	return nil
    31  }
    32  
    33  // GenMarkdown creates markdown output.
    34  func GenMarkdown(cmd *cobra.Command, w io.Writer) error {
    35  	return GenMarkdownCustom(cmd, w, func(s string) string { return s })
    36  }
    37  
    38  // GenMarkdownCustom creates custom markdown output.
    39  func GenMarkdownCustom(cmd *cobra.Command, w io.Writer, linkHandler func(string) string) error {
    40  	cmd.InitDefaultHelpCmd()
    41  	cmd.InitDefaultHelpFlag()
    42  
    43  	buf := new(bytes.Buffer)
    44  	name := cmd.CommandPath()
    45  
    46  	buf.WriteString("## " + name + "\n\n")
    47  	buf.WriteString(cmd.Short + "\n\n")
    48  	if len(cmd.Long) > 0 {
    49  		buf.WriteString("### Synopsis\n\n")
    50  		buf.WriteString(cmd.Long + "\n\n")
    51  	}
    52  
    53  	if cmd.Runnable() {
    54  		buf.WriteString(fmt.Sprintf("```\n%s\n```\n\n", cmd.UseLine()))
    55  	}
    56  
    57  	if len(cmd.Example) > 0 {
    58  		buf.WriteString("### Examples\n\n")
    59  		buf.WriteString(fmt.Sprintf("```\n%s\n```\n\n", cmd.Example))
    60  	}
    61  
    62  	if err := printOptions(buf, cmd, name); err != nil {
    63  		return err
    64  	}
    65  	_, err := buf.WriteTo(w)
    66  	return err
    67  }
    68  
    69  // GenMarkdownTree will generate a markdown page for this command and all
    70  // descendants in the directory given. The header may be nil.
    71  // This function may not work correctly if your command names have `-` in them.
    72  // If you have `cmd` with two subcmds, `sub` and `sub-third`,
    73  // and `sub` has a subcommand called `third`, it is undefined which
    74  // help output will be in the file `cmd-sub-third.1`.
    75  func GenMarkdownTree(cmd *cobra.Command, dir string) error {
    76  	identity := func(s string) string { return s }
    77  	emptyStr := func(s string) string { return "" }
    78  	return GenMarkdownTreeCustom(cmd, dir, emptyStr, identity)
    79  }
    80  
    81  // GenMarkdownTreeCustom is the the same as GenMarkdownTree, but
    82  // with custom filePrepender and linkHandler.
    83  func GenMarkdownTreeCustom(cmd *cobra.Command, dir string, filePrepender, linkHandler func(string) string) error {
    84  	for _, c := range cmd.Commands() {
    85  		_, forceGeneration := c.Annotations["markdown:generate"]
    86  		if c.Hidden && !forceGeneration {
    87  			continue
    88  		}
    89  
    90  		if err := GenMarkdownTreeCustom(c, dir, filePrepender, linkHandler); err != nil {
    91  			return err
    92  		}
    93  	}
    94  
    95  	basename := strings.Replace(cmd.CommandPath(), " ", "_", -1) + ".md"
    96  	if basenameOverride, found := cmd.Annotations["markdown:basename"]; found {
    97  		basename = basenameOverride + ".md"
    98  	}
    99  
   100  	filename := filepath.Join(dir, basename)
   101  	f, err := os.Create(filename)
   102  	if err != nil {
   103  		return err
   104  	}
   105  	defer f.Close()
   106  
   107  	if _, err := io.WriteString(f, filePrepender(filename)); err != nil {
   108  		return err
   109  	}
   110  	if err := GenMarkdownCustom(cmd, f, linkHandler); err != nil {
   111  		return err
   112  	}
   113  	return nil
   114  }