markdown

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Sep 29, 2025 License: MIT Imports: 8 Imported by: 1

README

markdown

markdown is a lightweight builder for generating Markdown programmatically using the goldmark AST. It mirrors the API provided by github.com/nao1215/markdown while dropping external dependencies (such as tablewriter) and relying entirely on goldmark nodes for construction and rendering.

Features

  • Chainable builder API for headings, lists, blockquotes, tables, callouts, badges, links, and more
  • Table of Contents generation with configurable depth
  • Table rendering with per-column alignment and auto-formatting helpers
  • Custom table handling without tablewriter
  • Goldmark-backed internal representation ensures consistent Markdown output across platforms
  • Simple syntax sugar helpers for inline formatting

Installation

go get github.com/ivanvanderbyl/markdown

Quick Start

package main

import (
    "fmt"
    "os"

    "github.com/ivanvanderbyl/markdown"
)

func main() {
    md := markdown.NewMarkdown(os.Stdout)
    md.H1("Guide to markdown").
        PlainText("Markdown built through goldmark AST.").
        Table(markdown.TableSet{
            Header: []string{"Feature", "Description"},
            Rows: [][]string{
                {"TOC", "Generate nested table of contents"},
                {"Tables", "Alignment-aware rendering without tablewriter"},
            },
        }).
        Build()
}

Output:

# Guide to markdown
Markdown built through goldmark AST.
| Feature | Description                                   |
| ------- | --------------------------------------------- |
| TOC     | Generate nested table of contents             |
| Tables  | Alignment-aware rendering without tablewriter |

Building Documents

Every method on *Markdown returns the same builder, enabling fluent composition. When you’re done, call Build() to write the rendered Markdown to the provided io.Writer.

md := markdown.NewMarkdown(os.Stdout)
md.H1("Release Notes").
    H2("v1.0.0").
    BulletList("Initial release", "Markdown builder", "Table support").
    LF().
    Important("Remember to pin dependencies").
    Build()

Adding a Table of Contents

TableOfContents consumes the recorded heading metadata and writes a Markdown TOC up to a specified depth.

md := markdown.NewMarkdown(os.Stdout)
md.H1("Project").
    H2("Overview").
    H2("Usage").
    TableOfContents(markdown.TableOfContentsDepthH2).
    Build()

The generated TOC uses bullet indentation to reflect heading levels.

Working with Tables

Tables are defined through TableSet. The renderer automatically pads columns to fit the widest cell and emits separators honoring column alignment.

md.Table(markdown.TableSet{
    Header: []string{"Left", "Center", "Right"},
    Rows: [][]string{
        {"L", "C", "R"},
    },
    Alignment: []markdown.TableAlignment{
        markdown.AlignLeft,
        markdown.AlignCenter,
        markdown.AlignRight,
    },
})

Output:

| Left | Center | Right |
| :--- | :----: | ----: |
| L    |   C    |     R |
Custom Table Helpers

CustomTable applies optional formatting on top of standard rendering. Currently, it supports:

  • AutoFormatHeaders: Title-cases header cells by splitting on whitespace
md.CustomTable(markdown.TableSet{
    Header: []string{"first name", "status"},
    Rows: [][]string{{"Alice", "active"}},
}, markdown.TableOptions{AutoFormatHeaders: true})

Inline Formatting Helpers

Use the standalone helpers for inline Markdown strings:

markdown.Bold("text")       // **text**
markdown.Italic("text")     // *text*
markdown.Link("Docs", "https://example.com")
markdown.Image("Logo", "https://example.com/logo.png")
markdown.Highlight("Note") // ==Note==

Callouts and Badges

The builder supports GitHub-style callouts and shield badges:

md.Note("Heads up!")
md.Tip("Try the new API.")
md.BlueBadge("stable")

Each callout renders a blockquote with the appropriate label (e.g., [!NOTE]).

Rendering Programmatically Generated Data

The powered example below demonstrates building a weekly price table from structs:

func ExampleMarkdown_Table_bars() {
    bars := []Bar{ /* ... seven days ... */ }

    rows := make([][]string, len(bars))
    for i, bar := range bars {
        rows[i] = []string{
            bar.Timestamp.Format("2006-01-02"),
            fmt.Sprintf("%.2f", bar.Open),
            fmt.Sprintf("%.2f", bar.High),
            fmt.Sprintf("%.2f", bar.Low),
            fmt.Sprintf("%.2f", bar.Close),
            fmt.Sprintf("%d", bar.Volume),
            fmt.Sprintf("%d", bar.TradeCount),
            fmt.Sprintf("%.2f", bar.VWAP),
        }
    }

    md := markdown.NewMarkdown(os.Stdout)
    md.H2("Daily Bars")
    md.Table(markdown.TableSet{
        Header: []string{"Day", "Open", "High", "Low", "Close", "Volume", "Trades", "VWAP"},
        Rows:   rows,
    })
    md.Build()
}

