Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file element_content.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256(* TyXML
* http://www.ocsigen.org/tyxml
* Copyright (C) 2016 Anton Bachin
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, with linking exception;
* either version 2.1 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02111-1307, USA.
*)openAsttypesopenParsetreetypeassembler=lang:Common.lang->loc:Location.t->name:string->Parsetree.expressionCommon.valuelist->(Common.Label.t*Parsetree.expression)list(* Helpers. *)(* Given a parse tree [e], if [e] represents [_.txt s], where [s] is a string
constant, evaluates to [Some s]. Otherwise, evaluates to [None]. *)letto_txt=function|[%expr[%e?{pexp_desc=Pexp_identf;_}]([%e?{pexp_desc=Pexp_identf2;_}][%e?arg])]->beginmatchLongident.lastf.txt,Longident.lastf2.txt,Ast_convenience.get_strargwith|"txt","return",Somes->Somes|_->Noneend|_->None(** Test if the expression is a txt containing only whitespaces. *)letis_whitespace=function|Common.Vale->beginmatchto_txtewith|SomeswhenString.trims=""->true|_->falseend|_->false(* Given a list of parse trees representing children of an element, filters out
all children that consist of applications of [txt] to strings containing
only whitespace. *)letfilter_whitespace=List.filter(fune->not@@is_whitespacee)letfilter_surrounding_whitespacechildren=letrecaux=function|[]->[]|h::twhenis_whitespaceh->auxt|l->List.revlinaux@@auxchildren(* Given a parse tree and a string [name], checks whether the parse tree is an
application of a function with name [name]. *)letis_element_with_namename=function|Common.Val{pexp_desc=Pexp_apply({pexp_desc=Pexp_ident{txt}},_)}whentxt=name->true|_->false(* Partitions a list of elements according to [is_element_with_name name]. *)letpartitionnamechildren=List.partition(is_element_with_namename)children(* Given the name [n] of a function in [Html_sigs.T], evaluates to
["Html." ^ n]. *)lethtmllocal_name=Longident.Ldot(LidentCommon.(implementationHtml),local_name)(* Generic. *)letnullary~lang:_~loc~namechildren=ifchildren<>[]thenCommon.errorloc"%s should have no content"name;[Common.Label.nolabel,[%expr()][@metalocloc]]letunary~lang~loc~namechildren=matchchildrenwith|[child]->letchild=Common.wrap_valuelanglocchildin[Common.Label.nolabel,child]|_->Common.errorloc"%s should have exactly one child"nameletstar~lang~loc~name:_children=[Common.Label.nolabel,Common.list_wrap_valuelanglocchildren](* Special-cased. *)letul~lang~loc~namechildren=letchildren=filter_whitespacechildreninstar~lang~loc~namechildrenletol~lang~loc~namechildren=letchildren=filter_whitespacechildreninstar~lang~loc~namechildrenletselect~lang~loc~namechildren=letchildren=filter_whitespacechildreninstar~lang~loc~namechildrenlethead~lang~loc~namechildren=letchildren=filter_whitespacechildreninlettitle,others=partition(html"title")childreninmatchtitlewith|[title]->(Common.Label.nolabel,Common.wrap_valuelangloctitle)::star~lang~loc~nameothers|_->Common.errorloc"%s element must have exactly one title child element"nameletfigure~lang~loc~namechildren=letcaption,children=letrecis_first_figcaption=function|[]->is_last_figcaption(List.revchildren)|h::t->ifis_whitespacehthenis_first_figcaptiontelseifis_element_with_name(html"figcaption")hthen`Toph,telseis_last_figcaption(List.revchildren)andis_last_figcaption=function|[]->`No,children|h::t->ifis_whitespacehthenis_last_figcaptiontelseifis_element_with_name(html"figcaption")hthen`Bottomh,(List.revt)else`No,childreninis_first_figcaptionchildreninbeginmatchcaptionwith|`No->star~lang~loc~namechildren|`Topelt->(Common.Label.labelled"figcaption",[%expr`Top[%eCommon.wrap_valuelanglocelt]])::(star~lang~loc~namechildren)|`Bottomelt->(Common.Label.labelled"figcaption",[%expr`Bottom[%eCommon.wrap_valuelanglocelt]])::(star~lang~loc~namechildren)end[@metalocloc]letobject_~lang~loc~namechildren=letparams,others=partition(html"param")childreninifparams<>[]then(Common.Label.labelled"params",Common.list_wrap_valuelanglocparams)::star~lang~loc~nameotherselsestar~lang~loc~nameothersletaudio_video~lang~loc~namechildren=letsources,others=partition(html"source")childreninifsources<>[]then(Common.Label.labelled"srcs",Common.list_wrap_valuelanglocsources)::star~lang~loc~nameotherselsestar~lang~loc~nameotherslettable~lang~loc~namechildren=letcaption,others=partition(html"caption")childreninletcolumns,others=partition(html"colgroup")othersinletthead,others=partition(html"thead")othersinlettfoot,others=partition(html"tfoot")othersinletonelabel=function|[]->[]|[child]->[Common.Label.labelledlabel,Common.wrap_valuelanglocchild]|_->Common.errorloc"%s cannot have more than one %s"namelabelinletcolumns=ifcolumns=[]then[]else[Common.Label.labelled"columns",Common.list_wrap_valuelangloccolumns]in(one"caption"caption)@columns@(one"thead"thead)@(one"tfoot"tfoot)@(star~lang~loc~nameothers)letfieldset~lang~loc~namechildren=letlegend,others=partition(html"legend")childreninmatchlegendwith|[]->star~lang~loc~nameothers|[legend]->(Common.Label.labelled"legend",Common.wrap_valuelangloclegend)::(star~lang~loc~nameothers)|_->Common.errorloc"%s cannot have more than one legend"nameletdatalist~lang~loc~namechildren=letoptions,others=partition(html"option")childreninletchildren=beginmatchotherswith|[]->Common.Label.labelled"children",[%expr`Options[%eCommon.list_wrap_valuelanglocoptions]]|_->Common.Label.labelled"children",[%expr`Phras[%eCommon.list_wrap_valuelanglocchildren]]end[@metalocloc]inchildren::(nullary~lang~loc~name[])letdetails~lang~loc~namechildren=letsummary,others=partition(html"summary")childreninmatchsummarywith|[summary]->(Common.Label.nolabel,Common.wrap_valuelanglocsummary)::(star~lang~loc~nameothers)|_->Common.errorloc"%s must have exactly one summary child"nameletmenu~lang~loc~namechildren=letchildren=Common.Label.labelled"child",[%expr`Flows[%eCommon.list_wrap_valuelanglocchildren]][@metalocloc]inchildren::(nullary~lang~loc~name[])lethtml~lang~loc~namechildren=letchildren=filter_whitespacechildreninlethead,others=partition(html"head")childreninletbody,others=partition(html"body")othersinmatchhead,body,otherswith|[head],[body],[]->[Common.Label.nolabel,Common.wrap_valuelanglochead;Common.Label.nolabel,Common.wrap_valuelanglocbody]|_->Common.errorloc"%s element must have exactly head and body child elements"name