Browse Source

make markup renderers cache the latest result so scrolling doesn't rerender constantly

Benton Edmondson 1 year ago
parent
commit
7d6e0671f8
4 changed files with 56 additions and 23 deletions
  1. 18 5
      gemtext/gemtext.go
  2. 18 5
      hypertext/hypertext.go
  3. 2 9
      markdown/markdown.go
  4. 18 4
      plaintext/plaintext.go

+ 18 - 5
gemtext/gemtext.go

@@ -11,16 +11,29 @@ import (
 	https://gemini.circumlunar.space/docs/specification.html
 */
 
-type Markup []string
+type Markup struct {
+	tree []string
+	cached string
+	cachedWidth int
+}
 
 func NewMarkup(text string) (*Markup, []string, error) {
 	lines := strings.Split(text, "\n")
-	_, links := renderWithLinks(lines, 80)
-	return (*Markup)(&lines), links, nil
+	rendered, links := renderWithLinks(lines, 80)
+	return &Markup{
+		tree: lines,
+		cached: rendered,
+		cachedWidth: 80,
+	}, links, nil
 }
 
-func (m Markup) Render(width int) string {
-	rendered, _ := renderWithLinks(([]string)(m), width)
+func (m *Markup) Render(width int) string {
+	if m.cachedWidth == width {
+		return m.cached
+	}
+	rendered, _ := renderWithLinks(m.tree, width)
+	m.cached = rendered
+	m.cachedWidth = width
 	return rendered
 }
 

+ 18 - 5
hypertext/hypertext.go

@@ -9,7 +9,11 @@ import (
 	"strings"
 )
 
-type Markup []*html.Node
+type Markup struct {
+	tree []*html.Node
+	cached string
+	cachedWidth int
+}
 
 type context struct {
 	preserveWhitespace bool
@@ -26,12 +30,21 @@ func NewMarkup(text string) (*Markup, []string, error) {
 	if err != nil {
 		return nil, []string{}, err
 	}
-	_, links := renderWithLinks(nodes, 80)
-	return (*Markup)(&nodes), links, nil
+	rendered, links := renderWithLinks(nodes, 80)
+	return &Markup{
+		tree: nodes,
+		cached: rendered,
+		cachedWidth: 80,
+	}, links, nil
 }
 
-func (m Markup) Render(width int) string {
-	rendered, _ := renderWithLinks(([]*html.Node)(m), width)
+func (m *Markup) Render(width int) string {
+	if m.cachedWidth == width {
+		return m.cached
+	}
+	rendered, _ := renderWithLinks(m.tree, width)
+	m.cachedWidth = width
+	m.cached = rendered
 	return rendered
 }
 

+ 2 - 9
markdown/markdown.go

@@ -9,18 +9,11 @@ import (
 
 var renderer = goldmark.New(goldmark.WithExtensions(extension.GFM))
 
-type Markup hypertext.Markup
-
-func NewMarkup(text string) (*Markup, []string, error) {
+func NewMarkup(text string) (*hypertext.Markup, []string, error) {
 	var buf bytes.Buffer
 	if err := renderer.Convert([]byte(text), &buf); err != nil {
 		return nil, []string{}, err
 	}
 	output := buf.String()
-	hypertextMarkup, links, err := hypertext.NewMarkup(output)
-	return (*Markup)(hypertextMarkup), links, err
-}
-
-func (m *Markup) Render(width int) string {
-	return (*hypertext.Markup)(m).Render(width)
+	return hypertext.NewMarkup(output)
 }

+ 18 - 4
plaintext/plaintext.go

@@ -7,15 +7,29 @@ import (
 	"strings"
 )
 
-type Markup string
+type Markup struct {
+	text string
+	cached string
+	cachedWidth int
+}
 
 func NewMarkup(text string) (*Markup, []string, error) {
 	rendered, links := renderWithLinks(text, 80)
-	return (*Markup)(&rendered), links, nil
+
+	return &Markup{
+		text: text,
+		cached: rendered,
+		cachedWidth: 80,
+	}, links, nil
 }
 
-func (m Markup) Render(width int) string {
-	rendered, _ := renderWithLinks(string(m), width)
+func (m *Markup) Render(width int) string {
+	if m.cachedWidth == width {
+		return m.cached
+	}
+	rendered, _ := renderWithLinks(m.text, width)
+	m.cached = rendered
+	m.cachedWidth = width
 	return rendered
 }