Go Doc Comments

Purpose and Scope

Go doc comments are the comments that immediately precede top-level package, constant, function, type, and variable declarations without an intervening blank line. The public documentation page describes them as the writing convention expected for exported names, while the repository code turns that convention into parseable, printable structure. In this repository, the main implementation lives in the go/doc/comment package, which parses simplified Markdown-like comment text into a document tree and prints that tree back to documentation formats used by tools, websites, and generated output.

Sources: src/go/doc/comment/doc.go, src/go/doc/comment/parse.go

The important reader problem is not only how to write a good comment, but how Go tooling interprets that comment after source parsing removes the comment markers. The comment package deliberately models doc comments as structured content rather than as arbitrary Markdown. That means headings, paragraphs, lists, code blocks, links, and documentation links have well-defined representations, and printers can make consistent choices for HTML, Markdown, plain text, or canonical Go comment formatting. This structure is what lets different tools share the same expectations instead of each inventing a separate documentation dialect.

Sources: src/go/doc/comment/doc.go, src/go/doc/comment/html.go, src/go/doc/comment/markdown.go, src/go/doc/comment/print.go

Relevant Source Files

  • src/go/doc/comment.go — legacy go/doc formatting entry points that now delegate through the newer parser and printer model, with deprecation notes for package-aware links.
  • src/go/doc/comment/doc.go — package documentation for go/doc/comment, including the public description of Parser, Printer, Doc, and supported comment syntax.
  • src/go/doc/comment/html.go — HTML rendering implementation for parsed blocks and inline text, including escaping, heading IDs, links, lists, and preformatted code.
  • src/go/doc/comment/markdown.go — Markdown rendering implementation, including heading prefixes, list formatting, code indentation, and escaping of ambiguous Markdown starts.
  • src/go/doc/comment/parse.go — core parsed syntax model, including Doc, Block, Heading, List, ListItem, Paragraph, Code, and link definition data.
  • src/go/doc/comment/print.go — Printer configuration, document-link URL generation, heading level and heading ID defaults, and text output customization fields.

Core Concepts

The central data type is Doc, which represents a parsed Go doc comment. Its Content field holds an ordered sequence of block-level elements, and its Links field records link definitions. A Block is one of Heading, List, Paragraph, or Code. Lists are explicitly constrained: they are non-empty, are either numbered or bullet lists, and currently require item content compatible with paragraph-based printing. These constraints explain why the documentation syntax is described as a simplified subset rather than full Markdown, and they make printer behavior predictable across output formats.

Sources: src/go/doc/comment/parse.go

Inline content is also represented structurally. The snippets show printers handling plain text, italic text, ordinary links, and documentation links. Ordinary links already contain a URL, while documentation links require package-aware URL resolution. That distinction is the reason older go/doc helpers are deprecated: functions that receive only raw comment text cannot know which package the comment came from, so they cannot reliably resolve links to packages, symbols, or methods. Modern callers should parse through a Package-aware parser and print through a Package-aware printer when documentation links matter.

Sources: src/go/doc/comment.go, src/go/doc/comment/html.go, src/go/doc/comment/markdown.go, src/go/doc/comment/print.go

Parsing and Formatting Flow

The typical flow begins with raw doc comment text after comment markers have been removed. A caller creates a Parser, calls Parse, and receives a Doc. The result can then be passed to a Printer. The package documentation shows that the same Doc can be emitted as plain text, HTML, Markdown, or Go comment text. This separation matters because parsing is the step that recognizes the documentation language, while printing is the step that adapts the recognized content for a particular consumer, display environment, or formatting convention.

Sources: src/go/doc/comment/doc.go, src/go/doc/comment/parse.go, src/go/doc/comment/print.go

var p comment.Parser
doc := p.Parse(text)
 
var pr comment.Printer
os.Stdout.Write(pr.Text(doc))

HTML output walks each block in document order. Paragraphs become paragraph text unless list-tightness suppresses the opening tag, headings become heading elements at the configured level, code blocks become preformatted elements with escaped text, and lists become ordered or unordered lists depending on whether item numbers are present. The HTML printer escapes characters that could be interpreted by the browser, including less-than, ampersand, quotation marks, apostrophes, and greater-than. Documentation links are printed as anchors only when a URL can be computed.

Sources: src/go/doc/comment/html.go, src/go/doc/comment/print.go

