123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143open!Coreopen!Import(* From https://en.wikipedia.org/wiki/ANSI_escape_code last accessed 2016-05-26 *)moduleRGB6=structincludePatdiff_format.Color.RGB6letescape_code{r;g;b}=16+(36*r)+(6*g)+bendmoduleGray24=structincludePatdiff_format.Color.Gray24letescape_code{level}=232+levelendletcodes_of_foreground_color:Patdiff_format.Color.t->string=function|Black->"30"|Red->"31"|Green->"32"|Yellow->"33"|Blue->"34"|Magenta->"35"|Cyan->"36"|White->"37"|Default->"39"|Gray|Bright_black->"90"|Bright_red->"91"|Bright_green->"92"|Bright_yellow->"93"|Bright_blue->"94"|Bright_magenta->"95"|Bright_cyan->"96"|Bright_white->"97"|RGB6x->sprintf"38;5;%d"(RGB6.escape_codex)|Gray24x->sprintf"38;5;%d"(Gray24.escape_codex);;letcodes_of_background_color:Patdiff_format.Color.t->string=function|Black->"40"|Red->"41"|Green->"42"|Yellow->"43"|Blue->"44"|Magenta->"45"|Cyan->"46"|White->"47"|Default->"49"|Gray|Bright_black->"100"|Bright_red->"101"|Bright_green->"102"|Bright_yellow->"103"|Bright_blue->"104"|Bright_magenta->"105"|Bright_cyan->"106"|Bright_white->"107"|RGB6x->sprintf"48;5;%d"(RGB6.escape_codex)|Gray24x->sprintf"48;5;%d"(Gray24.escape_codex);;letcodes_of_style:Patdiff_format.Style.t->string=function|Reset->"0"|Bold->"1"|Dim->"2"|Underline|Emph->"4"|Blink->"5"|Inverse->"7"|Hide->"8"|Fgc|Foregroundc->codes_of_foreground_colorc|Bgc|Backgroundc->codes_of_background_colorc;;letapply_styles?(drop_leading_resets=false)(styles:Patdiff_format.Style.tlist)str=letstyles=ifdrop_leading_resetsthenList.drop_whilestyles~f:(function|Reset->true|_->false)else(matchstyleswith|[]->[]|Reset::_->styles|_::_->Reset::styles)inmatchstyleswith|[]->str|_->sprintf"\027[%sm%s\027[0m"(List.mapstyles~f:codes_of_style|>String.concat~sep:";")str;;moduleRule=structletapplytext~(rule:Patdiff_format.Rule.t)~refined=letonly_whitespace=not(String.is_emptytext)&&String.for_alltext~f:Char.is_whitespaceinlettext_style:Patdiff_format.Style.tlist=ifList.is_emptyrule.stylesthen[]else(matchrefined,only_whitespacewith|true,_->[Reset]|false,true->Inverse::rule.styles|false,false->rule.styles)insprintf"%s%s%s"(apply_stylesrule.pre.stylesrule.pre.text)(apply_stylestext_styletext)(apply_stylesrule.suf.stylesrule.suf.text);;endletprint_header~rules~file_names:(old_file,new_file)~print=letprint_linefilerule=print(Rule.applyfile~rule~refined:false)inletmoduleRz=Patdiff_format.Rulesinprint_lineold_filerules.Rz.header_old;print_linenew_filerules.Rz.header_new;;letprint~print_global_header~file_names~rules~print~location_stylehunks=letmoduleRz=Patdiff_format.Rulesinletf_hunk_breakhunk=Patdiff_format.Location_style.sprintlocation_stylehunk~prev_filename:(fstfile_names)~rule:(Rule.apply~rule:rules.Rz.hunk~refined:false)|>printinifprint_global_headerthenprint_header~rules~file_names~print;Patdiff_hunks.iter'~f_hunk_break~f_line:printhunks;;