tyxml icon indicating copy to clipboard operation
tyxml copied to clipboard

Indentation changes rendering of <pre>

Open Julow opened this issue 2 years ago • 6 comments

The following code with indentation enabled renders a line break before the closing </pre>:

    <div><p>some doc ..............................</p>
     <pre><code><span>some code of just the right length ....</span></code>
     </pre><p>some more doc</p>

This adds an extra blank line to the pre element, which renders differently whether indentation is enabled or not.

open Tyxml.Html

let content =
  html
    (head (title (txt "example")) [])
    (body
       [
         div
           [
             div
               [
                 div
                   [
                     p [ txt "some doc .............................." ];
                     pre
                       [
                         code
                           [
                             span
                               [ txt "some code of just the right length ...." ];
                           ];
                       ];
                     p [ txt "some more doc" ];
                   ];
               ];
           ];
       ])

let () =
  Format.printf "%a" (pp ~indent:true ()) content

Julow avatar Jul 13 '21 13:07 Julow

I have an other example where the indent option adds a blank line before and after the code block but also adds visible indentation to every lines:

open Tyxml.Html

let content =
  html
    (head (title (txt "example")) [])
    (body
       [
         div
           [
             h2 [ txt "example" ];
             pre
               [
                 code
                   [
                     txt
                       (List.init 20 (fun _ -> "a lot of code")
                       |> String.concat "\n");
                   ];
               ];
           ];
       ])

let () =
  Format.printf "%a" (pp ~indent:true ()) content

Julow avatar Jul 13 '21 13:07 Julow

Yes, it's sort-of-known that indent:true is not very good with pre elements (see https://github.com/ocsigen/tyxml/issues/285). In the meantime, disable indentation should work well. It's not clear to me how to solve the problem reliably within tyxml ....

Drup avatar Jul 13 '21 13:07 Drup

I've found a similar bug that doesn't involve the pre element: https://github.com/ocsigen/tyxml/issues/288 It's less of an edge case but perhaps it can be fixed easily, which would help the pre issue ?

Would this work (to fix https://github.com/ocsigen/tyxml/issues/288) ?

  • Never insert a line break before or after a text element
  • Never indent text (if a txt element contains a newline, it is not indented)

Julow avatar Jul 13 '21 13:07 Julow

@Drup I just had a similar problem with ~indent:true adding unwanted white space.

Would it work to just add some List.fold instead of pp_list here: https://github.com/ocsigen/tyxml/blob/157c7951f5a67b88cb3c465768bbcc1f8f1d91fa/lib/xml_print.ml#L273-L279 ?

So that children of the node that are PCDATA would not have cuts before and after them?

smondet avatar Sep 05 '21 13:09 smondet

That might work, could you try it ?

Drup avatar Sep 08 '21 12:09 Drup

It seems the only safe way to add whitespace is to check whether we are in a context where inter-element whitespace does not matter. (Which was called the "box model" in HTML4). Only in such a context we cut; otherwise we should proceed as if indent is false.

favonia avatar Jun 08 '22 16:06 favonia