man.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. package flags
  2. import (
  3. "fmt"
  4. "io"
  5. "strings"
  6. "time"
  7. )
  8. func formatForMan(wr io.Writer, s string) {
  9. for {
  10. idx := strings.IndexRune(s, '`')
  11. if idx < 0 {
  12. fmt.Fprintf(wr, "%s", s)
  13. break
  14. }
  15. fmt.Fprintf(wr, "%s", s[:idx])
  16. s = s[idx+1:]
  17. idx = strings.IndexRune(s, '\'')
  18. if idx < 0 {
  19. fmt.Fprintf(wr, "%s", s)
  20. break
  21. }
  22. fmt.Fprintf(wr, "\\fB%s\\fP", s[:idx])
  23. s = s[idx+1:]
  24. }
  25. }
  26. func writeManPageOptions(wr io.Writer, grp *Group) {
  27. grp.eachGroup(func(group *Group) {
  28. for _, opt := range group.options {
  29. if !opt.canCli() {
  30. continue
  31. }
  32. fmt.Fprintln(wr, ".TP")
  33. fmt.Fprintf(wr, "\\fB")
  34. if opt.ShortName != 0 {
  35. fmt.Fprintf(wr, "-%c", opt.ShortName)
  36. }
  37. if len(opt.LongName) != 0 {
  38. if opt.ShortName != 0 {
  39. fmt.Fprintf(wr, ", ")
  40. }
  41. fmt.Fprintf(wr, "--%s", opt.LongName)
  42. }
  43. fmt.Fprintln(wr, "\\fP")
  44. formatForMan(wr, opt.Description)
  45. fmt.Fprintln(wr, "")
  46. }
  47. })
  48. }
  49. func writeManPageSubCommands(wr io.Writer, name string, root *Command) {
  50. commands := root.sortedCommands()
  51. for _, c := range commands {
  52. var nn string
  53. if len(name) != 0 {
  54. nn = name + " " + c.Name
  55. } else {
  56. nn = c.Name
  57. }
  58. writeManPageCommand(wr, nn, c)
  59. }
  60. }
  61. func writeManPageCommand(wr io.Writer, name string, command *Command) {
  62. fmt.Fprintf(wr, ".SS %s\n", name)
  63. fmt.Fprintln(wr, command.ShortDescription)
  64. if len(command.LongDescription) > 0 {
  65. fmt.Fprintln(wr, "")
  66. cmdstart := fmt.Sprintf("The %s command", command.Name)
  67. if strings.HasPrefix(command.LongDescription, cmdstart) {
  68. fmt.Fprintf(wr, "The \\fI%s\\fP command", command.Name)
  69. formatForMan(wr, command.LongDescription[len(cmdstart):])
  70. fmt.Fprintln(wr, "")
  71. } else {
  72. formatForMan(wr, command.LongDescription)
  73. fmt.Fprintln(wr, "")
  74. }
  75. }
  76. writeManPageOptions(wr, command.Group)
  77. writeManPageSubCommands(wr, name, command)
  78. }
  79. // WriteManPage writes a basic man page in groff format to the specified
  80. // writer.
  81. func (p *Parser) WriteManPage(wr io.Writer) {
  82. t := time.Now()
  83. fmt.Fprintf(wr, ".TH %s 1 \"%s\"\n", p.Name, t.Format("2 January 2006"))
  84. fmt.Fprintln(wr, ".SH NAME")
  85. fmt.Fprintf(wr, "%s \\- %s\n", p.Name, p.ShortDescription)
  86. fmt.Fprintln(wr, ".SH SYNOPSIS")
  87. usage := p.Usage
  88. if len(usage) == 0 {
  89. usage = "[OPTIONS]"
  90. }
  91. fmt.Fprintf(wr, "\\fB%s\\fP %s\n", p.Name, usage)
  92. fmt.Fprintln(wr, ".SH DESCRIPTION")
  93. formatForMan(wr, p.LongDescription)
  94. fmt.Fprintln(wr, "")
  95. fmt.Fprintln(wr, ".SH OPTIONS")
  96. writeManPageOptions(wr, p.Command.Group)
  97. if len(p.commands) > 0 {
  98. fmt.Fprintln(wr, ".SH COMMANDS")
  99. writeManPageSubCommands(wr, "", p.Command)
  100. }
  101. }