all repos — grayfriday @ 70c92fefd4330506d553d7a1a173a9ee51bc4df3

blackfriday fork with a few changes

inline helpers put parser arg first
Russ Ross russ@dixie.edu
Wed, 29 Jun 2011 11:21:46 -0600
commit

70c92fefd4330506d553d7a1a173a9ee51bc4df3

parent

3c6f18afc72d1a27f6eb0673a3ee387f4a0548b5

3 files changed, 29 insertions(+), 25 deletions(-)

jump to
M README.mdREADME.md

@@ -71,6 +71,10 @@ * Good performance. I have not done rigorous benchmarking, but

informal testing suggests it is around 3--4x slower than upskirt for general input. It blows away most other markdown processors. +* Thread safe. You can run multiple parsers is different + goroutines without ill effect. There is no dependence on global + shared state. + * Minimal dependencies. Blackfriday only depends on standard library packages in Go. The source code is pretty self-contained, so it is easy to add to any project.
M inline.goinline.go

@@ -45,7 +45,7 @@ i = end

// call the trigger handler := parser.inline[data[end]] - if consumed := handler(out, parser, data, i); consumed == 0 { + if consumed := handler(parser, out, data, i); consumed == 0 { // no action from the callback; buffer the byte for later end = i + 1 } else {

@@ -59,7 +59,7 @@ parser.nesting--

} // single and double emphasis parsing -func inlineEmphasis(out *bytes.Buffer, parser *Parser, data []byte, offset int) int { +func inlineEmphasis(parser *Parser, out *bytes.Buffer, data []byte, offset int) int { data = data[offset:] c := data[0] ret := 0

@@ -70,7 +70,7 @@ // strikethrough only takes two characters '~~'

