markdown

package
v1.50.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 21, 2026 License: Apache-2.0 Imports: 14 Imported by: 0

Documentation

Overview

Package markdown provides markdown parsing and terminal rendering capabilities.

Index

Constants

This section is empty.

Variables

View Source
var DarkStyleConfig = ansi.StyleConfig{
	Document: ansi.StyleBlock{
		StylePrimitive: ansi.StylePrimitive{
			BlockPrefix: "\n",
			BlockSuffix: "\n",
			Color:       strPtr("252"),
		},
		Margin: uintPtr(defaultMargin),
	},
	BlockQuote: ansi.StyleBlock{
		Indent:      uintPtr(1),
		IndentToken: strPtr("│ "),
	},
	List: ansi.StyleList{
		LevelIndent: defaultListIndent,
	},
	Heading: ansi.StyleBlock{
		StylePrimitive: ansi.StylePrimitive{
			BlockSuffix: "\n",
			Color:       strPtr("39"),
			Bold:        boolPtr(true),
		},
	},
	H1: ansi.StyleBlock{
		StylePrimitive: ansi.StylePrimitive{
			Prefix:          " ",
			Suffix:          " ",
			Color:           strPtr("255"),
			BackgroundColor: strPtr("63"),
			Bold:            boolPtr(true),
		},
	},
	H2: ansi.StyleBlock{
		StylePrimitive: ansi.StylePrimitive{
			Prefix: "## ",
		},
	},
	H3: ansi.StyleBlock{
		StylePrimitive: ansi.StylePrimitive{
			Prefix: "### ",
		},
	},
	H4: ansi.StyleBlock{
		StylePrimitive: ansi.StylePrimitive{
			Prefix: "#### ",
		},
	},
	H5: ansi.StyleBlock{
		StylePrimitive: ansi.StylePrimitive{
			Prefix: "##### ",
		},
	},
	H6: ansi.StyleBlock{
		StylePrimitive: ansi.StylePrimitive{
			Prefix: "###### ",
			Color:  strPtr("35"),
			Bold:   boolPtr(false),
		},
	},
	Strikethrough: ansi.StylePrimitive{
		CrossedOut: boolPtr(true),
	},
	Emph: ansi.StylePrimitive{
		Italic: boolPtr(true),
	},
	Strong: ansi.StylePrimitive{
		Bold: boolPtr(true),
	},
	HorizontalRule: ansi.StylePrimitive{
		Color:  strPtr("240"),
		Format: "\n--------\n",
	},
	Item: ansi.StylePrimitive{
		BlockPrefix: "• ",
	},
	Enumeration: ansi.StylePrimitive{
		BlockPrefix: ". ",
	},
	Task: ansi.StyleTask{
		Ticked:   "[✓] ",
		Unticked: "[ ] ",
	},
	Link: ansi.StylePrimitive{
		Color:     strPtr("30"),
		Underline: boolPtr(true),
	},
	LinkText: ansi.StylePrimitive{
		Color: strPtr("35"),
		Bold:  boolPtr(true),
	},
	Image: ansi.StylePrimitive{
		Color:     strPtr("212"),
		Underline: boolPtr(true),
	},
	ImageText: ansi.StylePrimitive{
		Color:  strPtr("243"),
		Format: "Image: {{.text}} →",
	},
	Code: ansi.StyleBlock{
		StylePrimitive: ansi.StylePrimitive{
			Prefix:          " ",
			Suffix:          " ",
			Color:           strPtr("203"),
			BackgroundColor: strPtr("236"),
		},
	},
	CodeBlock: ansi.StyleCodeBlock{
		StyleBlock: ansi.StyleBlock{
			StylePrimitive: ansi.StylePrimitive{
				Color: strPtr("244"),
			},
			Margin: uintPtr(defaultMargin),
		},
		Chroma: &ansi.Chroma{
			Text:                ansi.StylePrimitive{Color: strPtr("#C4C4C4")},
			Error:               ansi.StylePrimitive{Color: strPtr("#F1F1F1"), BackgroundColor: strPtr("#F05B5B")},
			Comment:             ansi.StylePrimitive{Color: strPtr("#676767")},
			CommentPreproc:      ansi.StylePrimitive{Color: strPtr("#FF875F")},
			Keyword:             ansi.StylePrimitive{Color: strPtr("#00AAFF")},
			KeywordReserved:     ansi.StylePrimitive{Color: strPtr("#FF5FD2")},
			KeywordNamespace:    ansi.StylePrimitive{Color: strPtr("#FF5F87")},
			KeywordType:         ansi.StylePrimitive{Color: strPtr("#6E6ED8")},
			Operator:            ansi.StylePrimitive{Color: strPtr("#EF8080")},
			Punctuation:         ansi.StylePrimitive{Color: strPtr("#E8E8A8")},
			Name:                ansi.StylePrimitive{Color: strPtr("#C4C4C4")},
			NameBuiltin:         ansi.StylePrimitive{Color: strPtr("#FF8EC7")},
			NameTag:             ansi.StylePrimitive{Color: strPtr("#B083EA")},
			NameAttribute:       ansi.StylePrimitive{Color: strPtr("#7A7AE6")},
			NameClass:           ansi.StylePrimitive{Color: strPtr("#F1F1F1"), Underline: boolPtr(true), Bold: boolPtr(true)},
			NameDecorator:       ansi.StylePrimitive{Color: strPtr("#FFFF87")},
			NameFunction:        ansi.StylePrimitive{Color: strPtr("#00D787")},
			LiteralNumber:       ansi.StylePrimitive{Color: strPtr("#6EEFC0")},
			LiteralString:       ansi.StylePrimitive{Color: strPtr("#C69669")},
			LiteralStringEscape: ansi.StylePrimitive{Color: strPtr("#AFFFD7")},
			GenericDeleted:      ansi.StylePrimitive{Color: strPtr("#FD5B5B")},
			GenericEmph:         ansi.StylePrimitive{Italic: boolPtr(true)},
			GenericInserted:     ansi.StylePrimitive{Color: strPtr("#00D787")},
			GenericStrong:       ansi.StylePrimitive{Bold: boolPtr(true)},
			GenericSubheading:   ansi.StylePrimitive{Color: strPtr("#777777")},
			Background:          ansi.StylePrimitive{BackgroundColor: strPtr("#373737")},
		},
	},
	Table: ansi.StyleTable{},
	DefinitionDescription: ansi.StylePrimitive{
		BlockPrefix: "\n🠶 ",
	},
}

