struct

(** A (line structured) text is a list of strings. *)

type t = string list ;;

(** A text filter is a function from and to string lists. *)

type filter = string list -> string list ;;

(** Convert a string list in a raw text. Each string in the input list is treated by the function to_line in order to add a newline if needed, then the list is folded by a simple catenation (^). If the input list is empty, the result is the empty string. Examples:
# Text.to_string ["AAA";"BBB";"CCC"];;
  : string = "AAA\nBBB\nCCC\n"

# Text.to_string ["AAA";"BBB\n";"CCC"];;
  : string = "AAA\nBBB\nCCC\n"

# Text.to_string ["AAA";"BBB\n\n";"CCC"];;
  : string = "AAA\nBBB\n\nCCC\n"
*)

let to_string (sl : string list) : string = 
 let ll = List.map to_line sl in
 big (^) ll
;;


(** Convert a raw text in a structured text (a string list). This function is simply an alias for split ~squeeze ~d:'\\'. Examples:
# Text.of_string (Unix.cat "/etc/fstab")  ;;
  : string list =
["/dev/sda1   /                    reiserfs   acl,user_xattr    1 1";
 "/dev/sda3   swap                 swap       defaults          0 0";
 "/dev/sda4   /home                reiserfs   acl,user_xattr    1 1";
 "proc        /proc                proc       defaults          0 0";
 "/dev/fd0    /media/floppy        auto       noauto,user,sync  0 0"]

# Text.of_string (Unix.shell "echo aaa; echo; echo bbb");;
  : string list = ["aaa"; "bbb"]

# Text.of_string ~squeeze:false (Unix.shell "echo aaa; echo; echo bbb");;
  : string list = ["aaa"; ""; "bbb"] 
*)

let of_string = (split ~d:'\n') ;;


(** Converting raw text to matrix (list of list) of strings (words) and vice-versa. *)

module Matrix = struct

(** A (word structured) text is a matrix of strings. *)

type t = string list list;; 

(** A text matrix filter is a function from and to string list lists. *)

type filter = t -> t ;;

(** Convert a raw text in a matrix of words. By default the word delimiter is the char d=' ' and squeeze=true. Example:
# Text.Matrix.of_string (Unix.shell "ls -i -w1 /etc/ssh/")  ;;
  : string list list =
[["98624"; "moduli"]; ["98625"; "ssh_config"]; ["98626"; "sshd_config"];
 ["274747"; "ssh_host_dsa_key"]; ["274748"; "ssh_host_dsa_key.pub"];
 ["274712"; "ssh_host_key"]; ["274713"; "ssh_host_key.pub"];
 ["274750"; "ssh_host_rsa_key"]; ["274751"; "ssh_host_rsa_key.pub"]]
*)

let of_string ?(squeeze=true) ?(d=' ') x = 
 List.map (split ~squeeze ~d) (of_string x) 
;; 

(** Convert a matrix of words in a raw text. By default the word delimiter is the string d=" ".
# let m = Text.Matrix.of_string (Unix.shell "ls -l /etc/ssh/") 
  in print_string (Text.Matrix.to_string m);;
total 164
-rw------- 1 root root 132839 2006-11-11 00:12 moduli
-rw-r--r-- 1 root root 2517 2006-11-11 00:12 ssh_config
-rw-r----- 1 root root 3474 2006-11-11 00:12 sshd_config
-rw------- 1 root root 668 2006-11-20 12:50 ssh_host_dsa_key
-rw-r--r-- 1 root root 600 2006-11-20 12:50 ssh_host_dsa_key.pub
-rw------- 1 root root 525 2006-11-20 12:50 ssh_host_key
-rw-r--r-- 1 root root 329 2006-11-20 12:50 ssh_host_key.pub
-rw------- 1 root root 887 2006-11-20 12:50 ssh_host_rsa_key
-rw-r--r-- 1 root root 220 2006-11-20 12:50 ssh_host_rsa_key.pub
  : unit = ()
*)

let to_string ?(d=" ") m = 
 to_line (big (merge "\n") (List.map (big (merge d)) m)) ;;

end;; (* module Text.Matrix *)


end