all repos — grayfriday @ dce6df90b9363579a8609fa70faef3a8b56b85b4

blackfriday fork with a few changes

Add infrastructure to collect output in a buffer

Add a structure to collect output in a buffer (replaces what used to be
the 'out' parameter all over the place).

Notable things about this struct are the captureBuff and copyBuff
buffers. They're intended to redirect all the output (captureBuff) or
make a copy of all the output (copyBuff) while they're set to non-nil.
Here's an example of their intended use:

    // what used to be a temp buffer as an 'out' parameter
    //     var cellWork bytes.Buffer
    //     p.inline(&cellWork, data[cellStart:cellEnd])
    // can now be captured like this:
    cellWork := p.r.CaptureWrites(func() {
           p.inline(data[cellStart:cellEnd])
    })
Vytautas Ĺ altenis vytas@rtfb.lt
Tue, 03 Nov 2015 21:43:00 +0200
commit

dce6df90b9363579a8609fa70faef3a8b56b85b4

parent

352ffdefa470eb5221a71a951b5d1db436b3e862

2 files changed, 82 insertions(+), 0 deletions(-)

jump to
M html.gohtml.go

@@ -96,6 +96,7 @@ // Track header IDs to prevent ID collision in a single generation.

headerIDs map[string]int smartypants *smartypantsRenderer + w HtmlWriter } const (

@@ -114,6 +115,82 @@ func HtmlRenderer(flags HtmlFlags, title string, css string) Renderer {

return HtmlRendererWithParameters(flags, title, css, HtmlRendererParameters{}) } +type HtmlWriter struct { + output bytes.Buffer + captureBuff *bytes.Buffer + copyBuff *bytes.Buffer + dirty bool +} + +func (w *HtmlWriter) Write(p []byte) (n int, err error) { + w.dirty = true + if w.copyBuff != nil { + w.copyBuff.Write(p) + } + if w.captureBuff != nil { + w.captureBuff.Write(p) + return + } + return w.output.Write(p) +} + +func (w *HtmlWriter) WriteString(s string) (n int, err error) { + w.dirty = true + if w.copyBuff != nil { + w.copyBuff.WriteString(s) + } + if w.captureBuff != nil { + w.captureBuff.WriteString(s) + return + } + return w.output.WriteString(s) +} + +func (w *HtmlWriter) WriteByte(b byte) error { + w.dirty = true + if w.copyBuff != nil { + w.copyBuff.WriteByte(b) + } + if w.captureBuff != nil { + return w.captureBuff.WriteByte(b) + } + return w.output.WriteByte(b) +} + +// Writes out a newline if the output is not pristine. Used at the beginning of +// every rendering func +func (w *HtmlWriter) Newline() { + if w.dirty { + w.WriteByte('\n') + } +} + +func (r *Html) CaptureWrites(processor func()) []byte { + var output bytes.Buffer + // preserve old captureBuff state for possible nested captures: + tmp := r.w.captureBuff + tmpd := r.w.dirty + r.w.captureBuff = &output + r.w.dirty = false + processor() + // restore: + r.w.captureBuff = tmp + r.w.dirty = tmpd + return output.Bytes() +} + +func (r *Html) CopyWrites(processor func()) []byte { + var output bytes.Buffer + r.w.copyBuff = &output + processor() + r.w.copyBuff = nil + return output.Bytes() +} + +func (r *Html) GetResult() []byte { + return r.w.output.Bytes() +} + func HtmlRendererWithParameters(flags HtmlFlags, title string, css string, renderParameters HtmlRendererParameters) Renderer { // configure the rendering engine

@@ -126,6 +203,7 @@ if renderParameters.FootnoteReturnLinkContents == "" {

renderParameters.FootnoteReturnLinkContents = `<sup>[return]</sup>` } + var writer HtmlWriter return &Html{ flags: flags, closeTag: closeTag,

@@ -140,6 +218,7 @@

headerIDs: make(map[string]int), smartypants: smartypants(flags), + w: writer, } }
M markdown.gomarkdown.go

@@ -202,6 +202,9 @@ DocumentHeader()

DocumentFooter() GetFlags() HtmlFlags + CaptureWrites(processor func()) []byte + CopyWrites(processor func()) []byte + GetResult() []byte } // Callback functions for inline parsing. One such function is defined