Merge pull request #56 from muhqu/issue/45

Fix for Fenced Code Blocks without a blank line before
This commit is contained in:
Vytautas Šaltenis 2014-04-08 13:00:13 +03:00
commit 1fd57a277b
4 changed files with 37 additions and 7 deletions

View File

@ -86,7 +86,7 @@ func (p *parser) block(out *bytes.Buffer, data []byte) {
// }
// ```
if p.flags&EXTENSION_FENCED_CODE != 0 {
if i := p.fencedCode(out, data); i > 0 {
if i := p.fencedCode(out, data, true); i > 0 {
data = data[i:]
continue
}
@ -584,7 +584,7 @@ func (p *parser) isFencedCode(data []byte, syntax **string, oldmarker string) (s
return
}
func (p *parser) fencedCode(out *bytes.Buffer, data []byte) int {
func (p *parser) fencedCode(out *bytes.Buffer, data []byte, doRender bool) int {
var lang *string
beg, marker := p.isFencedCode(data, &lang, "")
if beg == 0 || beg >= len(data) {
@ -616,7 +616,9 @@ func (p *parser) fencedCode(out *bytes.Buffer, data []byte) int {
}
// verbatim copy to the working buffer
work.Write(data[beg:end])
if doRender {
work.Write(data[beg:end])
}
beg = end
}
@ -625,7 +627,9 @@ func (p *parser) fencedCode(out *bytes.Buffer, data []byte) int {
syntax = *lang
}
p.r.BlockCode(out, work.Bytes(), syntax)
if doRender {
p.r.BlockCode(out, work.Bytes(), syntax)
}
return beg
}

View File

@ -31,7 +31,7 @@ func doTestsBlock(t *testing.T, tests []string, extensions int) {
var candidate string
defer func() {
if err := recover(); err != nil {
t.Errorf("\npanic while processing [%#v]\n", candidate)
t.Errorf("\npanic while processing [%#v]: %s\n", candidate, err)
}
}()
@ -642,6 +642,15 @@ func TestFencedCodeBlock(t *testing.T) {
" ``` oz\nleading spaces\n ```\n",
"<pre><code>``` oz\n</code></pre>\n\n<p>leading spaces\n ```</p>\n",
"Bla bla\n\n``` oz\ncode blocks breakup paragraphs\n```\n\nBla Bla\n",
"<p>Bla bla</p>\n\n<pre><code class=\"oz\">code blocks breakup paragraphs\n</code></pre>\n\n<p>Bla Bla</p>\n",
"Some text before a fenced code block\n``` oz\ncode blocks breakup paragraphs\n```\nAnd some text after a fenced code block",
"<p>Some text before a fenced code block</p>\n\n<pre><code class=\"oz\">code blocks breakup paragraphs\n</code></pre>\n\n<p>And some text after a fenced code block</p>\n",
"`",
"<p>`</p>\n",
}
doTestsBlock(t, tests, EXTENSION_FENCED_CODE)
}

View File

@ -305,6 +305,7 @@ func Markdown(input []byte, renderer Renderer, extensions int) []byte {
// - expand tabs
// - normalize newlines
// - copy everything else
// - add missing newlines before fenced code blocks
func firstPass(p *parser, input []byte) []byte {
var out bytes.Buffer
tabSize := TAB_SIZE_DEFAULT
@ -312,6 +313,8 @@ func firstPass(p *parser, input []byte) []byte {
tabSize = TAB_SIZE_EIGHT
}
beg, end := 0, 0
lastLineWasBlank := false
lastFencedCodeBlockEnd := 0
for beg < len(input) { // iterate over lines
if end = isReference(p, input[beg:], tabSize); end > 0 {
beg += end
@ -321,6 +324,17 @@ func firstPass(p *parser, input []byte) []byte {
end++
}
if p.flags&EXTENSION_FENCED_CODE != 0 {
// when last line was none blank and a fenced code block comes after
if !lastLineWasBlank && beg >= lastFencedCodeBlockEnd {
if i := p.fencedCode(&out, append(input[beg:], '\n'), false); i > 0 {
out.WriteByte('\n') // need to inject additional linebreak
lastFencedCodeBlockEnd = beg + i
}
}
lastLineWasBlank = end == beg
}
// add the line body if present
if end > beg {
expandTabs(&out, input[beg:end], tabSize)

View File

@ -50,18 +50,21 @@ func doTestsReference(t *testing.T, files []string, flag int) {
}
expected := string(expectedBytes)
// fmt.Fprintf(os.Stderr, "processing %s ...", filename)
actual := string(runMarkdownReference(input, flag))
if actual != expected {
t.Errorf("\n [%#v]\nExpected[%#v]\nActual [%#v]",
basename+".text", expected, actual)
}
// fmt.Fprintf(os.Stderr, " ok\n")
// now test every prefix of every input to check for
// bounds checking
if !testing.Short() {
start := 0
for end := start + 1; end <= len(input); end++ {
start, max := 0, len(input)
for end := start + 1; end <= max; end++ {
candidate = input[start:end]
// fmt.Fprintf(os.Stderr, " %s %d:%d/%d\n", filename, start, end, max)
_ = runMarkdownReference(candidate, flag)
}
}