CSV to HTML translation: Difference between revisions

Content added Content deleted
Line 1,283: Line 1,283:
=={{header|OCaml}}==
=={{header|OCaml}}==


OCaml posseses a [http://forge.ocamlcore.org/projects/csv/ CSV module] but we do not use it hereafter because the CSV data does not contain comas.
<lang ocaml>let csv_data = "\

<lang ocaml>open Printf

let csv_data = "\
Character,Speech
Character,Speech
The multitude,The messiah! Show us the messiah!
The multitude,The messiah! Show us the messiah!
Line 1,292: Line 1,296:
The multitude,Behold his mother! Behold his mother!"
The multitude,Behold his mother! Behold his mother!"


(* some utility functions *)
(* General HTML escape *)
let escape =
let html_escapes = Str.regexp "\\([^A-Za-z0-9 ;!?'/]\\)" in
let esc s = sprintf "&#%04d;" (Char.code s.[Str.group_beginning 1]) in
Str.global_substitute html_escapes esc


let string_of_char = String.make 1 ;;
let nl = Str.regexp "\n\r?"
let coma = Str.regexp ","


let list_of_csv csv =
let string_of_string_list = String.concat ""
List.map (fun l -> Str.split coma l) (Str.split nl csv)

let char_list_of_string str =
let lst = ref [] in
String.iter (fun c -> lst := c :: !lst) str;
(List.rev !lst)

(** escape chars that need to be escaped *)
let escape str =
let chars = char_list_of_string str in
let rec aux acc = function
| [] -> (List.rev acc)
| c :: tl ->
match c with
| 'A'..'Z'
| 'a'..'z'
| '0'..'9'
| ' ' | ';' | '!' | '?' ->
aux ((string_of_char c)::acc) tl
| c ->
let esc_char = (Printf.sprintf "&#%04d;" (Char.code c)) in
aux (esc_char::acc) tl
in
string_of_string_list (aux [] chars)

(* now the main part *)

let extract_csv_data ~csv_data:s =
let len = String.length s in
let rec aux acc_line acc i j =
if i = len
then
let sub = String.sub s j (i - j) in
List.rev ((acc_line @ [escape sub])::acc)
else
match csv_data.[i] with
| ',' ->
let sub = String.sub s (j+1) (i - j - 1) in
aux ((escape sub)::acc_line) acc (succ i) (succ i)
| '\n' ->
let sub = String.sub s j (i - j) in
let acc_line = List.rev (escape sub::acc_line) in
aux [] (acc_line::acc) (succ i) i
| _ ->
aux acc_line acc (succ i) j
in
aux [] [] 0 (-1)


let print_html_table segments =
let print_html_table segments =
print_string "<table>\n";
printf "<table>\n";
List.iter (fun line ->
List.iter (fun line ->
print_string "<tr>\n";
printf "<tr>";
List.iter (Printf.printf " <td>%s</td>") line;
List.iter (fun c -> printf "<td>%s</td>" (escape c)) line;
print_string "\n</tr>\n";
printf "</tr>\n";
) segments;
) segments;
print_string "</table>\n";
printf "</table>\n";
;;
;;


let () =
let () =
print_html_table (list_of_csv csv_data)</lang>
let segments = extract_csv_data ~csv_data in
print_html_table segments</lang>


Sample html output:
Sample html output:


<lang html5><table>
<lang html5><table>
<tr><td>Character</td><td>Speech</td></tr>
<tr>
<td>Character</td> <td>Speech</td>
<tr><td>The multitude</td><td>The messiah! Show us the messiah!</td></tr>
<tr><td>Brians mother</td><td>&#0060;angry&#0062;Now you listen here! He's not the messiah; he's a very naughty boy! Now go away!&#0060;/angry&#0062;</td></tr>
</tr>
<tr><td>The multitude</td><td>Who are you?</td></tr>
<tr>
<td>The multitude</td> <td>The messiah! Show us the messiah!</td>
<tr><td>Brians mother</td><td>I'm his mother; that's who!</td></tr>
<tr><td>The multitude</td><td>Behold his mother! Behold his mother!</td></tr>
</tr>
</table> </lang>
<tr>
<td>Brians mother</td> <td>&#0060;angry&#0062;Now you listen here! He&#0039;s not the messiah; he&#0039;s a very naughty boy! Now go away!&#0060;&#0047;angry&#0062;</td>
</tr>
<tr>
<td>The multitude</td> <td>Who are you?</td>
</tr>
<tr>
<td>Brians mother</td> <td>I&#0039;m his mother; that&#0039;s who!</td>
</tr>
<tr>
<td>The multitude</td> <td>Behold his mother! Behold his mother!</td>
</tr>
</table></lang>


Extra credit version:
Extra credit version:
<lang ocaml>let csv_data = "\
<lang ocaml>open Printf

let csv_data = "\
Character,Speech
Character,Speech
The multitude,The messiah! Show us the messiah!
The multitude,The messiah! Show us the messiah!
Line 1,391: Line 1,344:
The multitude,Behold his mother! Behold his mother!"
The multitude,Behold his mother! Behold his mother!"


(* some utility functions *)
(* General HTML escape *)
let escape =
let html_escapes = Str.regexp "\\([^A-Za-z0-9 ;!?'/]\\)" in
let esc s = sprintf "&#%04d;" (Char.code s.[Str.group_beginning 1]) in
Str.global_substitute html_escapes esc


let string_of_char = String.make 1 ;;
let nl = Str.regexp "\n\r?"
let coma = Str.regexp ","


let list_of_csv csv =
let string_of_string_list = String.concat ""
List.map (fun l -> Str.split coma l) (Str.split nl csv)

let char_list_of_string str =
let lst = ref [] in
String.iter (fun c -> lst := c :: !lst) str;
(List.rev !lst)

(** escape chars that need to be escaped *)
let escape str =
let chars = char_list_of_string str in
let rec aux acc = function
| [] -> (List.rev acc)
| c :: tl ->
match c with
| 'A'..'Z'
| 'a'..'z'
| '0'..'9'
| ' ' | ';' | '!' | '?' ->
aux ((string_of_char c)::acc) tl
| c ->
let esc_char = (Printf.sprintf "&#%04d;" (Char.code c)) in
aux (esc_char::acc) tl
in
string_of_string_list (aux [] chars)

(* now the main part *)

let extract_csv_data ~csv_data:s =
let len = String.length s in
let rec aux acc_line acc i j =
if i = len
then
let sub = String.sub s j (i - j) in
List.rev ((acc_line @ [escape sub])::acc)
else
match csv_data.[i] with
| ',' ->
let sub = String.sub s (j+1) (i - j - 1) in
aux (escape sub::acc_line) acc (succ i) (succ i)
| '\n' ->
let sub = String.sub s j (i - j) in
let acc_line = List.rev (escape sub::acc_line) in
aux [] (acc_line::acc) (succ i) i
| _ ->
aux acc_line acc (succ i) j
in
aux [] [] 0 (-1)


let style_th = "style='color:#000; background:#FF0;'"
let style_td = "style='color:#000; background:#8FF; \
border:1px #000 solid; padding:0.6em;'"


let print_html_table segments =
let print_html_table segments =
let print_row line =
print_string "<table>\n";
printf "<tr>";
let print_line tag_open tag_close lines =
List.iter (fun line ->
List.iter (fun c -> printf "<td>%s</td>" (escape c)) line;
Printf.printf " %s%s%s" tag_open line tag_close;
printf "</tr>\n" in
printf "<html>
) lines
in
<head>
<style type=\"text/css\">
begin match segments with
td {background-color:#ddddff; }
| head :: body ->
thead td {background-color:#ddffdd; text-align:center; }
print_string " <thead>\n";
</style>
print_string " <tr>\n";
</head>";
print_line (" <th " ^ style_th ^ ">") "</th>\n" head;
print_string " </tr>\n";
printf "<table>\n<thead>";
print_row (List.hd segments);
print_string " </thead>\n";
printf "</thead><tbody>\n";
();
List.iter print_row (List.tl segments);
print_string " <tbody>\n";
printf "</tbody>\n</table>\n</html>";

List.iter (fun line ->
print_string " <tr>\n";
List.iter (Printf.printf " <td %s>%s</td>\n" style_td) line;
print_string " </tr>\n";
) body;

print_string " </tbody>\n";
| _ -> ()
end;
print_string "</table>\n";
;;
;;


let () =
let () =
print_html_table (list_of_csv csv_data)</lang>
let segments = extract_csv_data ~csv_data in
print_html_table segments</lang>


Output:
Output:
<lang html5><table>
<lang html5><html>
<head>
<thead>
<style type="text/css">
<tr>
<th style='color:#000; background:#FF0;'>Character</th>
td {background-color:#ddddff; }
<th style='color:#000; background:#FF0;'>Speech</th>
thead td {background-color:#ddffdd; text-align:center; }
</tr>
</style>
</head><table>
</thead>
<thead><tr><td>Character</td><td>Speech</td></tr>
<tbody>
</thead><tbody>
<tr>
<tr><td>The multitude</td><td>The messiah! Show us the messiah!</td></tr>
<td style='color:#000; background:#8FF; border:1px #000 solid; padding:0.6em;'>The multitude</td>
<tr><td>Brians mother</td><td>&#0060;angry&#0062;Now you listen here! He's not the messiah; he's a very naughty boy! Now go away!&#0060;/angry&#0062;</td></tr>
<td style='color:#000; background:#8FF; border:1px #000 solid; padding:0.6em;'>The messiah! Show us the messiah!</td>
<tr><td>The multitude</td><td>Who are you?</td></tr>
</tr>
<tr><td>Brians mother</td><td>I'm his mother; that's who!</td></tr>
<tr>
<tr><td>The multitude</td><td>Behold his mother! Behold his mother!</td></tr>
<td style='color:#000; background:#8FF; border:1px #000 solid; padding:0.6em;'>Brians mother</td>
</tbody>
<td style='color:#000; background:#8FF; border:1px #000 solid; padding:0.6em;'>&#0060;angry&#0062;Now you listen here! He&#0039;s not the messiah; he&#0039;s a very naughty boy! Now go away!&#0060;&#0047;angry&#0062;</td>
</tr>
</table>
</html></lang>
<tr>
<td style='color:#000; background:#8FF; border:1px #000 solid; padding:0.6em;'>The multitude</td>
<td style='color:#000; background:#8FF; border:1px #000 solid; padding:0.6em;'>Who are you?</td>
</tr>
<tr>
<td style='color:#000; background:#8FF; border:1px #000 solid; padding:0.6em;'>Brians mother</td>
<td style='color:#000; background:#8FF; border:1px #000 solid; padding:0.6em;'>I&#0039;m his mother; that&#0039;s who!</td>
</tr>
<tr>
<td style='color:#000; background:#8FF; border:1px #000 solid; padding:0.6em;'>The multitude</td>
<td style='color:#000; background:#8FF; border:1px #000 solid; padding:0.6em;'>Behold his mother! Behold his mother!</td>
</tr>
</tbody>
</table></lang>


=={{header|OpenEdge/Progress}}==
=={{header|OpenEdge/Progress}}==