mirror of
https://github.com/c-cube/ocaml-containers.git
synced 2025-12-05 19:00:31 -05:00
use stag properly, add with_styling.
all tests pass again.
This commit is contained in:
parent
e397d90279
commit
38552f5c0c
2 changed files with 80 additions and 39 deletions
|
|
@ -312,8 +312,7 @@ module ANSI_codes = struct
|
||||||
|
|
||||||
exception No_such_style
|
exception No_such_style
|
||||||
|
|
||||||
(* parse a string tag.
|
(* parse a string tag. *)
|
||||||
TODO: use [stag], for OCaml >= 4.08… *)
|
|
||||||
let style_of_tag_ s = match String.trim s with
|
let style_of_tag_ s = match String.trim s with
|
||||||
| "reset" -> [`Reset]
|
| "reset" -> [`Reset]
|
||||||
| "black" -> [`FG `Black]
|
| "black" -> [`FG `Black]
|
||||||
|
|
@ -343,32 +342,44 @@ let color_enabled = ref false
|
||||||
|
|
||||||
let mark_open_style st style =
|
let mark_open_style st style =
|
||||||
Stack.push style st;
|
Stack.push style st;
|
||||||
if !color_enabled then string_of_style_list style else ""
|
if !color_enabled then ANSI_codes.string_of_style_list style else ""
|
||||||
|
|
||||||
let mark_close_style st style =
|
let mark_close_style st : string =
|
||||||
|
let style =
|
||||||
|
try
|
||||||
|
ignore (Stack.pop st); (* pop current style (if well-scoped …) *)
|
||||||
|
Stack.top st (* look at previous style *)
|
||||||
|
with Stack.Empty ->
|
||||||
|
[`Reset]
|
||||||
|
in
|
||||||
|
if !color_enabled then ANSI_codes.string_of_style_list style else ""
|
||||||
|
|
||||||
(* either prints the tag of [s] or delegate to [or_else] *)
|
(* either prints the tag of [s] or delegate to [or_else] *)
|
||||||
let mark_open_tag st ~or_else s =
|
let mark_open_tag st ~or_else (tag:stag) : string =
|
||||||
let open ANSI_codes in
|
match tag with
|
||||||
try
|
| Style style ->
|
||||||
let style = style_of_tag_ s in
|
mark_open_style st style;
|
||||||
mark_open_style st style
|
| String_tag s ->
|
||||||
with No_such_style -> or_else s
|
let open ANSI_codes in
|
||||||
|
begin
|
||||||
|
try
|
||||||
|
let style = style_of_tag_ s in
|
||||||
|
mark_open_style st style
|
||||||
|
with No_such_style -> or_else tag
|
||||||
|
end
|
||||||
|
| _ -> or_else tag
|
||||||
|
|
||||||
let mark_close_tag st ~or_else s =
|
let mark_close_tag st ~or_else (tag:stag) : string =
|
||||||
let open ANSI_codes in
|
match tag with
|
||||||
(* check if it's indeed about color *)
|
| Style _ -> mark_close_style st
|
||||||
match style_of_tag_ s with
|
| String_tag s ->
|
||||||
| _ ->
|
let open ANSI_codes in
|
||||||
let style =
|
(* check if it's indeed about color *)
|
||||||
try
|
begin match style_of_tag_ s with
|
||||||
ignore (Stack.pop st); (* pop current style (if well-scoped …) *)
|
| _ -> mark_close_style st
|
||||||
Stack.top st (* look at previous style *)
|
| exception No_such_style -> or_else tag
|
||||||
with Stack.Empty ->
|
end
|
||||||
[`Reset]
|
| _ -> or_else tag
|
||||||
in
|
|
||||||
if !color_enabled then string_of_style_list style else ""
|
|
||||||
| exception No_such_style -> or_else s
|
|
||||||
|
|
||||||
[@@@ifge 4.8]
|
[@@@ifge 4.8]
|
||||||
|
|
||||||
|
|
@ -376,36 +387,33 @@ let mark_close_tag st ~or_else s =
|
||||||
let pp_open_tag out s = pp_open_stag out (String_tag s)
|
let pp_open_tag out s = pp_open_stag out (String_tag s)
|
||||||
let pp_close_tag out () = pp_close_stag out ()
|
let pp_close_tag out () = pp_close_stag out ()
|
||||||
|
|
||||||
[@@@ocaml.warning "-3"]
|
let update_tag_funs_ (funs:formatter_stag_functions) f1 f2 =
|
||||||
let pp_get_formatter_tag_functions = pp_get_formatter_tag_functions
|
|
||||||
let pp_set_formatter_tag_functions = pp_set_formatter_tag_functions
|
|
||||||
|
|
||||||
let update_tag_funs_ funs f1 f2 =
|
|
||||||
{ funs with
|
{ funs with
|
||||||
mark_open_tag = f1 ~or_else:funs.mark_open_tag;
|
mark_open_stag = f1 ~or_else:funs.mark_open_stag;
|
||||||
mark_close_tag = f2 ~or_else:funs.mark_close_tag;
|
mark_close_stag = f2 ~or_else:funs.mark_close_stag;
|
||||||
}
|
}
|
||||||
|
|
||||||
let styling stl pp out x =
|
let with_styling stl out f =
|
||||||
pp_open_stag out (Style stl);
|
pp_open_stag out (Style stl);
|
||||||
try pp out x; pp_close_stag out ()
|
try let x = f() in pp_close_stag out (); x
|
||||||
with e -> pp_close_stag out (); raise e
|
with e -> pp_close_stag out (); raise e
|
||||||
|
|
||||||
[@@@ocaml.warning "+3"]
|
let styling stl pp out x =
|
||||||
|
with_styling stl out @@ fun () -> pp out x
|
||||||
|
|
||||||
[@@@else_]
|
[@@@else_]
|
||||||
|
|
||||||
let update_tag_funs_ funs f1 f2 =
|
let update_tag_funs_ (funs:formatter_stag_functions) f1 f2 =
|
||||||
{ funs with
|
{ funs with
|
||||||
mark_open_tag = f1 funs.mark_open_tag;
|
mark_open_stag = f1 funs.mark_open_stag;
|
||||||
mark_close_tag = f2 funs.mark_close_tag;
|
mark_close_stag = f2 funs.mark_close_stag;
|
||||||
}
|
}
|
||||||
|
|
||||||
[@@@endif]
|
[@@@endif]
|
||||||
|
|
||||||
(* add color handling to formatter [ppf] *)
|
(* add color handling to formatter [ppf] *)
|
||||||
let set_color_tag_handling ppf =
|
let set_color_tag_handling ppf =
|
||||||
let functions = pp_get_formatter_tag_functions ppf () in
|
let functions = pp_get_formatter_stag_functions ppf () in
|
||||||
let st = Stack.create () in (* stack of styles *)
|
let st = Stack.create () in (* stack of styles *)
|
||||||
let functions' =
|
let functions' =
|
||||||
update_tag_funs_ functions
|
update_tag_funs_ functions
|
||||||
|
|
@ -413,7 +421,7 @@ let set_color_tag_handling ppf =
|
||||||
(mark_close_tag st)
|
(mark_close_tag st)
|
||||||
in
|
in
|
||||||
pp_set_mark_tags ppf true; (* enable tags *)
|
pp_set_mark_tags ppf true; (* enable tags *)
|
||||||
pp_set_formatter_tag_functions ppf functions'
|
pp_set_formatter_stag_functions ppf functions'
|
||||||
|
|
||||||
let set_color_default =
|
let set_color_default =
|
||||||
let first = ref true in
|
let first = ref true in
|
||||||
|
|
@ -437,6 +445,19 @@ let set_color_default =
|
||||||
s
|
s
|
||||||
*)
|
*)
|
||||||
|
|
||||||
|
(*$R
|
||||||
|
set_color_default true;
|
||||||
|
let s = sprintf
|
||||||
|
"what is your %a? %a! No, %a! Ahhhhhhh@."
|
||||||
|
(styling [`FG `White; `Bold] string) "favorite color"
|
||||||
|
(styling [`FG `Blue] string) "blue"
|
||||||
|
(styling [`FG `Red] string) "red"
|
||||||
|
in
|
||||||
|
assert_equal ~printer:CCFun.id
|
||||||
|
"what is your \027[37;1mfavorite color\027[0m? \027[34mblue\027[0m! No, \027[31mred\027[0m! Ahhhhhhh\n"
|
||||||
|
s
|
||||||
|
*)
|
||||||
|
|
||||||
let with_color s pp out x =
|
let with_color s pp out x =
|
||||||
pp_open_tag out s;
|
pp_open_tag out s;
|
||||||
pp out x;
|
pp out x;
|
||||||
|
|
|
||||||
|
|
@ -330,6 +330,26 @@ val styling : ANSI_codes.style list -> 'a printer -> 'a printer
|
||||||
(** [styling st p] is the same printer as [p], except it locally sets
|
(** [styling st p] is the same printer as [p], except it locally sets
|
||||||
the style [st].
|
the style [st].
|
||||||
|
|
||||||
|
Example:
|
||||||
|
{[
|
||||||
|
|
||||||
|
open CCFormat;
|
||||||
|
set_color_default true;
|
||||||
|
sprintf
|
||||||
|
"what is your %a? %a! No, %a! Ahhhhhhh@."
|
||||||
|
(styling [`FG `White; `Bold] string) "favorite color"
|
||||||
|
(styling [`FG `Blue] string) "blue"
|
||||||
|
(styling [`FG `Red] string) "red"
|
||||||
|
]}
|
||||||
|
|
||||||
|
Available only on OCaml >= 4.08.
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
|
val with_styling : ANSI_codes.style list -> t -> (unit -> 'a) -> 'a
|
||||||
|
(** [with_styling style fmt f] sets the given style on [fmt],
|
||||||
|
calls [f()], then restores the previous style.
|
||||||
|
It is useful in imperative-style printers (a sequence of "print a; print b; …").
|
||||||
|
|
||||||
Available only on OCaml >= 4.08.
|
Available only on OCaml >= 4.08.
|
||||||
@since NEXT_RELEASE *)
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue