diff options
Diffstat (limited to 'vendor/go.step.sm/cli-utils/usage/printer.go')
| -rw-r--r-- | vendor/go.step.sm/cli-utils/usage/printer.go | 234 |
1 files changed, 0 insertions, 234 deletions
diff --git a/vendor/go.step.sm/cli-utils/usage/printer.go b/vendor/go.step.sm/cli-utils/usage/printer.go deleted file mode 100644 index 2fbdeed..0000000 --- a/vendor/go.step.sm/cli-utils/usage/printer.go +++ /dev/null @@ -1,234 +0,0 @@ -package usage - -import ( - "bytes" - "fmt" - "io" - "regexp" - "strings" - "text/template" - "unicode" - - "github.com/urfave/cli" - md "go.step.sm/cli-utils/pkg/blackfriday" -) - -var sectionRe = regexp.MustCompile(`(?m:^##)`) -var sectionNameRe = regexp.MustCompile(`(?m:^## [^\n]+)`) -var indentRe = regexp.MustCompile(`(?m:^:[^\n]+)`) -var definitionListRe = regexp.MustCompile(`(?m:^[\t ]+\*\*[^\*]+\*\*[^\n]*\s+:[^\n]+)`) - -//var sectionRe = regexp.MustCompile(`^## [^\n]*$`) - -type frontmatterData struct { - Data interface{} - Parent string - Children []string -} - -// HelpPrinter overwrites cli.HelpPrinter and prints the formatted help to the terminal. -func HelpPrinter(w io.Writer, templ string, data interface{}) { - b := helpPreprocessor(w, templ, data, false) - w.Write(Render(b)) -} - -func htmlHelpPrinter(w io.Writer, templ string, data interface{}) []byte { - b := helpPreprocessor(w, templ, data, true) - w.Write([]byte(`<html><head><title>step command line documentation</title>`)) - w.Write([]byte(`<link href="/style.css" rel="stylesheet" type="text/css">`)) - w.Write([]byte(`</head><body><div class="wrapper markdown-body command">`)) - html := md.Run(b) - w.Write(html) - w.Write([]byte(`</div></body></html>`)) - - return html -} - -func markdownHelpPrinter(w io.Writer, templ, parent string, data interface{}) { - b := helpPreprocessor(w, templ, data, true) - - frontmatter := frontmatterData{ - Data: data, - Parent: parent, - } - - if app, ok := data.(*cli.App); ok { - for _, cmd := range app.Commands { - frontmatter.Children = append(frontmatter.Children, cmd.Name) - } - } - - var frontMatterTemplate = `--- -layout: auto-doc -category: reference -title: {{.Data.HelpName}} -menu: - docs: -{{- if .Parent}} - parent: {{.Parent}} -{{- end }} -{{- if .Children }} - children: -{{- range .Children }} - - {{.}} -{{- end }} -{{- end }} ---- - -` - t, err := template.New("frontmatter").Parse(frontMatterTemplate) - if err != nil { - panic(err) - } - err = t.Execute(w, frontmatter) - if err != nil { - panic(err) - } - w.Write(b) -} - -func helpPreprocessor(_ io.Writer, templ string, data interface{}, applyRx bool) []byte { - buf := new(bytes.Buffer) - cli.HelpPrinterCustom(buf, templ, data, nil) - //w.Write(buf.Bytes()) - // s := string(markdownify(buf.Bytes())) - s := markdownify(buf) - // Move the OPTIONS section to the right place. urfave puts them at the end - // of the file, we want them to be after POSITIONAL ARGUMENTS, DESCRIPTION, - // USAGE, or NAME (in that order, depending on which sections exist). - optLoc := strings.Index(s, "## OPTIONS") - if optLoc != -1 { - optEnd := findSectionEnd("OPTIONS", s) - if optEnd != -1 { - options := s[optLoc:optEnd] - s = s[:optLoc] + s[optEnd:] - if newLoc := findSectionEnd("POSITIONAL ARGUMENTS", s); newLoc != -1 { - s = s[:newLoc] + options + s[newLoc:] - } else if newLoc := findSectionEnd("DESCRIPTION", s); newLoc != -1 { - s = s[:newLoc] + options + s[newLoc:] - } else if newLoc := findSectionEnd("USAGE", s); newLoc != -1 { - s = s[:newLoc] + options + s[newLoc:] - } else if newLoc := findSectionEnd("NAME", s); newLoc != -1 { - s = s[:newLoc] + options + s[newLoc:] - } else { - // Keep it at the end I guess :/. - s += options - } - } - } - - if applyRx { - // Keep capitalized only the first letter in arguments names. - s = sectionNameRe.ReplaceAllStringFunc(s, func(s string) string { - return s[0:4] + strings.ToLower(s[4:]) - }) - // Remove `:` at the start of a line. - s = indentRe.ReplaceAllStringFunc(s, func(s string) string { - return strings.TrimSpace(s[1:]) - }) - // Convert lines like: - // **Foo** - // : Bar zar ... - // To: - // - **Foo**: Bar zar ... - s = definitionListRe.ReplaceAllStringFunc(s, func(s string) string { - i := strings.Index(s, "\n") - j := strings.Index(s, ":") - return "- " + strings.TrimSpace(s[:i]) + ": " + strings.TrimSpace(s[j+1:]) - }) - } - - return []byte(s) -} - -func findSectionEnd(h, s string) int { - start := strings.Index(s, fmt.Sprintf("## %s", h)) - if start == -1 { - return start - } - nextSection := sectionRe.FindStringIndex(s[start+2:]) - if nextSection == nil { - return len(s) - } - return start + 2 + nextSection[0] -} - -// Convert some stuff that we can't easily write in help files because -// -// backticks and raw strings don't mix: -// -// - "<foo>" to "`foo`" -// - "”'" to "```" -func markdownify(r *bytes.Buffer) string { - const escapeByte = byte('\\') - var last byte - var inCode bool - - w := new(bytes.Buffer) - for { - b, err := r.ReadByte() - if err != nil { - return w.String() - } - loop: - switch b { - case '<': - if last != escapeByte && !inCode { - w.WriteByte('`') - } else { - w.WriteByte(b) - } - case '>': - if last != escapeByte && !inCode { - w.WriteByte('`') - } else { - w.WriteByte(b) - } - case '\'': - b1, _ := r.ReadByte() - b2, _ := r.ReadByte() - if b1 == b && b2 == b { - w.WriteString("```") - if !inCode { - if n, _, err := r.ReadRune(); err == nil { - if unicode.IsSpace(n) { - w.WriteString("shell") - } - r.UnreadRune() - } - } - inCode = !inCode - } else { - // We can only unread the last one (b2) - w.WriteByte(b) - r.UnreadByte() - b = b1 - last = b - goto loop - } - case '*': - if inCode { - if b1, _ := r.ReadByte(); b1 != '*' { - w.WriteByte(b) - w.UnreadByte() - } - } else { - w.WriteByte(b) - } - case escapeByte: - if last == escapeByte { - w.WriteByte(escapeByte) - b = 0 - } else if n, _, err := r.ReadRune(); err == nil { - if unicode.IsSpace(n) { - w.WriteByte(escapeByte) - } - r.UnreadRune() - } - case 0: // probably because io.EOF - default: - w.WriteByte(b) - } - last = b - } -} |
