Merge pull request #225 from russross/issue-165

Implement support for CDATA section
This commit is contained in:
Vytautas Šaltenis 2015-12-25 13:14:44 +02:00
commit b8031576aa
3 changed files with 79 additions and 21 deletions

View File

@ -320,6 +320,11 @@ func (p *parser) html(out *bytes.Buffer, data []byte, doRender bool) int {
return size
}
// check for HTML CDATA
if size := p.htmlCDATA(out, data, doRender); size > 0 {
return size
}
// no special case recognized
return 0
}
@ -397,12 +402,10 @@ func (p *parser) html(out *bytes.Buffer, data []byte, doRender bool) int {
return i
}
// HTML comment, lax form
func (p *parser) htmlComment(out *bytes.Buffer, data []byte, doRender bool) int {
i := p.inlineHtmlComment(out, data)
// needs to end with a blank line
if j := p.isEmpty(data[i:]); j > 0 {
size := i + j
func (p *parser) renderHTMLBlock(out *bytes.Buffer, data []byte, start int, doRender bool) int {
// html block needs to end with a blank line
if i := p.isEmpty(data[start:]); i > 0 {
size := start + i
if doRender {
// trim trailing newlines
end := size
@ -416,6 +419,35 @@ func (p *parser) htmlComment(out *bytes.Buffer, data []byte, doRender bool) int
return 0
}
// HTML comment, lax form
func (p *parser) htmlComment(out *bytes.Buffer, data []byte, doRender bool) int {
i := p.inlineHTMLComment(out, data)
return p.renderHTMLBlock(out, data, i, doRender)
}
// HTML CDATA section
func (p *parser) htmlCDATA(out *bytes.Buffer, data []byte, doRender bool) int {
const cdataTag = "<![cdata["
const cdataTagLen = len(cdataTag)
if len(data) < cdataTagLen+1 {
return 0
}
if !bytes.Equal(bytes.ToLower(data[:cdataTagLen]), []byte(cdataTag)) {
return 0
}
i := cdataTagLen
// scan for an end-of-comment marker, across lines if necessary
for i < len(data) && !(data[i-2] == ']' && data[i-1] == ']' && data[i] == '>') {
i++
}
i++
// no end-of-comment marker
if i >= len(data) {
return 0
}
return p.renderHTMLBlock(out, data, i, doRender)
}
// HR, which is the only self-closing block tag considered
func (p *parser) htmlHr(out *bytes.Buffer, data []byte, doRender bool) int {
if data[0] != '<' || (data[1] != 'h' && data[1] != 'H') || (data[2] != 'r' && data[2] != 'R') {
@ -432,19 +464,7 @@ func (p *parser) htmlHr(out *bytes.Buffer, data []byte, doRender bool) int {
}
if data[i] == '>' {
i++
if j := p.isEmpty(data[i:]); j > 0 {
size := i + j
if doRender {
// trim newlines
end := size
for end > 0 && data[end-1] == '\n' {
end--
}
p.r.BlockHtml(out, data[:end])
}
return size
}
return p.renderHTMLBlock(out, data, i+1, doRender)
}
return 0

View File

@ -1530,3 +1530,41 @@ func TestBlockComments(t *testing.T) {
}
doTestsBlock(t, tests, 0)
}
func TestCDATA(t *testing.T) {
var tests = []string{
"Some text\n\n<![CDATA[foo]]>\n",
"<p>Some text</p>\n\n<![CDATA[foo]]>\n",
"CDATA ]]\n\n<![CDATA[]]]]>\n",
"<p>CDATA ]]</p>\n\n<![CDATA[]]]]>\n",
"CDATA >\n\n<![CDATA[>]]>\n",
"<p>CDATA &gt;</p>\n\n<![CDATA[>]]>\n",
"Lots of text\n\n<![CDATA[lots of te><t\non\nseveral\nlines]]>\n",
"<p>Lots of text</p>\n\n<![CDATA[lots of te><t\non\nseveral\nlines]]>\n",
"<![CDATA[>]]>\n",
"<![CDATA[>]]>\n",
}
doTestsBlock(t, tests, 0)
doTestsBlock(t, []string{
"``` html\n<![CDATA[foo]]>\n```\n",
"<pre><code class=\"language-html\">&lt;![CDATA[foo]]&gt;\n</code></pre>\n",
"<![CDATA[\n``` python\ndef func():\n pass\n```\n]]>\n",
"<![CDATA[\n``` python\ndef func():\n pass\n```\n]]>\n",
`<![CDATA[
> def func():
> pass
]]>
`,
`<![CDATA[
> def func():
> pass
]]>
`,
}, EXTENSION_FENCED_CODE)
}

View File

@ -575,7 +575,7 @@ func link(p *parser, out *bytes.Buffer, data []byte, offset int) int {
return i
}
func (p *parser) inlineHtmlComment(out *bytes.Buffer, data []byte) int {
func (p *parser) inlineHTMLComment(out *bytes.Buffer, data []byte) int {
if len(data) < 5 {
return 0
}
@ -599,7 +599,7 @@ func leftAngle(p *parser, out *bytes.Buffer, data []byte, offset int) int {
data = data[offset:]
altype := LINK_TYPE_NOT_AUTOLINK
end := tagLength(data, &altype)
if size := p.inlineHtmlComment(out, data); size > 0 {
if size := p.inlineHTMLComment(out, data); size > 0 {
end = size
}
if end > 2 {