From d8644af0a695074a1004b687fadcea72f1abd166 Mon Sep 17 00:00:00 2001 From: ageekymonk Date: Tue, 3 Oct 2017 08:38:27 +1100 Subject: [PATCH 1/2] 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 --- goorgeous.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/goorgeous.go b/goorgeous.go index f1b2671..21acfe2 100644 --- a/goorgeous.go +++ b/goorgeous.go @@ -525,7 +525,7 @@ func IsKeyword(data []byte) bool { // ~~ Comments func isComment(data []byte) bool { - return charMatches(data[0], '#') && charMatches(data[1], ' ') + return len(data) > 1 && charMatches(data[0], '#') && charMatches(data[1], ' ') } func (p *parser) generateComment(out *bytes.Buffer, data []byte) { From 715f7ec08c693067a1be2a219e57eafbda3a8988 Mon Sep 17 00:00:00 2001 From: ageekymonk Date: Tue, 3 Oct 2017 22:18:06 +1100 Subject: [PATCH 2/2] Adding support for multiline paragraphs within footnotes. --- goorgeous.go | 29 ++++++++++++++++++++++++----- goorgeous_test.go | 33 ++++++++++++++++++++++----------- 2 files changed, 46 insertions(+), 16 deletions(-) diff --git a/goorgeous.go b/goorgeous.go index 21acfe2..3351583 100644 --- a/goorgeous.go +++ b/goorgeous.go @@ -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() { @@ -100,6 +102,9 @@ func OrgOptions(input []byte, renderer blackfriday.Renderer) []byte { } inFixedWidthArea = false tmpBlock.Reset() + case inFootNote: + inFootNote = false + curFootNoteId = "" } } @@ -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: @@ -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): diff --git a/goorgeous_test.go b/goorgeous_test.go index 0b7ab13..92bed98 100644 --- a/goorgeous_test.go +++ b/goorgeous_test.go @@ -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??", - "

Test 11 and Test 2[fn: 2] and Test 32 also test lettres3 then final test4

\n\n

Footnotes

\n
\n\n
\n\n
    \n
  1. Test 1
  2. \n\n
  3. Test 3
  4. \n\n
  5. what?
  6. \n\n
  7. DEFINITION NOT FOUND
  8. \n
\n
\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??", + "

Test 11 and Test 2[fn: 2] and Test 32 also test lettres3 then final test4

\n\n

Footnotes

\n
\n\n
\n\n
    \n
  1. Test 1
  2. \n\n
  3. Test 3
  4. \n\n
  5. what?
  6. \n\n
  7. DEFINITION NOT FOUND
  8. \n
\n
\n", + }, + "multiline": { + "Test 1[fn:1]\n\n* Footnotes\n\n[fn:1] Test 1\nMore details", + "

Test 11

\n\n

Footnotes

\n
\n\n
\n\n
    \n
  1. Test 1 More details
  2. \n
\n
\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 = "" + var parameters blackfriday.HtmlRendererParameters + parameters.FootnoteReturnLinkContents = "" - 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) {