Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file generator.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397openOdoc_utilsmoduleTypes=Odoc_document.TypesmoduleDoctree=Odoc_document.DoctreemoduleUrl=Odoc_document.Urlletsourcefn(t:Types.Source.t)=letrectoken(x:Types.Source.token)=match xwithElti->fni|Tag(_,l)->tokenslandtokenst=List.concat_maptokentintokenstandstyledstylecontent=matchstylewith|`Bold->letinlines_as_one_inline =Renderer.Inline.Inlinescontent in[Renderer.Inline.Strong_emphasisinlines_as_one_inline]|`Italic|`Emphasis->(* We treat emphasis as italic, since there's no difference in Markdown *)letinlines_as_one_inline=Renderer.Inline.Inlinescontent in[Renderer.Inline.Emphasisinlines_as_one_inline]|`Superscript|`Subscript->(* CommonMark doesn't have support for superscript/subscript, we fallback to inline *)contentletentity=function"#45"->"-"|"gt"-> ">"|e->"&"^e^";"letrecinline_text_onlyinline=List.concat_map(fun(i:Types.Inline.one)->matchi.descwith|Text""->[]|Texts->[s]|Entitys->[entitys]|Linebreak->[]|Styled(_,content)->inline_text_onlycontent|Link{content;_}->inline_text_only content|Sources->sourceinline_text_onlys|_->[])inlineandblock_text_onlyblocks:stringlist=List.concat_map(fun (b:Types.Block.one)->matchb.descwith|Paragraphinline|Inlineinline->inline_text_onlyinline|Source(_,s)->sourceinline_text_onlys|List(_,items)->List.concat_mapblock_text_onlyitems|Verbatims->[s]|_->[])blocksandinline~(config:Config.t)~resolvel=letone (t:Types.Inline.one)=matcht.descwith|Texts->[Renderer.Inline.Texts]|Entitys->(* In CommonMark, HTML entities are supported directly, so we can just output them as text. Some markdown parsers may not support some entities. *)[Renderer.Inline.Texts]|Linebreak->[Renderer.Inline.Break]|Styled(style,c)->letinline_content=inline~config~resolvecinstyledstyleinline_content|Linklink->inline_link~config~resolvelink|Sourcec->(* CommonMark doesn't allow any complex node inside inline text, rendering inline nodes as text *)letcontent=sourceinline_text_onlycin[Renderer.Inline.Code_spancontent]|Maths->(* Since CommonMark doesn't support Math's, we treat it a inline code *)[Renderer.Inline.Code_span[s]]|Raw_markup(target,content)->(matchAstring.String.Ascii.lowercasetargetwith|"html"->letblock_lines=contentin[Renderer.Inline.Raw_html[block_lines]]|_->(* Markdown only supports html blocks *)[])inList.concat_maponelandinline_link~config~resolvelink=lethref=matchlink.targetwith|Externalhref->Somehref|Internalinternal->(matchinternalwith|Resolveduri->Some (Link.href~config~resolveuri)|Unresolved->None)inmatchhrefwith|Somehref->letinline_content=inline ~config~resolvelink.content inletlink_inline=Renderer.Inline.Inlinesinline_contentin[Renderer.Inline.Link{text=link_inline;url=Somehref}]|None->[Renderer.Inline.Code_span(inline_text_onlylink.content)]letrecblock~config~resolvel=letone(t:Types.Block.one)=matcht.descwith|Paragraphparagraph->letinlines=inline~config~resolveparagraph inlet inlines=Renderer.Inline.Inlinesinlines inletparagraph_block=Renderer.Block.Paragraphinlines in(* CommonMark treats paragraph as a block, to align the behavior with other generators such as HTML, we add a blank line after it *)letbreak=Renderer.Block.Blank_linein[paragraph_block;break]|List(type_,l)->letitems=List.map(funitems->letblock=block ~config~resolveitemsinRenderer.Block.Blocksblock)lin[(matchtype_with|Ordered->Renderer.Block.Ordered_listitems|Unordered->Renderer.Block.Unordered_listitems);]|Inlinei->letinlines=Renderer.Inline.Inlines(inline ~config~resolvei)in[Renderer.Block.Paragraph inlines]|Tablet->block_table~config~resolvet|Descriptionl->letitem({key;definition;attr=_}:Types.Description.one)=letterm=inline~config~resolvekeyin(* We extract definition as inline *)letdefinition_inline=Renderer.Inline.Text(String.concat~sep:""(block_text_onlydefinition))inletspace =Renderer.Inline.Text" "inletterm_inline=Renderer.Inline.Inlines(term@[space;definition_inline])in[Renderer.Block.Paragraphterm_inline]inList.concat_map iteml|Verbatims->letcode_snippet=Renderer.Block.Code_block {info_string=None;code=[s]}in[code_snippet]|Source(lang,s)->letcode=s|>source inline_text_only|>List.map(funs->s)inletcode_snippet =Renderer.Block.Code_block {info_string=Somelang;code}in[code_snippet ]|Maths->(* Since CommonMark doesn't support Math's, we just treat it as code. Maybe could use Ext_math_block or Ext_math_display *)letblock=Renderer.Block.Code_block{info_string=None;code=[s]}in[block]|Raw_markup(target,content)->(matchAstring.String.Ascii.lowercasetargetwith|"html"->lethtml_block_lines=Renderer.block_line_of_stringcontentin[Renderer.Block.Html_blockhtml_block_lines]|_->(* Markdown only supports html blocks *) [])|Image(target,alt)->leturl=match(target:Types.Target.t)with|Externalurl->Someurl|Internal(Resolveduri)->Some(Link.href~config~resolveuri)|InternalUnresolved->Noneinletimage:Renderer.Inline.link={text=Renderer.Inline.Textalt;url}in[Renderer.Block.Paragraph(Renderer.Inline.Inlines[Renderer.Inline.Imageimage]);]|Audio(_target,_alt)|Video(_target,_alt)->(* Audio and video aren't supported in markdown *)[]inList.concat_maponelandblock_table~config~resolvet=letalignment =function|Types.Table.Left ->Some`Left|Types.Table.Center->Some`Center|Types.Table.Right->Some`Right|Types.Table.Default->Noneinletconvert_cellcontent=matchcontentwith|[{Types.Block.desc=Paragraphp;_}]|[{Types.Block.desc=Inlinep;_}]->inline~config~resolvep|blocks->lettext=String.concat~sep:" "(block_text_onlyblocks)in[Renderer.Inline.Texttext]inletconvert_row(row:(Types.Block.t*[`Data|`Header ])list)=letcells=List.map(fun(content,_)->Renderer.Inline.Inlines(convert_cellcontent))rowinmatchrow with(_,`Header)::_->`Headercells|_->`Datacellsinmatcht.datawith|[]->[Renderer.Block.Paragraph(Renderer.Inline.Inlines[])]|rows->lettable_rows=List.mapconvert_rowrowsinletseparator =`Sep (List.mapalignmentt.align)inletrecinsert_separatoracc=function|[]->List.revacc|(`Header_ash)::(`Data_::_asrest)->List.rev(h::acc)@[separator]@rest|(`Header_ash)::rest->insert_separator(h::acc)rest|rows-> List.revacc@[separator]@rowsinletfinal_rows =insert_separator[]table_rowsinlettable=Renderer.Block.Table.makefinal_rows in[Renderer.Block.Tabletable]anditems~config~resolvel:Renderer.Block.tlist=letrecwalk_itemsacc(t:Types.Item.tlist)=let continue_withrestelts=(walk_items[@tailcall])(List.rev_appendeltsacc)restinmatchtwith|[]->List.revacc|Text_::_ast->lettext,_,rest=Doctree.Take.untilt~classify:(function|Types.Item.Texttext->Accumtext|_->Stop_and_keep)inletcontent=block~config~resolvetextin(continue_with[@tailcall])restcontent|Headingh::rest->(* Markdown headings are rendered as a blank line before and after the heading, otherwise it treats it as an inline paragraph *)letbreak=Renderer.Block.Blank_lineinletinlines=inline~config~resolveh.title inletcontent=Renderer.Inline.Inlinesinlines inletblock:Renderer.Block.heading={level=h.level+1;inline=content;id=None}inletheading_block=Renderer.Block.Headingblockin(continue_with[@tailcall])rest[break;heading_block;break ]|Include{attr=_attr;anchor=_anchor;source_anchor=_source_anchor;doc;content ={summary=_summary;status=_status;content};}::rest ->letdoc_content=block ~config~resolvedocinletincluded_content=walk_items[]contentinletall_content =doc_content @included_contentin(continue_with [@tailcall])restall_content|Declaration{attr=_attr;anchor=_anchor;source_anchor=_source_anchor;content;doc;}::rest->letspec=documentedSrc~config~resolvecontentinletdoc=block~config~resolvedocinletcontent=spec@docin(continue_with[@tailcall])restcontentanditemsl=walk_items []linitemslanddocumentedSrc~config~resolvet=letopenTypes.DocumentedSrcinlettake_codel=Doctree.Take.untill~classify:(funx->match(x:one)with|Codecode->Accumcode|Alternative(Expansion{summary;_})->Accumsummary|_->Stop_and_keep)inlettake_descrl=Doctree.Take.untill~classify:(function|Documented{attrs;anchor;code;doc;markers}->Accum[{attrs;anchor;code=`Dcode;doc;markers}]|Nested{attrs;anchor;code;doc;markers}->Accum[{attrs;anchor;code=`Ncode;doc;markers}]|_->Stop_and_keep)inletrecto_markdownt:Renderer.Block.tlist=matchtwith|[]->[]|(Code_|Alternative_)::_->letcode,header,rest=take_codetinletinfo_string =matchheaderwithSomeheader->Someheader|None->Noneinletinline_source=sourceinline_text_onlycodeinletcode=[String.concat~sep:""inline_source]inletblock=Renderer.Block.Code_block{info_string;code}in[block]@to_markdown rest|Subpagesubp::_->subpage~config~resolvesubp|(Documented_|Nested_)::_->letl,_,rest=take_descrtinletone {attrs=_;anchor=_;code;doc;markers=_}=letcontent=matchcodewith|`Dcode->letinline_source=inline~config~resolvecodeinletinlines=Renderer.Inline.Inlinesinline_source inletblock=Renderer.Block.Paragraphinlinesin[block]|`Nn->to_markdownninletblock_doc =block~config~resolvedocinList.append contentblock_docinletall_blocks=List.concat_maponelinall_blocks@to_markdown restinto_markdowntandsubpage~config~resolve(subp:Types.Subpage.t)=items~config ~resolvesubp.content.itemsmodulePage=structleton_sub=function|`Page_->None|`Include(x:Types.Include.t)->(matchx.statuswith|`Closed|`Open|`Default->None|`Inline->Some0)letrecinclude_~config{Types.Subpage.content;_}=page~configcontentand subpages~configsubpages=List.map(include_ ~config)subpagesand page~configp=letsubpages=subpages ~config@@Doctree.Subpages.computepinletresolve=Link.Currentp.urlinleti=Doctree.Shift.compute~on_subp.itemsinletheader,preamble=Doctree.PageTitle.render_title ?source_anchor:p.source_anchorpinletheader=items~config~resolveheaderinletpreamble =items ~config ~resolvepreamble inletcontent=items~config~resolveiinletroot_block=Renderer.Block.Blocks(header@preamble@content)inletdoc=root_blockinMarkdown_page.make~config~url:p.urldocsubpagesandsource_page ~configsp=let{Types.Source_page.url;contents;_}=spinletresolve =Link.Current sp.urlinlettitle=url.Url.Path.nameinletheader =items~config~resolve(Doctree.PageTitle.render_src_titlesp)inletextract_source_textdocs=letrecdoc_to_textspan=match(span:Types.Source_page.span)with|Plain_codes->s|Tagged_code(_,docs)->String.concat~sep:""(List.mapdoc_to_textdocs)indocs|>List.map doc_to_text|>String.concat~sep:""|>String.triminletsource_block=Renderer.Block.Code_block{info_string=Some"ocaml";code=[extract_source_textcontents]}inletdoc=header@[source_block]inMarkdown_page.make_src~config~urltitledocendletrender~(config:Config.t)doc=match (doc:Types.Document.t)with(* .mld *)|Pagepage->[Page.page~configpage](* .mli docs *)|Source_page src->[Page.source_page~configsrc ]letinline~config~xref_base_uri b=letresolve=Link.Basexref_base_uriininline ~config~resolvebletfilepath~configurl=Link.Path.as_filename~configurl