Markdown output follows the same parsed structure but must protect against accidental syntax changes. The Markdown printer computes a heading prefix from the configured heading level, emits code blocks by indenting non-empty lines, and formats numbered and bullet lists with spacing rules derived from whether list items are loose. Its text logic escapes line starts that would otherwise be interpreted as headings or lists, and it escapes special inline characters. This is why a parsed comment can be round-tripped into Markdown without silently turning ordinary prose into a different Markdown construct.

Sources: src/go/doc/comment/markdown.go, src/go/doc/comment/print.go

API Components and Configuration

Printer is the main formatting configuration surface. HeadingLevel controls the nesting level used for HTML and Markdown headings, defaulting to level three when unset. HeadingID can override how anchor identifiers are computed, otherwise the heading default is used. DocLinkURL can override documentation-link URL construction, while DocLinkBaseURL supplies the base used by the default algorithm. TextPrefix, TextCodePrefix, and TextWidth customize plain text output, including line prefixes, code block prefixes, and wrapping width for generated text.

Sources: src/go/doc/comment/print.go

DocLink default URL construction is intentionally explicit. A link to another package can become a package URL, a link to a named top-level symbol can add a fragment, and a method link can use a receiver-qualified fragment. For links in the same package, the result can be only a fragment such as a symbol or receiver-and-method anchor. The base URL handling also accounts for whether the configured base ends in a slash, so callers can adapt output for different documentation hosts without rewriting the parsed document tree.

Sources: src/go/doc/comment/print.go

ComponentRoleNotable behavior
ParserConverts comment text into a DocRecognizes simplified doc comment syntax after comment markers are removed
DocParsed document rootHolds Content blocks and link definitions
BlockBlock-level syntax interfaceImplemented by Heading, List, Paragraph, and Code
PrinterConverts a Doc to output formatsConfigures headings, links, and text wrapping
DocLinkDocumentation referenceCan resolve to package, symbol, or method URLs

Legacy go/doc Helpers

The older go/doc functions ToHTML and ToText still exist, but their comments explain why they are deprecated. They operate on comment text directly, so they cannot identify documentation links whose meaning depends on the package that supplied the text. Their implementations now build a parser and printer internally, then write generated bytes to the provided writer. The source comments provide replacement patterns: obtain the package Parser and Printer, parse the comment text, configure any word map or text settings, and then call the desired printer method.

Sources: src/go/doc/comment.go

This deprecation is a useful migration signal for tool authors. If a tool is rendering comments for a known package, it should keep that package context attached long enough to resolve doc links. If a tool is only converting anonymous comment text, the older helpers may still produce formatted prose, but the result lacks package-aware linking. That distinction matters for editors, documentation servers, and static-analysis tools because readers expect bracketed documentation references to become navigable links when the target package or symbol can be identified.

Sources: src/go/doc/comment.go, src/go/doc/comment/print.go

Writing and Tooling Guidance

For authors, the implementation reinforces the public writing guidance: use complete sentences, place package comments in one source file for multi-file packages, and use the bracketed documentation link syntax when referring to packages or symbols. For tool builders, the stronger rule is to preserve structure rather than manipulating comment strings with ad hoc substitutions. Parse once, inspect or transform the Doc tree when necessary, and then print through the format-specific method that matches the destination. That approach avoids inconsistent heading, list, code, and link behavior.

Sources: src/go/doc/comment/doc.go, src/go/doc/comment/parse.go, src/go/doc/comment/print.go

When customizing output, start with the smallest necessary Printer change. For a documentation website, set a base URL or custom DocLinkURL so package and symbol references point at the correct host. For embedded documentation fragments, adjust HeadingLevel so generated headings fit the surrounding page hierarchy. For command-line output, use TextPrefix, TextCodePrefix, and TextWidth to match terminal conventions. Because these options live on Printer, the parsed Doc remains reusable across multiple renderings, which is especially useful for tools that support both terminal and web output.

Sources: src/go/doc/comment/html.go, src/go/doc/comment/markdown.go, src/go/doc/comment/print.go

Next Steps

If you are writing Go source, read this page alongside Effective Go and the standard documentation guidance so comments communicate intent before tools ever parse them. If you are implementing documentation tooling, focus next on the go/doc package that extracts declarations and associates comments with packages and symbols, then use go/doc/comment for the comment language itself. If your output must be compatible with generated sites or editors, test the same parsed Doc through HTML, Markdown, and text printers so link resolution, escaping, and list spacing stay consistent.