From 539b27a6242239ab88f86e8756318cfc9b28ee74 Mon Sep 17 00:00:00 2001 From: Brian Goff Date: Fri, 1 Aug 2014 22:54:21 -0400 Subject: [PATCH] Add titleblock support --- block.go | 41 ++++++++++++++++++++++++++++++++++++----- block_test.go | 16 ++++++++++++++++ html.go | 8 ++++++++ latex.go | 4 ++++ markdown.go | 2 ++ 5 files changed, 66 insertions(+), 5 deletions(-) diff --git a/block.go b/block.go index c992d43..d21a0e6 100644 --- a/block.go +++ b/block.go @@ -13,9 +13,7 @@ package blackfriday -import ( - "bytes" -) +import "bytes" // Parse block-level data. // Note: this function and many that it calls assume that @@ -56,6 +54,20 @@ func (p *parser) block(out *bytes.Buffer, data []byte) { } } + // title block + // + // % stuff + // % more stuff + // % even more stuff + if p.flags&EXTENSION_TITLEBLOCK != 0 { + if data[0] == '%' { + if i := p.titleBlock(out, data, true); i > 0 { + data = data[i:] + continue + } + } + } + // blank lines. note: returns the # of bytes to skip if i := p.isEmpty(data); i > 0 { data = data[i:] @@ -190,13 +202,13 @@ func (p *parser) prefixHeader(out *bytes.Buffer, data []byte) int { if p.flags&EXTENSION_HEADER_IDS != 0 { j, k := 0, 0 // find start/end of header id - for j = i; j < end - 1 && (data[j] != '{' || data[j+1] != '#'); j++ { + for j = i; j < end-1 && (data[j] != '{' || data[j+1] != '#'); j++ { } for k = j + 1; k < end && data[k] != '}'; k++ { } // extract header id iff found if j < end && k < end { - id = string(data[j+2:k]) + id = string(data[j+2 : k]) end = j skip = k + 1 for end > 0 && data[end-1] == ' ' { @@ -256,6 +268,25 @@ func (p *parser) isUnderlinedHeader(data []byte) int { return 0 } +func (p *parser) titleBlock(out *bytes.Buffer, data []byte, doRender bool) int { + if data[0] != '%' { + return 0 + } + splitData := bytes.Split(data, []byte("\n")) + var i int + for idx, b := range splitData { + if !bytes.HasPrefix(b, []byte("%")) { + i = idx // - 1 + break + } + } + + data = bytes.Join(splitData[0:i], []byte("\n")) + p.r.TitleBlock(out, data) + + return len(data) +} + func (p *parser) html(out *bytes.Buffer, data []byte, doRender bool) int { var i, j int diff --git a/block_test.go b/block_test.go index 3c37202..c9d4a88 100644 --- a/block_test.go +++ b/block_test.go @@ -1045,3 +1045,19 @@ func TestFencedCodeBlock_EXTENSION_NO_EMPTY_LINE_BEFORE_BLOCK(t *testing.T) { } doTestsBlock(t, tests, EXTENSION_FENCED_CODE|EXTENSION_NO_EMPTY_LINE_BEFORE_BLOCK) } + +func TestTitleBlock_EXTENSION_TITLEBLOCK(t *testing.T) { + var tests = []string{ + "% Some title\n" + + "% Another title line\n" + + "% Yep, more here too\n", + "

" + + "Some title\n" + + "Another title line\n" + + "Yep, more here too\n" + + "

", + } + + doTestsBlock(t, tests, EXTENSION_TITLEBLOCK) + +} diff --git a/html.go b/html.go index acf2bb7..982131c 100644 --- a/html.go +++ b/html.go @@ -180,6 +180,14 @@ func (options *Html) GetFlags() int { return options.flags } +func (options *Html) TitleBlock(out *bytes.Buffer, text []byte) { + text = bytes.TrimPrefix(text, []byte("% ")) + text = bytes.Replace(text, []byte("\n% "), []byte("\n"), -1) + out.WriteString("

") + out.Write(text) + out.WriteString("\n

") +} + func (options *Html) Header(out *bytes.Buffer, text func() bool, level int, id string) { marker := out.Len() doubleSpace(out) diff --git a/latex.go b/latex.go index 8924aca..8562746 100644 --- a/latex.go +++ b/latex.go @@ -55,6 +55,10 @@ func (options *Latex) BlockCode(out *bytes.Buffer, text []byte, lang string) { } } +func (options *Latex) TitleBlock(out *bytes.Buffer, text []byte) { + +} + func (options *Latex) BlockQuote(out *bytes.Buffer, text []byte) { out.WriteString("\n\\begin{quotation}\n") out.Write(text) diff --git a/markdown.go b/markdown.go index ca67cc6..023c056 100644 --- a/markdown.go +++ b/markdown.go @@ -40,6 +40,7 @@ const ( 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 ) // These are the possible flag values for the link renderer. @@ -145,6 +146,7 @@ type Renderer interface { TableCell(out *bytes.Buffer, text []byte, flags int) Footnotes(out *bytes.Buffer, text func() bool) FootnoteItem(out *bytes.Buffer, name, text []byte, flags int) + TitleBlock(out *bytes.Buffer, text []byte) // Span-level callbacks AutoLink(out *bytes.Buffer, link []byte, kind int)