comment

Imports

Imports #

"bytes"
"fmt"
"strconv"
"bytes"
"fmt"
"strings"
"slices"
"strings"
"unicode"
"unicode/utf8"
"bytes"
"fmt"
"strings"
"bytes"
"fmt"
"sort"
"strings"
"unicode/utf8"

Constants & Variables

_ const #

const _ spanKind = iota

spanCode const #

const spanCode

spanHeading const #

const spanHeading

spanList const #

const spanList

spanOldHeading const #

const spanOldHeading

spanPara const #

const spanPara

stdPkgs var #

var stdPkgs = []string{...}

Type Aliases

Italic type #

An Italic is a string rendered as italicized text.

type Italic string

Plain type #

A Plain is a string rendered as plain text (not italicized).

type Plain string

spanKind type #

A spanKind describes the kind of span.

type spanKind int

Interfaces

Block interface #

A Block is block-level content in a doc comment, one of [*Code], [*Heading], [*List], or [*Paragraph].

type Block interface {
block()
}

Text interface #

A Text is text-level content in a doc comment, one of [Plain], [Italic], [*Link], or [*DocLink].

type Text interface {
text()
}

Structs

Code struct #

A Code is a preformatted code block.

type Code struct {
Text string
}

Doc struct #

A Doc is a parsed Go doc comment.

type Doc struct {
Content []Block
Links []*LinkDef
}

Heading struct #

A Heading is a doc comment heading.

type Heading struct {
Text []Text
}

LinkDef struct #

A LinkDef is a single link definition.

type LinkDef struct {
Text string
URL string
Used bool
}

List struct #

A List is a numbered or bullet list. Lists are always non-empty: len(Items) > 0. In a numbered list, every Items[i].Number is a non-empty string. In a bullet list, every Items[i].Number is an empty string.

type List struct {
Items []*ListItem
ForceBlankBefore bool
ForceBlankBetween bool
}

ListItem struct #

A ListItem is a single item in a numbered or bullet list.

type ListItem struct {
Number string
Content []Block
}

Paragraph struct #

A Paragraph is a paragraph of text.

type Paragraph struct {
Text []Text
}

Parser struct #

A Parser is a doc comment parser. The fields in the struct can be filled in before calling [Parser.Parse] in order to customize the details of the parsing process.

type Parser struct {
Words map[string]string
LookupPackage func(name string) (importPath string, ok bool)
LookupSym func(recv string, name string) ok bool
}

Printer struct #

A Printer is a doc comment printer. The fields in the struct can be filled in before calling any of the printing methods in order to customize the details of the printing process.

type Printer struct {
HeadingLevel int
HeadingID func(h *Heading) string
DocLinkURL func(link *DocLink) string
DocLinkBaseURL string
TextPrefix string
TextCodePrefix string
TextWidth int
}

commentPrinter struct #

type commentPrinter struct {
*Printer
}

htmlPrinter struct #

An htmlPrinter holds the state needed for printing a [Doc] as HTML.

type htmlPrinter struct {
*Printer
tight bool
}

mdPrinter struct #

An mdPrinter holds the state needed for printing a Doc as Markdown.

type mdPrinter struct {
*Printer
headingPrefix string
raw bytes.Buffer
}

parseDoc struct #

parseDoc is parsing state for a single doc comment.

type parseDoc struct {
*Parser
*Doc
links map[string]*LinkDef
lines []string
lookupSym func(recv string, name string) bool
}

span struct #

A span represents a single span of comment lines (lines[start:end]) of an identified kind (code, heading, paragraph, and so on).

type span struct {
start int
end int
kind spanKind
}

textPrinter struct #

A textPrinter holds the state needed for printing a Doc as plain text.

type textPrinter struct {
*Printer
long strings.Builder
prefix string
codePrefix string
width int
}

Functions

BlankBefore method #

BlankBefore reports whether a reformatting of the comment should include a blank line before the list. The default rule is the same as for [BlankBetween]: if the list item content contains any blank lines (meaning at least one item has multiple paragraphs) then the list itself must be preceded by a blank line. A preceding blank line can be forced by setting [List].ForceBlankBefore.

