From 15d9fd129b110e53165a9db0b62a27591156b0f4 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Wed, 4 Dec 2019 13:37:14 +0100 Subject: [PATCH] Handle Lists as a block element, which supports margins & indents --- elements.go | 4 +++- list.go | 61 +++++++++++++++++++++++++++++++++++++++++++++++------ listitem.go | 15 ++----------- 3 files changed, 59 insertions(+), 21 deletions(-) diff --git a/elements.go b/elements.go index c814479..75edb66 100644 --- a/elements.go +++ b/elements.go @@ -41,8 +41,10 @@ func (tr *TermRenderer) NewElement(node *bf.Node) Element { }, } case bf.List: + le := &ListElement{} return Element{ - Renderer: &ListElement{}, + Renderer: le, + Finisher: le, } case bf.Item: return Element{ diff --git a/list.go b/list.go index 8436fc7..8a53632 100644 --- a/list.go +++ b/list.go @@ -1,8 +1,10 @@ package gold import ( + "bytes" "io" + "github.com/muesli/reflow" bf "gopkg.in/russross/blackfriday.v2" ) @@ -10,15 +12,60 @@ type ListElement struct { } func (e *ListElement) Render(w io.Writer, node *bf.Node, tr *TermRenderer) error { - pre := "" + rules := tr.style[List] if node.Parent.Type != bf.Item { - pre = "\n" + _, _ = w.Write([]byte("\n")) } - el := &BaseElement{ - Prefix: pre, - Token: string(node.Literal), - Style: List, + be := BlockElement{ + Block: &bytes.Buffer{}, + Style: cascadeStyle(tr.blockStack.Current().Style, rules), } - return el.Render(w, node, tr) + tr.blockStack.Push(be) + + if rules != nil { + renderText(w, tr.blockStack.Current().Style, rules.Prefix) + } + return nil +} + +func (e *ListElement) Finish(w io.Writer, node *bf.Node, tr *TermRenderer) error { + var indent uint + var margin uint + var suffix string + rules := tr.blockStack.Current().Style + if rules != nil { + indent = rules.Indent + margin = rules.Margin + suffix = rules.Suffix + } + renderText(tr.blockStack.Current().Block, rules, suffix) + + pw := &PaddingWriter{ + Padding: uint(tr.WordWrap - int(tr.blockStack.Indent()) - int(tr.blockStack.Margin()*2)), + PadFunc: func(wr io.Writer) { + renderText(w, rules, " ") + }, + Forward: &AnsiWriter{ + Forward: w, + }, + } + iw := &IndentWriter{ + Indent: indent + margin, + IndentFunc: func(wr io.Writer) { + renderText(w, tr.blockStack.Parent().Style, " ") + }, + Forward: &AnsiWriter{ + Forward: pw, + }, + } + + _, err := iw.Write(reflow.ReflowBytes(tr.blockStack.Current().Block.Bytes(), tr.WordWrap-int(tr.blockStack.Indent())-int(tr.blockStack.Margin())*2)) + if err != nil { + return err + } + + tr.blockStack.Current().Block.Reset() + tr.blockStack.Pop() + return nil } diff --git a/listitem.go b/listitem.go index 1ea2df5..fee8af8 100644 --- a/listitem.go +++ b/listitem.go @@ -2,7 +2,6 @@ package gold import ( "io" - "strings" bf "gopkg.in/russross/blackfriday.v2" ) @@ -11,19 +10,9 @@ type ItemElement struct { } func (e *ItemElement) Render(w io.Writer, node *bf.Node, tr *TermRenderer) error { - l := 0 - n := node - for n.Parent != nil && (n.Parent.Type == bf.List || n.Parent.Type == bf.Item) { - if n.Parent.Type == bf.List { - l++ - } - n = n.Parent - } - el := &BaseElement{ - Prefix: strings.Repeat(" ", l-1), - Token: string(node.Literal), - Style: Item, + Token: string(node.Literal), + Style: Item, } return el.Render(w, node, tr) }