Documentation
¶
Overview ¶
Package toc provides support for building a Table of Contents from a goldmark Markdown document.
The package operates in two stages: inspection and rendering. During inspection, the package analyzes an existing Markdown document, and builds a Table of Contents from it.
markdown := goldmark.New(...) parser := markdown.Parser() doc := parser.Parse(text.NewReader(src)) tocTree, err := toc.Inspect(doc, src)
During rendering, it converts the Table of Contents into a list of headings with nested items under each as a goldmark Markdown document. You may manipulate the TOC, removing items from it or simplifying it, before rendering.
tocList := toc.RenderList(tocTree)
You can render that Markdown document using goldmark into whatever form you prefer.
renderer := markdown.Renderer() renderer.Render(out, src, tocList)
The following diagram summarizes the flow of information with goldmark-toc.
src +--------+ +-------------------+ | | goldmark/Parser.Parse | | | []byte :---------------------------> goldmark/ast.Node | | | | | +---.----+ +-------.-----.-----+ | | | '----------------. .-----------------' | \ / | \ / | | | | toc.Inspect | | | +----v----+ | | | | | toc.TOC | | | | | +----.----+ | | | | toc/Renderer.Render | | | +---------v---------+ | | | | | goldmark/ast.Node | | | | | +---------.---------+ | | | '-------. .--------------' \ / | goldmark/Renderer.Render | | v +------+ | HTML | +------+
Example ¶
src := []byte(` # A section Hello # Another section ## A sub-section ### A sub-sub-section Bye `) markdown := goldmark.New() // Request that IDs are automatically assigned to headers. markdown.Parser().AddOptions(parser.WithAutoHeadingID()) // Alternatively, we can provide our own implementation of parser.IDs // and use, // // pctx := parser.NewContext(parser.WithIDs(ids)) // doc := parser.Parse(text.NewReader(src), parser.WithContext(pctx)) doc := markdown.Parser().Parse(text.NewReader(src)) // Inspect the parsed Markdown document to find headers and build a // tree for the table of contents. tree, err := toc.Inspect(doc, src) if err != nil { panic(err) } // Render the tree as-is into a Markdown list. treeList := toc.RenderList(tree) // Render the Markdown list into HTML. markdown.Renderer().Render(os.Stdout, src, treeList)
Output: <ul> <li> <a href="#a-section">A section</a></li> <li> <a href="#another-section">Another section</a><ul> <li> <a href="#a-sub-section">A sub-section</a><ul> <li> <a href="#a-sub-sub-section">A sub-sub-section</a></li> </ul> </li> </ul> </li> </ul>
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func RenderList ¶
RenderList renders a table of contents as a nested list with a sane, default configuration for the ListRenderer.
Types ¶
type Extender ¶
type Extender struct { // Title is the title of the table of contents section. // Defaults to "Table of Contents" if unspecified. Title string // MaxDepth is the maximum depth of the table of contents. // Headings with a level greater than the specified depth will be ignored. // See the documentation for MaxDepth for more information. // // Defaults to 0 (no limit) if unspecified. MaxDepth int // MinDepth is the minimum depth of the table of contents. // Headings with a level greater than the specified depth will be ignored. // See the documentation for MaxDepth for more information. // // Defaults to 0 (no limit) if unspecified. MinDepth int }
Extender extends a Goldmark Markdown parser and renderer to always include a table of contents in the output.
To use this, install it into your Goldmark Markdown object.
md := goldmark.New( // ... goldmark.WithParserOptions(parser.WithAutoHeadingID()), goldmark.WithExtensions( // ... &toc.Extender{ }, ), )
This will install the default Transformer. For more control, install the Transformer directly on the Markdown Parser.
NOTE: Unless you've supplied your own parser.IDs implementation, you'll need to enable the WithAutoHeadingID option on the parser to generate IDs and links for headings.
type InspectOption ¶
type InspectOption interface {
// contains filtered or unexported methods
}
InspectOption customizes the behavior of Inspect.
func MaxDepth ¶
func MaxDepth(depth int) InspectOption
MaxDepth limits the depth of the table of contents. Headings with a level greater than the specified depth will be ignored.
For example, given the following:
# Foo ## Bar ### Baz # Quux ## Qux
MaxDepth(1) will result in the following:
TOC{Items: ...} | +--- &Item{Title: "Foo", ID: "foo"} | +--- &Item{Title: "Quux", ID: "quux", Items: ...}
Whereas, MaxDepth(2) will result in the following:
TOC{Items: ...} | +--- &Item{Title: "Foo", ID: "foo", Items: ...} | | | +--- &Item{Title: "Bar", ID: "bar"} | +--- &Item{Title: "Quux", ID: "quux", Items: ...} | +--- &Item{Title: "Qux", ID: "qux"}
A value of 0 or less will result in no limit.
The default is no limit.
type Item ¶
type Item struct { // Title of this item in the table of contents. // // This may be blank for items that don't refer to a heading, and only // have sub-items. Title []byte // ID is the identifier for the heading that this item refers to. This // is the fragment portion of the link without the "#". // // This may be blank if the item doesn't have an id assigned to it, or // if it doesn't have a title. // // Enable AutoHeadingID in your parser if you expected these to be set // but they weren't. ID []byte // Items references children of this item. // // For a heading at level 3, Items, contains the headings at level 4 // under that section. Items Items }
Item is a single item in the table of contents.
type ListRenderer ¶
type ListRenderer struct { // Marker for elements of the list, e.g. '-', '*', etc. // // Defaults to '*'. Marker byte }
ListRenderer builds a nested list from a table of contents.
For example,
# Foo ## Bar ## Baz # Qux // becomes - Foo - Bar - Baz - Qux
type TOC ¶
type TOC struct { // Items holds the top-level headings under the table of contents. Items Items }
TOC is the table of contents. It's the top-level object under which the rest of the table of contents resides.
func Inspect ¶
Inspect builds a table of contents by inspecting the provided document.
The table of contents is represents as a tree where each item represents a heading or a heading level with zero or more children.
For example,
# Section 1 ## Subsection 1.1 ## Subsection 1.2 # Section 2 ## Subsection 2.1 # Section 3
Will result in the following items.
TOC{Items: ...} | +--- &Item{Title: "Section 1", ID: "section-1", Items: ...} | | | +--- &Item{Title: "Subsection 1.1", ID: "subsection-1-1"} | | | +--- &Item{Title: "Subsection 1.2", ID: "subsection-1-2"} | +--- &Item{Title: "Section 2", ID: "section-2", Items: ...} | | | +--- &Item{Title: "Subsection 2.1", ID: "subsection-2-1"} | +--- &Item{Title: "Section 3", ID: "section-3"}
You may analyze or manipulate the table of contents before rendering it.
type Transformer ¶
type Transformer struct { // Title is the title of the table of contents section. // Defaults to "Table of Contents" if unspecified. Title string // MaxDepth is the maximum depth of the table of contents. // See the documentation for MaxDepth for more information. MaxDepth int // MinDepth is the minimum depth of the table of contents. // See the documentation for MinDepth for more information. MinDepth int }
Transformer is a Goldmark AST transformer adds a TOC to the top of a Markdown document.
To use this, either install the Extender on the goldmark.Markdown object, or install the AST transformer on the Markdown parser like so.
markdown := goldmark.New(...) markdown.Parser().AddOptions( parser.WithAutoHeadingID(), parser.WithASTTransformers( util.Prioritized(&toc.Transformer{}, 100), ), )
NOTE: Unless you've supplied your own parser.IDs implementation, you'll need to enable the WithAutoHeadingID option on the parser to generate IDs and links for headings.