Error Handling

Most builder methods return the builder and only record errors internally. Retrieve the combined error from Error() or defer the check to Build():

md.Table(markdown.TableSet{Header: []string{"A"}, Rows: [][]string{{"x", "y"}}})
if err := md.Build(); err != nil {
    log.Fatalf("build failed: %v", err)
}

Testing

Run project tests with:

go test ./...

License

MIT Licensed. See LICENSE for details.

Documentation

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	// ErrMismatchColumn is returned when the number of columns in the record doesn't match the header.
	ErrMismatchColumn = errors.New("number of columns in the record doesn't match the header")
	// ErrInitMarkdownIndex is returned when the index can't be initialized.
	ErrInitMarkdownIndex = errors.New("markdown index can't be initialized")
	// ErrCreateMarkdownIndex is returned when the index can't be created.
	ErrCreateMarkdownIndex = errors.New("markdown index can't be created")
	// ErrWriteMarkdownIndex is returned when the index can't be written.
	ErrWriteMarkdownIndex = errors.New("markdown index can't be written")
)

Functions

func Bold

func Bold(text string) string

Bold return text with bold format.

func BoldItalic

func BoldItalic(text string) string

BoldItalic return text with bold and italic format.

func Code

func Code(text string) string

Code return text with code format.

func Highlight

func Highlight(text string) string

Highlight return text with highlight format.

func Image

func Image(text, url string) string

Image return text with image format.

func Italic

func Italic(text string) string

Italic return text with italic format.

func Link(text, url string) string

Link return text with link format.

func Strikethrough

func Strikethrough(text string) string

Strikethrough return text with strikethrough format.

Types

type CheckBoxSet

type CheckBoxSet struct {
	Checked bool
	Text    string
}

CheckBoxSet configures a single checkbox entry.

type Markdown

type Markdown struct {
	// contains filtered or unexported fields
}

Markdown is markdown text.

func NewMarkdown

func NewMarkdown(w io.Writer) *Markdown

NewMarkdown returns new Markdown.

func (*Markdown) Blockquote

func (m *Markdown) Blockquote(text string) *Markdown

Blockquote appends a blockquote block.

func (*Markdown) BlueBadge

func (m *Markdown) BlueBadge(text string) *Markdown

BlueBadge set text with blue badge format.

func (*Markdown) BlueBadgef

func (m *Markdown) BlueBadgef(format string, args ...interface{}) *Markdown

BlueBadgef set text with blue badge format.

func (*Markdown) Build

func (m *Markdown) Build() error

Build writes markdown text to output destination.

func (*Markdown) BulletList

func (m *Markdown) BulletList(items ...string) *Markdown

BulletList appends an unordered list.

func (*Markdown) Caution

func (m *Markdown) Caution(text string) *Markdown

Caution set text with caution format.

func (*Markdown) Cautionf

func (m *Markdown) Cautionf(format string, args ...interface{}) *Markdown

Cautionf set text with caution format.

func (*Markdown) CheckBox

func (m *Markdown) CheckBox(set []CheckBoxSet) *Markdown

CheckBox appends a checkbox list.

func (*Markdown) CodeBlocks

func (m *Markdown) CodeBlocks(lang SyntaxHighlight, text string) *Markdown

CodeBlocks appends a fenced code block.

func (*Markdown) CustomTable

func (m *Markdown) CustomTable(set TableSet, options TableOptions) *Markdown

CustomTable renders a table with optional formatting behaviors.

func (*Markdown) Details

func (m *Markdown) Details(summary, text string) *Markdown

Details renders an HTML <details> block.

func (*Markdown) Detailsf

func (m *Markdown) Detailsf(summary, format string, args ...interface{}) *Markdown

Detailsf renders formatted <details> block content.

func (*Markdown) Error

func (m *Markdown) Error() error

Error returns error.

func (*Markdown) GreenBadge

func (m *Markdown) GreenBadge(text string) *Markdown

GreenBadge set text with green badge format.

func (*Markdown) GreenBadgef

func (m *Markdown) GreenBadgef(format string, args ...interface{}) *Markdown

