stringify.ml 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. open Types
  2. let tab = " "
  3. let indent = Str.global_replace (Str.regexp "^\\(.\\)") (tab ^ "\\1")
  4. let rec cat sep fn = function
  5. | [] -> ""
  6. | [hd] -> fn hd
  7. | hd :: tl -> fn hd ^ sep ^ cat sep fn tl
  8. let string_of_num n =
  9. if float_of_int (int_of_float n) = n
  10. then string_of_int (int_of_float n)
  11. else string_of_float n
  12. (*
  13. * Pretty-printing
  14. *)
  15. let rec string_of_expr = function
  16. | Ident id -> id
  17. | Strlit str -> "\"" ^ str ^ "\""
  18. | Uri uri when String.contains uri ')' -> "url(\"" ^ uri ^ "\")"
  19. | Uri uri -> "url(" ^ uri ^ ")"
  20. | Concat values -> cat " " string_of_expr values
  21. | Number (n, None) -> string_of_num n
  22. | Number (n, Some u) -> string_of_num n ^ u
  23. | Function (name, arg) -> name ^ "(" ^ string_of_expr arg ^ ")"
  24. | Hexcolor hex -> "#" ^ hex
  25. | Unary (op, opnd) -> op ^ string_of_expr opnd
  26. | Nary (",", opnds) -> cat ", " string_of_expr opnds
  27. | Nary (op, opnds) -> cat op string_of_expr opnds
  28. let string_of_declaration (name, value, important) =
  29. let imp = if important then " !important" else "" in
  30. name ^ ": " ^ string_of_expr value ^ imp ^ ";"
  31. let rec string_of_selector = function
  32. | Simple simple -> simple
  33. | Combinator (left, " ", right) ->
  34. string_of_selector left ^ " " ^ string_of_selector right
  35. | Combinator (left, com, right) ->
  36. string_of_selector left ^ " " ^ com ^ " " ^ string_of_selector right
  37. let block body = " {\n" ^ indent body ^ "\n}"
  38. let rec string_of_statement = function
  39. | Ruleset (selectors, decls) ->
  40. cat ", " string_of_selector selectors ^
  41. block (cat "\n" string_of_declaration decls)
  42. | Media (queries, rulesets) ->
  43. "@media " ^ String.concat ", " queries ^
  44. block (cat "\n\n" string_of_statement rulesets)
  45. | Import (target, []) ->
  46. "@import " ^ string_of_expr target ^ ";"
  47. | Import (target, queries) ->
  48. "@import " ^ string_of_expr target ^ " " ^ String.concat ", " queries ^ ";"
  49. | Charset charset ->
  50. "@charset \"" ^ charset ^ "\";"
  51. | Page (None, decls) ->
  52. "@page" ^ block (cat "\n" string_of_declaration decls)
  53. | Page (Some pseudo, decls) ->
  54. "@page :" ^ pseudo ^ block (cat "\n" string_of_declaration decls)
  55. | Fontface decls ->
  56. "@font-face " ^ block (cat "\n" string_of_declaration decls)
  57. | Namespace (None, uri) ->
  58. "@namespace \"" ^ uri ^ "\";"
  59. | Namespace (Some prefix, uri) ->
  60. "@namespace " ^ prefix ^ " \"" ^ uri ^ "\";"
  61. let string_of_stylesheet = cat "\n\n" string_of_statement
  62. (*
  63. * Minified stringification
  64. *)
  65. let rec minify_expr = function
  66. | Concat values -> cat " " minify_expr values
  67. | Function (name, arg) -> name ^ "(" ^ minify_expr arg ^ ")"
  68. | Unary (op, opnd) -> op ^ minify_expr opnd
  69. | Nary (",", opnds) -> cat "," minify_expr opnds
  70. | Nary (op, opnds) -> cat op minify_expr opnds
  71. | expr -> string_of_expr expr
  72. let minify_declaration (name, value, important) =
  73. let imp = if important then "!important" else "" in
  74. name ^ ":" ^ minify_expr value ^ imp
  75. let rec minify_selector = function
  76. | Simple simple -> simple
  77. | Combinator (left, com, right) ->
  78. minify_selector left ^ com ^ minify_selector right
  79. let rec minify_statement = function
  80. | Ruleset (selectors, decls) ->
  81. cat "," minify_selector selectors ^
  82. "{" ^ (cat ";" minify_declaration decls) ^ "}"
  83. | Media (queries, rulesets) ->
  84. "@media " ^ String.concat "," queries ^
  85. "{" ^ (cat "" minify_statement rulesets) ^ "}"
  86. | Import (target, []) ->
  87. "@import " ^ string_of_expr target ^ ";"
  88. | Import (target, queries) ->
  89. "@import " ^ string_of_expr target ^ " " ^ String.concat "," queries ^ ";"
  90. | Page (None, decls) ->
  91. "@page{" ^ cat "" minify_declaration decls ^ "}"
  92. | Page (Some pseudo, decls) ->
  93. "@page :" ^ pseudo ^ "{" ^ cat "" minify_declaration decls ^ "}"
  94. | Fontface decls ->
  95. "@font-face{" ^ cat "" minify_declaration decls ^ "}"
  96. | statement -> string_of_statement statement
  97. let minify_stylesheet = cat "" minify_statement