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!" |
||
(* |
(* 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 |
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 = |
||
printf "<table>\n"; |
|||
List.iter (fun line -> |
List.iter (fun line -> |
||
printf "<tr>"; |
|||
List.iter ( |
List.iter (fun c -> printf "<td>%s</td>" (escape c)) line; |
||
printf "</tr>\n"; |
|||
) segments; |
) segments; |
||
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> |
|||
<tr><td>The multitude</td><td>The messiah! Show us the messiah!</td></tr> |
|||
<tr><td>Brians mother</td><td><angry>Now you listen here! He's not the messiah; he's a very naughty boy! Now go away!</angry></td></tr> |
|||
</tr> |
|||
<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><td>The multitude</td><td>Behold his mother! Behold his mother!</td></tr> |
|||
</tr> |
|||
</table> </lang> |
|||
<tr> |
|||
<td>Brians mother</td> <td><angry>Now you listen here! He's not the messiah; he's a very naughty boy! Now go away!</angry></td> |
|||
</tr> |
|||
<tr> |
|||
<td>The multitude</td> <td>Who are you?</td> |
|||
</tr> |
|||
<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> |
|||
</table></lang> |
|||
Extra credit version: |
Extra credit version: |
||
<lang ocaml> |
<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!" |
||
(* |
(* 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 |
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 |
List.iter (fun c -> printf "<td>%s</td>" (escape c)) line; |
||
printf "</tr>\n" in |
|||
printf "<html> |
|||
) lines |
|||
<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; |
|||
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>< |
<lang html5><html> |
||
<head> |
|||
<thead> |
|||
<style type="text/css"> |
|||
<tr> |
|||
td {background-color:#ddddff; } |
|||
thead td {background-color:#ddffdd; text-align:center; } |
|||
</ |
</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><angry>Now you listen here! He's not the messiah; he's a very naughty boy! Now go away!</angry></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;'><angry>Now you listen here! He's not the messiah; he's a very naughty boy! Now go away!</angry></td> |
|||
</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'm his mother; that'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}}== |