123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389openResultopenOdoc_model.PathsopenOdoc_model.NamesmoduleRoot=Odoc_model.Rootletfunctor_arg_pos(`Parameter(p,_))=letrecinner_sig=function|`Resultp->1+inner_sigp|`Module_|`ModuleType_|`Root_|`Parameter_->1ininner_sigpletrender_path:Odoc_model.Paths.Path.t->string=letopenOdoc_model.Paths.Pathinletrecrender_resolved:Odoc_model.Paths.Path.Resolved.t->string=letopenResolvedinfunction|`Identifierid->Identifier.nameid|`OpaqueModulep->render_resolved(p:>t)|`OpaqueModuleTypep->render_resolved(p:>t)|`Subst(_,p)->render_resolved(p:>t)|`SubstT(_,p)->render_resolved(p:>t)|`Alias(p1,p2)->ifOdoc_model.Paths.Path.is_hidden(`Resolved(p2:>t))thenrender_resolved(p1:>t)elserender_resolved(p2:>t)|`AliasModuleType(p1,p2)->ifOdoc_model.Paths.Path.is_hidden(`Resolved(p2:>t))thenrender_resolved(p1:>t)elserender_resolved(p2:>t)|`Hiddenp->render_resolved(p:>t)|`Module(p,s)->render_resolved(p:>t)^"."^ModuleName.to_strings|`Canonical(_,`Resolvedp)->render_resolved(p:>t)|`Canonical(p,_)->render_resolved(p:>t)|`CanonicalModuleType(_,`Resolvedp)->render_resolved(p:>t)|`CanonicalModuleType(p,_)->render_resolved(p:>t)|`CanonicalType(_,`Resolvedp)->render_resolved(p:>t)|`CanonicalType(p,_)->render_resolved(p:>t)|`Apply(rp,p)->render_resolved(rp:>t)^"("^render_resolved(p:>Odoc_model.Paths.Path.Resolved.t)^")"|`ModuleType(p,s)->render_resolved(p:>t)^"."^ModuleTypeName.to_strings|`Type(p,s)->render_resolved(p:>t)^"."^TypeName.to_strings|`Class(p,s)->render_resolved(p:>t)^"."^ClassName.to_strings|`ClassType(p,s)->render_resolved(p:>t)^"."^ClassTypeName.to_stringsandrender_path:Odoc_model.Paths.Path.t->string=function|`Identifier(id,_)->Identifier.nameid|`Rootroot->root|`Forwardroot->root|`Dot(prefix,suffix)->render_path(prefix:>t)^"."^suffix|`Apply(p1,p2)->render_path(p1:>t)^"("^render_path(p2:>t)^")"|`Resolvedrp->render_resolvedrpinrender_pathmoduleError=structtypenonrect=|Not_linkableofstring|Uncaught_exnofstring(* These should basicaly never happen *)|Unexpected_anchorofstringletto_string=function|Not_linkables->Printf.sprintf"Not_linkable %S"s|Uncaught_exns->Printf.sprintf"Uncaught_exn %S"s|Unexpected_anchors->Printf.sprintf"Unexpected_anchor %S"sendlet(>>=)xf=matchxwithOkx->fx|Error_ase->emodulePath=structtypesource=[Identifier.Page.t|Identifier.Signature.t|Identifier.ClassSignature.t]typekind=[`Module|`Page|`LeafPage|`ModuleType|`Argument|`Class|`ClassType|`File]letstring_of_kind:kind->string=function|`Page->"page"|`Module->"module"|`LeafPage->"leaf-page"|`ModuleType->"module-type"|`Argument->"argument"|`Class->"class"|`ClassType->"class-type"|`File->"file"letpp_kindfmtkind=Format.fprintffmt"%s"(string_of_kindkind)typet={kind:kind;parent:toption;name:string}letmk?parentkindname={kind;parent;name}letrecfrom_identifier:source->t=function|`Root(parent,unit_name)->letparent=matchparentwith|Somep->Some(from_identifier(p:>source))|None->Noneinletkind=`Moduleinletpage=ModuleName.to_stringunit_nameinmk?parentkindpage|`Page(parent,page_name)->letparent=matchparentwith|Somep->Some(from_identifier(p:>source))|None->Noneinletkind=`Pageinletpage=PageName.to_stringpage_nameinmk?parentkindpage|`LeafPage(parent,page_name)->letparent=matchparentwith|Somep->Some(from_identifier(p:>source))|None->Noneinletkind=`LeafPageinletpage=PageName.to_stringpage_nameinmk?parentkindpage|`Module(parent,mod_name)->letparent=from_identifier(parent:>source)inletkind=`Moduleinletpage=ModuleName.to_stringmod_nameinmk~parentkindpage|`Parameter(functor_id,arg_name)asp->letparent=from_identifier(functor_id:>source)inletkind=`Argumentinletarg_num=functor_arg_pospinletpage=Printf.sprintf"%d-%s"arg_num(ParameterName.to_stringarg_name)inmk~parentkindpage|`ModuleType(parent,modt_name)->letparent=from_identifier(parent:>source)inletkind=`ModuleTypeinletpage=ModuleTypeName.to_stringmodt_nameinmk~parentkindpage|`Class(parent,name)->letparent=from_identifier(parent:>source)inletkind=`Classinletpage=ClassName.to_stringnameinmk~parentkindpage|`ClassType(parent,name)->letparent=from_identifier(parent:>source)inletkind=`ClassTypeinletpage=ClassTypeName.to_stringnameinmk~parentkindpage|`Resultp->from_identifier(p:>source)letfrom_identifierp=from_identifier(p:[<source]:>source)letto_listurl=letrecloopacc{parent;name;kind}=matchparentwith|None->(kind,name)::acc|Somep->loop((kind,name)::acc)pinloop[]urlletof_listl=letrecinnerparent=function|[]->parent|(kind,name)::xs->inner(Some{parent;name;kind})xsininnerNonelletsplit:is_dir:(kind->[`Always|`Never|`IfNotLast])->(kind*string)list->(kind*string)list*(kind*string)list=fun~is_dirl->letrecinnerdirs=function|[((kind,_)asx)]whenis_dirkind=`IfNotLast->(List.revdirs,[x])|((kind,_)asx)::xswhenis_dirkind<>`Never->inner(x::dirs)xs|xs->(List.revdirs,xs)ininner[]lendmoduleAnchor=structtypekind=[Path.kind|`Section|`Type|`Extension|`ExtensionDecl|`Exception|`Method|`Val|`Constructor|`Field]letstring_of_kind:kind->string=function|#Path.kindask->Path.string_of_kindk|`Section->"section"|`Type->"type"|`Extension->"extension"|`ExtensionDecl->"extension-decl"|`Exception->"exception"|`Method->"method"|`Val->"val"|`Constructor->"constructor"|`Field->"field"letpp_kindfmtkind=Format.fprintffmt"%s"(string_of_kindkind)typet={page:Path.t;anchor:string;kind:kind}letanchorify_path{Path.parent;name;kind}=matchparentwith|None->assertfalse(* We got a root, should never happen *)|Somepage->letanchor=Printf.sprintf"%s-%s"(Path.string_of_kindkind)namein{page;anchor;kind=(kind:>kind)}letadd_suffix~kind{page;anchor;_}suffix={page;anchor=anchor^"."^suffix;kind}letmk~kindparentstr_name=letpage=Path.from_identifierparentinOk{page;anchor=str_name;kind}letrecfrom_identifier:Identifier.t->(t,Error.t)result=letopenErrorinfunction|`Module(parent,mod_name)->letparent=Path.from_identifier(parent:>Path.source)inletkind=`Moduleinletanchor=Printf.sprintf"%s-%s"(Path.string_of_kindkind)(ModuleName.to_stringmod_name)inOk{page=parent;anchor;kind}|`Root_asp->letpage=Path.from_identifier(p:>Path.source)inOk{page;kind=`Module;anchor=""}|`Page_asp->letpage=Path.from_identifier(p:>Path.source)inOk{page;kind=`Page;anchor=""}|`LeafPage_asp->letpage=Path.from_identifier(p:>Path.source)inOk{page;kind=`LeafPage;anchor=""}(* For all these identifiers, page names and anchors are the same *)|(`Parameter_|`Result_|`ModuleType_|`Class_|`ClassType_)asp->Ok(anchorify_path@@Path.from_identifierp)|`Type(parent,type_name)->letpage=Path.from_identifier(parent:>Path.source)inletkind=`TypeinOk{page;anchor=Format.asprintf"%a-%s"pp_kindkind(TypeName.to_stringtype_name);kind;}|`CoreTypety_name->Error(Not_linkable("core_type:"^TypeName.to_stringty_name))|`Extension(parent,name)->letpage=Path.from_identifier(parent:>Path.source)inletkind=`ExtensioninOk{page;anchor=Format.asprintf"%a-%s"pp_kindkind(ExtensionName.to_stringname);kind;}|`Exception(parent,name)->letpage=Path.from_identifier(parent:>Path.source)inletkind=`ExceptioninOk{page;anchor=Format.asprintf"%a-%s"pp_kindkind(ExceptionName.to_stringname);kind;}|`CoreExceptionname->Error(Not_linkable("core_exception:"^ExceptionName.to_stringname))|`Value(parent,name)->letpage=Path.from_identifier(parent:>Path.source)inletkind=`ValinOk{page;anchor=Format.asprintf"%a-%s"pp_kindkind(ValueName.to_stringname);kind;}|`Method(parent,name)->letstr_name=MethodName.to_stringnameinletpage=Path.from_identifier(parent:>Path.source)inletkind=`MethodinOk{page;anchor=Format.asprintf"%a-%s"pp_kindkindstr_name;kind}|`InstanceVariable(parent,name)->letstr_name=InstanceVariableName.to_stringnameinletpage=Path.from_identifier(parent:>Path.source)inletkind=`ValinOk{page;anchor=Format.asprintf"%a-%s"pp_kindkindstr_name;kind}|`Constructor(parent,name)->from_identifier(parent:>Identifier.t)>>=funpage->letkind=`Constructorinletsuffix=ConstructorName.to_stringnameinOk(add_suffix~kindpagesuffix)|`Field(parent,name)->from_identifier(parent:>Identifier.t)>>=funpage->letkind=`Fieldinletsuffix=FieldName.to_stringnameinOk(add_suffix~kindpagesuffix)|`Label(parent,anchor)->(letstr_name=LabelName.to_stringanchorin(* [Identifier.LabelParent.t] contains datatypes. [`CoreType] can't
happen, [`Type] may not happen either but just in case, use the
grand-parent. *)matchparentwith|#Path.sourceasparent->mk~kind:`Sectionparentstr_name|`CoreType_->Error(Unexpected_anchor"core_type label parent")|`Type(gp,_)->mk~kind:`Sectiongpstr_name)letpolymorphic_variant~type_identelt=letname_of_type_constrte=matchtewith|Odoc_model.Lang.TypeExpr.Constr(path,_)->render_path(path:>Odoc_model.Paths.Path.t)|_->invalid_arg"DocOckHtml.Url.Polymorphic_variant_decl.name_of_type_constr"inmatchfrom_identifiertype_identwith|Errore->failwith(Error.to_stringe)|Okurl->(matcheltwith|Odoc_model.Lang.TypeExpr.Polymorphic_variant.Typete->letkind=`Typeinletsuffix=name_of_type_constrteinadd_suffix~kindurlsuffix|Constructor{name;_}->letkind=`Constructorinletsuffix=nameinadd_suffix~kindurlsuffix)(** The anchor looks like
[extension-decl-"Path.target_type"-FirstConstructor]. *)letextension_decl(decl:Odoc_model.Lang.Extension.t)=letpage=Path.from_identifier(decl.parent:>Path.source)inletkind=`ExtensionDeclinletfirst_cons=Identifier.name(List.hddecl.constructors).idinletanchor=Format.asprintf"%a-%s"pp_kindkindfirst_consin{page;kind;anchor}endtypekind=Anchor.kindtypet=Anchor.tletfrom_pathpage={Anchor.page;anchor="";kind=(page.kind:>Anchor.kind)}letfrom_identifier~stop_before=function|#Path.sourceaspwhennotstop_before->Ok(from_path@@Path.from_identifierp)|p->Anchor.from_identifierpletkindid=matchAnchor.from_identifieridwith|Errore->failwith(Error.to_stringe)|Ok{kind;_}->kind