if c == '~' || isspace(data[1]) { return 0 } - if ret = inlineHelperEmph1(out, parser, data[1:], c); ret == 0 { + if ret = inlineHelperEmph1(parser, out, data[1:], c); ret == 0 { return 0 }

@@ -81,7 +81,7 @@ if len(data) > 3 && data[1] == c && data[2] != c {

if isspace(data[2]) { return 0 } - if ret = inlineHelperEmph2(out, parser, data[2:], c); ret == 0 { + if ret = inlineHelperEmph2(parser, out, data[2:], c); ret == 0 { return 0 }

@@ -92,7 +92,7 @@ if len(data) > 4 && data[1] == c && data[2] == c && data[3] != c {

if c == '~' || isspace(data[3]) { return 0 } - if ret = inlineHelperEmph3(out, parser, data, 3, c); ret == 0 { + if ret = inlineHelperEmph3(parser, out, data, 3, c); ret == 0 { return 0 }

@@ -102,7 +102,7 @@

return 0 } -func inlineCodeSpan(out *bytes.Buffer, parser *Parser, data []byte, offset int) int { +func inlineCodeSpan(parser *Parser, out *bytes.Buffer, data []byte, offset int) int { data = data[offset:] nb := 0

@@ -149,7 +149,7 @@ }

// newline preceded by two spaces becomes <br> // newline without two spaces works when EXTENSION_HARD_LINE_BREAK is enabled -func inlineLineBreak(out *bytes.Buffer, parser *Parser, data []byte, offset int) int { +func inlineLineBreak(parser *Parser, out *bytes.Buffer, data []byte, offset int) int { // remove trailing spaces from out outBytes := out.Bytes() end := len(outBytes)

@@ -174,7 +174,7 @@ return 0

} // '[': parse a link or an image -func inlineLink(out *bytes.Buffer, parser *Parser, data []byte, offset int) int { +func inlineLink(parser *Parser, out *bytes.Buffer, data []byte, offset int) int { // no links allowed inside other links if parser.insideLink { return 0

@@ -436,7 +436,7 @@ return 0

} // '<' when tags or autolinks are allowed -func inlineLAngle(out *bytes.Buffer, parser *Parser, data []byte, offset int) int { +func inlineLAngle(parser *Parser, out *bytes.Buffer, data []byte, offset int) int { data = data[offset:] altype := LINK_TYPE_NOT_AUTOLINK end := tagLength(data, &altype)

@@ -461,7 +461,7 @@

// '\\' backslash escape var escapeChars = []byte("\\`*_{}[]()#+-.!:|&<>") -func inlineEscape(out *bytes.Buffer, parser *Parser, data []byte, offset int) int { +func inlineEscape(parser *Parser, out *bytes.Buffer, data []byte, offset int) int { data = data[offset:] if len(data) > 1 {

@@ -498,7 +498,7 @@ }

// '&' escaped when it doesn't belong to an entity // valid entities are assumed to be anything matching &#?[A-Za-z0-9]+; -func inlineEntity(out *bytes.Buffer, parser *Parser, data []byte, offset int) int { +func inlineEntity(parser *Parser, out *bytes.Buffer, data []byte, offset int) int { data = data[offset:] end := 1

@@ -522,7 +522,7 @@

return end } -func inlineAutoLink(out *bytes.Buffer, parser *Parser, data []byte, offset int) int { +func inlineAutoLink(parser *Parser, out *bytes.Buffer, data []byte, offset int) int { // quick check to rule out most false hits on ':' if parser.insideLink || len(data) < offset+3 || data[offset+1] != '/' || data[offset+2] != '/' { return 0

@@ -834,7 +834,7 @@ }

return 0 } -func inlineHelperEmph1(out *bytes.Buffer, parser *Parser, data []byte, c byte) int { +func inlineHelperEmph1(parser *Parser, out *bytes.Buffer, data []byte, c byte) int { i := 0 // skip one symbol if coming from emph3

@@ -878,7 +878,7 @@

return 0 } -func inlineHelperEmph2(out *bytes.Buffer, parser *Parser, data []byte, c byte) int { +func inlineHelperEmph2(parser *Parser, out *bytes.Buffer, data []byte, c byte) int { i := 0 for i < len(data) {

@@ -910,7 +910,7 @@ }

return 0 } -func inlineHelperEmph3(out *bytes.Buffer, parser *Parser, data []byte, offset int, c byte) int { +func inlineHelperEmph3(parser *Parser, out *bytes.Buffer, data []byte, offset int, c byte) int { i := 0 origData := data data = data[offset:]

@@ -940,7 +940,7 @@ return 0

} case (i+1 < len(data) && data[i+1] == c): // double symbol found, hand over to emph1 - length = inlineHelperEmph1(out, parser, origData[offset-2:], c) + length = inlineHelperEmph1(parser, out, origData[offset-2:], c) if length == 0 { return 0 } else {

@@ -948,7 +948,7 @@ return length - 2

} default: // single symbol found, hand over to emph2 - length = inlineHelperEmph2(out, parser, origData[offset-1:], c) + length = inlineHelperEmph2(parser, out, origData[offset-1:], c) if length == 0 { return 0 } else {
M markdown.gomarkdown.go

@@ -97,14 +97,9 @@ "noscript": true,

"blockquote": true, } -// This struct defines the rendering interface. -// A series of callback functions are registered to form a complete renderer. -// A single interface{} value field is provided, and that value is handed to -// each callback. Leaving a field blank suppresses rendering that type of output -// except where noted. -// +// This interface defines the rendering interface. // This is mostly of interest if you are implementing a new rendering format. -// Most users will use the convenience functions to fill in this structure. +// Currently Html and Latex implementations are provided type Renderer interface { // block-level callbacks BlockCode(out *bytes.Buffer, text []byte, lang string)

@@ -140,8 +135,13 @@ DocumentHeader(out *bytes.Buffer)

DocumentFooter(out *bytes.Buffer) } -type inlineParser func(out *bytes.Buffer, parser *Parser, data []byte, offset int) int +// Callback functions for inline parsing. One such function is defined +// for each character that triggers a response when parsing inline data. +type inlineParser func(parser *Parser, out *bytes.Buffer, data []byte, offset int) int +// The main parser object. +// This is constructed by the Markdown function and +// contains state used during the parsing process. type Parser struct { r Renderer refs map[string]*reference