background.go 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. package styles
  2. import (
  3. "fmt"
  4. "regexp"
  5. "strconv"
  6. "strings"
  7. "github.com/charmbracelet/lipgloss"
  8. )
  9. var ansiEscape = regexp.MustCompile("\x1b\\[[0-9;]*m")
  10. func getColorRGB(c lipgloss.TerminalColor) (uint8, uint8, uint8) {
  11. r, g, b, a := c.RGBA()
  12. // Un-premultiply alpha if needed
  13. if a > 0 && a < 0xffff {
  14. r = (r * 0xffff) / a
  15. g = (g * 0xffff) / a
  16. b = (b * 0xffff) / a
  17. }
  18. // Convert from 16-bit to 8-bit color
  19. return uint8(r >> 8), uint8(g >> 8), uint8(b >> 8)
  20. }
  21. func ForceReplaceBackgroundWithLipgloss(input string, newBgColor lipgloss.TerminalColor) string {
  22. r, g, b := getColorRGB(newBgColor)
  23. newBg := fmt.Sprintf("48;2;%d;%d;%d", r, g, b)
  24. return ansiEscape.ReplaceAllStringFunc(input, func(seq string) string {
  25. // Extract content between "\x1b[" and "m"
  26. content := seq[2 : len(seq)-1]
  27. tokens := strings.Split(content, ";")
  28. var newTokens []string
  29. // Skip background color tokens
  30. for i := 0; i < len(tokens); i++ {
  31. if tokens[i] == "" {
  32. continue
  33. }
  34. val, err := strconv.Atoi(tokens[i])
  35. if err != nil {
  36. newTokens = append(newTokens, tokens[i])
  37. continue
  38. }
  39. // Skip background color tokens
  40. if val == 48 {
  41. // Skip "48;5;N" or "48;2;R;G;B" sequences
  42. if i+1 < len(tokens) {
  43. if nextVal, err := strconv.Atoi(tokens[i+1]); err == nil {
  44. switch nextVal {
  45. case 5:
  46. i += 2 // Skip "5" and color index
  47. case 2:
  48. i += 4 // Skip "2" and RGB components
  49. }
  50. }
  51. }
  52. } else if (val < 40 || val > 47) && (val < 100 || val > 107) && val != 49 {
  53. // Keep non-background tokens
  54. newTokens = append(newTokens, tokens[i])
  55. }
  56. }
  57. // Add new background if provided
  58. if newBg != "" {
  59. newTokens = append(newTokens, strings.Split(newBg, ";")...)
  60. }
  61. if len(newTokens) == 0 {
  62. return ""
  63. }
  64. return "\x1b[" + strings.Join(newTokens, ";") + "m"
  65. })
  66. }