GreenBadgef set text with green badge format.

func (*Markdown) H1

func (m *Markdown) H1(text string) *Markdown

H1 is markdown header.

func (*Markdown) H1f

func (m *Markdown) H1f(format string, args ...interface{}) *Markdown

H1f is markdown header with format.

func (*Markdown) H2

func (m *Markdown) H2(text string) *Markdown

H2 is markdown header.

func (*Markdown) H2f

func (m *Markdown) H2f(format string, args ...interface{}) *Markdown

H2f is markdown header with format.

func (*Markdown) H3

func (m *Markdown) H3(text string) *Markdown

H3 is markdown header.

func (*Markdown) H3f

func (m *Markdown) H3f(format string, args ...interface{}) *Markdown

H3f is markdown header with format.

func (*Markdown) H4

func (m *Markdown) H4(text string) *Markdown

H4 is markdown header.

func (*Markdown) H4f

func (m *Markdown) H4f(format string, args ...interface{}) *Markdown

H4f is markdown header with format.

func (*Markdown) H5

func (m *Markdown) H5(text string) *Markdown

H5 is markdown header.

func (*Markdown) H5f

func (m *Markdown) H5f(format string, args ...interface{}) *Markdown

H5f is markdown header with format.

func (*Markdown) H6

func (m *Markdown) H6(text string) *Markdown

H6 is markdown header.

func (*Markdown) H6f

func (m *Markdown) H6f(format string, args ...interface{}) *Markdown

H6f is markdown header with format.

func (*Markdown) HorizontalRule

func (m *Markdown) HorizontalRule() *Markdown

HorizontalRule appends a thematic break.

func (*Markdown) Important

func (m *Markdown) Important(text string) *Markdown

Important set text with important format.

func (*Markdown) Importantf

func (m *Markdown) Importantf(format string, args ...interface{}) *Markdown

Importantf set text with important format.

func (*Markdown) LF

func (m *Markdown) LF() *Markdown

LF appends a markdown line feed (two spaces).

func (*Markdown) Note

func (m *Markdown) Note(text string) *Markdown

Note set text with note format.

func (*Markdown) Notef

func (m *Markdown) Notef(format string, args ...interface{}) *Markdown

Notef set text with note format.

func (*Markdown) OrderedList

func (m *Markdown) OrderedList(items ...string) *Markdown

OrderedList appends an ordered list.

func (*Markdown) PlainText

func (m *Markdown) PlainText(text string) *Markdown

PlainText set plain text

func (*Markdown) PlainTextf

func (m *Markdown) PlainTextf(format string, args ...interface{}) *Markdown

PlainTextf set plain text with format

func (*Markdown) RedBadge

func (m *Markdown) RedBadge(text string) *Markdown

RedBadge set text with red badge format.

func (*Markdown) RedBadgef

func (m *Markdown) RedBadgef(format string, args ...interface{}) *Markdown

RedBadgef set text with red badge format.

func (*Markdown) String

func (m *Markdown) String() string

String returns markdown text.

func (*Markdown) Table

func (m *Markdown) Table(set TableSet) *Markdown

Table renders a markdown table using goldmark table AST nodes.

Example (Bars)

ExampleMarkdown_Table_bars shows how to turn seven daily Bar values into a markdown table.

package main

import (
	"fmt"
	"os"
	"time"
)

// Bar is an aggregate of trades.
type Bar struct {
	Timestamp  time.Time
	Open       float64
	High       float64
	Low        float64
	Close      float64
	Volume     uint64
	TradeCount uint64
	VWAP       float64
}

