aboutsummaryrefslogtreecommitdiff
path: root/ui/messages/html/entity.go
diff options
context:
space:
mode:
Diffstat (limited to 'ui/messages/html/entity.go')
-rw-r--r--ui/messages/html/entity.go266
1 files changed, 0 insertions, 266 deletions
diff --git a/ui/messages/html/entity.go b/ui/messages/html/entity.go
index be58d61..0c7785d 100644
--- a/ui/messages/html/entity.go
+++ b/ui/messages/html/entity.go
@@ -17,13 +17,6 @@
package html
import (
- "fmt"
- "regexp"
- "strings"
-
- "github.com/mattn/go-runewidth"
-
- "maunium.net/go/gomuks/ui/widget"
"maunium.net/go/mauview"
"maunium.net/go/tcell"
)
@@ -54,262 +47,3 @@ type Entity interface {
getStartX() int
}
-
-type BaseEntity struct {
- // The HTML tag of this entity.
- Tag string
- // Text in this entity.
- Text string
- // Style for this entity.
- Style tcell.Style
- // Child entities.
- Children []Entity
- // Whether or not this is a block-type entity.
- Block bool
- // Number of cells to indent children.
- Indent int
-
- // Height to use for entity if both text and children are empty.
- DefaultHeight int
-
- buffer []string
- prevWidth int
- startX int
- height int
-}
-
-// NewTextEntity creates a new text-only Entity.
-func NewTextEntity(text string) *BaseEntity {
- return &BaseEntity{
- Tag: "text",
- Text: text,
- }
-}
-
-// AdjustStyle recursively changes the style of this entity and all its children.
-func (he *BaseEntity) AdjustStyle(fn AdjustStyleFunc) Entity {
- for _, child := range he.Children {
- child.AdjustStyle(fn)
- }
- he.Style = fn(he.Style)
- return he
-}
-
-// IsBlock returns whether or not this is a block-type entity.
-func (he *BaseEntity) IsBlock() bool {
- return he.Block
-}
-
-// GetTag returns the HTML tag of this entity.
-func (he *BaseEntity) GetTag() string {
- return he.Tag
-}
-
-// Height returns the render height of this entity.
-func (he *BaseEntity) Height() int {
- return he.height
-}
-
-func (he *BaseEntity) getStartX() int {
- return he.startX
-}
-
-// Clone creates a deep copy of this entity.
-func (he *BaseEntity) Clone() Entity {
- children := make([]Entity, len(he.Children))
- for i, child := range he.Children {
- children[i] = child.Clone()
- }
- return &BaseEntity{
- Tag: he.Tag,
- Text: he.Text,
- Style: he.Style,
- Children: children,
- Block: he.Block,
- Indent: he.Indent,
- DefaultHeight: he.DefaultHeight,
- }
-}
-
-// String returns a textual representation of this BaseEntity struct.
-func (he *BaseEntity) String() string {
- var buf strings.Builder
- buf.WriteString("&html.BaseEntity{\n")
- _, _ = fmt.Fprintf(&buf, ` Tag="%s", Style=%d, Block=%t, Indent=%d, startX=%d, height=%d,`,
- he.Tag, he.Style, he.Block, he.Indent, he.startX, he.height)
- buf.WriteRune('\n')
- _, _ = fmt.Fprintf(&buf, ` Buffer=["%s"]`, strings.Join(he.buffer, "\", \""))
- if len(he.Text) > 0 {
- buf.WriteString(",\n")
- _, _ = fmt.Fprintf(&buf, ` Text="%s"`, he.Text)
- }
- if len(he.Children) > 0 {
- buf.WriteString(",\n")
- buf.WriteString(" Children={")
- for _, child := range he.Children {
- buf.WriteString("\n ")
- buf.WriteString(strings.Join(strings.Split(strings.TrimRight(child.String(), "\n"), "\n"), "\n "))
- }
- buf.WriteString("\n },")
- }
- buf.WriteString("\n},\n")
- return buf.String()
-}
-
-// PlainText returns the plaintext content in this entity and all its children.
-func (he *BaseEntity) PlainText() string {
- if len(he.Children) == 0 {
- return he.Text
- }
- var buf strings.Builder
- buf.WriteString(he.Text)
- newlined := false
- for _, child := range he.Children {
- text := child.PlainText()
- if !strings.HasPrefix(text, "\n") && child.IsBlock() && !newlined {
- buf.WriteRune('\n')
- }
- newlined = false
- buf.WriteString(text)
- if child.IsBlock() {
- if !strings.HasSuffix(text, "\n") {
- buf.WriteRune('\n')
- }
- newlined = true
- }
- }
- return strings.TrimSpace(buf.String())
-}
-
-// Draw draws this entity onto the given mauview Screen.
-func (he *BaseEntity) Draw(screen mauview.Screen) {
- width, _ := screen.Size()
- if len(he.buffer) > 0 {
- x := he.startX
- for y, line := range he.buffer {
- widget.WriteLine(screen, mauview.AlignLeft, line, x, y, width, he.Style)
- x = 0
- }
- }
- if len(he.Children) > 0 {
- prevBreak := false
- proxyScreen := &mauview.ProxyScreen{Parent: screen, OffsetX: he.Indent, Width: width - he.Indent, Style: he.Style}
- for i, entity := range he.Children {
- if i != 0 && entity.getStartX() == 0 {
- proxyScreen.OffsetY++
- }
- proxyScreen.Height = entity.Height()
- entity.Draw(proxyScreen)
- proxyScreen.SetStyle(he.Style)
- proxyScreen.OffsetY += entity.Height() - 1
- _, isBreak := entity.(*BreakEntity)
- if prevBreak && isBreak {
- proxyScreen.OffsetY++
- }
- prevBreak = isBreak
- }
- }
-}
-
-// CalculateBuffer prepares this entity and all its children for rendering with the given parameters
-func (he *BaseEntity) CalculateBuffer(width, startX int, bare bool) int {
- he.startX = startX
- if he.Block {
- he.startX = 0
- }
- he.height = 0
- if len(he.Children) > 0 {
- childStartX := he.startX
- prevBreak := false
- for _, entity := range he.Children {
- if entity.IsBlock() || childStartX == 0 || he.height == 0 {
- he.height++
- }
- childStartX = entity.CalculateBuffer(width-he.Indent, childStartX, bare)
- he.height += entity.Height() - 1
- _, isBreak := entity.(*BreakEntity)
- if prevBreak && isBreak {
- he.height++
- }
- prevBreak = isBreak
- }
- if len(he.Text) == 0 && !he.Block {
- return childStartX
- }
- }
- if len(he.Text) > 0 {
- he.prevWidth = width
- if he.buffer == nil {
- he.buffer = []string{}
- }
- bufPtr := 0
- text := he.Text
- textStartX := he.startX
- for {
- // TODO add option no wrap and character wrap options
- extract := runewidth.Truncate(text, width-textStartX, "")
- extract, wordWrapped := trim(extract, text, bare)
- if !wordWrapped && textStartX > 0 {
- if bufPtr < len(he.buffer) {
- he.buffer[bufPtr] = ""
- } else {
- he.buffer = append(he.buffer, "")
- }
- bufPtr++
- textStartX = 0
- continue
- }
- if bufPtr < len(he.buffer) {
- he.buffer[bufPtr] = extract
- } else {
- he.buffer = append(he.buffer, extract)
- }
- bufPtr++
- text = text[len(extract):]
- if len(text) == 0 {
- he.buffer = he.buffer[:bufPtr]
- he.height += len(he.buffer)
- // This entity is over, return the startX for the next entity
- if he.Block {
- // ...except if it's a block entity
- return 0
- }
- return textStartX + runewidth.StringWidth(extract)
- }
- textStartX = 0
- }
- }
- if len(he.Text) == 0 && len(he.Children) == 0 {
- he.height = he.DefaultHeight
- }
- return he.startX
-}
-
-var (
- boundaryPattern = regexp.MustCompile(`([[:punct:]]\s*|\s+)`)
- bareBoundaryPattern = regexp.MustCompile(`(\s+)`)
- spacePattern = regexp.MustCompile(`\s+`)
-)
-
-func trim(extract, full string, bare bool) (string, bool) {
- if len(extract) == len(full) {
- return extract, true
- }
- if spaces := spacePattern.FindStringIndex(full[len(extract):]); spaces != nil && spaces[0] == 0 {
- extract = full[:len(extract)+spaces[1]]
- }
- regex := boundaryPattern
- if bare {
- regex = bareBoundaryPattern
- }
- matches := regex.FindAllStringIndex(extract, -1)
- if len(matches) > 0 {
- if match := matches[len(matches)-1]; len(match) >= 2 {
- if until := match[1]; until < len(extract) {
- extract = extract[:until]
- return extract, true
- }
- }
- }
- return extract, len(extract) > 0 && extract[len(extract)-1] == ' '
-}