123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270open!CoreopenCss_parserletsexp_of_with_locsexp_of_a(a,_)=sexp_of_aamoduleSexpers=struct(* All the sexp-of functions are written in a single let-rec
so that I can avoid having to deal with mutually recursive modules. *)letrecsexp_of_dimension:Types.dimension->Sexp.t=function|Length->[%sexpLength]|Angle->[%sexpAngle]|Time->[%sexpTime]|Frequency->[%sexpFrequency]andsexp_of_component_value:Types.Component_value.t->Sexp.t=function|Paren_blockt_list->[%sexpParen_block(t_list:component_valuewith_loclist)]|Bracket_blockt_list->[%sexpBracket_block(t_list:component_valuewith_loclist)]|Percentages->[%sexpPercentage(s:string)]|Idents->[%sexpIdent(s:string)]|Strings->[%sexpString(s:string)]|Uris->[%sexpUri(s:string)]|Operators->[%sexpOperator(s:string)]|Delims->[%sexpDelim(s:string)]|Function(s,t_list)->[%sexpFunction((s,t_list):stringwith_loc*component_valuewith_loclistwith_loc)]|Hashs->[%sexpHash(s:string)]|Numbers->[%sexpNumber(s:string)]|Unicode_ranges->[%sexpUnicode_range(s:string)]|Float_dimension(s1,s2,dim)->[%sexpFloat_dimension((s1,s2,dim):string*string*dimension)]|Dimension(s1,s2)->[%sexpDimension((s1,s2):string*string)]andsexp_of_declaration:Types.Declaration.t->Sexp.t=function|{name;value;important;loc=_}->[%sexp{name:stringwith_loc;value:component_valuewith_loclistwith_loc;important:boolwith_loc}]andsexp_of_brace_block:Types.Brace_block.t->Sexp.t=function|Empty->[%sexpEmpty]|Declaration_listd->[%sexpDeclaration_list(d:declaration_list)]|Stylesheets->[%sexpStylesheet(s:stylesheet)]andsexp_of_at_rule:Types.At_rule.t->Sexp.t=function|{name;prelude;block;loc=_}->[%sexp{name:stringwith_loc;prelude:component_valuewith_loclistwith_loc;block:brace_block}]andsexp_of_declaration_list_kind:Types.Declaration_list.kind->Sexp.t=function|Declarationd->[%sexpDeclaration(d:declaration)]|At_rulea->[%sexpAt_rule(a:at_rule)]andsexp_of_declaration_list:Types.Declaration_list.t->Sexp.t=function|d->[%sexp(d:declaration_list_kindlistwith_loc)]andsexp_of_style_rule:Types.Style_rule.t->Sexp.t=function|{prelude;block;loc=_}->[%sexp{prelude:component_valuewith_loclistwith_loc;block:declaration_list}]andsexp_of_rule:Types.Rule.t->Sexp.t=function|Style_rules->[%sexpStyle_rule(s:style_rule)]|At_rules->[%sexpAt_rule(s:at_rule)]andsexp_of_stylesheet:Types.Stylesheet.t->Sexp.t=function|s->[%sexp(s:rulelistwith_loc)];;end[@@@warning"-30"](* Disabling duplicate definition of record fields warning. *)(* NOTE: The reason we have an almost identical type definition AST is because
[ppxlib_traverse] ppx needs to be derived on a set of types defined like this for
it to be able to fully instrospect and create traverse classes nicely. *)type'awith_loc='a*locationanddimension=Types.dimension=|Length|Angle|Time|Frequencyandcomponent_value=Types.Component_value.t=|Paren_blockofcomponent_valuewith_loclist|Bracket_blockofcomponent_valuewith_loclist|Percentageofstring|Identofstring|Stringofstring|Uriofstring|Operatorofstring|Delimofstring|Functionofstringwith_loc*component_valuewith_loclistwith_loc|Hashofstring|Numberofstring|Unicode_rangeofstring|Float_dimensionof(string*string*dimension)|Dimensionof(string*string)anddeclaration=Types.Declaration.t={name:stringwith_loc;value:component_valuewith_loclistwith_loc;important:boolwith_loc;loc:location}andlocation=Location.tandbrace_block=Types.Brace_block.t=|Empty|Declaration_listofdeclaration_list|Stylesheetofstylesheetandat_rule=Types.At_rule.t={name:stringwith_loc;prelude:component_valuewith_loclistwith_loc;block:brace_block;loc:location}anddeclaration_list_kind=Types.Declaration_list.kind=|Declarationofdeclaration|At_ruleofat_ruleanddeclaration_list=declaration_list_kindlistwith_locandstyle_rule=Types.Style_rule.t={prelude:component_valuewith_loclistwith_loc;block:declaration_list;loc:location}andrule=Types.Rule.t=|Style_ruleofstyle_rule|At_ruleofat_ruleandstylesheet=rulelistwith_loc[@@derivingtraverse_map]moduleDimension=structtypet=Types.dimension=|Length|Angle|Time|Frequencyletsexp_of_t=Sexpers.sexp_of_dimensionendmoduleComponent_value=structtypet=Types.Component_value.t=|Paren_blockoftwith_loclist|Bracket_blockoftwith_loclist|Percentageofstring|Identofstring|Stringofstring|Uriofstring|Operatorofstring|Delimofstring|Functionofstringwith_loc*twith_loclistwith_loc|Hashofstring|Numberofstring|Unicode_rangeofstring|Float_dimensionof(string*string*Dimension.t)|Dimensionof(string*string)letsexp_of_t=Sexpers.sexp_of_component_valueendmoduleDeclaration=structtypet=Types.Declaration.t={name:stringwith_loc;value:Component_value.twith_loclistwith_loc;important:boolwith_loc;loc:Location.t}letsexp_of_t=Sexpers.sexp_of_declarationendmoduleBrace_block=structtypet=Types.Brace_block.t=|Empty|Declaration_listofTypes.Declaration_list.t|StylesheetofTypes.Stylesheet.tletsexp_of_t=Sexpers.sexp_of_brace_blockendmoduleAt_rule=structtypet=Types.At_rule.t={name:stringwith_loc;prelude:Component_value.twith_loclistwith_loc;block:Brace_block.t;loc:Location.t}letsexp_of_t=Sexpers.sexp_of_at_ruleendmoduleDeclaration_list=structtypekind=Types.Declaration_list.kind=|DeclarationofDeclaration.t|At_ruleofAt_rule.tandt=kindlistwith_locletsexp_of_kind=Sexpers.sexp_of_declaration_list_kindletsexp_of_t=Sexpers.sexp_of_declaration_listendmoduleStyle_rule=structtypet=Types.Style_rule.t={prelude:Component_value.twith_loclistwith_loc;block:Declaration_list.t;loc:Location.t}letsexp_of_t=Sexpers.sexp_of_style_ruleendmoduleRule=structtypet=Types.Rule.t=|Style_ruleofStyle_rule.t|At_ruleofAt_rule.tletsexp_of_t=Sexpers.sexp_of_ruleendmoduleStylesheet=structtypet=Rule.tlistwith_locletto_stringwhicht=letbuffer=Buffer.create64inletformatter=Format.formatter_of_bufferbufferinCss_printer.Print.(csswhich)formattert;Buffer.contentsbuffer;;letto_string_hum=to_stringCss_printer.Print.pretty_printerletto_string_minified=to_stringCss_printer.Print.minify_printerletof_string?poss=(* the parser produces different output depending on if there is
a leading space or not. They're equivalent semantically, but
I can add this to remove ambiguity. *)lets=" "^sinCss_parser.Parser.parse_stylesheet?poss;;letsexp_of_t=Sexpers.sexp_of_stylesheetendmoduleTraverse=structclassmap'=objectinheritmapmethodbool:bool->bool=Fn.idmethodlist:'a.('a->'a)->'alist->'alist=funf->List.map~fmethodstring:string->string=Fn.idmethodlocation__t:Location.t->Location.t=Fn.idendclassmap=map'end