func (l *List) BlankBefore() bool

BlankBetween method #

BlankBetween reports whether a reformatting of the comment should include a blank line between each pair of list items. The default rule is that if the list item content contains any blank lines (meaning at least one item has multiple paragraphs) then list items must themselves be separated by blank lines. Blank line separators can be forced by setting [List].ForceBlankBetween.

func (l *List) BlankBetween() bool

Comment method #

Comment returns the standard Go formatting of the [Doc], without any comment markers.

func (p *Printer) Comment(d *Doc) []byte

DefaultID method #

DefaultID returns the default anchor ID for the heading h. The default anchor ID is constructed by converting every rune that is not alphanumeric ASCII to an underscore and then adding the prefix “hdr-”. For example, if the heading text is “Go Doc Comments”, the default ID is “hdr-Go_Doc_Comments”.

func (h *Heading) DefaultID() string

DefaultLookupPackage function #

DefaultLookupPackage is the default package lookup function, used when [Parser.LookupPackage] is nil. It recognizes names of the packages from the standard library with single-element import paths, such as math, which would otherwise be impossible to name. Note that the go/doc package provides a more sophisticated lookup based on the imports used in the current package.

func DefaultLookupPackage(name string) (importPath string, ok bool)

DefaultURL method #

DefaultURL constructs and returns the documentation URL for l, using baseURL as a prefix for links to other packages. The possible forms returned by DefaultURL are: - baseURL/ImportPath, for a link to another package - baseURL/ImportPath#Name, for a link to a const, func, type, or var in another package - baseURL/ImportPath#Recv.Name, for a link to a method in another package - #Name, for a link to a const, func, type, or var in this package - #Recv.Name, for a link to a method in this package If baseURL ends in a trailing slash, then DefaultURL inserts a slash between ImportPath and # in the anchored forms. For example, here are some baseURL values and URLs they can generate: "/pkg/" → "/pkg/math/#Sqrt" "/pkg" → "/pkg/math#Sqrt" "/" → "/math/#Sqrt" "" → "/math#Sqrt"

func (l *DocLink) DefaultURL(baseURL string) string

HTML method #

HTML returns an HTML formatting of the [Doc]. See the [Printer] documentation for ways to customize the HTML output.

func (p *Printer) HTML(d *Doc) []byte

Markdown method #

Markdown returns a Markdown formatting of the Doc. See the [Printer] documentation for ways to customize the Markdown output.

func (p *Printer) Markdown(d *Doc) []byte

Parse method #

Parse parses the doc comment text and returns the *[Doc] form. Comment markers (/* // and */) in the text must have already been removed.

func (p *Parser) Parse(text string) *Doc

Text method #

Text returns a textual formatting of the [Doc]. See the [Printer] documentation for ways to customize the text output.

func (p *Printer) Text(d *Doc) []byte

autoURL function #

autoURL checks whether s begins with a URL that should be hyperlinked. If so, it returns the URL, which is a prefix of s, and ok == true. Otherwise it returns "", false. The caller should skip over the first len(url) bytes of s before further processing.

func autoURL(s string) (url string, ok bool)

blankBefore function #

blankBefore reports whether the block x requires a blank line before it. All blocks do, except for Lists that return false from x.BlankBefore().

func blankBefore(x Block) bool

block method #

func (*Paragraph) block()

block method #

block prints the block x to out.

func (p *htmlPrinter) block(out *bytes.Buffer, x Block)

block method #

block prints the block x to out.

func (p *textPrinter) block(out *bytes.Buffer, x Block)

block method #

func (*Code) block()

block method #

func (*Heading) block()

block method #

block prints the block x to out.

func (p *commentPrinter) block(out *bytes.Buffer, x Block)

block method #

func (*List) block()

block method #

block prints the block x to out.

func (p *mdPrinter) block(out *bytes.Buffer, x Block)

code method #

code returns a code block built from the lines.

func (d *parseDoc) code(lines []string) *Code

commonPrefix function #

commonPrefix returns the longest common prefix of a and b.

func commonPrefix(a string, b string) string

docLinkURL method #

