Skip to content

Commit e538c89

Browse files
committed
Restore styled-ppx.generate CLI for static CSS extraction
1 parent dba7cbe commit e538c89

File tree

2 files changed

+98
-0
lines changed

2 files changed

+98
-0
lines changed

packages/generate/dune

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
(executable
2+
(name generate)
3+
(public_name styled-ppx.generate)
4+
(modules generate)
5+
(libraries styled-ppx ppxlib ppxlib.astlib)
6+
(preprocess
7+
(pps ppxlib.metaquot)))

packages/generate/generate.ml

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
module String_map = Map.Make (String)
2+
3+
let of_structure ~verbose ~filename structure stylesheet =
4+
let get_string (e : Ppxlib.expression) =
5+
match e.pexp_desc with
6+
| Pexp_constant (Pconst_string (v, _, None)) -> Some v
7+
| _ -> None
8+
in
9+
List.fold_left
10+
(fun stylesheet item ->
11+
match item with
12+
| [%stri [@@@css [%e? value]]] ->
13+
(match get_string value with
14+
| Some v ->
15+
if verbose then (
16+
Format.eprintf "Adding %a\n" Ppxlib.Pprintast.expression value;
17+
Printf.eprintf "Adding %s\n" v);
18+
String_map.add filename v stylesheet
19+
| None -> stylesheet)
20+
| _ -> stylesheet)
21+
stylesheet structure
22+
23+
let of_pp_ml ~verbose ~filename stylesheet =
24+
match Ppxlib.Ast_io.read_binary filename with
25+
| Error msg ->
26+
if verbose then Printf.eprintf "Error reading file %s: %s\n" filename msg;
27+
stylesheet
28+
| Ok t ->
29+
(match Ppxlib.Ast_io.get_ast t with
30+
| Impl structure -> of_structure ~verbose ~filename structure stylesheet
31+
| Intf _ -> stylesheet)
32+
33+
let of_ml ~verbose ~filename stylesheet =
34+
try
35+
let ic = open_in filename in
36+
let len = in_channel_length ic in
37+
let content = really_input_string ic len in
38+
close_in ic;
39+
let lexbuf = Lexing.from_string content in
40+
lexbuf.lex_curr_p <- { lexbuf.lex_curr_p with pos_fname = filename };
41+
let structure = Ppxlib.Parse.implementation lexbuf in
42+
of_structure ~verbose ~filename structure stylesheet
43+
with
44+
| Sys_error msg ->
45+
if verbose then Printf.eprintf "Error reading file %s: %s\n" filename msg;
46+
stylesheet
47+
| exn ->
48+
if verbose then
49+
Printf.eprintf "Error parsing file %s: %s\n" filename
50+
(Printexc.to_string exn);
51+
stylesheet
52+
53+
let extract_stylesheet ~verbose input_files =
54+
List.fold_left
55+
(fun stylesheet filename ->
56+
if verbose then Printf.eprintf "Processing %s...\n" filename;
57+
if String.ends_with filename ~suffix:".css" then
58+
failwith "Extracting from .css files is not supported yet"
59+
else if String.ends_with filename ~suffix:".pp.ml" then
60+
of_pp_ml ~verbose ~filename stylesheet
61+
else if String.ends_with filename ~suffix:".ml" then
62+
of_ml ~verbose ~filename stylesheet
63+
else failwith "Expected .css, .ml or .pp.ml file")
64+
String_map.empty input_files
65+
66+
let parse_args args =
67+
let rec parse acc output_file verbose = function
68+
| "-o" :: file :: rest
69+
| "-output" :: file :: rest
70+
| "--output" :: file :: rest ->
71+
parse acc (Some file) verbose rest
72+
| "-v" :: rest | "-verbose" :: rest | "--verbose" :: rest ->
73+
parse acc output_file true rest
74+
| arg :: rest -> parse (arg :: acc) output_file verbose rest
75+
| [] -> List.rev acc, output_file, verbose
76+
in
77+
parse [] None false (Array.to_list args |> List.tl)
78+
79+
let () =
80+
let input_files, output_file, verbose = parse_args Sys.argv in
81+
if verbose then (
82+
Printf.eprintf "Extracting stylesheets...\n";
83+
Printf.eprintf "Input files: %i\n" (List.length input_files));
84+
let stylesheet = extract_stylesheet ~verbose input_files in
85+
let out_channel =
86+
match output_file with Some file -> open_out file | None -> Stdlib.stdout
87+
in
88+
Stdlib.output_string out_channel
89+
"/* This file is generated by styled-ppx, do not edit manually */\n";
90+
String_map.iter (fun _ v -> Stdlib.output_string out_channel v) stylesheet;
91+
match output_file with Some _ -> close_out out_channel | None -> ()

0 commit comments

Comments
 (0)