100 lines
2.9 KiB
Go
100 lines
2.9 KiB
Go
package main
|
|
|
|
import (
|
|
"bufio"
|
|
"bytes"
|
|
"io"
|
|
"regexp"
|
|
"strings"
|
|
)
|
|
|
|
var (
|
|
boldItalicReg = regexp.MustCompile(`\*\*\*(.*?)\*\*\*`)
|
|
boldReg = regexp.MustCompile(`\*\*(.*?)\*\*`)
|
|
italicReg = regexp.MustCompile(`\*(.*?)\*`)
|
|
strikeReg = regexp.MustCompile(`\~\~(.*?)\~\~`)
|
|
underscoreReg = regexp.MustCompile(`__(.*?)__`)
|
|
anchorReg = regexp.MustCompile(`\[(.*?)\]\((.*?)\)[^\)]`)
|
|
imgReg = regexp.MustCompile(`\!\[(.*?)\]\((.*?)\)[^\)]`)
|
|
escapeReg = regexp.MustCompile(`^\>(\s|)`)
|
|
blockquoteReg = regexp.MustCompile(`\>\;(.*?)$`)
|
|
backtipReg = regexp.MustCompile("`(.*?)`")
|
|
|
|
h1Reg = regexp.MustCompile(`^#(\s|)(.*?)$`)
|
|
h2Reg = regexp.MustCompile(`^##(\s|)(.*?)$`)
|
|
h3Reg = regexp.MustCompile(`^###(\s|)(.*?)$`)
|
|
h4Reg = regexp.MustCompile(`^####(\s|)(.*?)$`)
|
|
h5Reg = regexp.MustCompile(`^#####(\s|)(.*?)$`)
|
|
h6Reg = regexp.MustCompile(`^######(\s|)(.*?)$`)
|
|
)
|
|
|
|
func NewMarkdown(input io.Reader) string {
|
|
buf := bytes.NewBuffer(nil)
|
|
|
|
inParagraph := false
|
|
|
|
scanner := bufio.NewScanner(input)
|
|
for scanner.Scan() {
|
|
|
|
line := bytes.TrimSpace(scanner.Bytes())
|
|
if len(line) == 0 {
|
|
buf.WriteByte('\n')
|
|
if inParagraph {
|
|
buf.WriteString("</p>")
|
|
}
|
|
continue
|
|
}
|
|
|
|
// wrap bold and italic text in "<b>" and "<i>" elements
|
|
line = boldItalicReg.ReplaceAll(line, []byte(`<b><i>$1</i></b>`))
|
|
line = boldReg.ReplaceAll(line, []byte(`<b>$1</b>`))
|
|
line = italicReg.ReplaceAll(line, []byte(`<i>$1</i>`))
|
|
// wrap strikethrough text in "<s>" tags
|
|
line = strikeReg.ReplaceAll(line, []byte(`<s>$1</s>`))
|
|
// wrap underscored text in "<u>" tags
|
|
line = underscoreReg.ReplaceAll(line, []byte(`<u>$1</u>`))
|
|
// convert images to image tags
|
|
line = imgReg.ReplaceAll(line, []byte(`<img src="$2" alt="$1">`))
|
|
// convert links to anchor tags
|
|
line = anchorReg.ReplaceAll(line, []byte(`<a href="$2" class="inline-link">$1</a> `))
|
|
// escape and wrap blockquotes in "<blockquote>" tags
|
|
line = escapeReg.ReplaceAll(line, []byte(`>`))
|
|
line = blockquoteReg.ReplaceAll(line, []byte(`<blockquote>$1</blockquote>`))
|
|
// wrap the content of backticks inside of "<code>" tags
|
|
line = backtipReg.ReplaceAll(line, []byte(`<code>$1</code>`))
|
|
// convert headings
|
|
if line[0] == '#' {
|
|
count := bytes.Count(line, []byte(`#`))
|
|
switch count {
|
|
case 1:
|
|
line = h1Reg.ReplaceAll(line, []byte(`<h1>$2</h1>`))
|
|
case 2:
|
|
line = h2Reg.ReplaceAll(line, []byte(`<h2>$2</h2>`))
|
|
case 3:
|
|
line = h3Reg.ReplaceAll(line, []byte(`<h3>$2</h3>`))
|
|
case 4:
|
|
line = h4Reg.ReplaceAll(line, []byte(`<h4>$2</h4>`))
|
|
case 5:
|
|
line = h5Reg.ReplaceAll(line, []byte(`<h5>$2</h5>`))
|
|
case 6:
|
|
line = h6Reg.ReplaceAll(line, []byte(`<h6>$2</h6>`))
|
|
}
|
|
} else {
|
|
if !inParagraph {
|
|
buf.WriteString("<p>")
|
|
}
|
|
buf.WriteByte(' ')
|
|
inParagraph = true
|
|
}
|
|
buf.Write(line)
|
|
buf.WriteByte('\n')
|
|
}
|
|
return buf.String()
|
|
}
|
|
|
|
func ParseMarkdown(md string) string {
|
|
return NewMarkdown(strings.NewReader(md))
|
|
|
|
}
|
|
|