Пример #1
0
func (c *Application) writeHelp(width int, w io.Writer) {
	s := []string{formatArgsAndFlags(c.Name, c.argGroup, c.flagGroup)}
	if len(c.commands) > 0 {
		s = append(s, "<command>", "[<flags>]", "[<args> ...]")
	}

	prefix := "usage: "
	usage := strings.Join(s, " ")
	buf := bytes.NewBuffer(nil)
	doc.ToText(buf, usage, "", preIndent, width-len(prefix))
	lines := strings.Split(strings.TrimRight(buf.String(), "\n"), "\n")

	fmt.Fprintf(w, "%s%s\n", prefix, lines[0])
	for _, l := range lines[1:] {
		fmt.Fprintf(w, "%*s%s\n", len(prefix), "", l)
	}
	if c.Help != "" {
		fmt.Fprintf(w, "\n")
		doc.ToText(w, c.Help, "", preIndent, width)
	}

	c.flagGroup.writeHelp(width, w)
	c.argGroup.writeHelp(width, w)

	if len(c.commands) > 0 {
		fmt.Fprintf(w, "\nCommands:\n")
		c.helpCommands(width, w)
	}
}
Пример #2
0
func godoc(member, content string) string {
	undocumented := "// " + exportable(member) + " is undocumented.\n"

	node, err := html.Parse(strings.NewReader(content))
	if err != nil {
		return undocumented
	}

	_, v, err := sandblast.Extract(node)
	if err != nil {
		return undocumented
	}

	v = strings.TrimSpace(v)
	if v == "" {
		return undocumented
	}

	if member != "" {
		v = exportable(member) + " " + strings.ToLower(v[0:1]) + v[1:]
	}

	out := bytes.NewBuffer(nil)
	doc.ToText(out, v, "// ", "", 72)
	return out.String()
}
Пример #3
0
func (p *docPrinter) printText(s string) {
	s = strings.TrimRight(s, " \t\n")
	if s != "" {
		p.scratch.Reset()
		godoc.ToText(&p.scratch, s, textIndent, textIndent+"\t", textWidth)
		blank := 0
		for _, line := range bytes.Split(p.scratch.Bytes(), []byte{'\n'}) {
			if len(line) == 0 {
				blank++
			} else {
				const k = len(textIndent) + 1
				if blank == 2 && len(line) > k && line[k] != ' ' {
					p.WriteString("\n")
					p.PushHighlight(headerGroup)
					p.Write(line)
					p.PopHighlight()
					p.WriteString("\n")
				} else {
					for i := 0; i < blank; i++ {
						p.WriteString("\n")
					}
					p.Write(line)
					p.WriteString("\n")
				}
				blank = 0
			}
		}
		p.WriteString("\n")
	}
}
Пример #4
0
// packageDoc prints the docs for the package (package doc plus one-liners of the rest).
func (pkg *Package) packageDoc(showRaml bool) {
	defer pkg.flush()
	if pkg.showInternals() && !showRaml {
		pkg.packageClause(false)
	}

	doc.ToText(&pkg.buf, pkg.doc.Doc, "", indent, indentedWidth)
	pkg.newlines(1)

	if !pkg.showInternals() {
		// Show only package docs for commands.
		return
	}

	pkg.newlines(1)

	if showRaml == true {
		pkg.ramls()
	} else {
		pkg.valueSummary(pkg.doc.Consts)
		pkg.valueSummary(pkg.doc.Vars)
		pkg.funcSummary(pkg.doc.Funcs)
		pkg.typeSummary()
		pkg.bugs()
	}
}
Пример #5
0
// commentTextFn formats a source code comment as text.
func commentTextFn(v string) string {
	const indent = "    "
	var buf bytes.Buffer
	godoc.ToText(&buf, v, indent, "\t", 80-2*len(indent))
	p := buf.Bytes()
	return string(p)
}
Пример #6
0
func formatTwoColumns(w io.Writer, indent, padding, width int, rows [][2]string) {
	// Find size of first column.
	s := 0
	for _, row := range rows {
		if c := len(row[0]); c > s && c < 30 {
			s = c
		}
	}

	indentStr := strings.Repeat(" ", indent)
	offsetStr := strings.Repeat(" ", s+padding)

	for _, row := range rows {
		buf := bytes.NewBuffer(nil)
		doc.ToText(buf, row[1], "", preIndent, width-s-padding-indent)
		lines := strings.Split(strings.TrimRight(buf.String(), "\n"), "\n")
		fmt.Fprintf(w, "%s%-*s%*s", indentStr, s, row[0], padding, "")
		if len(row[0]) >= 30 {
			fmt.Fprintf(w, "\n%s%s", indentStr, offsetStr)
		}
		fmt.Fprintf(w, "%s\n", lines[0])
		for _, line := range lines[1:] {
			fmt.Fprintf(w, "%s%s%s\n", indentStr, offsetStr, line)
		}
	}
}
Пример #7
0
Файл: pkg.go Проект: achanda/go
// printMethodDoc prints the docs for matches of symbol.method.
// If symbol is empty, it prints all methods that match the name.
// It reports whether it found any methods.
func (pkg *Package) printMethodDoc(symbol, method string) bool {
	defer pkg.flush()
	types := pkg.findTypes(symbol)
	if types == nil {
		if symbol == "" {
			return false
		}
		pkg.Fatalf("symbol %s is not a type in package %s installed in %q", symbol, pkg.name, pkg.build.ImportPath)
	}
	found := false
	for _, typ := range types {
		if len(typ.Methods) > 0 {
			for _, meth := range typ.Methods {
				if match(method, meth.Name) {
					decl := meth.Decl
					decl.Body = nil
					pkg.emit(meth.Doc, decl)
					found = true
				}
			}
			continue
		}
		// Type may be an interface. The go/doc package does not attach
		// an interface's methods to the doc.Type. We need to dig around.
		spec := pkg.findTypeSpec(typ.Decl, typ.Name)
		inter, ok := spec.Type.(*ast.InterfaceType)
		if !ok {
			// Not an interface type.
			// TODO? Maybe handle struct fields here.
			continue
		}
		for _, iMethod := range inter.Methods.List {
			// This is an interface, so there can be only one name.
			// TODO: Anonymous methods (embedding)
			if len(iMethod.Names) == 0 {
				continue
			}
			name := iMethod.Names[0].Name
			if match(method, name) {
				// pkg.oneLineField(iMethod, 0)
				if iMethod.Doc != nil {
					for _, comment := range iMethod.Doc.List {
						doc.ToText(&pkg.buf, comment.Text, "", indent, indentedWidth)
					}
				}
				s := pkg.oneLineNode(iMethod.Type)
				// Hack: s starts "func" but there is no name present.
				// We could instead build a FuncDecl but it's not worthwhile.
				lineComment := ""
				if iMethod.Comment != nil {
					lineComment = fmt.Sprintf("  %s", iMethod.Comment.List[0].Text)
				}
				pkg.Printf("func %s%s%s\n", name, s[4:], lineComment)
				found = true
			}
		}
	}
	return found
}
Пример #8
0
func writeEnum(scope Scope, opt Option, delta int) {
	fmt.Println()
	if opt.Description != "" {
		doc.ToText(os.Stdout, opt.Description, "    // ", "", 73)
		// fmt.Printf("	// %s\n", opt.Description)
	}
	fmt.Printf("	%s %s = %d\n", scope.Name+translateName(opt.Name), scope.Name, opt.Code+delta)
}
Пример #9
0
func comment_textFunc(comment, indent, preIndent string) string {
	var buf bytes.Buffer
	doc.ToText(&buf, comment, indent, preIndent, punchCardWidth-2*len(indent))
	if containsOnlySpace(buf.Bytes()) {
		return ""
	}
	return buf.String()
}
Пример #10
0
Файл: main.go Проект: qt/qtqa
func printParagraph(indent string, bulletCharacter byte, text string) {
	var buf bytes.Buffer
	doc.ToText(&buf, text, indent, indent, 79-len(indent))
	output := buf.Bytes()
	if len(output) > len(indent) && len(indent) > 2 {
		bulletPos := len(indent) - 2
		output[bulletPos] = bulletCharacter
	}
	os.Stdout.Write(output)
}
Пример #11
0
func (p *docPrinter) printText(s string) {
	s = strings.TrimRight(s, " \t\n")
	if s != "" {
		doc.ToText(&p.buf, s, textIndent, textIndent+"\t", textWidth)
		b := p.buf.Bytes()
		if b[len(b)-1] != '\n' {
			p.buf.WriteByte('\n')
		}
		p.buf.WriteByte('\n')
	}
}
Пример #12
0
func (d *Doc) String() string {
	buf := &bytes.Buffer{}
	if d.Import != "" {
		fmt.Fprintf(buf, "import \"%s\"\n\n", d.Import)
	}
	fmt.Fprintf(buf, "%s\n\n", d.Decl)
	if d.Doc == "" {
		d.Doc = "Undocumented."
	}
	doc.ToText(buf, d.Doc, indent, preIndent, *linelength)
	return buf.String()
}
Пример #13
0
func (c *Application) helpCommands(width int, w io.Writer) {
	for _, cmd := range c.commandOrder {
		fmt.Fprintf(w, "  %s\n", formatArgsAndFlags(cmd.name, cmd.argGroup, cmd.flagGroup))
		buf := bytes.NewBuffer(nil)
		doc.ToText(buf, cmd.help, "", preIndent, width-4)
		lines := strings.Split(strings.TrimRight(buf.String(), "\n"), "\n")
		for _, line := range lines {
			fmt.Fprintf(w, "    %s\n", line)
		}
		fmt.Fprintf(w, "\n")
	}
}
Пример #14
0
// packageDoc prints the docs for the package (package doc plus one-liners of the rest).
func (pkg *Package) packageDoc() {
	defer pkg.flush()
	pkg.packageClause(false)

	doc.ToText(&pkg.buf, pkg.doc.Doc, "", "\t", 80)
	pkg.newlines(2)

	pkg.valueSummary(pkg.doc.Consts)
	pkg.valueSummary(pkg.doc.Vars)
	pkg.funcSummary(pkg.doc.Funcs)
	pkg.typeSummary()
	pkg.bugs()
}
Пример #15
0
// emit prints the node.
func (pkg *Package) emit(comment string, node ast.Node) {
	if node != nil {
		err := format.Node(&pkg.buf, pkg.fs, node)
		if err != nil {
			log.Fatal(err)
		}
		if comment != "" {
			pkg.newlines(2) // Guarantee blank line before comment.
			doc.ToText(&pkg.buf, comment, "    ", indent, indentedWidth)
		}
		pkg.newlines(1)
	}
}
Пример #16
0
Файл: pkg.go Проект: sreis/go
// emit prints the node.
func (pkg *Package) emit(comment string, node ast.Node) {
	if node != nil {
		err := format.Node(&pkg.buf, pkg.fs, node)
		if err != nil {
			log.Fatal(err)
		}
		if comment != "" {
			pkg.newlines(1)
			doc.ToText(&pkg.buf, comment, "    ", indent, indentedWidth)
			pkg.newlines(2) // Blank line after comment to separate from next item.
		} else {
			pkg.newlines(1)
		}
	}
}
Пример #17
0
func (c *cmdGroup) writeHelp(width int, w io.Writer) {
	if len(c.commands) == 0 {
		return
	}
	fmt.Fprintf(w, "\nCommands:\n")
	flattened := c.flattenedCommands()
	for _, cmd := range flattened {
		fmt.Fprintf(w, "  %s\n", formatArgsAndFlags(cmd.FullCommand(), cmd.argGroup, cmd.flagGroup, cmd.cmdGroup))
		buf := bytes.NewBuffer(nil)
		doc.ToText(buf, cmd.help, "", preIndent, width-4)
		lines := strings.Split(strings.TrimRight(buf.String(), "\n"), "\n")
		for _, line := range lines {
			fmt.Fprintf(w, "    %s\n", line)
		}
		fmt.Fprintf(w, "\n")
	}
}
Пример #18
0
Файл: sample.go Проект: cmars/oo
// writeSampleDescription writes the given attribute to w
// prefixed by the given indentation string.
func writeSampleDescription(w io.Writer, f Attr, indent string) {
	previousText := false

	// section marks the start of a new section of the comment;
	// sections are separated with empty lines.
	section := func() {
		if previousText {
			fmt.Fprintf(w, "%s\n", strings.TrimRightFunc(indent, unicode.IsSpace))
		}
		previousText = true
	}

	descr := strings.TrimSpace(f.Description)
	if descr != "" {
		section()
		doc.ToText(w, descr, indent, "    ", textWidth-len(indent))
	}
	vars := make([]string, 0, len(f.EnvVars)+1)
	if f.EnvVar != "" {
		vars = append(vars, "$"+f.EnvVar)
	}
	for _, v := range f.EnvVars {
		vars = append(vars, "$"+v)
	}
	if len(vars) > 0 {
		section()
		fmt.Fprintf(w, "%sDefault value taken from %s.\n", indent, wordyList(vars))
	}
	attrText := ""
	switch {
	case f.Secret && f.Immutable:
		attrText = "immutable and considered secret"
	case f.Secret:
		attrText = "considered secret"
	case f.Immutable:
		attrText = "immutable"
	}
	if attrText != "" {
		section()
		fmt.Fprintf(w, "%sThis attribute is %s.\n", indent, attrText)
	}
	section()
}
Пример #19
0
func godoc(name, helpText string, indent string) string {
	node, err := html.Parse(strings.NewReader(helpText))
	if err != nil {
		return "no documentation"
	}

	_, helpText, err = sandblast.Extract(node)
	if err != nil {
		return "no documentation"
	}

	helpText = strings.TrimSpace(helpText)
	if helpText == "" {
		helpText = "no documentation"
	}

	text := upper(name) + " - " + helpText
	out := bytes.NewBuffer(nil)
	doc.ToText(out, text, indent+"// ", "", 100)
	return out.String()
}
Пример #20
0
Файл: pkg.go Проект: sreis/go
// packageDoc prints the docs for the package (package doc plus one-liners of the rest).
func (pkg *Package) packageDoc() {
	defer pkg.flush()
	if pkg.showInternals() {
		pkg.packageClause(false)
	}

	doc.ToText(&pkg.buf, pkg.doc.Doc, "", indent, indentedWidth)
	pkg.newlines(1)

	if !pkg.showInternals() {
		// Show only package docs for commands.
		return
	}

	pkg.newlines(2) // Guarantee blank line before the components.
	pkg.valueSummary(pkg.doc.Consts)
	pkg.valueSummary(pkg.doc.Vars)
	pkg.funcSummary(pkg.doc.Funcs)
	pkg.typeSummary()
	pkg.bugs()
}
Пример #21
0
Файл: pkg.go Проект: divoxx/go
// packageDoc prints the docs for the package (package doc plus one-liners of the rest).
func (pkg *Package) packageDoc() {
	defer pkg.flush()
	if pkg.showInternals() {
		pkg.packageClause(false)
	}

	doc.ToText(&pkg.buf, pkg.doc.Doc, "", "\t", 80)
	pkg.newlines(1)

	if !pkg.showInternals() {
		// Show only package docs for commands.
		return
	}

	pkg.newlines(1)
	pkg.valueSummary(pkg.doc.Consts)
	pkg.valueSummary(pkg.doc.Vars)
	pkg.funcSummary(pkg.doc.Funcs)
	pkg.typeSummary()
	pkg.bugs()
}
Пример #22
0
// UsageForContextWithTemplate is the base usage function. You generally don't need to use this.
func (a *Application) UsageForContextWithTemplate(context *ParseContext, indent int, tmpl string) error {
	width := guessWidth(a.writer)
	funcs := template.FuncMap{
		"Indent": func(level int) string {
			return strings.Repeat(" ", level*indent)
		},
		"Wrap": func(indent int, s string) string {
			buf := bytes.NewBuffer(nil)
			indentText := strings.Repeat(" ", indent)
			doc.ToText(buf, s, indentText, indentText, width-indent)
			return buf.String()
		},
		"FormatFlag": formatFlag,
		"FlagsToTwoColumns": func(f []*FlagModel) [][2]string {
			rows := [][2]string{}
			haveShort := false
			for _, flag := range f {
				if flag.Short != 0 {
					haveShort = true
					break
				}
			}
			for _, flag := range f {
				if !flag.Hidden {
					rows = append(rows, [2]string{formatFlag(haveShort, flag), flag.Help})
				}
			}
			return rows
		},
		"RequiredFlags": func(f []*FlagModel) []*FlagModel {
			requiredFlags := []*FlagModel{}
			for _, flag := range f {
				if flag.Required == true {
					requiredFlags = append(requiredFlags, flag)
				}
			}
			return requiredFlags
		},
		"OptionalFlags": func(f []*FlagModel) []*FlagModel {
			optionalFlags := []*FlagModel{}
			for _, flag := range f {
				if flag.Required == false {
					optionalFlags = append(optionalFlags, flag)
				}
			}
			return optionalFlags
		},
		"ArgsToTwoColumns": func(a []*ArgModel) [][2]string {
			rows := [][2]string{}
			for _, arg := range a {
				s := "<" + arg.Name + ">"
				if !arg.Required {
					s = "[" + s + "]"
				}
				rows = append(rows, [2]string{s, arg.Help})
			}
			return rows
		},
		"FormatTwoColumns": func(rows [][2]string) string {
			buf := bytes.NewBuffer(nil)
			formatTwoColumns(buf, indent, indent, width, rows)
			return buf.String()
		},
		"FormatTwoColumnsWithIndent": func(rows [][2]string, indent, padding int) string {
			buf := bytes.NewBuffer(nil)
			formatTwoColumns(buf, indent, padding, width, rows)
			return buf.String()
		},
		"FormatAppUsage":     formatAppUsage,
		"FormatCommandUsage": formatCmdUsage,
		"IsCumulative": func(value Value) bool {
			r, ok := value.(remainderArg)
			return ok && r.IsCumulative()
		},
		"Char": func(c rune) string {
			return string(c)
		},
	}
	t, err := template.New("usage").Funcs(funcs).Parse(tmpl)
	if err != nil {
		return err
	}
	var selectedCommand *CmdModel
	if context.SelectedCommand != nil {
		selectedCommand = context.SelectedCommand.Model()
	}
	ctx := templateContext{
		App:   a.Model(),
		Width: width,
		Context: &templateParseContext{
			SelectedCommand: selectedCommand,
			FlagGroupModel:  context.flags.Model(),
			ArgGroupModel:   context.arguments.Model(),
		},
	}
	return t.Execute(a.writer, ctx)
}
Пример #23
0
func comment_textFunc(comment, indent, preIndent string) string {
	var buf bytes.Buffer
	doc.ToText(&buf, comment, indent, preIndent, punchCardWidth-2*len(indent))
	return buf.String()
}
Пример #24
0
func _formatIndent(target, indent, preIndent string) string {
	var buffer bytes.Buffer
	doc.ToText(&buffer, target, indent, preIndent, punchCardWidth-2*len(indent))
	return buffer.String()
}
Пример #25
0
// WordWrap wraps paragraphs of text to width.
func WordWrap(s string, width int) string {
	buf := new(bytes.Buffer)
	doc.ToText(buf, s, "", "", width)
	return buf.String()
}
func wrap(indent string, s string) string {
	var buf bytes.Buffer
	doc.ToText(&buf, s, indent, indent+"  ", 80-len(indent))
	return buf.String()
}
Пример #27
0
// Wrap wraps the string s to the maximum line length given. Each line
// will be prefaced with leading.
func Wrap(s, leading string, max int) string {
	buf := &bytes.Buffer{}
	doc.ToText(buf, s, leading, "", max)
	return string(buf.Bytes())
}