simple.ml 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. open Str
  2. open Types
  3. let hex6 = regexp "\\([0-9a-f]\\)\\1\\([0-9a-f]\\)\\2\\([0-9a-f]\\)\\3"
  4. let is_num = function
  5. | Number (n, (None | Some "%")) -> true
  6. | _ -> false
  7. let clip = function
  8. | Number (n, u) when n < 0. -> Number (0., u)
  9. | Number (n, None) when n > 255. -> Number (255., None)
  10. | Number (n, Some "%") when n > 100. -> Number (100., Some "%")
  11. | value -> value
  12. let rec shorten_expr = function
  13. (* #aabbcc -> #abc *)
  14. | Hexcolor h when string_match hex6 h 0 ->
  15. let gr n = matched_group n h in
  16. shorten_expr (Hexcolor (gr 1 ^ gr 2 ^ gr 3))
  17. (* rgb(r,g,b) -> #rrggbb *)
  18. | Function ("rgb", Nary (",", [r; g; b]))
  19. when is_num r && is_num g && is_num b ->
  20. let i c =
  21. match clip c with
  22. | Number (n, None) -> int_of_float n
  23. | Number (n, Some "%") -> int_of_float (n *. 2.55 +. 0.5)
  24. | _ -> assert false
  25. in
  26. shorten_expr (Hexcolor (Printf.sprintf "%02x%02x%02x" (i r) (i g) (i b)))
  27. (* clip rgb values, e.g. rgb(-1,256,0) -> rgb(0,255,0) *)
  28. | Function ("rgb", Nary (",", [r; g; b])) ->
  29. Function ("rgb", Nary (",", [clip r; clip g; clip b]))
  30. (* rgba(r,g,b,1.0) -> rgb(r,g,b) *)
  31. | Function ("rgba", Nary (",", [r; g; b; Number (1., None)])) ->
  32. shorten_expr (Function ("rgb", Nary (",", [r; g; b])))
  33. (* TODO: hsl[a](...) *)
  34. (* 0px -> 0 *)
  35. | Number (0., Some _) -> Number (0., None)
  36. (* transform color names to shorter hex codes and vice-versa *)
  37. | v -> Color_names.compress v
  38. let shorten_font_weight = function
  39. | Ident "normal" -> Number (400.0, None)
  40. | Ident "bold" -> Number (700.0, None)
  41. | v -> v
  42. let shorten_nth = function
  43. (* even -> 2n *)
  44. | Even -> Formula (2, 0)
  45. (* 2n+1 | 2n-1 -> odd *)
  46. | Formula (2, (1 | -1)) -> Odd
  47. (* -n+1 -> 1 *)
  48. | Formula (-1, 1) -> Formula (0, 1)
  49. | v -> v
  50. let compress =
  51. Util.transform_stylesheet begin function
  52. | Expr value ->
  53. Expr (shorten_expr value)
  54. | Declaration ("font-weight", value, imp) ->
  55. Declaration ("font-weight", shorten_font_weight value, imp)
  56. | Declaration (("border" | "outline") as name, Ident "none", imp) ->
  57. Declaration (name, Number (0., None), imp)
  58. | Pseudo_class_arg (Nth nth) ->
  59. Pseudo_class_arg (Nth (shorten_nth nth))
  60. (* Remove rulesets with :nth-child(0) selector *)
  61. | Selector (Pseudo_class (_, cls, Some [Nth (Formula (0, 0))]))
  62. when string_match (regexp "nth-") cls 0 ->
  63. Clear
  64. (* Remove rulesets with no selectors or declarations *)
  65. | Statement (Ruleset ([], _))
  66. | Statement (Ruleset (_, [])) ->
  67. Clear
  68. | v -> v
  69. end