GitPedia

Mark

A markdown processor written in Go. built for fun.

From a8m·Updated January 18, 2026·View on GitHub·
·Archived

Archived. use https://github.com/russross/blackfriday instead The project is written primarily in Go, distributed under the MIT License license, first published in 2015. Key topics include: go, markdown, markdown-processor, processor.

Archived. use https://github.com/russross/blackfriday instead

Mark Test coverage Build status Go doc license

A markdown processor written in Go. built for fun.

Mark is a markdown processor that supports all the features of GFM, smartypants and smart-fractions rendering.
It was built with a nice-ish concurrency model that fully inspired from Rob Pike - Lexical Scanning talk and marked project.
Please note that any contribution is welcomed and appreciated, so feel free to take some task here.

Table of contents:

Get Started

Installation

sh
$ go get github.com/a8m/mark

Examples

Add to your project:

go
import ( "fmt" "github.com/a8m/mark" ) func main() { html := mark.Render("I am using __markdown__.") fmt.Println(html) // <p>I am using <strong>markdown</strong>.</p> }

or using as a command line tool:

1. install:

sh
$ go get github.com/a8m/mark/cmd/mark

2. usage:

sh
$ echo 'hello __world__...' | mark -smartypants

or:

sh
$ mark -i hello.text -o hello.html

Documentation

Render

Staic rendering function.

go
html := mark.Render("I am using __markdown__.") fmt.Println(html) // <p>I am using <strong>markdown</strong>.</p>
Mark
New

New get string as an input, and mark.Options as configuration and return a new Mark.

go
m := mark.New("hello world...", &mark.Options{ Smartypants: true, }) fmt.Println(m.Render()) // <p>hello world…</p> // Note: you can instantiate it like so: mark.New("...", nil) to get the default options.
Mark.AddRenderFn

AddRenderFn let you pass NodeType, and RenderFn function and override the default Node rendering.
To get all Nodes type and their fields/methods, see the full documentation: go-doc

Example 1:

go
m := mark.New("hello", nil) m.AddRenderFn(mark.NodeParagraph, func(node mark.Node) (s string) { p, _ := node.(*mark.ParagraphNode) s += "<p class=\"mv-msg\">" for _, n := range p.Nodes { s += n.Render() } s += "</p>" return }) fmt.Println(m.Render()) // <p class="mv-msg">hello</p>

Example 2:

go
m := mark.New("# Hello world", &mark.Options{ Smartypants: true, Fractions: true, }) m.AddRenderFn(mark.NodeHeading, func(node mark.Node) string { h, _ := node.(*mark.HeadingNode) return fmt.Sprintf("<angular-heading-directive level=\"%d\" text=\"%s\"/>", h.Level, h.Text) }) fmt.Println(m.Render()) // <angular-heading-directive level="1" text="Hello world"/>
Mark.Render

Parse and render input.

go
m := mark.New("hello", nil) fmt.Println(m.Render()) // <p>hello</p>

Smartypants and Smartfractions

Mark also support smartypants and smartfractions rendering

go
func main() { opts := mark.DefaultOptions() opts.Smartypants = true opts.Fractions = true m := mark.New("'hello', 1/2 beer please...", opts) fmt.Println(m.Render()) // ‘hello’, ½ beer please… }

Todo

  • Commonmark support v0.2
  • Expand documentation
  • Configuration options
    • gfm, table
    • heading(auto hashing)

License

MIT

Contributors

Showing top 1 contributor by commit count.

View all contributors on GitHub →

This article is auto-generated from a8m/mark via the GitHub API.Last fetched: 6/21/2026