// ExampleMarkdown_Table_bars shows how to turn seven daily Bar values into a markdown table.
func main() {
	bars := []Bar{
		{Timestamp: time.Date(2024, 10, 1, 0, 0, 0, 0, time.UTC), Open: 101.25, High: 105.50, Low: 100.90, Close: 104.20, Volume: 1200345, TradeCount: 3456, VWAP: 103.45},
		{Timestamp: time.Date(2024, 10, 2, 0, 0, 0, 0, time.UTC), Open: 104.20, High: 106.80, Low: 103.75, Close: 105.10, Volume: 980456, TradeCount: 2980, VWAP: 104.95},
		{Timestamp: time.Date(2024, 10, 3, 0, 0, 0, 0, time.UTC), Open: 105.10, High: 107.20, Low: 104.10, Close: 106.75, Volume: 1100456, TradeCount: 3104, VWAP: 106.15},
		{Timestamp: time.Date(2024, 10, 4, 0, 0, 0, 0, time.UTC), Open: 106.75, High: 108.90, Low: 105.30, Close: 108.40, Volume: 1023400, TradeCount: 2890, VWAP: 107.85},
		{Timestamp: time.Date(2024, 10, 5, 0, 0, 0, 0, time.UTC), Open: 108.40, High: 109.25, Low: 106.80, Close: 107.10, Volume: 954320, TradeCount: 2605, VWAP: 107.35},
		{Timestamp: time.Date(2024, 10, 6, 0, 0, 0, 0, time.UTC), Open: 107.10, High: 108.75, Low: 106.40, Close: 108.20, Volume: 876540, TradeCount: 2400, VWAP: 107.95},
		{Timestamp: time.Date(2024, 10, 7, 0, 0, 0, 0, time.UTC), Open: 108.20, High: 110.15, Low: 107.95, Close: 109.60, Volume: 1132050, TradeCount: 3250, VWAP: 109.05},
	}

	rows := make([][]string, len(bars))
	for i, bar := range bars {
		rows[i] = []string{
			bar.Timestamp.Format("2006-01-02"),
			fmt.Sprintf("%.2f", bar.Open),
			fmt.Sprintf("%.2f", bar.High),
			fmt.Sprintf("%.2f", bar.Low),
			fmt.Sprintf("%.2f", bar.Close),
			fmt.Sprintf("%d", bar.Volume),
			fmt.Sprintf("%d", bar.TradeCount),
			fmt.Sprintf("%.2f", bar.VWAP),
		}
	}

	md := NewMarkdown(os.Stdout)
	md.H2("Daily Bars")
	md.Table(TableSet{
		Header: []string{"Day", "Open", "High", "Low", "Close", "Volume", "Trades", "VWAP"},
		Rows:   rows,
	})

	if err := md.Build(); err != nil {
		fmt.Fprintf(os.Stderr, "Error building markdown: %v\n", err)
		return
	}

}
Output:
## Daily Bars
| Day        | Open   | High   | Low    | Close  | Volume  | Trades | VWAP   |
| ---------- | ------ | ------ | ------ | ------ | ------- | ------ | ------ |
| 2024-10-01 | 101.25 | 105.50 | 100.90 | 104.20 | 1200345 | 3456   | 103.45 |
| 2024-10-02 | 104.20 | 106.80 | 103.75 | 105.10 | 980456  | 2980   | 104.95 |
| 2024-10-03 | 105.10 | 107.20 | 104.10 | 106.75 | 1100456 | 3104   | 106.15 |
| 2024-10-04 | 106.75 | 108.90 | 105.30 | 108.40 | 1023400 | 2890   | 107.85 |
| 2024-10-05 | 108.40 | 109.25 | 106.80 | 107.10 | 954320  | 2605   | 107.35 |
| 2024-10-06 | 107.10 | 108.75 | 106.40 | 108.20 | 876540  | 2400   | 107.95 |
| 2024-10-07 | 108.20 | 110.15 | 107.95 | 109.60 | 1132050 | 3250   | 109.05 |

func (*Markdown) TableOfContents

func (m *Markdown) TableOfContents(depth TableOfContentsDepth) *Markdown

TableOfContents generates a table of contents from the recorded headers.

func (*Markdown) Tip

func (m *Markdown) Tip(text string) *Markdown

Tip set text with tip format.

func (*Markdown) Tipf

func (m *Markdown) Tipf(format string, args ...interface{}) *Markdown

Tipf set text with tip format.

func (*Markdown) Warning

func (m *Markdown) Warning(text string) *Markdown

Warning set text with warning format.

func (*Markdown) Warningf

func (m *Markdown) Warningf(format string, args ...interface{}) *Markdown

Warningf set text with warning format.

func (*Markdown) YellowBadge

func (m *Markdown) YellowBadge(text string) *Markdown

YellowBadge set text with yellow badge format.

func (*Markdown) YellowBadgef

func (m *Markdown) YellowBadgef(format string, args ...interface{}) *Markdown

YellowBadgef set text with yellow badge format.

type SyntaxHighlight

type SyntaxHighlight string

SyntaxHighlight is syntax highlight language.

