Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

style.go::Render at 'Render core text' is not ansi aware when using a spaced styler #233

Open
Sojamann opened this issue Oct 7, 2023 · 1 comment

Comments

@Sojamann
Copy link

Sojamann commented Oct 7, 2023

Describe the bug
The Render function gumbles up a potentially already rendered string or some other input which contains ansi sequences when using a spaced styler (useSpaceStyler==true). This happens because the processing happens rune wise and is not ansi aware.

Setup

  • OS: Fedora release 38 (Thirty Eight)
  • Shell bash
  • Terminal Emulator gnome-terminal-server
  • Terminal Multiplexer
  • Locale en_US.UTF-8

To Reproduce
see source code which results in

Source Code

package main

import (
	"fmt"

	"github.com/charmbracelet/lipgloss"
)

func main() {
	fancy := "Fancy"
	fmt.Println(fancy)

	fancyBold := lipgloss.NewStyle().Bold(true).Render(fancy)
	fmt.Println(fancyBold)

	fancyBoldStrikethrough := lipgloss.NewStyle().Strikethrough(true).Render(fancyBold)
	fmt.Println(fancyBoldStrikethrough)
}
Result

Fancy
Fancy
1mFancy[0m

Expected behavior
Fancy
Fancy
Fancy (with strike-through effect)

Additional context
space styling can be enabled other ways as well but ".Strikethrough(true)" will do just fine.

@Sojamann
Copy link
Author

Sojamann commented Oct 7, 2023

I thought of something like:

if useSpaceStyler {
         // Look for spaces and apply a different styler
         // while remaining ansi aware
	withinAnsi := false
	for _, r := range l[i] {
		switch {
		case withinAnsi && ansi.IsTerminator(r):
			withinAnsi = false
			b.WriteRune(r)
		case r == ansi.Marker || withinAnsi:
			withinAnsi = true
			b.WriteRune(r)
		default: // aka !withinAnsi
			if unicode.IsSpace(r) {
				b.WriteString(teSpace.Styled(string(r)))
				continue
			}
			b.WriteString(te.Styled(string(r)))
		}
	}
} // ....

while this solution correctly applies the strike through effect only the first letter 'F' is bold as the first render call places the reset at the end which ends the bold effect after rendering the 'F' ...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant