mirror of
https://github.com/russross/blackfriday.git
synced 2024-03-22 13:40:34 +08:00
Merge pull request #56 from muhqu/issue/45
Fix for Fenced Code Blocks without a blank line before
This commit is contained in:
commit
1fd57a277b
12
block.go
12
block.go
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
14
markdown.go
14
markdown.go
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user