Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoid breaking between text nodes #300

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 18 additions & 6 deletions lib/xml_print.ml
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,10 @@ struct
close_box indent fmt
end

let elt_needs_cut = function
| Comment _ | Node _ | Leaf _ -> true
| Entity _ | PCDATA _ | EncodedPCDATA _ | Empty -> false

let rec pp_tag encode indent fmt tag attrs children =
match children with
| [] -> pp_closedtag encode indent fmt tag attrs
Expand All @@ -276,13 +280,13 @@ struct
(open_box indent)
(pp_tag_and_attribs encode indent) (tag, attrs)
(cut indent)
(pp_elts encode indent) children
(pp_elts true encode indent) children
(close_box indent)
(cut indent)
tag ;
close_box indent fmt

and pp_elt encode indent fmt elt = match content elt with
and pp_elt encode indent fmt = function
| Comment texte ->
Format.fprintf fmt "<!--%s-->" (escape_comment texte)

Expand All @@ -303,10 +307,18 @@ struct

| Empty -> ()

and pp_elts encode indent =
Format.pp_print_list
~pp_sep:(fun fmt () -> cut indent fmt)
(pp_elt encode indent)
and pp_elts prev_did_cut encode indent fmt = function
| elt :: tl ->
let elt = content elt in
let need_cut = elt_needs_cut elt in
if not prev_did_cut && need_cut then cut indent fmt;
pp_elt encode indent fmt elt;
if need_cut then cut indent fmt;
pp_elts need_cut encode indent fmt tl
| [] -> ()

let pp_elt encode indent fmt elt =
pp_elt encode indent fmt (content elt)

let pp ?(encode=encode_unsafe_char) ?(indent=false) () =
pp_elt encode indent
Expand Down
17 changes: 17 additions & 0 deletions test/test_html.ml
Original file line number Diff line number Diff line change
Expand Up @@ -82,11 +82,28 @@ let escaping = "html escaping", tyxml_tests Html.[

]

let indent = "html indent", tyxml_tests ~indent:true Html.[
"no break between text nodes",
p [
span ~a:[ a_class [ "some padding ............................" ] ] [
txt "some text here"; txt ". and here"
]
],
"<p>\n <span class=\"some padding ............................\">\n some text here. and here\n </span>\n</p>";

"no break between inline nodes (failing)",
p ~a:[ a_class [ "some padding ............................" ] ] [
txt "some text here"; span [ txt ". and here" ]
],
"<p class=\"some padding ............................\">some text here\n <span>. and here</span>\n</p>"

]

let tests = [
html_elements ;
html_attributes ;
escaping ;
indent ;
]

let () = Alcotest.run "tyxml" tests
6 changes: 3 additions & 3 deletions test/tyxml_test.ml
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ open Tyxml

(* Basic alcotest machinery *)

let to_string = Format.asprintf "%a" (Html.pp_elt ())
let to_string ?indent = Format.asprintf "%a" (Html.pp_elt ?indent ())

let tyxml_tests l =
let tyxml_tests ?indent l =
let f (name, (ty : Html_types.body_content Html.elt), s) =
name, `Quick, fun () -> Alcotest.(check string) name (to_string ty) s
name, `Quick, fun () -> Alcotest.(check string) name (to_string ?indent ty) s
in
List.map f l

Expand Down