Calculate block width from BlockStack & RenderContext

This commit is contained in:
Christian Muehlhaeuser
2019-12-07 19:49:24 +01:00
parent 7404a91eb4
commit 71e84251b3
8 changed files with 41 additions and 37 deletions
+7
View File
@@ -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()
+1
View File
@@ -4,4 +4,5 @@ type RenderContext struct {
style map[StyleType]ElementStyle
blockStack *BlockStack
table *TableElement
options Options
}
+1 -2
View File
@@ -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, " ")
},
+3 -8
View File
@@ -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),
},
}
+21 -15
View File
@@ -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
}
+1 -4
View File
@@ -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 {
+4 -4
View File
@@ -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
}
+3 -4
View File
@@ -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()