glamour icon indicating copy to clipboard operation
glamour copied to clipboard

`Render` fills shorter lines with spaces

Open gsalvatella opened this issue 1 year ago • 5 comments

The following program:

func main() {
	txt, _ := glamour.Render("Hello World", "auto")
	fmt.Printf(strings.Replace(txt, " ", "_", -1))
}

Produces the following output:

__Hello_World_________________________________________________________________

The rendering engine adds spaces to every line until the value of WordWrap (80 by default). This resizes shorter strings and prevents lipgloss.{Width,Height} from measuring the actual size of a cell. Notice that strings.TrimSpace() won't work here. The spaces are intermingled with escape codes in a convoluted way. You can test this by writing txt to a file. Is this the intended behavior?

gsalvatella avatar May 20 '23 23:05 gsalvatella

I believe that is expected due to the nature of TUIs. In order to respect the widths defined by the user, in this case 80 characters, it needs to get filled with whitespace to make that width consistent across all lines. Otherwise any borders would be staggered depending on the width of each line.

Is this blocking something for you? We might be able to find a workaround if we have a better idea of what you're trying to do :)

bashbunni avatar May 22 '23 21:05 bashbunni

Let's say you want to center some glamorous text in the screen:

txt, _ := glamour.Render("Hello World", "auto")
vp, hp := viewport.Height - lipgloss.Height(txt), viewport.Width - lipgloss.Width(txt)
txt = lipgloss.NewStyle().Padding(vp/2, hp/2).Render(txt)

This will not work because the W and H that lipgloss measures are incorrect.

In order to respect the widths defined by the user

The word wrap width should have nothing to do with the margin or padding. The reflow library itself doesn't add any blank spaces for text shorter than the wrap width. The blank space addition happens here. It seems that BlockStack.Width computes the "available rendering width" using the passed WordWrap option, instead of the actual width of the stack.

If at all, I would say that padding and margin should be the ones defining the word wrap width, as it happens in e.g. HTML/CSS, and not the other way around?

gsalvatella avatar May 23 '23 01:05 gsalvatella

@gsalvatella ah gotcha, thank you so much for the info and context! @muesli any thoughts on this one?

bashbunni avatar May 23 '23 17:05 bashbunni

We pad the content to ensure the background color gets rendered.

muesli avatar May 23 '23 19:05 muesli

So the background width is set throught the WordWrap option? Why should glamour be anyway responsible for the background or the document layout? Don't you think this would be better handled in a higher level lib like a bubble (e.g viewport)? This would make glamour seamlessly integrate with lipgloss to create layouts containing rendered markdown in a flexible way, while resembling more the behavior of goldmark

gsalvatella avatar May 24 '23 01:05 gsalvatella