diff --git a/blockstack.go b/blockstack.go index 94808d7..67b70a2 100644 --- a/blockstack.go +++ b/blockstack.go @@ -51,6 +51,13 @@ func (s BlockStack) Margin() uint { return i } +func (s BlockStack) Width(ctx RenderContext) uint { + if s.Indent()+s.Margin()*2 > uint(ctx.options.WordWrap) { + return 0 + } + return uint(ctx.options.WordWrap) - s.Indent() - s.Margin()*2 +} + func (s BlockStack) Parent() BlockElement { if len(s) < 2 { return s.Current() diff --git a/context.go b/context.go index 41f8890..2bc12a7 100644 --- a/context.go +++ b/context.go @@ -4,4 +4,5 @@ type RenderContext struct { style map[StyleType]ElementStyle blockStack *BlockStack table *TableElement + options Options } diff --git a/document.go b/document.go index 970c2f5..e8dda80 100644 --- a/document.go +++ b/document.go @@ -6,7 +6,6 @@ import ( ) type DocumentElement struct { - Width uint } func (e *DocumentElement) Render(w io.Writer, ctx RenderContext) error { @@ -37,7 +36,7 @@ func (e *DocumentElement) Finish(w io.Writer, ctx RenderContext) error { suffix := rules.Suffix pw := &PaddingWriter{ - Padding: e.Width - margin, + Padding: uint(ctx.options.WordWrap) - margin, PadFunc: func(wr io.Writer) { renderText(w, rules, " ") }, diff --git a/elements.go b/elements.go index 719ce04..151122c 100644 --- a/elements.go +++ b/elements.go @@ -28,9 +28,7 @@ func (tr *TermRenderer) NewElement(node *bf.Node) Element { switch node.Type { case bf.Document: - de := &DocumentElement{ - Width: uint(tr.WordWrap), - } + de := &DocumentElement{} return Element{ Renderer: de, Finisher: de, @@ -46,7 +44,6 @@ func (tr *TermRenderer) NewElement(node *bf.Node) Element { } case bf.List: le := &ListElement{ - Width: uint(tr.WordWrap), Nested: node.Parent.Type == bf.Item, } return Element{ @@ -72,7 +69,6 @@ func (tr *TermRenderer) NewElement(node *bf.Node) Element { } case bf.Paragraph: pe := &ParagraphElement{ - Width: uint(tr.WordWrap), InsideList: node.Parent != nil && node.Parent.Type == bf.Item, } return Element{ @@ -83,7 +79,6 @@ func (tr *TermRenderer) NewElement(node *bf.Node) Element { return Element{ Exiting: "\n", Renderer: &HeadingElement{ - Width: uint(tr.WordWrap), Text: string(node.FirstChild.Literal), Level: node.HeadingData.Level, First: node.Prev == nil, @@ -126,7 +121,7 @@ func (tr *TermRenderer) NewElement(node *bf.Node) Element { return Element{ Renderer: &LinkElement{ Text: text, - BaseURL: tr.BaseURL, + BaseURL: tr.context.options.BaseURL, URL: string(node.LinkData.Destination), }, } @@ -138,7 +133,7 @@ func (tr *TermRenderer) NewElement(node *bf.Node) Element { return Element{ Renderer: &ImageElement{ Text: text, - BaseURL: tr.BaseURL, + BaseURL: tr.context.options.BaseURL, URL: string(node.LinkData.Destination), }, } diff --git a/gold.go b/gold.go index 5eb718e..ec73ecf 100644 --- a/gold.go +++ b/gold.go @@ -15,10 +15,12 @@ var ( stripper = bluemonday.StrictPolicy() ) -type TermRenderer struct { +type Options struct { BaseURL string WordWrap int +} +type TermRenderer struct { context RenderContext } @@ -27,43 +29,46 @@ func Render(in string, stylePath string) ([]byte, error) { } func RenderBytes(in []byte, stylePath string) ([]byte, error) { - r, err := NewTermRenderer(stylePath) + r, err := NewTermRenderer(stylePath, Options{ + WordWrap: 80, + }) if err != nil { return nil, err } return r.RenderBytes(in), nil } -func NewPlainTermRenderer() *TermRenderer { - return &TermRenderer{} +func NewPlainTermRenderer(options Options) *TermRenderer { + return &TermRenderer{ + context: RenderContext{ + style: make(map[StyleType]ElementStyle), + blockStack: &BlockStack{}, + table: &TableElement{}, + options: options, + }, + } } -func NewTermRenderer(stylePath string) (*TermRenderer, error) { +func NewTermRenderer(stylePath string, options Options) (*TermRenderer, error) { if stylePath == "" { - return NewTermRendererFromBytes([]byte("{}")) + return NewTermRendererFromBytes([]byte("{}"), options) } b, err := loadStyle(stylePath) if err != nil { return nil, err } - return NewTermRendererFromBytes(b) + return NewTermRendererFromBytes(b, options) } -func NewTermRendererFromBytes(b []byte) (*TermRenderer, error) { +func NewTermRendererFromBytes(b []byte, options Options) (*TermRenderer, error) { e := make(map[string]ElementStyle) err := json.Unmarshal(b, &e) if err != nil { return nil, err } - tr := &TermRenderer{ - context: RenderContext{ - style: make(map[StyleType]ElementStyle), - blockStack: &BlockStack{}, - table: &TableElement{}, - }, - } + tr := NewPlainTermRenderer(options) for k, v := range e { t, err := keyToType(k) if err != nil { @@ -72,6 +77,7 @@ func NewTermRendererFromBytes(b []byte) (*TermRenderer, error) { } tr.context.style[t] = v } + return tr, nil } diff --git a/heading.go b/heading.go index 7457149..492aa22 100644 --- a/heading.go +++ b/heading.go @@ -7,7 +7,6 @@ import ( ) type HeadingElement struct { - Width uint Text string Level int First bool @@ -51,9 +50,7 @@ func (e *HeadingElement) Render(w io.Writer, ctx RenderContext) error { }, } - flow := reflow.NewReflow(int(e.Width) - - int(indent) - int(margin*2) - - int(bs.Indent()) - int(bs.Margin())*2) + flow := reflow.NewReflow(int(bs.Width(ctx) - indent - margin*2)) var pre string if !e.First { diff --git a/list.go b/list.go index e129f79..8052cf7 100644 --- a/list.go +++ b/list.go @@ -8,7 +8,6 @@ import ( ) type ListElement struct { - Width uint Nested bool } @@ -39,11 +38,12 @@ func (e *ListElement) Finish(w io.Writer, ctx RenderContext) error { if rules.Margin != nil { margin = *rules.Margin } + suffix := rules.Suffix renderText(bs.Current().Block, rules, suffix) pw := &PaddingWriter{ - Padding: uint(int(e.Width) - int(bs.Indent()) - int(bs.Margin()*2)), + Padding: bs.Width(ctx), PadFunc: func(wr io.Writer) { renderText(w, rules, " ") }, @@ -61,8 +61,8 @@ func (e *ListElement) Finish(w io.Writer, ctx RenderContext) error { }, } - _, err := iw.Write(reflow.Bytes(bs.Current().Block.Bytes(), - int(e.Width)-int(bs.Indent())-int(bs.Margin())*2)) + _, err := iw.Write( + reflow.Bytes(bs.Current().Block.Bytes(), int(bs.Width(ctx)))) if err != nil { return err } diff --git a/paragraph.go b/paragraph.go index 478f4cc..801e2f4 100644 --- a/paragraph.go +++ b/paragraph.go @@ -9,7 +9,6 @@ import ( ) type ParagraphElement struct { - Width uint InsideList bool } @@ -53,12 +52,12 @@ func (e *ParagraphElement) Finish(w io.Writer, ctx RenderContext) error { if rules.Margin != nil { margin = *rules.Margin } - suffix := rules.Suffix + suffix := rules.Suffix renderText(bs.Current().Block, rules, suffix) pw := &PaddingWriter{ - Padding: uint(int(e.Width) - int(bs.Indent()) - int(bs.Margin()*2)), + Padding: bs.Width(ctx), PadFunc: func(wr io.Writer) { renderText(w, rules, " ") }, @@ -77,7 +76,7 @@ func (e *ParagraphElement) Finish(w io.Writer, ctx RenderContext) error { } if len(strings.TrimSpace(bs.Current().Block.String())) > 0 { - flow := reflow.NewReflow(int(e.Width) - int(bs.Indent()) - int(bs.Margin())*2) + flow := reflow.NewReflow(int(bs.Width(ctx))) flow.KeepNewlines = keepNewlines _, _ = flow.Write(bs.Current().Block.Bytes()) flow.Close()