A markdown processor written in Go. built for fun.
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
cmd/mark
test
.gitignore
.travis.yml
LICENSE
README.md
grammar.go
lexer.go
lexer_test.go
mark.go
mark_test.go
node.go
parser.go
parser_test.go

README.md

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

$ go get github.com/a8m/mark

Examples

Add to your project:

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:

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

2. usage:

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

or:

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

Documentation

Render

Staic rendering function.

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.

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:

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:

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.

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

Smartypants and Smartfractions

Mark also support smartypants and smartfractions rendering

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