artify.ml 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. open CamomileLibrary
  2. let input_all ic =
  3. let bufsize = 512 in
  4. let buf = Bytes.create bufsize in
  5. let rec loop cur =
  6. match input ic buf 0 bufsize with
  7. | 0 -> close_in ic; cur
  8. | nread -> loop (cur ^ Bytes.sub_string buf 0 nread)
  9. in
  10. loop ""
  11. let pad_right s =
  12. let rec repeat s n = if n < 1 then "" else s ^ (repeat s (n - 1)) in
  13. let lines = Str.split (Str.regexp " *\n") s in
  14. let cmp_length max line =
  15. let l = String.length line in
  16. if l > max then l else max
  17. in
  18. let w = List.fold_left cmp_length 0 lines in
  19. let pad buf line = buf ^ line ^ repeat " " (w - String.length line + 1) ^ "\n" in
  20. List.fold_left pad "" lines
  21. let artify replace_pat s =
  22. let w = try String.index s '\n' + 1 with Not_found -> String.length s in
  23. let h = String.length s / w in
  24. let char_at x y =
  25. if x < 0 || y < 0 || x >= w || y >= h
  26. then ' '
  27. else String.get s (y * w + x)
  28. in
  29. let make_pat i =
  30. let x = i mod w in
  31. let y = i / w in
  32. let o ox oy = char_at (x + ox) (y + oy) in
  33. let m1 = -1 in
  34. (o m1 m1, o 0 m1, o 1 m1,
  35. o m1 0, o 0 0, o 1 0,
  36. o m1 1, o 0 1, o 1 1)
  37. in
  38. UTF8.init (String.length s) (fun i -> replace_pat (make_pat i))
  39. let u s = UTF8.get s 0
  40. let replace_pat_safe = function
  41. | _ , ('|'|'+'), _ ,
  42. ('-'|'+'), '+' , ('-'|'+'),
  43. _ , ('|'|'+'), _ -> u "┼"
  44. | _ , _ , _ ,
  45. ('-'|'+'), '+' , ('-'|'+'),
  46. _ , ('|'|'+'), _ -> u "┬"
  47. | _ , ('|'|'+'), _ ,
  48. ('-'|'+'), '+' , ('-'|'+'),
  49. _ , _ , _ -> u "┴"
  50. | _ , ('|'|'+'), _ ,
  51. _ , '+' , ('-'|'+'),
  52. _ , ('|'|'+'), _ -> u "├"
  53. | _ , ('|'|'+'), _ ,
  54. ('-'|'+'), '+' , _ ,
  55. _ , ('|'|'+'), _ -> u "┤"
  56. | _ , _ , _ ,
  57. _ , '+' , ('-'|'+'),
  58. _ , ('|'|'+'), _ -> u "┌"
  59. | _ , ('|'|'+'), _ ,
  60. _ , '+' , ('-'|'+'),
  61. _ , _ , _ -> u "└"
  62. | _ , _ , _ ,
  63. ('-'|'+'), '+' , _ ,
  64. _ , ('|'|'+'), _ -> u "┐"
  65. | _ , ('|'|'+'), _ ,
  66. ('-'|'+'), '+' , _ ,
  67. _ , _ , _ -> u "┘"
  68. | _ , _ , _ ,
  69. _ , '-' , ('-'|'+'),
  70. _ , _ , _
  71. | _ , _ , _ ,
  72. ('-'|'+'), '-' , _ ,
  73. _ , _ , _ -> u "─"
  74. | _ , _ , _ ,
  75. _ , '|' , _ ,
  76. _ , ('|'|'+'), _
  77. | _ , ('|'|'+'), _ ,
  78. _ , '|' , _ ,
  79. _ , _ , _ -> u "│"
  80. | _ , ('|'|'+'), _ ,
  81. '=' , '+' , '=' ,
  82. _ , ('|'|'+'), _ -> u "╪"
  83. | _ , _ , _ ,
  84. '=' , '+' , '=' ,
  85. _ , ('|'|'+'), _ -> u "╤"
  86. | _ , ('|'|'+'), _ ,
  87. '=' , '+' , '=' ,
  88. _ , _ , _ -> u "╧"
  89. | _ , ('|'|'+'), _ ,
  90. _ , '+' , '=' ,
  91. _ , ('|'|'+'), _ -> u "╞"
  92. | _ , ('|'|'+'), _ ,
  93. '=' , '+' , _ ,
  94. _ , ('|'|'+'), _ -> u "╡"
  95. | _ , _ , _ ,
  96. _ , '+' , '=' ,
  97. _ , ('|'|'+'), _ -> u "╒"
  98. | _ , ('|'|'+'), _ ,
  99. _ , '+' , '=' ,
  100. _ , _ , _ -> u "╘"
  101. | _ , _ , _ ,
  102. '=' , '+' , _ ,
  103. _ , ('|'|'+'), _ -> u "╕"
  104. | _ , ('|'|'+'), _ ,
  105. '=' , '+' , _ ,
  106. _ , _ , _ -> u "╛"
  107. | _ , _ , _ ,
  108. _ , '=' , ('='|'+'),
  109. _ , _ , _
  110. | _ , _ , _ ,
  111. ('='|'+'), '=' , _ ,
  112. _ , _ , _ -> u "═"
  113. | _ , _ , _ ,
  114. _ , c , _ ,
  115. _ , _ , _ -> UChar.of_char c
  116. let replace_pat_unsafe =
  117. let both_double x y = if x = y then x else '-' in
  118. let pick_double x s = UTF8.get s (if x = '=' then 1 else 0) in
  119. function
  120. | _ , ' ', _ ,
  121. ' ', '+', ' ',
  122. _ , ' ', _ -> u "·" (* XXX: maybe just leave the '+' *)
  123. | _ , ' ', _ ,
  124. _ , '+', ' ',
  125. _ , ' ', _ -> u "╴"
  126. | _ , ' ', _ ,
  127. ' ', '+', _ ,
  128. _ , ' ', _ -> u "╶"
  129. | _ , ' ', _ ,
  130. ' ', '+', ' ',
  131. _ , _ , _ -> u "╷"
  132. | _ , _ , _ ,
  133. ' ', '+', ' ',
  134. _ , ' ', _ -> u "╵"
  135. | _ , ' ', _ ,
  136. ' ', '+', x ,
  137. _ , _ , _ -> pick_double x "┌╒"
  138. | _ , _ , _ ,
  139. ' ', '+', x ,
  140. _ , ' ', _ -> pick_double x "└╘"
  141. | _ , ' ', _ ,
  142. x , '+', ' ',
  143. _ , _ , _ -> pick_double x "┐╕"
  144. | _ , _ , _ ,
  145. x , '+', ' ',
  146. _ , ' ', _ -> pick_double x "┘╛"
  147. | _ , ' ', _ ,
  148. x , '+', y ,
  149. _ , _ , _ -> pick_double (both_double x y) "┬╤"
  150. | _ , _ , _ ,
  151. x , '+', y ,
  152. _ , ' ', _ -> pick_double (both_double x y) "┴╧"
  153. | _ , _ , _ ,
  154. ' ', '+', x ,
  155. _ , _ , _ -> pick_double x "├╞"
  156. | _ , _ , _ ,
  157. x , '+', ' ',
  158. _ , _ , _ -> pick_double x "┤╡"
  159. | _ , _ , _ ,
  160. x , '+', y ,
  161. _ , _ , _ -> pick_double (both_double x y) "┼╪"
  162. | _ , _ , _ ,
  163. _ , '-' , ('-'|'+'),
  164. _ , _ , _
  165. | _ , _ , _ ,
  166. ('-'|'+'), '-' , _ ,
  167. _ , _ , _ -> u "─"
  168. | _ , _ , _ ,
  169. _ , '|' , _ ,
  170. _ , ('|'|'+'), _
  171. | _ , ('|'|'+'), _ ,
  172. _ , '|' , _ ,
  173. _ , _ , _ -> u "│"
  174. | _ , _ , _ ,
  175. ('-'|'='|'+'), '=', _ ,
  176. _ , _ , _
  177. | _ , _ , _ ,
  178. _ , '=', ('-'|'='|'+'),
  179. _ , _ , _ -> u "═"
  180. | _, _, _,
  181. _, c, _,
  182. _, _, _ -> UChar.of_char c
  183. let () =
  184. let args = List.tl (Array.to_list Sys.argv) in
  185. let replace_pat =
  186. if List.mem "-s" args
  187. then replace_pat_safe
  188. else replace_pat_unsafe
  189. in
  190. stdin |> input_all |> pad_right |> artify replace_pat |> print_endline