DarkStyleConfig is our default style for dark terminal backgrounds.

View Source
var LightStyleConfig = ansi.StyleConfig{
	Document: ansi.StyleBlock{
		StylePrimitive: ansi.StylePrimitive{
			BlockPrefix: "\n",
			BlockSuffix: "\n",
			Color:       strPtr("234"),
		},
		Margin: uintPtr(defaultMargin),
	},
	BlockQuote: ansi.StyleBlock{
		Indent:      uintPtr(1),
		IndentToken: strPtr("│ "),
	},
	List: ansi.StyleList{
		LevelIndent: defaultListIndent,
	},
	Heading: ansi.StyleBlock{
		StylePrimitive: ansi.StylePrimitive{
			BlockSuffix: "\n",
			Color:       strPtr("27"),
			Bold:        boolPtr(true),
		},
	},
	H1: ansi.StyleBlock{
		StylePrimitive: ansi.StylePrimitive{
			Prefix:          " ",
			Suffix:          " ",
			Color:           strPtr("255"),
			BackgroundColor: strPtr("63"),
			Bold:            boolPtr(true),
		},
	},
	H2: ansi.StyleBlock{
		StylePrimitive: ansi.StylePrimitive{
			Prefix: "## ",
		},
	},
	H3: ansi.StyleBlock{
		StylePrimitive: ansi.StylePrimitive{
			Prefix: "### ",
		},
	},
	H4: ansi.StyleBlock{
		StylePrimitive: ansi.StylePrimitive{
			Prefix: "#### ",
		},
	},
	H5: ansi.StyleBlock{
		StylePrimitive: ansi.StylePrimitive{
			Prefix: "##### ",
		},
	},
	H6: ansi.StyleBlock{
		StylePrimitive: ansi.StylePrimitive{
			Prefix: "###### ",
			Bold:   boolPtr(false),
		},
	},
	Strikethrough: ansi.StylePrimitive{
		CrossedOut: boolPtr(true),
	},
	Emph: ansi.StylePrimitive{
		Italic: boolPtr(true),
	},
	Strong: ansi.StylePrimitive{
		Bold: boolPtr(true),
	},
	HorizontalRule: ansi.StylePrimitive{
		Color:  strPtr("249"),
		Format: "\n--------\n",
	},
	Item: ansi.StylePrimitive{
		BlockPrefix: "• ",
	},
	Enumeration: ansi.StylePrimitive{
		BlockPrefix: ". ",
	},
	Task: ansi.StyleTask{
		Ticked:   "[✓] ",
		Unticked: "[ ] ",
	},
	Link: ansi.StylePrimitive{
		Color:     strPtr("36"),
		Underline: boolPtr(true),
	},
	LinkText: ansi.StylePrimitive{
		Color: strPtr("29"),
		Bold:  boolPtr(true),
	},
	Image: ansi.StylePrimitive{
		Color:     strPtr("205"),
		Underline: boolPtr(true),
	},
	ImageText: ansi.StylePrimitive{
		Color:  strPtr("243"),
		Format: "Image: {{.text}} →",
	},
	Code: ansi.StyleBlock{
		StylePrimitive: ansi.StylePrimitive{
			Prefix:          " ",
			Suffix:          " ",
			Color:           strPtr("203"),
			BackgroundColor: strPtr("254"),
		},
	},
	CodeBlock: ansi.StyleCodeBlock{
		StyleBlock: ansi.StyleBlock{
			StylePrimitive: ansi.StylePrimitive{
				Color: strPtr("242"),
			},
			Margin: uintPtr(defaultMargin),
		},
		Chroma: &ansi.Chroma{
			Text:                ansi.StylePrimitive{Color: strPtr("#2A2A2A")},
			Error:               ansi.StylePrimitive{Color: strPtr("#F1F1F1"), BackgroundColor: strPtr("#FF5555")},
			Comment:             ansi.StylePrimitive{Color: strPtr("#8D8D8D")},
			CommentPreproc:      ansi.StylePrimitive{Color: strPtr("#FF875F")},
			Keyword:             ansi.StylePrimitive{Color: strPtr("#279EFC")},
			KeywordReserved:     ansi.StylePrimitive{Color: strPtr("#FF5FD2")},
			KeywordNamespace:    ansi.StylePrimitive{Color: strPtr("#FB406F")},
			KeywordType:         ansi.StylePrimitive{Color: strPtr("#7049C2")},
			Operator:            ansi.StylePrimitive{Color: strPtr("#FF2626")},
			Punctuation:         ansi.StylePrimitive{Color: strPtr("#FA7878")},
			NameBuiltin:         ansi.StylePrimitive{Color: strPtr("#0A1BB1")},
			NameTag:             ansi.StylePrimitive{Color: strPtr("#581290")},
			NameAttribute:       ansi.StylePrimitive{Color: strPtr("#8362CB")},
			NameClass:           ansi.StylePrimitive{Color: strPtr("#212121"), Underline: boolPtr(true), Bold: boolPtr(true)},
			NameConstant:        ansi.StylePrimitive{Color: strPtr("#581290")},
			NameDecorator:       ansi.StylePrimitive{Color: strPtr("#A3A322")},
			NameFunction:        ansi.StylePrimitive{Color: strPtr("#019F57")},
			LiteralNumber:       ansi.StylePrimitive{Color: strPtr("#22CCAE")},
			LiteralString:       ansi.StylePrimitive{Color: strPtr("#7E5B38")},
			LiteralStringEscape: ansi.StylePrimitive{Color: strPtr("#00AEAE")},
			GenericDeleted:      ansi.StylePrimitive{Color: strPtr("#FD5B5B")},
			GenericEmph:         ansi.StylePrimitive{Italic: boolPtr(true)},
			GenericInserted:     ansi.StylePrimitive{Color: strPtr("#00D787")},
			GenericStrong:       ansi.StylePrimitive{Bold: boolPtr(true)},
			GenericSubheading:   ansi.StylePrimitive{Color: strPtr("#777777")},
			Background:          ansi.StylePrimitive{BackgroundColor: strPtr("#F5F5F5")},
		},
	},
	Table: ansi.StyleTable{},
	DefinitionDescription: ansi.StylePrimitive{
		BlockPrefix: "\n🠶 ",
	},
}

LightStyleConfig is our default style for light terminal backgrounds.

Functions

func NormalizeFragment added in v1.50.5

func NormalizeFragment(s string) string

NormalizeFragment converts heading text to the fragment format used by docs URLs.

Types

type Document

type Document struct {
	Node   ast.Node
	Source []byte
}

Document holds a parsed markdown document, including the goldmark AST root and the original source bytes. Callers can walk Node to extract headings, links, code blocks, and other elements.

func Parse

func Parse(src []byte, opts ...ParseOption) (*Document, error)

Parse parses src as markdown and returns a Document containing the goldmark AST root and the original source bytes. The source is required for extracting text from AST nodes via Node.Text(source).

func (*Document) HeadingForFragment added in v1.50.5

func (d *Document) HeadingForFragment(fragment string) (Heading, bool)

HeadingForFragment returns the heading matching fragment.

func (*Document) Headings added in v1.50.5

func (d *Document) Headings() []Heading

Headings returns the document headings in source order. Repeated fragments receive the same numeric suffixes used by documentation URLs.

func (*Document) References

func (d *Document) References(currentURL *url.URL) []Reference

References returns all hyperlinks found in the document, in document order. currentURL is the URL of the page being viewed; links that resolve to the same page (with or without a fragment) are excluded so that on-page anchors do not clutter the reference palette.

