| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204 |
- open CamomileLibrary
- let input_all ic =
- let bufsize = 512 in
- let buf = Bytes.create bufsize in
- let rec loop cur =
- match input ic buf 0 bufsize with
- | 0 -> close_in ic; cur
- | nread -> loop (cur ^ Bytes.sub_string buf 0 nread)
- in
- loop ""
- let pad_right s =
- let rec repeat s n = if n < 1 then "" else s ^ (repeat s (n - 1)) in
- let lines = Str.split (Str.regexp " *\n") s in
- let cmp_length max line =
- let l = String.length line in
- if l > max then l else max
- in
- let w = List.fold_left cmp_length 0 lines in
- let pad buf line = buf ^ line ^ repeat " " (w - String.length line + 1) ^ "\n" in
- List.fold_left pad "" lines
- let artify replace_pat s =
- let w = try String.index s '\n' + 1 with Not_found -> String.length s in
- let h = String.length s / w in
- let char_at x y =
- if x < 0 || y < 0 || x >= w || y >= h
- then ' '
- else String.get s (y * w + x)
- in
- let make_pat i =
- let x = i mod w in
- let y = i / w in
- let o ox oy = char_at (x + ox) (y + oy) in
- let m1 = -1 in
- [|o m1 m1; o 0 m1; o 1 m1;
- o m1 0; o 0 0; o 1 0;
- o m1 1; o 0 1; o 1 1|]
- in
- UTF8.init (String.length s) (fun i -> replace_pat (make_pat i))
- let u s = UTF8.get s 0
- let replace_pat_safe = function
- | [| _ ; '|'|'+'; _ ;
- '-'|'+'; '+' ; '-'|'+';
- _ ; '|'|'+'; _ |] -> u "┼"
- | [| _ ; _ ; _ ;
- '-'|'+'; '+' ; '-'|'+';
- _ ; '|'|'+'; _ |] -> u "┬"
- | [| _ ; '|'|'+'; _ ;
- '-'|'+'; '+' ; '-'|'+';
- _ ; _ ; _ |] -> u "┴"
- | [| _ ; '|'|'+'; _ ;
- _ ; '+' ; '-'|'+';
- _ ; '|'|'+'; _ |] -> u "├"
- | [| _ ; '|'|'+'; _ ;
- '-'|'+'; '+' ; _ ;
- _ ; '|'|'+'; _ |] -> u "┤"
- | [| _ ; _ ; _ ;
- _ ; '+' ; '-'|'+';
- _ ; '|'|'+'; _ |] -> u "┌"
- | [| _ ; '|'|'+'; _ ;
- _ ; '+' ; '-'|'+';
- _ ; _ ; _ |] -> u "└"
- | [| _ ; _ ; _ ;
- '-'|'+'; '+' ; _ ;
- _ ; '|'|'+'; _ |] -> u "┐"
- | [| _ ; '|'|'+'; _ ;
- '-'|'+'; '+' ; _ ;
- _ ; _ ; _ |] -> u "┘"
- | [| _ ; _ ; _ ;
- _ ; '-' ; '-'|'+';
- _ ; _ ; _ |]
- | [| _ ; _ ; _ ;
- '-'|'+'; '-' ; _ ;
- _ ; _ ; _ |] -> u "─"
- | [| _ ; _ ; _ ;
- _ ; '|' ; _ ;
- _ ; '|'|'+'; _ |]
- | [| _ ; '|'|'+'; _ ;
- _ ; '|' ; _ ;
- _ ; _ ; _ |] -> u "│"
- | [| _ ; '|'|'+'; _ ;
- '=' ; '+' ; '=' ;
- _ ; '|'|'+'; _ |] -> u "╪"
- | [| _ ; _ ; _ ;
- '=' ; '+' ; '=' ;
- _ ; '|'|'+'; _ |] -> u "╤"
- | [| _ ; '|'|'+'; _ ;
- '=' ; '+' ; '=' ;
- _ ; _ ; _ |] -> u "╧"
- | [| _ ; '|'|'+'; _ ;
- _ ; '+' ; '=' ;
- _ ; '|'|'+'; _ |] -> u "╞"
- | [| _ ; '|'|'+'; _ ;
- '=' ; '+' ; _ ;
- _ ; '|'|'+'; _ |] -> u "╡"
- | [| _ ; _ ; _ ;
- _ ; '+' ; '=' ;
- _ ; '|'|'+'; _ |] -> u "╒"
- | [| _ ; '|'|'+'; _ ;
- _ ; '+' ; '=' ;
- _ ; _ ; _ |] -> u "╘"
- | [| _ ; _ ; _ ;
- '=' ; '+' ; _ ;
- _ ; '|'|'+'; _ |] -> u "╕"
- | [| _ ; '|'|'+'; _ ;
- '=' ; '+' ; _ ;
- _ ; _ ; _ |] -> u "╛"
- | [| _ ; _ ; _ ;
- _ ; '=' ; '='|'+';
- _ ; _ ; _ |]
- | [| _ ; _ ; _ ;
- '='|'+'; '=' ; _ ;
- _ ; _ ; _ |] -> u "═"
- | [| _ ; _ ; _ ;
- _ ; c ; _ ;
- _ ; _ ; _ |] -> UChar.of_char c
- | _ -> failwith "invalid pattern"
- let replace_pat_unsafe =
- let both_double x y = if x = y then x else '-' in
- let pick_double x s = UTF8.get s (if x = '=' then 1 else 0) in
- function
- | [| _ ; ' '; _ ;
- ' '; '+'; ' ';
- _ ; ' '; _ |] -> u "·" (* XXX: maybe just leave the '+' *)
- | [| _ ; ' '; _ ;
- _ ; '+'; ' ';
- _ ; ' '; _ |] -> u "╴"
- | [| _ ; ' '; _ ;
- ' '; '+'; _ ;
- _ ; ' '; _ |] -> u "╶"
- | [| _ ; ' '; _ ;
- ' '; '+'; ' ';
- _ ; _ ; _ |] -> u "╷"
- | [| _ ; _ ; _ ;
- ' '; '+'; ' ';
- _ ; ' '; _ |] -> u "╵"
- | [| _ ; ' '; _ ;
- ' '; '+'; x ;
- _ ; _ ; _ |] -> pick_double x "┌╒"
- | [| _ ; _ ; _ ;
- ' '; '+'; x ;
- _ ; ' '; _ |] -> pick_double x "└╘"
- | [| _ ; ' '; _ ;
- x ; '+'; ' ';
- _ ; _ ; _ |] -> pick_double x "┐╕"
- | [| _ ; _ ; _ ;
- x ; '+'; ' ';
- _ ; ' '; _ |] -> pick_double x "┘╛"
- | [| _ ; ' '; _ ;
- x ; '+'; y ;
- _ ; _ ; _ |] -> pick_double (both_double x y) "┬╤"
- | [| _ ; _ ; _ ;
- x ; '+'; y ;
- _ ; ' '; _ |] -> pick_double (both_double x y) "┴╧"
- | [| _ ; _ ; _ ;
- ' '; '+'; x ;
- _ ; _ ; _ |] -> pick_double x "├╞"
- | [| _ ; _ ; _ ;
- x ; '+'; ' ';
- _ ; _ ; _ |] -> pick_double x "┤╡"
- | [| _ ; _ ; _ ;
- x ; '+'; y ;
- _ ; _ ; _ |] -> pick_double (both_double x y) "┼╪"
- | [| _ ; _ ; _ ;
- _ ; '-' ; '-'|'+';
- _ ; _ ; _ |]
- | [| _ ; _ ; _ ;
- '-'|'+'; '-' ; _ ;
- _ ; _ ; _ |] -> u "─"
- | [| _ ; _ ; _ ;
- _ ; '|' ; _ ;
- _ ; '|'|'+'; _ |]
- | [| _ ; '|'|'+'; _ ;
- _ ; '|' ; _ ;
- _ ; _ ; _ |] -> u "│"
- | [| _ ; _ ; _ ;
- '-'|'='|'+'; '='; _ ;
- _ ; _ ; _ |]
- | [|_ ; _ ; _ ;
- _ ; '='; '-'|'='|'+';
- _ ; _ ; _ |] -> u "═"
- | [|_; _; _;
- _; c; _;
- _; _; _|] -> UChar.of_char c
- | _ -> failwith "invalid pattern"
- let () =
- let args = List.tl (Array.to_list Sys.argv) in
- let replace_pat =
- if List.mem "-s" args
- then replace_pat_safe
- else replace_pat_unsafe
- in
- stdin |> input_all |> pad_right |> artify replace_pat |> print_endline
|