Tailwind classes in OCaml
1(** Tailwind CLI integration for CSS processing *) 2 3open Unix 4 5type config = { 6 input_css: string; (** Path to input CSS file with Tailwind directives *) 7 output_css: string; (** Path to output CSS file *) 8 content: string list; (** List of content paths to scan for classes *) 9 minify: bool; (** Whether to minify the output *) 10} 11 12let default_config = { 13 input_css = "input.css"; 14 output_css = "output.css"; 15 content = ["*.html"; "*.ml"]; 16 minify = true; 17} 18 19(** Check if Tailwind CLI is available *) 20let check_tailwind_cli () = 21 try 22 let ic = open_process_in "npx @tailwindcss/cli --help 2>/dev/null" in 23 let _ = input_line ic in 24 let status = close_process_in ic in 25 status = WEXITED 0 26 with _ -> false 27 28(** Generate Tailwind CSS from input file *) 29let process_css config = 30 if not (check_tailwind_cli ()) then 31 failwith "Tailwind CLI not found. Install with: npm install -D @tailwindcss/cli" 32 else 33 let content_args = String.concat " " (List.map (fun p -> Printf.sprintf "--content '%s'" p) config.content) in 34 let minify_flag = if config.minify then "--minify" else "" in 35 let cmd = Printf.sprintf "npx @tailwindcss/cli -i %s -o %s %s %s 2>&1" 36 config.input_css 37 config.output_css 38 content_args 39 minify_flag 40 in 41 let ic = open_process_in cmd in 42 let rec read_output acc = 43 try 44 let line = input_line ic in 45 read_output (line :: acc) 46 with End_of_file -> 47 List.rev acc 48 in 49 let output = read_output [] in 50 let status = close_process_in ic in 51 match status with 52 | WEXITED 0 -> Ok output 53 | WEXITED n -> Error (Printf.sprintf "Tailwind CLI exited with code %d:\n%s" n (String.concat "\n" output)) 54 | _ -> Error "Tailwind CLI terminated abnormally" 55 56(** Process CSS for a specific HTML file *) 57let process_for_html ~input_css ~html_file ~output_css ?(minify=true) () = 58 let config = { 59 input_css; 60 output_css; 61 content = [html_file]; 62 minify; 63 } in 64 process_css config 65 66(** Write HTML to file and process CSS *) 67let write_and_process ~html_content ~html_file ~input_css ~output_css () = 68 (* Write HTML to file *) 69 let oc = open_out html_file in 70 output_string oc html_content; 71 close_out oc; 72 73 (* Process CSS *) 74 match process_for_html ~input_css ~html_file ~output_css () with 75 | Ok _ -> 76 Printf.eprintf "✅ Generated %s and %s\n" html_file output_css; 77 Ok () 78 | Error msg -> 79 Printf.eprintf "❌ CSS processing failed: %s\n" msg; 80 Error msg