const (
	SyntaxHighlightNone         SyntaxHighlight = ""
	SyntaxHighlightText         SyntaxHighlight = "text"
	SyntaxHighlightAPIBlueprint SyntaxHighlight = "markdown"
	SyntaxHighlightShell        SyntaxHighlight = "shell"
	SyntaxHighlightGo           SyntaxHighlight = "go"
	SyntaxHighlightJSON         SyntaxHighlight = "json"
	SyntaxHighlightYAML         SyntaxHighlight = "yaml"
	SyntaxHighlightXML          SyntaxHighlight = "xml"
	SyntaxHighlightHTML         SyntaxHighlight = "html"
	SyntaxHighlightCSS          SyntaxHighlight = "css"
	SyntaxHighlightJavaScript   SyntaxHighlight = "javascript"
	SyntaxHighlightTypeScript   SyntaxHighlight = "typescript"
	SyntaxHighlightSQL          SyntaxHighlight = "sql"
	SyntaxHighlightC            SyntaxHighlight = "c"
	SyntaxHighlightCSharp       SyntaxHighlight = "csharp"
	SyntaxHighlightCPlusPlus    SyntaxHighlight = "cpp"
	SyntaxHighlightJava         SyntaxHighlight = "java"
	SyntaxHighlightKotlin       SyntaxHighlight = "kotlin"
	SyntaxHighlightPHP          SyntaxHighlight = "php"
	SyntaxHighlightPython       SyntaxHighlight = "python"
	SyntaxHighlightRuby         SyntaxHighlight = "ruby"
	SyntaxHighlightSwift        SyntaxHighlight = "swift"
	SyntaxHighlightScala        SyntaxHighlight = "scala"
	SyntaxHighlightRust         SyntaxHighlight = "rust"
	SyntaxHighlightObjectiveC   SyntaxHighlight = "objectivec"
	SyntaxHighlightPerl         SyntaxHighlight = "perl"
	SyntaxHighlightLua          SyntaxHighlight = "lua"
	SyntaxHighlightDart         SyntaxHighlight = "dart"
	SyntaxHighlightClojure      SyntaxHighlight = "clojure"
	SyntaxHighlightGroovy       SyntaxHighlight = "groovy"
	SyntaxHighlightR            SyntaxHighlight = "r"
	SyntaxHighlightHaskell      SyntaxHighlight = "haskell"
	SyntaxHighlightErlang       SyntaxHighlight = "erlang"
	SyntaxHighlightElixir       SyntaxHighlight = "elixir"
	SyntaxHighlightOCaml        SyntaxHighlight = "ocaml"
	SyntaxHighlightJulia        SyntaxHighlight = "julia"
	SyntaxHighlightScheme       SyntaxHighlight = "scheme"
	SyntaxHighlightFSharp       SyntaxHighlight = "fsharp"
	SyntaxHighlightCoffeeScript SyntaxHighlight = "coffeescript"
	SyntaxHighlightVBNet        SyntaxHighlight = "vbnet"
	SyntaxHighlightTeX          SyntaxHighlight = "tex"
	SyntaxHighlightDiff         SyntaxHighlight = "diff"
	SyntaxHighlightApache       SyntaxHighlight = "apache"
	SyntaxHighlightDockerfile   SyntaxHighlight = "dockerfile"
	SyntaxHighlightMermaid      SyntaxHighlight = "mermaid"
)

type TableAlignment

type TableAlignment int

TableAlignment represents column alignment in markdown tables.

const (
	// AlignDefault represents no specific alignment (left by default).
	AlignDefault TableAlignment = iota
	// AlignLeft represents left alignment (:------).
	AlignLeft
	// AlignCenter represents center alignment (:-----:).
	AlignCenter
	// AlignRight represents right alignment (------:).
	AlignRight
)

type TableOfContentsDepth

type TableOfContentsDepth int

TableOfContentsDepth represents the depth level for table of contents.

const (
	TableOfContentsDepthH1 TableOfContentsDepth = 1
	TableOfContentsDepthH2 TableOfContentsDepth = 2
	TableOfContentsDepthH3 TableOfContentsDepth = 3
	TableOfContentsDepthH4 TableOfContentsDepth = 4
	TableOfContentsDepthH5 TableOfContentsDepth = 5
	TableOfContentsDepthH6 TableOfContentsDepth = 6
)

type TableOptions

type TableOptions struct {
	AutoWrapText      bool
	AutoFormatHeaders bool
}

TableOptions controls formatting when rendering custom tables.

type TableSet

type TableSet struct {
	Header    []string
	Rows      [][]string
	Alignment []TableAlignment
}

TableSet describes the content and layout for a markdown table.

func (*TableSet) ValidateColumns

func (t *TableSet) ValidateColumns() error

ValidateColumns checks if the number of columns in the header and records match.

Jump to

Keyboard shortcuts

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