Skip to content

Instantly share code, notes, and snippets.

@keleshev
Last active April 16, 2020 08:21
Show Gist options
  • Save keleshev/5af7502e6810b8986d9f5332e7e8a795 to your computer and use it in GitHub Desktop.
Save keleshev/5af7502e6810b8986d9f5332e7e8a795 to your computer and use it in GitHub Desktop.
Simple XML pretty-printing in OCaml using Format module
#! /usr/bin/env ocaml
let fprintf = Format.fprintf
type t =
| Tag of {name: string; attributes: (string * string) list; body: t list}
| String of string
let format_attribute f (key, value) = fprintf f " %s=\"%s\"" key value
let rec format f = function
| Tag {name; attributes=[]; body} ->
let format_body = Format.pp_print_list format in
fprintf f "@[<hv 3><%s>@,%a@;<0 -3></%s>@]" name format_body body name
| Tag {name; attributes; body} ->
let format_body = Format.pp_print_list format in
let format_attributes = Format.pp_print_list format_attribute in
fprintf f "@[<hv 3><%s@[<hv>%a@]>@,%a@;<0 -3></%s>@]"
name format_attributes attributes format_body body name
| String text -> fprintf f "%s" text
let tag ?(attributes=[]) name body = Tag {name; attributes; body}
let bar s = tag "bar" [String s]
let () =
Format.set_margin 50;
let xml = tag "foo" ~attributes:["bar", "baz"; "qux", "mux"] [
tag "foo" ~attributes:[
"one", "very long attribute";
"two", "very long attribute";
"three", "very long attribute";
"four", "very long attribute";
] [bar "x"];
tag "foo" [
bar "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; bar "b"; bar "c";
];
tag "foo" [bar "a"; bar "b"; bar "c"];
tag "foo" [bar "a"; bar "b"];
] in
format Format.std_formatter xml
<foo bar="baz" qux="mux">
<foo one="very long attribute"
two="very long attribute"
three="very long attribute"
four="very long attribute">
<bar>x</bar>
</foo>
<foo>
<bar>
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
</bar>
<bar>b</bar>
<bar>c</bar>
</foo>
<foo>
<bar>a</bar>
<bar>b</bar>
<bar>c</bar>
</foo>
<foo><bar>a</bar><bar>b</bar></foo>
</foo>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment