all repos — grayfriday @ 7c8f3c1dcc7e0f87c62af34ee193fc3251f6d8a4

blackfriday fork with a few changes

Merge pull request #125 from halostatue/auto-header-id

Add a flag to turn on header ID generation.
Vytautas Ĺ altenis vytas@rtfb.lt
Tue, 28 Oct 2014 16:34:49 +0200
commit

7c8f3c1dcc7e0f87c62af34ee193fc3251f6d8a4

parent

411a019e2d24ef772cfd0d7dddfdf1f0845a7a0c

3 files changed, 114 insertions(+), 2 deletions(-)

jump to
M block.goblock.go

@@ -13,7 +13,10 @@ //

package blackfriday -import "bytes" +import ( + "bytes" + "unicode" +) // Parse block-level data. // Note: this function and many that it calls assume that

@@ -223,6 +226,9 @@ for end > 0 && data[end-1] == ' ' {

end-- } if end > i { + if id == "" && p.flags&EXTENSION_AUTO_HEADER_IDS != 0 { + id = createSanitizedAnchorName(string(data[i:end])) + } work := func() bool { p.inline(out, data[i:end]) return true

@@ -1267,7 +1273,13 @@ pp.inline(o, d)

return true } }(out, p, data[prev:eol]) - p.r.Header(out, work, level, "") + + id := "" + if p.flags&EXTENSION_AUTO_HEADER_IDS != 0 { + id = createSanitizedAnchorName(string(data[prev:eol])) + } + + p.r.Header(out, work, level, id) // find the end of the underline for data[i] != '\n' {

@@ -1313,3 +1325,16 @@

p.renderParagraph(out, data[:i]) return i } + +func createSanitizedAnchorName(text string) string { + var anchorName []rune + for _, r := range []rune(text) { + switch { + case r == ' ': + anchorName = append(anchorName, '-') + case unicode.IsLetter(r) || unicode.IsNumber(r): + anchorName = append(anchorName, unicode.ToLower(r)) + } + } + return string(anchorName) +}
M block_test.goblock_test.go

@@ -237,6 +237,48 @@ }

doTestsBlock(t, tests, EXTENSION_HEADER_IDS) } +func TestPrefixAutoHeaderIdExtension(t *testing.T) { + var tests = []string{ + "# Header 1\n", + "<h1 id=\"header-1\">Header 1</h1>\n", + + "# Header 1 \n", + "<h1 id=\"header-1\">Header 1</h1>\n", + + "## Header 2\n", + "<h2 id=\"header-2\">Header 2</h2>\n", + + "### Header 3\n", + "<h3 id=\"header-3\">Header 3</h3>\n", + + "#### Header 4\n", + "<h4 id=\"header-4\">Header 4</h4>\n", + + "##### Header 5\n", + "<h5 id=\"header-5\">Header 5</h5>\n", + + "###### Header 6\n", + "<h6 id=\"header-6\">Header 6</h6>\n", + + "####### Header 7\n", + "<h6 id=\"-header-7\"># Header 7</h6>\n", + + "Hello\n# Header 1\nGoodbye\n", + "<p>Hello</p>\n\n<h1 id=\"header-1\">Header 1</h1>\n\n<p>Goodbye</p>\n", + + "* List\n# Header\n* List\n", + "<ul>\n<li><p>List</p>\n\n<h1 id=\"header\">Header</h1></li>\n\n<li><p>List</p></li>\n</ul>\n", + + "* List\n#Header\n* List\n", + "<ul>\n<li><p>List</p>\n\n<h1 id=\"header\">Header</h1></li>\n\n<li><p>List</p></li>\n</ul>\n", + + "* List\n * Nested list\n # Nested header\n", + "<ul>\n<li><p>List</p>\n\n<ul>\n<li><p>Nested list</p>\n\n" + + "<h1 id=\"nested-header\">Nested header</h1></li>\n</ul></li>\n</ul>\n", + } + doTestsBlock(t, tests, EXTENSION_AUTO_HEADER_IDS) +} + func TestUnderlineHeaders(t *testing.T) { var tests = []string{ "Header 1\n========\n",

@@ -285,6 +327,50 @@ "Double underline\n=====\n=====\n",

"<h1>Double underline</h1>\n\n<p>=====</p>\n", } doTestsBlock(t, tests, 0) +} + +func TestUnderlineHeadersAutoIDs(t *testing.T) { + var tests = []string{ + "Header 1\n========\n", + "<h1 id=\"header-1\">Header 1</h1>\n", + + "Header 2\n--------\n", + "<h2 id=\"header-2\">Header 2</h2>\n", + + "A\n=\n", + "<h1 id=\"a\">A</h1>\n", + + "B\n-\n", + "<h2 id=\"b\">B</h2>\n", + + "Paragraph\nHeader\n=\n", + "<p>Paragraph</p>\n\n<h1 id=\"header\">Header</h1>\n", + + "Header\n===\nParagraph\n", + "<h1 id=\"header\">Header</h1>\n\n<p>Paragraph</p>\n", + + "Header\n===\nAnother header\n---\n", + "<h1 id=\"header\">Header</h1>\n\n<h2 id=\"another-header\">Another header</h2>\n", + + " Header\n======\n", + "<h1 id=\"header\">Header</h1>\n", + + "Header with *inline*\n=====\n", + "<h1 id=\"header-with-inline\">Header with <em>inline</em></h1>\n", + + "Paragraph\n\n\n\n\nHeader\n===\n", + "<p>Paragraph</p>\n\n<h1 id=\"header\">Header</h1>\n", + + "Trailing space \n==== \n\n", + "<h1 id=\"trailing-space\">Trailing space</h1>\n", + + "Trailing spaces\n==== \n\n", + "<h1 id=\"trailing-spaces\">Trailing spaces</h1>\n", + + "Double underline\n=====\n=====\n", + "<h1 id=\"double-underline\">Double underline</h1>\n\n<p>=====</p>\n", + } + doTestsBlock(t, tests, EXTENSION_AUTO_HEADER_IDS) } func TestHorizontalRule(t *testing.T) {
M markdown.gomarkdown.go

@@ -41,6 +41,7 @@ EXTENSION_FOOTNOTES // Pandoc-style footnotes

EXTENSION_NO_EMPTY_LINE_BEFORE_BLOCK // No need to insert an empty line to start a (code, quote, order list, unorder list)block EXTENSION_HEADER_IDS // specify header IDs with {#id} EXTENSION_TITLEBLOCK // Titleblock ala pandoc + EXTENSION_AUTO_HEADER_IDS // Create the header ID from the text commonHtmlFlags = 0 | HTML_USE_XHTML |