all repos — grayfriday @ 7bdb82c53a065aab6aae8fa61530b47c6b9f3b87

blackfriday fork with a few changes

new tests pass but old tests now fail...
moshee moshee@displaynone.us
Wed, 26 Jun 2013 15:57:51 +0000
commit

7bdb82c53a065aab6aae8fa61530b47c6b9f3b87

parent

be082a1ef25d4211496762bbbdbab6df7e68c1f3

6 files changed, 119 insertions(+), 59 deletions(-)

jump to
M block.goblock.go

@@ -459,7 +459,7 @@ }

var i int for i = 0; data[i] != '\n'; i++ { - if data[i] != ' ' { + if data[i] != ' ' || data[i] != '\t' { return 0 } }
M html.gohtml.go

@@ -322,18 +322,22 @@ out.Write(text)

out.WriteString("</td>") } -func (options *Html) Footnotes(out *bytes.Buffer, p *parser) { +func (options *Html) Footnotes(out *bytes.Buffer, text func() bool) { out.WriteString("<div class=\"footnotes\">\n") options.HRule(out) - options.List(out, func() bool { - for _, ref := range p.notes { - out.WriteString("<li>\n") - out.Write(ref.title) - out.WriteString("</li>\n") - } - return true - }, LIST_TYPE_ORDERED) + options.List(out, text, LIST_TYPE_ORDERED) out.WriteString("</div>\n") +} + +func (options *Html) FootnoteItem(out *bytes.Buffer, name, text []byte, flags int) { + if flags&LIST_ITEM_CONTAINS_BLOCK != 0 || flags&LIST_ITEM_BEGINNING_OF_LIST != 0 { + doubleSpace(out) + } + out.WriteString(`<li class="`) + out.Write(slugify(name)) + out.WriteString(`">`) + out.Write(text) + out.WriteString("</li>\n") } func (options *Html) List(out *bytes.Buffer, text func() bool, flags int) {
M inline.goinline.go

@@ -193,7 +193,7 @@ var t linkType

if offset > 0 && data[offset-1] == '!' { t = linkImg } else if p.flags&EXTENSION_FOOTNOTES != 0 { - if len(data) > offset && data[offset+1] == '^' { + if len(data)-1 > offset && data[offset+1] == '^' { t = linkDeferredFootnote } }
M inline_test.goinline_test.go

@@ -35,12 +35,13 @@

func doTestsInlineParam(t *testing.T, tests []string, extensions, htmlFlags int) { // catch and report panics var candidate string - defer func() { - if err := recover(); err != nil { - panic(err) - t.Errorf("\npanic while processing [%#v] (%v)\n", candidate, err) - } - }() + /* + defer func() { + if err := recover(); err != nil { + t.Errorf("\npanic while processing [%#v] (%v)\n", candidate, err) + } + }() + */ for i := 0; i+1 < len(tests); i += 2 { input := tests[i]

@@ -506,25 +507,55 @@

func TestFootnotes(t *testing.T) { tests := []string{ "testing footnotes.[^a]\n\n[^a]: This is the note\n", - "", + `<p>testing footnotes.<sup class="footnote-ref" id="fnref:a"><a rel="footnote" href="#fn:a">1</a></sup></p> +<div class="footnotes"> + +<hr /> + +<ol> +<li class="a">This is the note +</li> +</ol> +</div> +`, `testing long[^b] notes. [^b]: Paragraph 1 Paragraph 2 - + ` + "```\n\tsome code\n\t```" + ` Paragraph 3 No longer in the footnote `, - "", + `<p>testing long<sup class="footnote-ref" id="fnref:b"><a rel="footnote" href="#fn:b">1</a></sup> notes.</p> + +<p>No longer in the footnote</p> +<div class="footnotes"> + +<hr /> + +<ol> +<li class="b"><p>Paragraph 1</p> + +<p>Paragraph 2</p> + +<p><code> +some code +</code></p> + +<p>Paragraph 3</p> +</li> +</ol> +</div> +`, `testing[^c] multiple[^d] notes. -[^c]: this is note c +[^c]: this is [note] c omg

@@ -532,15 +563,28 @@

[^d]: this is note d what happens here + +[note]: /link/c + `, - "", - } + `<p>testing<sup class="footnote-ref" id="fnref:c"><a rel="footnote" href="#fn:c">1</a></sup> multiple<sup class="footnote-ref" id="fnref:d"><a rel="footnote" href="#fn:d">2</a></sup> notes.</p> - for _, test := range tests { - if len(test) > 0 { - t.Errorf("Output:\n%s\n", runMarkdownInline(test, EXTENSION_FOOTNOTES, 0)) - } +<p>omg</p> + +<p>what happens here</p> +<div class="footnotes"> + +<hr /> + +<ol> +<li class="c">this is <a href="/link/c">note</a> c +</li> +<li class="d">this is note d +</li> +</ol> +</div> +`, } - //doTestsInlineParam(t, tests, EXTENSION_FOOTNOTES, 0) + doTestsInlineParam(t, tests, EXTENSION_FOOTNOTES, 0) }
M latex.golatex.go

@@ -159,7 +159,11 @@ out.Write(text)

} // TODO: this -func (options *Latex) Footnotes(out *bytes.Buffer, p *parser) { +func (options *Latex) Footnotes(out *bytes.Buffer, text func() bool) { + +} + +func (options *Latex) FootnoteItem(out *bytes.Buffer, name, text []byte, flags int) { }
M markdown.gomarkdown.go

@@ -140,7 +140,8 @@ Paragraph(out *bytes.Buffer, text func() bool)

Table(out *bytes.Buffer, header []byte, body []byte, columnData []int) TableRow(out *bytes.Buffer, text []byte) TableCell(out *bytes.Buffer, text []byte, flags int) - Footnotes(out *bytes.Buffer, p *parser) + Footnotes(out *bytes.Buffer, text func() bool) + FootnoteItem(out *bytes.Buffer, name, text []byte, flags int) // Span-level callbacks AutoLink(out *bytes.Buffer, link []byte, kind int)

@@ -344,10 +345,23 @@

p.r.DocumentHeader(&output) p.block(&output, input) - // NOTE: this is a big hack because we need the parser again for the - // footnotes, so this can't really go in the public interface if p.flags&EXTENSION_FOOTNOTES != 0 && len(p.notes) > 0 { - p.r.Footnotes(&output, p) + p.r.Footnotes(&output, func() bool { + flags := LIST_ITEM_BEGINNING_OF_LIST + for _, ref := range p.notes { + var buf bytes.Buffer + if ref.hasBlock { + flags |= LIST_ITEM_CONTAINS_BLOCK + p.block(&buf, ref.title) + } else { + p.inline(&buf, ref.title) + } + p.r.FootnoteItem(&output, ref.link, buf.Bytes(), flags) + flags &^= LIST_ITEM_BEGINNING_OF_LIST | LIST_ITEM_CONTAINS_BLOCK + } + + return true + }) } p.r.DocumentFooter(&output)

@@ -390,9 +404,10 @@ // are not yet supported.

// References are parsed and stored in this struct. type reference struct { - link []byte - title []byte - noteId int // 0 if not a footnote ref + link []byte + title []byte + noteId int // 0 if not a footnote ref + hasBlock bool } // Check whether or not data starts with a reference link.

@@ -401,7 +416,8 @@ // (in the render struct).

// Returns the number of bytes to skip to move past it, // or zero if the first line is not a reference. func isReference(p *parser, data []byte, tabSize int) int { - println("[", string(data), "]") + if len(data) >= 5 { + } // up to 3 optional leading spaces if len(data) < 4 { return 0

@@ -434,7 +450,6 @@ }

idEnd := i // spacer: colon (space | tab)* newline? (space | tab)* - // /:[ \t]*\n?[ \t]*/ i++ if i >= len(data) || data[i] != ':' { return 0

@@ -461,11 +476,12 @@ linkOffset, linkEnd int

titleOffset, titleEnd int lineEnd int raw []byte + hasBlock bool ) if p.flags&EXTENSION_FOOTNOTES != 0 && noteId > 0 { - linkOffset, linkEnd, raw = scanFootnote(p, data, i, tabSize) - lineEnd = linkEnd + linkOffset + linkOffset, linkEnd, raw, hasBlock = scanFootnote(p, data, i, tabSize) + lineEnd = linkEnd } else { linkOffset, linkEnd, titleOffset, titleEnd, lineEnd = scanLinkRef(p, data, i) }

@@ -476,11 +492,12 @@

// a valid ref has been found ref := &reference{ - noteId: noteId, + noteId: noteId, + hasBlock: hasBlock, } if noteId > 0 { - // reusing the link field for the id since footnotes don't have titles + // reusing the link field for the id since footnotes don't have links ref.link = data[idOffset:idEnd] // if footnote, it's not really a title, it's the contained text ref.title = raw

@@ -570,7 +587,7 @@ // over by one tab if it is indeed a block (just returns the line if it's not).

// blockEnd is the end of the section in the input buffer, and contents is the // extracted text that was shifted over one tab. It will need to be rendered at // the end of the document. -func scanFootnote(p *parser, data []byte, i, indentSize int) (blockStart, blockEnd int, contents []byte) { +func scanFootnote(p *parser, data []byte, i, indentSize int) (blockStart, blockEnd int, contents []byte, hasBlock bool) { if i == 0 { return }

@@ -584,10 +601,7 @@ blockStart = i

// find the end of the line blockEnd = i - for data[i-1] != '\n' { - if i >= len(data) { - return - } + for i < len(data) && data[i-1] != '\n' { i++ }

@@ -600,14 +614,13 @@ blockEnd = i

// process the following lines containsBlankLine := false - hasBlock := false gatherLines: for blockEnd < len(data) { i++ // find the end of this line - for data[i-1] != '\n' { + for i < len(data) && data[i-1] != '\n' { i++ }

@@ -628,27 +641,22 @@ }

// if there were blank lines before this one, insert a new one now if containsBlankLine { - hasBlock = true raw.WriteByte('\n') containsBlankLine = false } // get rid of that first tab, write to buffer raw.Write(data[blockEnd+n : i]) + hasBlock = true blockEnd = i } - rawBytes := raw.Bytes() - println("raw: {" + string(raw.Bytes()) + "}") - buf := new(bytes.Buffer) + if data[blockEnd-1] != '\n' { + raw.WriteByte('\n') + } - if hasBlock { - p.block(buf, rawBytes) - } else { - p.inline(buf, rawBytes) - } - contents = buf.Bytes() + contents = raw.Bytes() return }