Skip to content

Commit c6a420a

Browse files
committed
wip
1 parent 1c291c0 commit c6a420a

File tree

6 files changed

+78
-38
lines changed

6 files changed

+78
-38
lines changed

PROMPT.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
This is a TUI presentation tool with transition animations based on string manipulation. I am trying to integrate images, I have
2+
manged to output symbol based images and I want to when I am not animating to output high res ones based on terminal capabilities.
3+
The image based on capabilities part is already implemented @internal/img/chafa_backend.go. The other logic is located
4+
@internal/process/image.go. The idea I had on how to implement it was to render the high res image on top of the symbol one when not
5+
animating using placeOverlay function from @internal/tui/overlay.go on the Post hook or something similar. My problem is that between
6+
the Pre and Post hook the slide will get styled by lipgloss (which is the behaviour I want or else the high res image conflicts with
7+
the lipgloss styling) meaning the position of the image might change and I need it to find where to place the overlay.
8+

internal/img/chafa_backend.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ type chafaBackend struct{}
1111

1212
const nChannels = 4
1313

14-
func (b chafaBackend) Render(path string, width, height int32) (string, error) {
14+
func (b chafaBackend) Render(path string, width, height int32, animating bool) (string, error) {
1515
var err error
1616

1717
defer func() {
@@ -24,11 +24,11 @@ func (b chafaBackend) Render(path string, width, height int32) (string, error) {
2424
}
2525
}()
2626

27-
out, err := b.render(path, width, height)
27+
out, err := b.render(path, width, height, animating)
2828
return out, err
2929
}
3030

31-
func (b chafaBackend) render(path string, width, height int32) (string, error) {
31+
func (b chafaBackend) render(path string, width, height int32, animating bool) (string, error) {
3232
pixels, pixelWidth, pixelHeight, err := chafa.Load(path)
3333
if err != nil {
3434
return "", err
@@ -44,7 +44,11 @@ func (b chafaBackend) render(path string, width, height int32) (string, error) {
4444
chafa.CanvasConfigSetGeometry(config, width, height)
4545
chafa.CanvasConfigSetCellGeometry(config, 18, 36)
4646
chafa.CanvasConfigSetCanvasMode(config, capabilities.canvasMode)
47-
chafa.CanvasConfigSetPixelMode(config, capabilities.pixelMode)
47+
if animating {
48+
chafa.CanvasConfigSetPixelMode(config, chafa.CHAFA_PIXEL_MODE_SYMBOLS)
49+
} else {
50+
chafa.CanvasConfigSetPixelMode(config, capabilities.pixelMode)
51+
}
4852
chafa.CanvasConfigSetPassthrough(config, capabilities.passthrough)
4953
chafa.CanvasConfigSetSymbolMap(config, capabilities.symbolMap)
5054

internal/img/images.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package img
22

33
type ImageBackend interface {
4-
Render(path string, width, height int32) (string, error)
4+
Render(path string, width, height int32, animating bool) (string, error)
55
}
66

77
func Get(backend string) ImageBackend {

internal/process/image.go

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,9 @@ func NewImageProcessor() *ImageProcessor {
2020
}
2121
}
2222

23-
const imgPlaceholderToken = "{{IMG-TOKEN-%d}}"
24-
25-
func (p ImageProcessor) Pre(content string) (string, error) {
23+
func (p ImageProcessor) Pre(content string, themeName string) (string, error) {
2624
// Clear all images
27-
fmt.Print("\x1b_Ga=d\x1b\\")
25+
// fmt.Print("\x1b_Ga=d\x1b\\")
2826

2927
// Regex to match markdown image syntax: ![alt text](path)
3028
imageRegex := regexp.MustCompile(`!\[([^\]]*)\]\(([^)]+)\)`)
@@ -34,32 +32,46 @@ func (p ImageProcessor) Pre(content string) (string, error) {
3432
return content, nil
3533
}
3634

35+
var parts []string
36+
lastIndex := 0
37+
indices := imageRegex.FindAllStringIndex(content, -1)
38+
3739
for i, match := range matches {
38-
fullMatch := match[0] // Full match: ![alt](path)
40+
matchStart := indices[i][0]
41+
matchEnd := indices[i][1]
42+
43+
// fullMatch := match[0] // Full match: ![alt](path)
3944
altText := match[1] // Alt text
4045
imagePath := match[2] // Image path
4146

42-
token := fmt.Sprintf(imgPlaceholderToken, i)
47+
if matchStart > lastIndex {
48+
beforeText := content[lastIndex:matchStart]
49+
parts = append(parts, renderMarkdownSection(beforeText, themeName))
50+
}
4351

44-
renderedImage, err := p.backend.Render(imagePath, 10, 10)
52+
renderedImage, err := p.backend.Render(imagePath, 80, 15, true)
4553
if err != nil {
46-
p.imageData[token] = fmt.Sprintf("[Error rendering image: %s]", altText)
47-
content = strings.Replace(content, fullMatch, token, 1)
48-
continue
54+
parts = append(parts, fmt.Sprintf("[Error rendering image: %s]", altText))
55+
} else {
56+
parts = append(parts, renderedImage)
4957
}
5058

51-
p.imageData[token] = renderedImage
52-
content = strings.Replace(content, fullMatch, token, 1)
59+
lastIndex = matchEnd
5360
}
5461

55-
return content, nil
62+
if lastIndex < len(content) {
63+
remainingText := content[lastIndex:]
64+
parts = append(parts, renderMarkdownSection(remainingText, themeName))
65+
}
66+
67+
return strings.Join(parts, ""), nil
5668
}
5769

5870
func (p ImageProcessor) Post(content string) (string, error) {
59-
for token, imgData := range p.imageData {
60-
if strings.Contains(content, token) {
61-
content = strings.ReplaceAll(content, token, imgData)
62-
}
63-
}
71+
// for token, imgData := range p.imageData {
72+
// if strings.Contains(content, token) {
73+
// content = strings.ReplaceAll(content, token, imgData)
74+
// }
75+
// }
6476
return content, nil
6577
}

internal/process/process.go

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
package process
22

3+
import (
4+
"strings"
5+
6+
"github.com/charmbracelet/glamour"
7+
)
8+
39
type PreProcessor interface {
4-
Pre(content string) (string, error)
10+
Pre(content string, themeName string) (string, error)
511
}
612

713
type PostProcessor interface {
@@ -12,3 +18,15 @@ type Processor interface {
1218
PreProcessor
1319
PostProcessor
1420
}
21+
22+
func renderMarkdownSection(text, themeName string) string {
23+
if strings.TrimSpace(text) == "" {
24+
return ""
25+
}
26+
27+
rendered, err := glamour.Render(text, themeName)
28+
if err != nil {
29+
return text
30+
}
31+
return rendered
32+
}

internal/tui/slide.go

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@ import (
44
"strings"
55

66
tea "github.com/charmbracelet/bubbletea"
7-
"github.com/charmbracelet/glamour"
8-
"github.com/charmbracelet/lipgloss"
97

108
"github.com/museslabs/kyma/internal/config"
119
"github.com/museslabs/kyma/internal/process"
@@ -61,20 +59,20 @@ func (s Slide) view() string {
6159
}
6260

6361
p := process.NewImageProcessor()
64-
data, _ := p.Pre(s.Data)
62+
out, _ := p.Pre(s.Data, themeName)
6563

6664
// Pre-process markdown to handle custom highlighting syntax
67-
out, err := processMarkdownWithHighlighting(data, themeName)
68-
if err != nil {
69-
// If preprocessing fails, fall back to regular Glamour rendering
70-
out, err = glamour.Render(s.Data, themeName)
71-
if err != nil {
72-
b.WriteString("\n\n" + lipgloss.NewStyle().
73-
Foreground(lipgloss.Color("9")). // Red
74-
Render("Error: "+err.Error()))
75-
return b.String()
76-
}
77-
}
65+
// out, err := processMarkdownWithHighlighting(data, themeName)
66+
// if err != nil {
67+
// // If preprocessing fails, fall back to regular Glamour rendering
68+
// out, err = glamour.Render(s.Data, themeName)
69+
// if err != nil {
70+
// b.WriteString("\n\n" + lipgloss.NewStyle().
71+
// Foreground(lipgloss.Color("9")). // Red
72+
// Render("Error: "+err.Error()))
73+
// return b.String()
74+
// }
75+
// }
7876

7977
if s.ActiveTransition != nil && s.ActiveTransition.Animating() {
8078
direction := s.ActiveTransition.Direction()

0 commit comments

Comments
 (0)