inline helpers put parser arg first
Russ Ross russ@dixie.edu
Wed, 29 Jun 2011 11:21:46 -0600
3 files changed,
29 insertions(+),
25 deletions(-)
M
README.md
→
README.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.go
→
inline.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.go
→
markdown.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