culr/lib/processing.ml

88 lines
2.2 KiB
OCaml

open Types
open Array
(* TODO: implement this so cli can use a dsl to specify colourising patterns *)
type culr = {
colours : colour array;
sz : int;
mutable current : int;
mutable first : bool;
mutable text_output : bool;
}
module Culriser = struct
type filter = (colour -> bool) list
type sort = int array
let run_filters (f : filter) el =
List.fold_left (fun res filt -> if not (filt el) then false else res) true f
let create ?(filters = []) (c : colour array) =
let ( @ ) = append in
let colours =
if List.length filters > 0 then
fold_left
(fun acc el -> if run_filters filters el then acc @ [| el |] else acc)
[||] c
else c
in
{
colours;
sz = length colours;
current = 0;
first = true;
text_output = false;
}
let current t = t.colours.(t.current)
let next t =
t.current <- (t.current + 1) mod t.sz;
current t
let reset t =
t.current <- 0;
t.first <- true;
t.text_output <- false
let serialise_with_colour t serialiser chunk =
Emitter.serialise serialiser chunk;
match chunk with
| Separator _ ->
if not t.first then
if t.text_output then (
Emitter.serialise serialiser (Ansi [ Fg (next t) ]);
t.text_output <- false)
else Emitter.serialise serialiser (Ansi [ Fg (current t) ])
| Delimiter _ ->
reset t;
Emitter.serialise serialiser (Ansi [ Fg (current t) ])
| Text _ ->
if t.first then t.first <- false;
if not t.text_output then t.text_output <- true
| _ -> ()
end
let ansi_filter t s =
s |> function
| Ansi a -> (
let open List in
let ol = length a
and result =
a
|> filter (function Fg _ | Bg _ -> false | _ -> true)
|> fold_left
(fun acc el ->
if el = Reset then acc @ [ el; Fg (Culriser.current t) ]
else acc @ [ el ])
[]
in
let rl = length result in
match (rl, ol) with
(* empty ansi code is equivalent to a reset *)
| 0, 0 -> Ansi [ Reset; Fg (Culriser.current t) ]
(* if we filtered everything out of it produce no tokens *)
| 0, _ -> Empty
| _, _ -> Ansi result)
| n -> n