123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101open!StduneincludeTypes.Templateletvar_enclosers=function|Percent->"%{","}"|Dollar_brace->"${","}"|Dollar_paren->"$(",")"modulePp:sigvalto_string:t->syntax:Syntax.t->stringend=structletbuf=Buffer.create16letadd_var{loc=_;syntax;name;payload}=letbefore,after=var_encloserssyntaxinBuffer.add_stringbufbefore;Buffer.add_stringbufname;beginmatchpayloadwith|None->()|Somepayload->Buffer.add_charbuf':';Buffer.add_stringbufpayloadend;Buffer.add_stringbufafter(* TODO use the loc for the error *)letcheck_valid_unquoteds~syntax~loc:_=ifnot(Atom.is_valid(Atom.of_strings)syntax)thenPrintf.ksprintfinvalid_arg"Invalid text %S in unquoted template"sletto_string{parts;quoted;loc}~syntax=Buffer.clearbuf;ifquotedthenBuffer.add_charbuf'"';letcommit_texts=ifs=""then()elseifnotquotedthenbegincheck_valid_unquoted~loc~syntaxs;Buffer.add_stringbufsendelseBuffer.add_stringbuf(Escape.escaped~syntaxs)inletrecadd_partsacc_text=function|[]->commit_textacc_text|Texts::rest->add_parts(ifacc_text=""thenselseacc_text^s)rest|Varv::rest->commit_textacc_text;add_varv;add_parts""restinadd_parts""parts;ifquotedthenBuffer.add_charbuf'"';Buffer.contentsbufendletto_string=Pp.to_stringletstring_of_var{loc=_;syntax;name;payload}=letbefore,after=var_encloserssyntaxinmatchpayloadwith|None->before^name^after|Somep->before^name^":"^p^afterletppsyntaxppft=Format.pp_print_stringppf(Pp.to_string~syntaxt)letpp_split_stringsppf(t:t)=letsyntax=Syntax.Duneinift.quoted||List.existst.parts~f:(function|Texts->String.containss'\n'|Var_->false)thenbeginList.itert.parts~f:(function|Vars->Format.pp_print_stringppf(string_of_vars)|Texts->beginmatchString.splits~on:'\n'with|[]->assertfalse|[s]->Format.pp_print_stringppf(Escape.escaped~syntaxs)|split->Format.pp_print_list~pp_sep:(funppf()->Format.fprintfppf"@,\\n")Format.pp_print_stringppfsplitend);Format.fprintfppf"@}\"@]"endelseppsyntaxppftletremove_locst={twithloc=Loc.none;parts=List.mapt.parts~f:(function|Varv->Var{vwithloc=Loc.none}|Text_ass->s)}