func (p *Printer) docLinkURL(link *DocLink) string

escape method #

escape prints s to out as plain text, escaping < & " ' and > to avoid being misinterpreted in larger HTML constructs.

func (p *htmlPrinter) escape(out *bytes.Buffer, s string)

escape method #

escape prints s to out as plain text, escaping special characters to avoid being misinterpreted as Markdown markup sequences.

func (p *mdPrinter) escape(out *bytes.Buffer, s string)

heading method #

heading returns the *Heading for the given new-style section heading line.

func (d *parseDoc) heading(line string) Block

headingID method #

func (p *Printer) headingID(h *Heading) string

headingLevel method #

func (p *Printer) headingLevel() int

ident function #

ident checks whether s begins with a Go identifier. If so, it returns the identifier, which is a prefix of s, and ok == true. Otherwise it returns "", false. The caller should skip over the first len(id) bytes of s before further processing.

func ident(s string) (id string, ok bool)

importPathOK function #

func importPathOK(c byte) bool

inc function #

inc increments the decimal string s. For example, inc("1199") == "1200".

func inc(s string) string

indent method #

indent prints s to out, indenting with the indent string after each newline in s.

func (p *commentPrinter) indent(out *bytes.Buffer, indent string, s string)

indented function #

indented reports whether line is indented (starts with a leading space or tab).

func indented(line string) bool

isBlank function #

isBlank reports whether s is a blank line.

func isBlank(s string) bool

isHeading function #

isHeading reports whether line is a new-style section heading.

func isHeading(line string) bool

isHost function #

isHost reports whether c is a byte that can appear in a URL host, like www.example.com or user@[::1]:8080

func isHost(c byte) bool

isIdentASCII function #

isIdentASCII reports whether c is an ASCII identifier byte.

func isIdentASCII(c byte) bool

isList function #

isList reports whether the line is the first line of a list, meaning starts with a list marker after any indentation. (The caller is responsible for checking the line is indented, as appropriate.)

func isList(line string) bool

isName function #

isName reports whether s is a capitalized Go identifier (like Name).

func isName(s string) bool

isOldHeading function #

isOldHeading reports whether line is an old-style section heading. line is all[off].

func isOldHeading(line string, all []string, off int) bool

isPath function #

isPath reports whether c is a (non-punctuation) path byte.

func isPath(c byte) bool

isPunct function #

isPunct reports whether c is a punctuation byte that can appear inside a path but not at the end.

func isPunct(c byte) bool

isScheme function #

isScheme reports whether s is a recognized URL scheme. Note that if strings of new length (beyond 3-7) are added here, the fast path at the top of autoURL will need updating.

func isScheme(s string) bool

isStdPkg function #

func isStdPkg(path string) bool

leadingSpace function #

leadingSpace returns the longest prefix of s consisting of spaces and tabs.

func leadingSpace(s string) string

list method #

list returns a list built from the indented lines, using forceBlankBefore as the value of the List's ForceBlankBefore field.

func (d *parseDoc) list(lines []string, forceBlankBefore bool) *List

listMarker function #

listMarker parses the line as beginning with a list marker. If it can do that, it returns the numeric marker ("" for a bullet list), the rest of the line, and ok == true. Otherwise, it returns "", "", false.

func listMarker(line string) (num string, rest string, ok bool)

lookupPkg method #

lookupPkg is called to look up the pkg in [pkg], [pkg.Name], and [pkg.Name.Recv]. If pkg has a slash, it is assumed to be the full import path and is returned with ok = true. Otherwise, pkg is probably a simple package name like "rand" (not "crypto/rand" or "math/rand"). d.LookupPackage provides a way for the caller to allow resolving such names with reference to the imports in the surrounding package. There is one collision between these two cases: single-element standard library names like "math" are full import paths but don't contain slashes. We let d.LookupPackage have the first chance to resolve it, in case there's a different package imported as math, and otherwise we refer to a built-in list of single-element standard library package names.

func (d *parseDoc) lookupPkg(pkg string) (importPath string, ok bool)

oldHeading method #

oldHeading returns the *Heading for the given old-style section heading line.

