seanhess / web-view

Typed HTML with simplified layout, and easy composable styles. Inspired by Tailwindcss and Elm UI
Other
32 stars 1 forks source link

Multiple inline elements without extra whitespace #4

Closed kfigiela closed 2 weeks ago

kfigiela commented 3 weeks ago

Web-view renderer adds newlines and indentation for pretty formatted human-readable output. This is not a problem for block/flex elements, but is definitely an issue when it comes to inline elements and this is well known issue related to pretty printing.

Let's consider this trivial example, for real-world use-case consider code highlightning.

renderText $ do
  text "foo" 
  tag "span" id "/" 
  text "bar"

One would expect this to render foo<span>/</span>bar, however, this is rendered with extra whitespace as foo\n\n<span>/</span>\n\nbar\n and the user will see foo / bar instead of foo/bar. There are workarounds available and we can just use raw, but none of this is pretty.

Any ideas how to tackle this?

seanhess commented 3 weeks ago

Hmm... We could add a low-level variable to Element that specifies whether it should be followedf by a newline or not, which might allow us to collapse them when rendering

But, web-view strongly encourages flexbox (built in to row and col), which overrides any whitespace, and I believe dodges any rendering issues related to this. The top answer on your workaround link mentions this. Can we get some sample code demonstrating a real-world issue?

-- user sees "foo/bar"
renderText $ row id $ do
  text "foo" 
  tag "span" id "/" 
  text "bar"
-- user sees "foo / bar"
renderText $ row (gap 5) $ do
  text "foo" 
  tag "span" id "/" 
  text "bar"
kfigiela commented 3 weeks ago

The most trivial example is a sentence with a link, which is followed by punctation mark. My use case is "syntax" "highlighting" of shell command to dim shell escaping overhead. Flex does can visually help, but leaves copy-paste busted (copies excess newlines). I don't think using that would scale for any serious typesetting either. Demo: https://codepen.io/kfigiela/pen/mdYqyea

seanhess commented 2 weeks ago

@kfigiela Latest commit should fix this!

kfigiela commented 2 weeks ago

Thanks. We may still need to expose this a little bit more (add tag_ that will toggle to inline mode) and adjust a few existing helpers (e.g. Web.View.Element.link) to use it. Will open PR when time permits.

seanhess commented 1 week ago

You shouldn't need another helper: tag' will allow you to define an inline element: span = tag' (Element True) "span". The intention was that people would use tag sparingly: to define new tag functions, rather than using it directly. The way tag' is defined allows for complete cusomization of the Element (although there isn't anything to cover besides inline currently)

seanhess commented 1 week ago

But yeah, good idea to update link and similar friends