func (*Document) Title

func (d *Document) Title() string

Title returns the text of the first h1 heading in the document, or an empty string if none is found.

type Heading added in v1.50.5

type Heading struct {
	Level    int
	Text     string
	Fragment string
}

Heading describes a document heading and its URL fragment.

type ParseOption

type ParseOption func(*parseConfig)

ParseOption configures Parse behavior.

func WithRelativeURLs

func WithRelativeURLs(origin string) ParseOption

WithRelativeURLs strips the given origin (e.g. "https://docs.stripe.com") from absolute URLs in the document source before parsing, converting them to root-relative paths. It may be passed multiple times to strip multiple origins.

type Reference

type Reference struct {
	Title    string
	URL      *url.URL
	External bool // true when the URL points outside docs.stripe.com
}

Reference is a hyperlink extracted from a markdown document.

type RenderedDocument added in v1.50.5

type RenderedDocument struct {
	Content        string
	HeadingOffsets map[string]int
}

RenderedDocument contains rendered content and the line offset of each heading.

func RenderWithHeadingOffsets added in v1.50.5

func RenderWithHeadingOffsets(r Renderer, doc *Document) (RenderedDocument, error)

RenderWithHeadingOffsets renders doc and locates each heading in the output.

type Renderer

type Renderer interface {
	Render(doc *Document) (string, error)
}

Renderer renders a Document to a terminal-friendly string.

func NewRenderer

func NewRenderer(opts ...RendererOption) (Renderer, error)

NewRenderer constructs a Renderer backed by glamour with sensible defaults (auto-detected dark/light using our own style configs, 140-column word wrap). Options override individual defaults.

type RendererOption

type RendererOption func(*rendererConfig)

RendererOption configures a Renderer created by NewRenderer.

func WithStyle

func WithStyle(style string) RendererOption

WithStyle sets a built-in glamour style by name (e.g. "dark", "light", "dracula", "notty"). The default auto-detects dark/light from the terminal and applies our own style configs.

func WithStyleConfig

func WithStyleConfig(cfg ansi.StyleConfig) RendererOption

WithStyleConfig sets a fully custom ansi.StyleConfig, overriding both the named style and the auto-detected default. Use DarkStyleConfig or LightStyleConfig as a starting point.

func WithWordWrap

func WithWordWrap(width int) RendererOption

WithWordWrap sets the column width at which output is wrapped.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL