makehtml.py 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717
  1. import sys
  2. import xml.etree.ElementTree as ET
  3. from xml.sax.saxutils import escape, unescape
  4. html_escape_table = {
  5. '"': """,
  6. "'": "'"
  7. }
  8. html_unescape_table = {v:k for k, v in html_escape_table.items()}
  9. def html_escape(text):
  10. return escape(text, html_escape_table)
  11. def html_unescape(text):
  12. return unescape(text, html_unescape_table)
  13. input_list = []
  14. single_page=True
  15. for arg in sys.argv[1:]:
  16. if arg[:1] == "-":
  17. if arg[1:] == "multipage":
  18. single_page = False
  19. if arg[1:] == "singlepage":
  20. single_page = True
  21. else:
  22. input_list.append(arg)
  23. if len(input_list) < 1:
  24. print("usage: makehtml.py <class_list.xml>")
  25. sys.exit(0)
  26. def validate_tag(elem,tag):
  27. if (elem.tag != tag):
  28. print("Tag mismatch, expected '"+tag+"', got "+elem.tag);
  29. sys.exit(255)
  30. def make_html_bottom(body):
  31. #make_html_top(body,True)
  32. ET.SubElement(body,"hr")
  33. copyright = ET.SubElement(body,"span")
  34. copyright.text = "Copyright 2008-2010 Codenix SRL"
  35. def make_html_top(body,bottom=False):
  36. if (bottom):
  37. ET.SubElement(body,"hr")
  38. table = ET.SubElement(body,"table")
  39. table.attrib["class"]="top_table"
  40. tr = ET.SubElement(table,"tr")
  41. td = ET.SubElement(tr,"td")
  42. td.attrib["class"]="top_table"
  43. img = ET.SubElement(td,"image")
  44. img.attrib["src"]="images/logo.png"
  45. td = ET.SubElement(tr,"td")
  46. td.attrib["class"]="top_table"
  47. a = ET.SubElement(td,"a")
  48. a.attrib["href"]="index.html"
  49. a.text="Index"
  50. td = ET.SubElement(tr,"td")
  51. td.attrib["class"]="top_table"
  52. a = ET.SubElement(td,"a")
  53. a.attrib["href"]="alphabetical.html"
  54. a.text="Classes"
  55. td = ET.SubElement(tr,"td")
  56. td.attrib["class"]="top_table"
  57. a = ET.SubElement(td,"a")
  58. a.attrib["href"]="category.html"
  59. a.text="Categories"
  60. td = ET.SubElement(tr,"td")
  61. a = ET.SubElement(td,"a")
  62. a.attrib["href"]="inheritance.html"
  63. a.text="Inheritance"
  64. if (not bottom):
  65. ET.SubElement(body,"hr")
  66. def make_html_class_list(class_list,columns):
  67. div=ET.Element("div")
  68. div.attrib["class"]="ClassList";
  69. h1=ET.SubElement(div,"h2")
  70. h1.text="Alphabetical Class List"
  71. table=ET.SubElement(div,"table")
  72. table.attrib["class"]="class_table"
  73. table.attrib["width"]="100%"
  74. prev=0
  75. col_max = len(class_list) / columns + 1
  76. print("col max is ", col_max)
  77. col_count = 0
  78. row_count = 0
  79. last_initial = ""
  80. fit_columns=[]
  81. for n in range(0,columns):
  82. fit_columns+=[[]]
  83. indexers=[]
  84. last_initial=""
  85. idx=0
  86. for n in class_list:
  87. col = int(idx/col_max)
  88. if (col>=columns):
  89. col=columns-1
  90. fit_columns[col]+=[n]
  91. idx+=1
  92. if (n[:1]!=last_initial):
  93. indexers+=[n]
  94. last_initial=n[:1]
  95. row_max=0
  96. for n in range(0,columns):
  97. if (len(fit_columns[n])>row_max):
  98. row_max=len(fit_columns[n])
  99. for r in range(0,row_max):
  100. tr = ET.SubElement(table,"tr")
  101. for c in range(0,columns):
  102. tdi = ET.SubElement(tr,"td")
  103. tdi.attrib["align"]="right"
  104. td = ET.SubElement(tr,"td")
  105. if (r>=len(fit_columns[c])):
  106. continue
  107. classname = fit_columns[c][r]
  108. print(classname)
  109. if (classname in indexers):
  110. span = ET.SubElement(tdi, "span")
  111. span.attrib["class"] = "class_index_letter"
  112. span.text = classname[:1].upper()
  113. if (single_page):
  114. link="#"+classname
  115. else:
  116. link=classname+".html"
  117. a=ET.SubElement(td,"a")
  118. a.attrib["href"]=link
  119. a.text=classname
  120. if (not single_page):
  121. cat_class_list=ET.Element("html")
  122. csscc = ET.SubElement(cat_class_list, "link")
  123. csscc.attrib["href"] = "main.css"
  124. csscc.attrib["rel"] = "stylesheet"
  125. csscc.attrib["type"] = "text/css"
  126. bodycc = ET.SubElement(cat_class_list, "body")
  127. make_html_top(bodycc)
  128. cat_class_parent=bodycc
  129. else:
  130. cat_class_parent=div
  131. h1=ET.SubElement(cat_class_parent,"h2")
  132. h1.text="Class List By Category"
  133. class_cat_table={}
  134. class_cat_list=[]
  135. for c in class_list:
  136. clss = classes[c]
  137. if ("category" in clss.attrib):
  138. class_cat=clss.attrib["category"]
  139. else:
  140. class_cat="Core"
  141. if (class_cat.find("/")!=-1):
  142. class_cat=class_cat[class_cat.rfind("/")+1:]
  143. if (not class_cat in class_cat_list):
  144. class_cat_list.append(class_cat)
  145. class_cat_table[class_cat]=[]
  146. class_cat_table[class_cat].append(c)
  147. class_cat_list.sort()
  148. ct = ET.SubElement(cat_class_parent,"table")
  149. for cl in class_cat_list:
  150. l = class_cat_table[cl]
  151. l.sort()
  152. tr = ET.SubElement(ct,"tr")
  153. tr.attrib["class"]="category_title"
  154. td = ET.SubElement(ct,"td")
  155. td.attrib["class"]="category_title"
  156. a = ET.SubElement(td,"a")
  157. a.attrib["class"]="category_title"
  158. a.text=cl
  159. a.attrib["name"]="CATEGORY_"+cl
  160. td = ET.SubElement(ct,"td")
  161. td.attrib["class"]="category_title"
  162. for clt in l:
  163. tr = ET.SubElement(ct,"tr")
  164. td = ET.SubElement(ct,"td")
  165. make_type(clt,td)
  166. clss=classes[clt]
  167. bd = clss.find("brief_description")
  168. bdtext=""
  169. if (bd!=None):
  170. bdtext=bd.text
  171. td = ET.SubElement(ct,"td")
  172. td.text=bdtext
  173. if (not single_page):
  174. make_html_bottom(bodycc)
  175. catet_out = ET.ElementTree(cat_class_list)
  176. catet_out.write("category.html")
  177. if (not single_page):
  178. inh_class_list=ET.Element("html")
  179. cssic = ET.SubElement(inh_class_list, "link")
  180. cssic.attrib["href"] = "main.css"
  181. cssic.attrib["rel"] = "stylesheet"
  182. cssic.attrib["type"] = "text/css"
  183. bodyic = ET.SubElement(inh_class_list, "body")
  184. make_html_top(bodyic)
  185. inh_class_parent=bodyic
  186. else:
  187. inh_class_parent=div
  188. h1=ET.SubElement(inh_class_parent,"h2")
  189. h1.text="Class List By Inheritance"
  190. itemlist = ET.SubElement(inh_class_parent,"list")
  191. class_inh_table={}
  192. def add_class(clss):
  193. if (clss.attrib["name"] in class_inh_table):
  194. return #already added
  195. parent_list=None
  196. if ("inherits" in clss.attrib):
  197. inhc = clss.attrib["inherits"]
  198. if (not (inhc in class_inh_table)):
  199. add_class(classes[inhc])
  200. parent_list = class_inh_table[inhc].find("div")
  201. if (parent_list == None):
  202. parent_div = ET.SubElement(class_inh_table[inhc],"div")
  203. parent_list = ET.SubElement(parent_div,"list")
  204. parent_div.attrib["class"]="inh_class_list"
  205. else:
  206. parent_list = parent_list.find("list")
  207. else:
  208. parent_list=itemlist
  209. item = ET.SubElement(parent_list,"li")
  210. # item.attrib["class"]="inh_class_list"
  211. class_inh_table[clss.attrib["name"]]=item
  212. make_type(clss.attrib["name"],item)
  213. for c in class_list:
  214. add_class(classes[c])
  215. if (not single_page):
  216. make_html_bottom(bodyic)
  217. catet_out = ET.ElementTree(inh_class_list)
  218. catet_out.write("inheritance.html")
  219. #h1=ET.SubElement(div,"h2")
  220. #h1.text="Class List By Inheritance"
  221. return div
  222. def make_type(p_type,p_parent):
  223. if (p_type=="RefPtr"):
  224. p_type="Resource"
  225. if (p_type in class_names):
  226. a=ET.SubElement(p_parent,"a")
  227. a.attrib["class"]="datatype_existing"
  228. a.text=p_type+" "
  229. if (single_page):
  230. a.attrib["href"]="#"+p_type
  231. else:
  232. a.attrib["href"]=p_type+".html"
  233. else:
  234. span=ET.SubElement(p_parent,"span")
  235. span.attrib["class"]="datatype"
  236. span.text=p_type+" "
  237. def make_text_def(class_name,parent,text):
  238. text = html_escape(text)
  239. pos=0
  240. while(True):
  241. pos = text.find("[",pos)
  242. if (pos==-1):
  243. break
  244. endq_pos=text.find("]",pos+1)
  245. if (endq_pos==-1):
  246. break
  247. pre_text=text[:pos]
  248. post_text=text[endq_pos+1:]
  249. tag_text=text[pos+1:endq_pos]
  250. if (tag_text in class_names):
  251. if (single_page):
  252. tag_text='<a href="#'+tag_text+'">'+tag_text+'</a>'
  253. else:
  254. tag_text='<a href="'+tag_text+'.html">'+tag_text+'</a>'
  255. else: #command
  256. cmd=tag_text
  257. space_pos=tag_text.find(" ")
  258. if (cmd.find("html")==0):
  259. cmd=tag_text[:space_pos]
  260. param=tag_text[space_pos+1:]
  261. tag_text="<"+param+">"
  262. elif(cmd.find("method")==0):
  263. cmd=tag_text[:space_pos]
  264. param=tag_text[space_pos+1:]
  265. if (not single_page and param.find(".")!=-1):
  266. class_param,method_param=param.split(".")
  267. tag_text=tag_text='<a href="'+class_param+'.html#'+class_param+"_"+method_param+'">'+class_param+'.'+method_param+'()</a>'
  268. else:
  269. tag_text=tag_text='<a href="#'+class_name+"_"+param+'">'+class_name+'.'+param+'()</a>'
  270. elif (cmd.find("image=")==0):
  271. print("found image: "+cmd)
  272. tag_text="<img src="+cmd[6:]+"/>"
  273. elif (cmd.find("url=")==0):
  274. tag_text="<a href="+cmd[4:]+">"
  275. elif (cmd=="/url"):
  276. tag_text="</a>"
  277. elif (cmd=="center"):
  278. tag_text="<div align=\"center\">"
  279. elif (cmd=="/center"):
  280. tag_text="</div>"
  281. elif (cmd=="br"):
  282. tag_text="<br/>"
  283. elif (cmd=="i" or cmd=="/i" or cmd=="b" or cmd=="/b" or cmd=="u" or cmd=="/u"):
  284. tag_text="<"+tag_text+">" #html direct mapping
  285. else:
  286. tag_text="["+tag_text+"]"
  287. text=pre_text+tag_text+post_text
  288. pos=len(pre_text)+len(tag_text)
  289. #tnode = ET.SubElement(parent,"div")
  290. #tnode.text=text
  291. text="<div class=\"description\">"+text+"</div>"
  292. try:
  293. tnode=ET.XML(text)
  294. parent.append(tnode)
  295. except:
  296. print("Error parsing description text: '"+text+"'")
  297. sys.exit(255)
  298. return tnode
  299. def make_method_def(name,m,declare,event=False):
  300. mdata={}
  301. if (not declare):
  302. div=ET.Element("tr")
  303. div.attrib["class"]="method"
  304. ret_parent=ET.SubElement(div,"td")
  305. ret_parent.attrib["align"]="right"
  306. func_parent=ET.SubElement(div,"td")
  307. else:
  308. div=ET.Element("div")
  309. div.attrib["class"]="method"
  310. ret_parent=div
  311. func_parent=div
  312. mdata["argidx"]=[]
  313. mdata["name"]=m.attrib["name"]
  314. qualifiers=""
  315. if ("qualifiers" in m.attrib):
  316. qualifiers=m.attrib["qualifiers"]
  317. args=list(m)
  318. for a in args:
  319. if (a.tag=="return"):
  320. idx=-1
  321. elif (a.tag=="argument"):
  322. idx=int(a.attrib["index"])
  323. else:
  324. continue
  325. mdata["argidx"].append(idx)
  326. mdata[idx]=a
  327. if (not event):
  328. if (-1 in mdata["argidx"]):
  329. make_type(mdata[-1].attrib["type"],ret_parent)
  330. mdata["argidx"].remove(-1)
  331. else:
  332. make_type("void",ret_parent)
  333. span=ET.SubElement(func_parent,"span")
  334. if (declare):
  335. span.attrib["class"]="funcdecl"
  336. a=ET.SubElement(span,"a")
  337. a.attrib["name"]=name+"_"+m.attrib["name"]
  338. a.text=name+"::"+m.attrib["name"]
  339. else:
  340. span.attrib["class"]="identifier funcdef"
  341. a=ET.SubElement(span,"a")
  342. a.attrib["href"]="#"+name+"_"+m.attrib["name"]
  343. a.text=m.attrib["name"]
  344. span=ET.SubElement(func_parent,"span")
  345. span.attrib["class"]="symbol"
  346. span.text=" ("
  347. for a in mdata["argidx"]:
  348. arg=mdata[a]
  349. if (a>0):
  350. span=ET.SubElement(func_parent,"span")
  351. span.text=", "
  352. else:
  353. span=ET.SubElement(func_parent,"span")
  354. span.text=" "
  355. make_type(arg.attrib["type"],func_parent)
  356. span=ET.SubElement(func_parent,"span")
  357. span.text=arg.attrib["name"]
  358. if ("default" in arg.attrib):
  359. span.text=span.text+"="+arg.attrib["default"]
  360. span=ET.SubElement(func_parent,"span")
  361. span.attrib["class"]="symbol"
  362. if (len(mdata["argidx"])):
  363. span.text=" )"
  364. else:
  365. span.text=")"
  366. if (qualifiers):
  367. span=ET.SubElement(func_parent,"span")
  368. span.attrib["class"]="qualifier"
  369. span.text=" "+qualifiers
  370. return div
  371. def make_html_class(node):
  372. div=ET.Element("div")
  373. div.attrib["class"]="class";
  374. a=ET.SubElement(div,"a")
  375. a.attrib["name"]=node.attrib["name"]
  376. h3=ET.SubElement(a,"h3")
  377. h3.attrib["class"]="title class_title"
  378. h3.text=node.attrib["name"]
  379. briefd = node.find("brief_description")
  380. if (briefd!=None):
  381. div2=ET.SubElement(div,"div")
  382. div2.attrib["class"]="description class_description"
  383. div2.text=briefd.text
  384. if ("inherits" in node.attrib):
  385. ET.SubElement(div,"br")
  386. div2=ET.SubElement(div,"div")
  387. div2.attrib["class"]="inheritance";
  388. span=ET.SubElement(div2,"span")
  389. span.text="Inherits: "
  390. make_type(node.attrib["inherits"],div2)
  391. if ("category" in node.attrib):
  392. ET.SubElement(div,"br")
  393. div3=ET.SubElement(div,"div")
  394. div3.attrib["class"]="category";
  395. span=ET.SubElement(div3,"span")
  396. span.attrib["class"]="category"
  397. span.text="Category: "
  398. a = ET.SubElement(div3,"a")
  399. a.attrib["class"]="category_ref"
  400. a.text=node.attrib["category"]
  401. catname=a.text
  402. if (catname.rfind("/")!=-1):
  403. catname=catname[catname.rfind("/"):]
  404. catname="CATEGORY_"+catname
  405. if (single_page):
  406. a.attrib["href"]="#"+catname
  407. else:
  408. a.attrib["href"]="category.html#"+catname
  409. methods = node.find("methods")
  410. if(methods!=None and len(list(methods))>0):
  411. h4=ET.SubElement(div,"h4")
  412. h4.text="Public Methods:"
  413. method_table=ET.SubElement(div,"table")
  414. method_table.attrib["class"]="method_list";
  415. for m in list(methods):
  416. # li = ET.SubElement(div2, "li")
  417. method_table.append( make_method_def(node.attrib["name"],m,False) )
  418. events = node.find("signals")
  419. if(events!=None and len(list(events))>0):
  420. h4=ET.SubElement(div,"h4")
  421. h4.text="Events:"
  422. event_table=ET.SubElement(div,"table")
  423. event_table.attrib["class"]="method_list";
  424. for m in list(events):
  425. # li = ET.SubElement(div2, "li")
  426. event_table.append( make_method_def(node.attrib["name"],m,False,True) )
  427. members = node.find("members")
  428. if(members!=None and len(list(members))>0):
  429. h4=ET.SubElement(div,"h4")
  430. h4.text="Public Variables:"
  431. div2=ET.SubElement(div,"div")
  432. div2.attrib["class"]="member_list";
  433. for c in list(members):
  434. li = ET.SubElement(div2, "li")
  435. div3=ET.SubElement(li,"div")
  436. div3.attrib["class"]="member";
  437. make_type(c.attrib["type"],div3)
  438. span=ET.SubElement(div3,"span")
  439. span.attrib["class"]="identifier member_name"
  440. span.text=" "+c.attrib["name"]+" "
  441. span=ET.SubElement(div3,"span")
  442. span.attrib["class"]="member_description"
  443. span.text=c.text
  444. constants = node.find("constants")
  445. if(constants!=None and len(list(constants))>0):
  446. h4=ET.SubElement(div,"h4")
  447. h4.text="Constants:"
  448. div2=ET.SubElement(div,"div")
  449. div2.attrib["class"]="constant_list";
  450. for c in list(constants):
  451. li = ET.SubElement(div2, "li")
  452. div3=ET.SubElement(li,"div")
  453. div3.attrib["class"]="constant";
  454. span=ET.SubElement(div3,"span")
  455. span.attrib["class"]="identifier constant_name"
  456. span.text=c.attrib["name"]+" "
  457. if ("value" in c.attrib):
  458. span=ET.SubElement(div3,"span")
  459. span.attrib["class"]="symbol"
  460. span.text="= "
  461. span=ET.SubElement(div3,"span")
  462. span.attrib["class"]="constant_value"
  463. span.text=c.attrib["value"]+" "
  464. span=ET.SubElement(div3,"span")
  465. span.attrib["class"]="constant_description"
  466. span.text=c.text
  467. # ET.SubElement(div,"br")
  468. descr=node.find("description")
  469. if (descr!=None and descr.text.strip()!=""):
  470. h4=ET.SubElement(div,"h4")
  471. h4.text="Description:"
  472. make_text_def(node.attrib["name"],div,descr.text)
  473. # div2=ET.SubElement(div,"div")
  474. # div2.attrib["class"]="description";
  475. # div2.text=descr.text
  476. if(methods!=None or events!=None):
  477. h4=ET.SubElement(div,"h4")
  478. h4.text="Method Documentation:"
  479. iter_list = []
  480. if (methods!=None):
  481. iter_list+=list(methods)
  482. if (events!=None):
  483. iter_list+=list(events)
  484. for m in iter_list:
  485. descr=m.find("description")
  486. if (descr==None or descr.text.strip()==""):
  487. continue;
  488. div2=ET.SubElement(div,"div")
  489. div2.attrib["class"]="method_doc";
  490. div2.append( make_method_def(node.attrib["name"],m,True) )
  491. #anchor = ET.SubElement(div2, "a")
  492. #anchor.attrib["name"] =
  493. make_text_def(node.attrib["name"],div2,descr.text)
  494. #div3=ET.SubElement(div2,"div")
  495. #div3.attrib["class"]="description";
  496. #div3.text=descr.text
  497. return div
  498. class_names=[]
  499. classes={}
  500. for file in input_list:
  501. tree = ET.parse(file)
  502. doc=tree.getroot()
  503. if ("version" not in doc.attrib):
  504. print("Version missing from 'doc'")
  505. sys.exit(255)
  506. version=doc.attrib["version"]
  507. for c in list(doc):
  508. if (c.attrib["name"] in class_names):
  509. continue
  510. class_names.append(c.attrib["name"])
  511. classes[c.attrib["name"]]=c
  512. html = ET.Element("html")
  513. css = ET.SubElement(html, "link")
  514. css.attrib["href"] = "main.css"
  515. css.attrib["rel"] = "stylesheet"
  516. css.attrib["type"] = "text/css"
  517. body = ET.SubElement(html, "body")
  518. if (not single_page):
  519. make_html_top(body)
  520. class_names.sort()
  521. body.append( make_html_class_list(class_names,5) )
  522. for cn in class_names:
  523. c=classes[cn]
  524. if (single_page):
  525. body.append( make_html_class(c))
  526. else:
  527. html2 = ET.Element("html")
  528. css = ET.SubElement(html2, "link")
  529. css.attrib["href"] = "main.css"
  530. css.attrib["rel"] = "stylesheet"
  531. css.attrib["type"] = "text/css"
  532. body2 = ET.SubElement(html2, "body" )
  533. make_html_top(body2)
  534. body2.append( make_html_class(c) );
  535. make_html_bottom(body2)
  536. et_out = ET.ElementTree(html2)
  537. et_out.write(c.attrib["name"]+".html")
  538. et_out = ET.ElementTree(html)
  539. if (single_page):
  540. et_out.write("singlepage.html")
  541. else:
  542. make_html_bottom(body)
  543. et_out.write("alphabetical.html")