culr/lib/emitter.ml
2024-12-01 23:57:10 +11:00

55 lines
1.5 KiB
OCaml

open Types
type serialiser = { mutable buf : string; sz : int; mutable pos : int }
let write_ansi a =
let rec intersperse sep ls =
match ls with
| [] | [ _ ] -> ls
| hd :: tl -> hd :: sep :: intersperse sep tl
and string_of_colour ?(bg = false) c =
let prefix = if bg then "4" else "3" and si = string_of_int in
c |> function
| Intrinsic i -> prefix ^ si i
| Simple i -> prefix ^ "8;5;" ^ si i
| RGB (r, g, b) -> prefix ^ "8;2;" ^ si r ^ ";" ^ si g ^ ";" ^ si b
in
let ansi =
a
|> List.map (fun a ->
match a with
| Fg c -> string_of_colour c
| Bg c -> string_of_colour ~bg:true c
| Reset -> "0"
| Other i -> string_of_int i)
|> intersperse ";"
|> List.fold_left (fun acc el -> acc ^ el) ""
in
"\x1b[" ^ ansi ^ "m"
let flush t =
if t.pos > 0 then (
print_string (String.sub t.buf 0 t.pos);
t.pos <- 0)
let serialise t chunk =
let input =
match chunk with
| Text s -> s
| Separator s -> s
| Delimiter s -> s
| Ansi a -> write_ansi a
in
let input_sz = String.length input in
if t.pos + input_sz > t.sz then flush t;
if input_sz > t.sz then print_string input
else t.buf <- (if t.pos > 0 then String.sub t.buf 0 t.pos else "") ^ input;
t.pos <- t.pos + input_sz
let create = { buf = String.empty; sz = 4096; pos = 0 }
let print_debug t =
print_endline
("pos is " ^ string_of_int t.pos ^ "\nsz is " ^ string_of_int t.sz
^ "\ncontents are: " ^ t.buf)