Skip to content

Commit

Permalink
Adding support for multiline paragraphs within footnotes (#66)
Browse files Browse the repository at this point in the history
* Checking the length of the field before trying to access the content as this is
causing a crash when the first character is # without any subsequent characters

* Adding support for multiline paragraphs within footnotes.
  • Loading branch information
ageekymonk authored and chaseadamsio committed Oct 10, 2017
1 parent 7daffad commit d20fff1
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 16 deletions.
29 changes: 24 additions & 5 deletions goorgeous.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ func OrgOptions(input []byte, renderer blackfriday.Renderer) []byte {
inList := false
inTable := false
inFixedWidthArea := false
inFootNote := false
curFootNoteId := ""
var tmpBlock bytes.Buffer

for scanner.Scan() {
Expand Down Expand Up @@ -100,6 +102,9 @@ func OrgOptions(input []byte, renderer blackfriday.Renderer) []byte {
}
inFixedWidthArea = false
tmpBlock.Reset()
case inFootNote:
inFootNote = false
curFootNoteId = ""
}

}
Expand Down Expand Up @@ -133,6 +138,9 @@ func OrgOptions(input []byte, renderer blackfriday.Renderer) []byte {
}
inFixedWidthArea = false
tmpBlock.Reset()
case inFootNote:
inFootNote = false
curFootNoteId = ""
case marker != "":
tmpBlock.WriteByte('\n')
default:
Expand Down Expand Up @@ -189,11 +197,22 @@ func OrgOptions(input []byte, renderer blackfriday.Renderer) []byte {
marker = string(matches[2])
syntax = string(matches[3])
}
case isFootnoteDef(data):
matches := reFootnoteDef.FindSubmatch(data)
for i := range p.notes {
if p.notes[i].id == string(matches[1]) {
p.notes[i].def = string(matches[2])
case isFootnoteDef(data) || inFootNote:
if isFootnoteDef(data) {
matches := reFootnoteDef.FindSubmatch(data)
for i := range p.notes {
if p.notes[i].id == string(matches[1]) {
p.notes[i].def = string(matches[2])
inFootNote = true
curFootNoteId = string(matches[1])
}
}
} else if inFootNote {
for i := range p.notes {
if p.notes[i].id == curFootNoteId {
p.notes[i].def += " "
p.notes[i].def += string(data)
}
}
}
case isTable(data):
Expand Down
33 changes: 22 additions & 11 deletions goorgeous_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -405,22 +405,33 @@ func TestRenderingLinksAndImages(t *testing.T) {
}

func TestRenderingFootnotes(t *testing.T) {
testCases := testCase{"Test 1[fn:1] and Test 2[fn: 2] and Test 3[fn:3] also test lettres[fn:let] then final test[fn:4]\n\n[fn:let] what?\n\n\n[fn:6] And test it[fn:7].\n\n* Footnotes\n\n[fn:1] Test 1\n\n[fn:3] Test 3\n\n[fn:2] Test2\n\n[fn:5] missing?\n\n[fn:6] Six?\n\n[fn:7] Seven??",
"<p>Test 1<sup class=\"footnote-ref\" id=\"fnref:1\"><a rel=\"footnote\" href=\"#fn:1\">1</a></sup> and Test 2[fn: 2] and Test 3<sup class=\"footnote-ref\" id=\"fnref:3\"><a rel=\"footnote\" href=\"#fn:3\">2</a></sup> also test lettres<sup class=\"footnote-ref\" id=\"fnref:let\"><a rel=\"footnote\" href=\"#fn:let\">3</a></sup> then final test<sup class=\"footnote-ref\" id=\"fnref:4\"><a rel=\"footnote\" href=\"#fn:4\">4</a></sup></p>\n\n<h1 id=\"footnotes\">Footnotes</h1>\n<div class=\"footnotes\">\n\n<hr />\n\n<ol>\n<li id=\"fn:1\">Test 1 <a class=\"footnote-return\" href=\"#fnref:1\"><sup>↩</sup></a></li>\n\n<li id=\"fn:3\">Test 3 <a class=\"footnote-return\" href=\"#fnref:3\"><sup>↩</sup></a></li>\n\n<li id=\"fn:let\">what? <a class=\"footnote-return\" href=\"#fnref:let\"><sup>↩</sup></a></li>\n\n<li id=\"fn:4\">DEFINITION NOT FOUND <a class=\"footnote-return\" href=\"#fnref:4\"><sup>↩</sup></a></li>\n</ol>\n</div>\n"}
testCases := map[string]testCase{
"simple": {
"Test 1[fn:1] and Test 2[fn: 2] and Test 3[fn:3] also test lettres[fn:let] then final test[fn:4]\n\n[fn:let] what?\n\n\n[fn:6] And test it[fn:7].\n\n* Footnotes\n\n[fn:1] Test 1\n\n[fn:3] Test 3\n\n[fn:2] Test2\n\n[fn:5] missing?\n\n[fn:6] Six?\n\n[fn:7] Seven??",
"<p>Test 1<sup class=\"footnote-ref\" id=\"fnref:1\"><a rel=\"footnote\" href=\"#fn:1\">1</a></sup> and Test 2[fn: 2] and Test 3<sup class=\"footnote-ref\" id=\"fnref:3\"><a rel=\"footnote\" href=\"#fn:3\">2</a></sup> also test lettres<sup class=\"footnote-ref\" id=\"fnref:let\"><a rel=\"footnote\" href=\"#fn:let\">3</a></sup> then final test<sup class=\"footnote-ref\" id=\"fnref:4\"><a rel=\"footnote\" href=\"#fn:4\">4</a></sup></p>\n\n<h1 id=\"footnotes\">Footnotes</h1>\n<div class=\"footnotes\">\n\n<hr />\n\n<ol>\n<li id=\"fn:1\">Test 1 <a class=\"footnote-return\" href=\"#fnref:1\"><sup>↩</sup></a></li>\n\n<li id=\"fn:3\">Test 3 <a class=\"footnote-return\" href=\"#fnref:3\"><sup>↩</sup></a></li>\n\n<li id=\"fn:let\">what? <a class=\"footnote-return\" href=\"#fnref:let\"><sup>↩</sup></a></li>\n\n<li id=\"fn:4\">DEFINITION NOT FOUND <a class=\"footnote-return\" href=\"#fnref:4\"><sup>↩</sup></a></li>\n</ol>\n</div>\n",
},
"multiline": {
"Test 1[fn:1]\n\n* Footnotes\n\n[fn:1] Test 1\nMore details",
"<p>Test 1<sup class=\"footnote-ref\" id=\"fnref:1\"><a rel=\"footnote\" href=\"#fn:1\">1</a></sup></p>\n\n<h1 id=\"footnotes\">Footnotes</h1>\n<div class=\"footnotes\">\n\n<hr />\n\n<ol>\n<li id=\"fn:1\">Test 1 More details <a class=\"footnote-return\" href=\"#fnref:1\"><sup>↩</sup></a></li>\n</ol>\n</div>\n",
},
}

flags := blackfriday.HTML_USE_XHTML
flags |= blackfriday.LIST_ITEM_BEGINNING_OF_LIST
flags |= blackfriday.HTML_FOOTNOTE_RETURN_LINKS
for caseName, tc := range testCases {
flags := blackfriday.HTML_USE_XHTML
flags |= blackfriday.LIST_ITEM_BEGINNING_OF_LIST
flags |= blackfriday.HTML_FOOTNOTE_RETURN_LINKS

var parameters blackfriday.HtmlRendererParameters
parameters.FootnoteReturnLinkContents = "<sup>↩</sup>"
var parameters blackfriday.HtmlRendererParameters
parameters.FootnoteReturnLinkContents = "<sup>↩</sup>"

renderer := blackfriday.HtmlRendererWithParameters(flags, "", "", parameters)
out := Org([]byte(testCases.in), renderer)
renderer := blackfriday.HtmlRendererWithParameters(flags, "", "", parameters)

if !bytes.Equal(out, []byte(testCases.expected)) {
t.Errorf("Footnote for Org() from: \n %s \n result: \n %s\n wants:\n %s", testCases.in, string(out), testCases.expected)
out := Org([]byte(tc.in), renderer)
if !bytes.Equal(out, []byte(tc.expected)) {
t.Errorf("%s: Footnote for Org() from: \n %s \n result: \n %s\n wants:\n %s", caseName, tc.in, string(out), tc.expected)
}
}

}

func TestRenderingBlock(t *testing.T) {
Expand Down

0 comments on commit d20fff1

Please sign in to comment.