(** csv.mli - comma separated values parser
*
- * $Id: csv.mli,v 1.4 2005-02-17 15:51:47 rich Exp $
+ * $Id: csv.mli,v 1.11 2007-04-23 16:42:33 rich Exp $
*)
type t = string list list
(** Representation of CSV files. *)
exception Bad_CSV_file of string
-(** Badly formed CSV files throw this exception: *)
+(** Badly formed CSV files throw this exception. *)
val lines : t -> int
(** Work out the number of lines in a CSV file. *)
val load : ?separator:char -> string -> t
(** Load a CSV file.
* @param filename CSV filename.
+ * If [filename] is ["-"] then load from [stdin].
*)
val load_rows : ?separator:char -> (string list -> unit) -> in_channel -> unit
* this function is appropriate. It parses the input one row at a time and
* calls your function once for each row.
*
- * Note that if you CSV file contains cells which have embedded
- * line feeds, then it is non-trivial to parse these lines and
- * pass them correctly to [load_rows].
- *
* @param f Callout function.
* @param chan Input file stream.
*)
(** Make the CSV data "square" (actually rectangular). This pads out
* each row with empty cells so that all rows are the same length as
* the longest row. After this operation, every row will have length
- * {!columns}.
+ * {!Csv.columns}.
+ *)
+
+val is_square : t -> bool
+(** Return true iff the CSV is "square" (actually rectangular). This
+ * means that each row has the same number of cells.
+ *)
+
+val set_columns : int -> t -> t
+(** [set_columns cols csv] makes the CSV data square by forcing the width
+ * to the given number of [cols]. Any short rows are padded with blank
+ * cells. Any long rows are truncated.
+ *)
+
+val set_rows : int -> t -> t
+(** [set_rows rows csv] makes the CSV data have exactly [rows] rows
+ * by adding empty rows or truncating rows as necessary.
+ *
+ * Note that [set_rows] does not make the CSV square. If you want it
+ * to be square, call either {!Csv.square} or {!Csv.set_columns} after.
+ *)
+
+val set_size : int -> int -> t -> t
+(** [set_size rows cols csv] makes the CSV data square by forcing the
+ * size to [rows * cols], adding blank cells or truncating as necessary.
+ * It is the same as calling [set_columns cols (set_rows rows csv)]
+ *)
+
+val sub : int -> int -> int -> int -> t -> t
+(** [sub r c rows cols csv] returns a subset of [csv]. The subset is
+ * defined as having top left corner at row [r], column [c] (counting
+ * from [0]) and being [rows] deep and [cols] wide.
+ *
+ * The returned CSV will be square.
+ *)
+
+val compare : t -> t -> int
+(** Compare two CSV files for equality, ignoring blank cells at the end
+ * of a row, and empty rows appended to one or the other. This is
+ * "semantic" equality - roughly speaking, the two CSV files would
+ * look the same if opened in a spreadsheet program.
+ *)
+
+val concat : t list -> t
+(** Concatenate CSV files so that they appear side by side, arranged
+ * left to right across the page. Each CSV file (except the final
+ * one) is first squared.
+ *
+ * (To concatenate CSV files so that they appear from top to bottom,
+ * just use {!List.concat}).
+ *)
+
+val to_array : t -> string array array
+val of_array : string array array -> t
+(** Convenience functions to convert to and from a matrix representation.
+ * [to_array] will produce a ragged matrix (not all rows will have the
+ * same length) unless you call {!Csv.square} first.
*)
val associate : string list -> t -> (string * string) list list
* etc. ]
* v}
*
- * Each row is turned into an assoc list (see {!List.assoc}).
+ * Each row is turned into an assoc list (see [List.assoc]).
*
* If a row is too short, it is padded with empty cells ([""]). If
* a row is too long, it is truncated.
val print_readable : t -> unit
(** Print the CSV data to [stdout] in a human-readable format. Not much
* is guaranteed about how the CSV is printed, except that it will be
- * easier to follow than a "raw" output done with {!print}. This is
+ * easier to follow than a "raw" output done with {!Csv.print}. This is
* a one-way operation. There is no easy way to parse the output of
* this command back into CSV data.
*)
val save_out_readable : out_channel -> t -> unit
-(** As for {!print_readable}, allowing the output to be sent to a channel. *)
+(** As for {!Csv.print_readable}, allowing the output to be sent to a channel.
+ *)