mirror of
https://github.com/42wim/matterbridge.git
synced 2024-11-22 02:32:02 -08:00
113 lines
2.4 KiB
Go
113 lines
2.4 KiB
Go
|
// Copyright 2015 The Authors. All rights reserved.
|
|||
|
// Use of this source code is governed by a BSD-style
|
|||
|
// license that can be found in the LICENSE file.
|
|||
|
|
|||
|
// Package markdown provides CommonMark-compliant markdown parser and renderer.
|
|||
|
package markdown
|
|||
|
|
|||
|
import (
|
|||
|
"bytes"
|
|||
|
"io"
|
|||
|
)
|
|||
|
|
|||
|
type Markdown struct {
|
|||
|
options
|
|||
|
Block ParserBlock
|
|||
|
Inline ParserInline
|
|||
|
renderOptions RenderOptions
|
|||
|
}
|
|||
|
|
|||
|
type RenderOptions struct {
|
|||
|
LangPrefix string // CSS language class prefix for fenced blocks
|
|||
|
XHTML bool // render as XHTML instead of HTML
|
|||
|
Breaks bool // convert \n in paragraphs into <br>
|
|||
|
Nofollow bool // add rel="nofollow" to the links
|
|||
|
}
|
|||
|
|
|||
|
type options struct {
|
|||
|
HTML bool // allow raw HTML in the markup
|
|||
|
Tables bool // GFM tables
|
|||
|
Linkify bool // autoconvert URL-like text to links
|
|||
|
Typographer bool // enable some typographic replacements
|
|||
|
Quotes [4]string // double/single quotes replacement pairs
|
|||
|
MaxNesting int // maximum nesting level
|
|||
|
}
|
|||
|
|
|||
|
type Environment struct {
|
|||
|
References map[string]map[string]string
|
|||
|
}
|
|||
|
|
|||
|
type CoreRule func(*StateCore)
|
|||
|
|
|||
|
var coreRules []CoreRule
|
|||
|
|
|||
|
func New(opts ...option) *Markdown {
|
|||
|
m := &Markdown{
|
|||
|
options: options{
|
|||
|
Tables: true,
|
|||
|
Linkify: true,
|
|||
|
Typographer: true,
|
|||
|
Quotes: [4]string{"“", "”", "‘", "’"},
|
|||
|
MaxNesting: 20,
|
|||
|
},
|
|||
|
renderOptions: RenderOptions{LangPrefix: "language-"},
|
|||
|
}
|
|||
|
for _, opt := range opts {
|
|||
|
opt(m)
|
|||
|
}
|
|||
|
return m
|
|||
|
}
|
|||
|
|
|||
|
func (m *Markdown) Parse(src []byte) []Token {
|
|||
|
if len(src) == 0 {
|
|||
|
return nil
|
|||
|
}
|
|||
|
|
|||
|
s := &StateCore{
|
|||
|
Md: m,
|
|||
|
Env: &Environment{},
|
|||
|
}
|
|||
|
s.Tokens = m.Block.Parse(src, m, s.Env)
|
|||
|
|
|||
|
for _, r := range coreRules {
|
|||
|
r(s)
|
|||
|
}
|
|||
|
return s.Tokens
|
|||
|
}
|
|||
|
|
|||
|
func (m *Markdown) Render(w io.Writer, src []byte) error {
|
|||
|
if len(src) == 0 {
|
|||
|
return nil
|
|||
|
}
|
|||
|
|
|||
|
return NewRenderer(w).Render(m.Parse(src), m.renderOptions)
|
|||
|
}
|
|||
|
|
|||
|
func (m *Markdown) RenderTokens(w io.Writer, tokens []Token) error {
|
|||
|
if len(tokens) == 0 {
|
|||
|
return nil
|
|||
|
}
|
|||
|
|
|||
|
return NewRenderer(w).Render(tokens, m.renderOptions)
|
|||
|
}
|
|||
|
|
|||
|
func (m *Markdown) RenderToString(src []byte) string {
|
|||
|
if len(src) == 0 {
|
|||
|
return ""
|
|||
|
}
|
|||
|
|
|||
|
var buf bytes.Buffer
|
|||
|
NewRenderer(&buf).Render(m.Parse(src), m.renderOptions)
|
|||
|
return buf.String()
|
|||
|
}
|
|||
|
|
|||
|
func (m *Markdown) RenderTokensToString(tokens []Token) string {
|
|||
|
if len(tokens) == 0 {
|
|||
|
return ""
|
|||
|
}
|
|||
|
|
|||
|
var buf bytes.Buffer
|
|||
|
NewRenderer(&buf).Render(tokens, m.renderOptions)
|
|||
|
return buf.String()
|
|||
|
}
|