func (d *parseDoc) oldHeading(line string) Block

oneLongLine method #

oneLongLine prints the text sequence x to out as one long line, without worrying about line wrapping. Explicit links have the [ ] dropped to improve readability.

func (p *textPrinter) oneLongLine(out *strings.Builder, x []Text)

paragraph method #

paragraph returns a paragraph block built from the lines. If the lines are link definitions, paragraph adds them to d and returns nil.

func (d *parseDoc) paragraph(lines []string) Block

parseLinkedText method #

parseLinkedText parses text that is allowed to contain explicit links, such as [math.Sin] or [Go home page], into a slice of Text items. A “pkg” is only assumed to be a full import path if it starts with a domain name (a path element with a dot) or is one of the packages from the standard library (“[os]”, “[encoding/json]”, and so on). To avoid problems with maps, generics, and array types, doc links must be both preceded and followed by punctuation, spaces, tabs, or the start or end of a line. An example problem would be treating map[ast.Expr]TypeAndValue as containing a link.

func (d *parseDoc) parseLinkedText(text string) []Text

parseSpans function #

func parseSpans(lines []string) []span

parseText method #

parseText parses s as text and returns the result of appending those parsed Text elements to out. parseText does not handle explicit links like [math.Sin] or [Go home page]: those are handled by parseLinkedText. If autoLink is true, then parseText recognizes URLs and words from d.Words and converts those to links as appropriate.

func (d *parseDoc) parseText(out []Text, s string, autoLink bool) []Text

rawText method #

rawText prints the text sequence x to out, without worrying about escaping characters that have special meaning at the start of a Markdown line.

func (p *mdPrinter) rawText(out *bytes.Buffer, x []Text)

splitDocName function #

If text is of the form before.Name, where Name is a capitalized Go identifier, then splitDocName returns before, name, true. Otherwise it returns text, "", false.

func splitDocName(text string) (before string, name string, foundDot bool)

text method #

func (Italic) text()

text method #

text prints the text sequence x to out.

func (p *mdPrinter) text(out *bytes.Buffer, x []Text)

text method #

func (*DocLink) text()

text method #

func (*Link) text()

text method #

text prints the text sequence x to out.

func (p *commentPrinter) text(out *bytes.Buffer, indent string, x []Text)

text method #

func (Plain) text()

text method #

text prints the text sequence x to out.

func (p *htmlPrinter) text(out *bytes.Buffer, x []Text)

text method #

text prints the text sequence x to out.

func (p *textPrinter) text(out *bytes.Buffer, indent string, x []Text)

unindent function #

unindent removes any common space/tab prefix from each line in lines, returning a copy of lines in which those prefixes have been trimmed from each line. It also replaces any lines containing only spaces with blank lines (empty strings).

func unindent(lines []string) []string

validImportPath function #

validImportPath reports whether path is a valid import path. It is a lightly edited copy of golang.org/x/mod/module.CheckImportPath.

func validImportPath(path string) bool

validImportPathElem function #

func validImportPathElem(elem string) bool

wrap function #

wrap wraps words into lines of at most max runes, minimizing the sum of the squares of the leftover lengths at the end of each line (except the last, of course), with a preference for ending lines at punctuation (.,:;). The returned slice gives the indexes of the first words on each line in the wrapped text with a final entry of len(words). Thus the lines are words[seq[0]:seq[1]], words[seq[1]:seq[2]], ..., words[seq[len(seq)-2]:seq[len(seq)-1]]. The implementation runs in O(n log n) time, where n = len(words), using the algorithm described in D. S. Hirschberg and L. L. Larmore, “[The least weight subsequence problem],” FOCS 1985, pp. 137-143. [The least weight subsequence problem]: https://doi.org/10.1109/SFCS.1985.60

func wrap(words []string, max int) (seq []int)

wrapPenalty function #

wrapPenalty is the penalty for inserting a line break after word s.

func wrapPenalty(s string) int64

writeNL function #

writeNL calls out.WriteByte('\n') but first trims trailing spaces on the previous line.

func writeNL(out *bytes.Buffer)

Generated with Arrow