123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115moduleUrl=Odoc_document.Urltypelink=Relativeofstring list*string|Absoluteofstring(* Translation from Url.Path *)modulePath=structletfor_printingurl=List.mapsnd@@Url.Path.to_listurlletsegment_to_string(kind,name)=Format.asprintf"%a%s"Url.Path.pp_disambiguating_prefixkindnameletis_leaf_pageurl=url.Url.Path.kind=`LeafPageletremap_configf=letl=String.concat"/"finletremaps=[](* List.filter
(fun (prefix, _replacement) -> Astring.String.is_prefix ~affix:prefix l)
false (* (Config.remap config) *) *)inletremaps=List.sort(fun(a,_)(b,_)->compare(String.lengthb)(String.lengtha))remapsinmatchremapswith|[]->None|(prefix,replacement)::_->letlen=String.lengthprefixinletl=String.sub llen(String.lengthl-len)inSome(replacement ^l)letget_dir_and_file~config:_url=letl=Url.Path.to_listurlinletis_dir=if (* Config.flat config *)truethenfunction|`Page->`Always|_->`Neverelsefunction`LeafPage|`File|`SourcePage->`Never|_->`Alwaysinletdir,file=Url.Path.split~is_dirlinletdir=List.mapsegment_to_stringdirinletfile=matchfilewith|[]->"index.md"|[(`LeafPage,name)]->name^".md"|[(`File,name)]->name|[(`SourcePage,name)]->name^".md"|xs->(* assert (Config.flat config); *)String.concat"-"(List.mapsegment_to_stringxs)^".md"in(dir,file)letfor_linking~configurl=letdir,file=get_dir_and_file~config urlinmatchremapconfigdirwith|None->Relative(dir,file)|Somex->Absolute(x^"/"^file)letas_filename~config(url:Url.Path.t)=let dir,file=get_dir_and_file~config urlinFpath.(v@@String.concatFpath.dir_sep(dir@[file]))endtyperesolve=Current ofUrl.Path.t|Baseofstringletrecdrop_shared_prefixl1l2=match(l1,l2)with|l1::l1s,l2::l2swhenl1=l2->drop_shared_prefixl1sl2s|_,_->(l1,l2)let href ~config~resolvet=let{Url.Anchor.page;anchor;_}=tinletadd_anchor y=matchanchorwith""->y|anchor->y^"#"^anchorinlettarget_loc=Path.for_linking~configpageinmatchtarget_locwith|Absolutey->add_anchor y|Relative(dir,file)->(lettarget_loc=dir@[file]in(* If xref_base_uri is defined, do not perform relative URI resolution. *)matchresolvewith|Basexref_base_uri->letpage=xref_base_uri^String.concat"/"target_locinadd_anchorpage|Currentpath->(letcurrent_loc=letdir,file=Path.get_dir_and_file~config pathindir@[file]inlet current_from_common_ancestor,target_from_common_ancestor =drop_shared_prefix current_loctarget_locinletrelative_target=matchcurrent_from_common_ancestorwith|[]->(* We're already on the right page *)(* If we're already on the right page, the target from our common
ancestor can't be anything other than the empty list *)assert(target_from_common_ancestor=[]);[]|[_]->(* We're already in the right dir *)target_from_common_ancestor|l->(* We need to go up some dirs *)List.map(fun_->"..")(List.tll)@target_from_common_ancestorinmatch (relative_target,anchor)with|[],""->"#"(* TODO: This looks wrong ./ could technically be the current page *)|page,_->"./"^add_anchor@@String.concat"/"page))