ocaml-mlx / mlx

OCaml .mlx syntax dialect which adds JSX syntax expressions
Other
95 stars 2 forks source link

Generated html is all on a single line which makes it hard to embed code blocks in pages #12

Open gridbugs opened 17 hours ago

gridbugs commented 17 hours ago

It's common to embed code snippets in web pages using html like:

<pre><code><span>first line</span>
<span>second line</span>
<span>third line</span></code></pre>

I've tried to do this in a page generated with mlx:

let page () =
  <html>
    <body>
<pre><code><span>"first line"</span>
<span>"second line"</span>
<span>"third line"</span></code></pre>
    </body>
  </html>

let () =
  Dream.run
  @@ Dream.logger
  @@ Dream.router [
    Dream.get "/" (fun _ ->
      let html = JSX.render <page /> in
      Dream.html html)
  ]

But this generates a page where all three lines of code are concatenated on a single line:

first linesecond linethird line

Looking at the generated html, the reason is clear:

<!DOCTYPE html><html><body><pre><code><span>first line</span><span>second line</span><span>third line</span></code></pre></body></html>

The html is all on a single line. My intention of using <pre> tags was for the line breaks in the code to be respected by the browser, and because MLX looks like html, I expected it to work the same way with regard to <pre> tags.

It's tempting to use css to treat each line of code as a block element but note that this will not work, as copy/pasted code will not include line breaks and all appear on a single line (which is kind of ironic!). My current workaround is to explicitly add a <br/> tag to the end of each line of code, but I would rather not have to do this.

Is it possible to generate html that respects the original layout of the mlx template in terms of whitespace (at least inside <pre> tags)? If not, what would be the recommended way of embedding code blocks in pages generated by mlx?

andreypopp commented 15 hours ago

I assume JSX comes from https://github.com/davesnx/html_of_jsx cc @davesnx

andreypopp commented 13 hours ago

I actually think this is works as expected and also matches how React's JSX work.

Need to include newline explicitly either via <br/> or just include \n in the string content.

andreypopp commented 11 hours ago

or use block element, e.g. <div /> instead of span

davesnx commented 9 hours ago

It's related on how JSX.render work indeed. It looks like you don't want to render and send it as an HTML, but rather "inline" HTML, but not run it.

A few options:

In the html_of_jsx side of things, there's no information about the indentation, since it's just a DSL for HTML, and also don't expect mlx to respect it neither.