mirror of
https://github.com/rwinkhart/glamour-temp-MUTN.git
synced 2026-09-06 00:47:15 -04:00
Calculate block width from BlockStack & RenderContext
This commit is contained in:
@@ -51,6 +51,13 @@ func (s BlockStack) Margin() uint {
|
|||||||
return i
|
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 {
|
func (s BlockStack) Parent() BlockElement {
|
||||||
if len(s) < 2 {
|
if len(s) < 2 {
|
||||||
return s.Current()
|
return s.Current()
|
||||||
|
|||||||
@@ -4,4 +4,5 @@ type RenderContext struct {
|
|||||||
style map[StyleType]ElementStyle
|
style map[StyleType]ElementStyle
|
||||||
blockStack *BlockStack
|
blockStack *BlockStack
|
||||||
table *TableElement
|
table *TableElement
|
||||||
|
options Options
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-2
@@ -6,7 +6,6 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type DocumentElement struct {
|
type DocumentElement struct {
|
||||||
Width uint
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *DocumentElement) Render(w io.Writer, ctx RenderContext) error {
|
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
|
suffix := rules.Suffix
|
||||||
|
|
||||||
pw := &PaddingWriter{
|
pw := &PaddingWriter{
|
||||||
Padding: e.Width - margin,
|
Padding: uint(ctx.options.WordWrap) - margin,
|
||||||
PadFunc: func(wr io.Writer) {
|
PadFunc: func(wr io.Writer) {
|
||||||
renderText(w, rules, " ")
|
renderText(w, rules, " ")
|
||||||
},
|
},
|
||||||
|
|||||||
+3
-8
@@ -28,9 +28,7 @@ func (tr *TermRenderer) NewElement(node *bf.Node) Element {
|
|||||||
|
|
||||||
switch node.Type {
|
switch node.Type {
|
||||||
case bf.Document:
|
case bf.Document:
|
||||||
de := &DocumentElement{
|
de := &DocumentElement{}
|
||||||
Width: uint(tr.WordWrap),
|
|
||||||
}
|
|
||||||
return Element{
|
return Element{
|
||||||
Renderer: de,
|
Renderer: de,
|
||||||
Finisher: de,
|
Finisher: de,
|
||||||
@@ -46,7 +44,6 @@ func (tr *TermRenderer) NewElement(node *bf.Node) Element {
|
|||||||
}
|
}
|
||||||
case bf.List:
|
case bf.List:
|
||||||
le := &ListElement{
|
le := &ListElement{
|
||||||
Width: uint(tr.WordWrap),
|
|
||||||
Nested: node.Parent.Type == bf.Item,
|
Nested: node.Parent.Type == bf.Item,
|
||||||
}
|
}
|
||||||
return Element{
|
return Element{
|
||||||
@@ -72,7 +69,6 @@ func (tr *TermRenderer) NewElement(node *bf.Node) Element {
|
|||||||
}
|
}
|
||||||
case bf.Paragraph:
|
case bf.Paragraph:
|
||||||
pe := &ParagraphElement{
|
pe := &ParagraphElement{
|
||||||
Width: uint(tr.WordWrap),
|
|
||||||
InsideList: node.Parent != nil && node.Parent.Type == bf.Item,
|
InsideList: node.Parent != nil && node.Parent.Type == bf.Item,
|
||||||
}
|
}
|
||||||
return Element{
|
return Element{
|
||||||
@@ -83,7 +79,6 @@ func (tr *TermRenderer) NewElement(node *bf.Node) Element {
|
|||||||
return Element{
|
return Element{
|
||||||
Exiting: "\n",
|
Exiting: "\n",
|
||||||
Renderer: &HeadingElement{
|
Renderer: &HeadingElement{
|
||||||
Width: uint(tr.WordWrap),
|
|
||||||
Text: string(node.FirstChild.Literal),
|
Text: string(node.FirstChild.Literal),
|
||||||
Level: node.HeadingData.Level,
|
Level: node.HeadingData.Level,
|
||||||
First: node.Prev == nil,
|
First: node.Prev == nil,
|
||||||
@@ -126,7 +121,7 @@ func (tr *TermRenderer) NewElement(node *bf.Node) Element {
|
|||||||
return Element{
|
return Element{
|
||||||
Renderer: &LinkElement{
|
Renderer: &LinkElement{
|
||||||
Text: text,
|
Text: text,
|
||||||
BaseURL: tr.BaseURL,
|
BaseURL: tr.context.options.BaseURL,
|
||||||
URL: string(node.LinkData.Destination),
|
URL: string(node.LinkData.Destination),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -138,7 +133,7 @@ func (tr *TermRenderer) NewElement(node *bf.Node) Element {
|
|||||||
return Element{
|
return Element{
|
||||||
Renderer: &ImageElement{
|
Renderer: &ImageElement{
|
||||||
Text: text,
|
Text: text,
|
||||||
BaseURL: tr.BaseURL,
|
BaseURL: tr.context.options.BaseURL,
|
||||||
URL: string(node.LinkData.Destination),
|
URL: string(node.LinkData.Destination),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,10 +15,12 @@ var (
|
|||||||
stripper = bluemonday.StrictPolicy()
|
stripper = bluemonday.StrictPolicy()
|
||||||
)
|
)
|
||||||
|
|
||||||
type TermRenderer struct {
|
type Options struct {
|
||||||
BaseURL string
|
BaseURL string
|
||||||
WordWrap int
|
WordWrap int
|
||||||
|
}
|
||||||
|
|
||||||
|
type TermRenderer struct {
|
||||||
context RenderContext
|
context RenderContext
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -27,43 +29,46 @@ func Render(in string, stylePath string) ([]byte, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func RenderBytes(in []byte, 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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return r.RenderBytes(in), nil
|
return r.RenderBytes(in), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPlainTermRenderer() *TermRenderer {
|
func NewPlainTermRenderer(options Options) *TermRenderer {
|
||||||
return &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 == "" {
|
if stylePath == "" {
|
||||||
return NewTermRendererFromBytes([]byte("{}"))
|
return NewTermRendererFromBytes([]byte("{}"), options)
|
||||||
}
|
}
|
||||||
|
|
||||||
b, err := loadStyle(stylePath)
|
b, err := loadStyle(stylePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
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)
|
e := make(map[string]ElementStyle)
|
||||||
err := json.Unmarshal(b, &e)
|
err := json.Unmarshal(b, &e)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
tr := &TermRenderer{
|
tr := NewPlainTermRenderer(options)
|
||||||
context: RenderContext{
|
|
||||||
style: make(map[StyleType]ElementStyle),
|
|
||||||
blockStack: &BlockStack{},
|
|
||||||
table: &TableElement{},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for k, v := range e {
|
for k, v := range e {
|
||||||
t, err := keyToType(k)
|
t, err := keyToType(k)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -72,6 +77,7 @@ func NewTermRendererFromBytes(b []byte) (*TermRenderer, error) {
|
|||||||
}
|
}
|
||||||
tr.context.style[t] = v
|
tr.context.style[t] = v
|
||||||
}
|
}
|
||||||
|
|
||||||
return tr, nil
|
return tr, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-4
@@ -7,7 +7,6 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type HeadingElement struct {
|
type HeadingElement struct {
|
||||||
Width uint
|
|
||||||
Text string
|
Text string
|
||||||
Level int
|
Level int
|
||||||
First bool
|
First bool
|
||||||
@@ -51,9 +50,7 @@ func (e *HeadingElement) Render(w io.Writer, ctx RenderContext) error {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
flow := reflow.NewReflow(int(e.Width) -
|
flow := reflow.NewReflow(int(bs.Width(ctx) - indent - margin*2))
|
||||||
int(indent) - int(margin*2) -
|
|
||||||
int(bs.Indent()) - int(bs.Margin())*2)
|
|
||||||
|
|
||||||
var pre string
|
var pre string
|
||||||
if !e.First {
|
if !e.First {
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type ListElement struct {
|
type ListElement struct {
|
||||||
Width uint
|
|
||||||
Nested bool
|
Nested bool
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,11 +38,12 @@ func (e *ListElement) Finish(w io.Writer, ctx RenderContext) error {
|
|||||||
if rules.Margin != nil {
|
if rules.Margin != nil {
|
||||||
margin = *rules.Margin
|
margin = *rules.Margin
|
||||||
}
|
}
|
||||||
|
|
||||||
suffix := rules.Suffix
|
suffix := rules.Suffix
|
||||||
renderText(bs.Current().Block, rules, suffix)
|
renderText(bs.Current().Block, rules, suffix)
|
||||||
|
|
||||||
pw := &PaddingWriter{
|
pw := &PaddingWriter{
|
||||||
Padding: uint(int(e.Width) - int(bs.Indent()) - int(bs.Margin()*2)),
|
Padding: bs.Width(ctx),
|
||||||
PadFunc: func(wr io.Writer) {
|
PadFunc: func(wr io.Writer) {
|
||||||
renderText(w, rules, " ")
|
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(),
|
_, err := iw.Write(
|
||||||
int(e.Width)-int(bs.Indent())-int(bs.Margin())*2))
|
reflow.Bytes(bs.Current().Block.Bytes(), int(bs.Width(ctx))))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-4
@@ -9,7 +9,6 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type ParagraphElement struct {
|
type ParagraphElement struct {
|
||||||
Width uint
|
|
||||||
InsideList bool
|
InsideList bool
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,12 +52,12 @@ func (e *ParagraphElement) Finish(w io.Writer, ctx RenderContext) error {
|
|||||||
if rules.Margin != nil {
|
if rules.Margin != nil {
|
||||||
margin = *rules.Margin
|
margin = *rules.Margin
|
||||||
}
|
}
|
||||||
suffix := rules.Suffix
|
|
||||||
|
|
||||||
|
suffix := rules.Suffix
|
||||||
renderText(bs.Current().Block, rules, suffix)
|
renderText(bs.Current().Block, rules, suffix)
|
||||||
|
|
||||||
pw := &PaddingWriter{
|
pw := &PaddingWriter{
|
||||||
Padding: uint(int(e.Width) - int(bs.Indent()) - int(bs.Margin()*2)),
|
Padding: bs.Width(ctx),
|
||||||
PadFunc: func(wr io.Writer) {
|
PadFunc: func(wr io.Writer) {
|
||||||
renderText(w, rules, " ")
|
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 {
|
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.KeepNewlines = keepNewlines
|
||||||
_, _ = flow.Write(bs.Current().Block.Bytes())
|
_, _ = flow.Write(bs.Current().Block.Bytes())
|
||||||
flow.Close()
|
flow.Close()
|
||||||
|
|||||||
Reference in New Issue
Block a user