makehtml.py 16 KB

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