#!/usr/bin/python import monkDebug as debug import sys import monkTools #import CppHeaderParser import re import codeBB import collections global_class_link = { "std::string" : "http://www.cplusplus.com/reference/string/string/", "std::u16string" : "http://www.cplusplus.com/reference/string/u16string/", "std::u32string" : "http://www.cplusplus.com/reference/string/u32string/", "std::wstring" : "http://www.cplusplus.com/reference/string/wstring/", "std::vector" : "http://www.cplusplus.com/reference/vector/vector/" } def display_color(val): # storage keyword : val = re.sub(r'(inline|const|class|virtual|private|public|protected|friend|const|extern|auto|register|static|volatile|typedef|struct|union|enum)', r'\1', val) # type : val = re.sub(r'(bool|BOOL|char(16_t|32_t)?|double|float|u?int(8|16|32|64|128)?(_t)?|long|short|signed|size_t|unsigned|void|(I|U)(8|16|32|64|128))', r'\1', val) return val def display_doxygen_param(comment, input, output): data = "Parameter" if input == True: data += " [input]" if output == True: data += " [output]" data += ": " #extract first element: val = comment.find(" ") var = comment[:val] endComment = comment[val:] # TODO : Check if it exist in the parameter list ... data += "" + var + " " + endComment data += "
" return data def parse_doxygen(data) : streams = data.split("@") data2 = '' for element in streams: if element[:1] == "\n" \ or element[:2] == "\n\n": # nothing to do : Nomale case of the first \n None elif element[:6] == "brief ": data2 += element[6:] data2 += "
" for element in streams: if element[:1] == "\n" \ or element[:2] == "\n\n": # nothing to do : Nomale case of the first \n None elif element[:5] == "note ": data2 += "Notes: " data2 += element[5:] data2 += "
" data3 = '' for element in streams: if element[:1] == "\n" \ or element[:2] == "\n\n": # nothing to do : Nomale case of the first \n None elif element[:14] == "param[in,out] " \ or element[:14] == "param[out,in] ": data3 += display_doxygen_param(element[14:], True, True) elif element[:10] == "param[in] ": data3 += display_doxygen_param(element[10:], True, False) elif element[:11] == "param[out] ": data3 += display_doxygen_param(element[11:], False, True) elif element[:6] == "param ": data3 += display_doxygen_param(element[6:], False, False) elif element[:7] == "return ": data3 += "Return: " data3 += element[7:] data3 += "
" if data3 != '': data2 += "\n" return data2 def white_space(size) : ret = '' for iii in range(len(ret), size): ret += " " return ret def generate_menu(element, level=1): namespaceStack = element.get_namespace() listBase = element.get_all_sub_type(['namespace']) if len(listBase) == 0: return "" ret = "" ret += '\n' return ret def generate_html_page_name(element): namespaceStack = element.get_namespace() link = "" for name in namespaceStack: link += name + "__" return element.get_node_type() + "_" + link + element.get_name() + '.html' def generate_name(element): namespaceStack = element.get_namespace() link = "" for name in namespaceStack: link += name + "::" return element.get_node_type() + ": " + link + element.get_name() def generate_link(element): return '' + element.get_name() + '' def calculate_methode_size(list): returnSize = 0; methodeSize = 0; for element in list: retType = "" if element['node'].get_virtual() == True: retType += 'virtual ' retType += element['node'].get_return_type().to_str() tmpLen = len(retType) if returnSize < tmpLen: returnSize = tmpLen tmpLen = len(element['node'].get_name()) if methodeSize < tmpLen: methodeSize = tmpLen return [returnSize, methodeSize] def write_methode(element, namespaceStack, displaySize = None, link = True): if displaySize == None: displaySize = calculate_methode_size([element]) ret = "" if 'access' in element.keys(): if element['access'] == 'private': ret += '- ' elif element['access'] == 'protected': ret += '# ' elif element['access'] == 'public': ret += '+ ' else: ret += ' ' retType = "" if element['node'].get_virtual() == True: retType += 'virtual ' retType += element['node'].get_return_type().to_str() if retType != "": retType2 = re.sub("<","<", retType) retType2 = re.sub(">",">", retType2) retType2 = display_color(retType2) ret += retType2 ret += " " retType += " " ret += white_space(displaySize[0] - len(retType)+1) name = element['node'].get_name() if link == True: ret += '' + name + '' else: ret += '' + name + '' ret += white_space(displaySize[1] - len(name)) + ' (' listParam = element['node'].get_param() first = True for param in listParam: if first == False: ret += ',
' ret += white_space(displaySize[0] + displaySize[1] +5) first = False retParam = display_color(param.get_type().to_str()) if retParam != "": ret += retParam ret += " " ret += "" + param.get_name() + "" ret += ')' if element['node'].get_virtual_pure() == True: ret += ' = 0' if element['node'].get_constant() == True: ret += display_color(' const') ret += ';' ret += '
' return ret def generate_stupid_index_page(outFolder, header, footer, myLutinDoc): # create index.hml : filename = outFolder + "/index.html" monkTools.create_directory_of_file(filename); file = open(filename, "w") file.write(header) file.write("

" + myLutinDoc.get_base_doc_node().get_name() + "

"); file.write("
"); file.write("TODO : Main page ..."); file.write("
"); file.write("
"); file.write(footer) file.close(); def generate_page(outFolder, header, footer, element): namespaceStack = element.get_namespace() if element.get_node_type() in ['library', 'application', 'namespace', 'class', 'struct', 'enum', 'union']: listBase = element.get_all_sub_type(['library', 'application', 'namespace', 'class', 'struct', 'enum', 'union']) for elem in listBase: generate_page(outFolder, header, footer, elem['node']) filename = outFolder + '/' + generate_html_page_name(element) monkTools.create_directory_of_file(filename); file = open(filename, "w") file.write(header) file.write('

' + generate_name(element) + '

'); file.write('
'); documentation = parse_doxygen(element.get_doc()) if len(documentation) != 0: file.write('

Description:

\n') file.write(documentation) file.write('
\n') if element.get_node_type() in ['library', 'application', 'namespace', 'class', 'struct']: for nameElement in ['namespace', 'class', 'struct', 'enum', 'union']: listBase = element.get_all_sub_type(nameElement) if len(listBase) == 0: continue file.write('

' + nameElement + ':

\n'); file.write('\n'); # calculate element size : listBase = element.get_all_sub_type(['methode', 'constructor', 'destructor']) displayLen = calculate_methode_size(listBase) if element.get_node_type() == 'class' \ or element.get_node_type() == 'struct': if len(element.get_all_sub_type(['constructor', 'destructor'])) != 0: file.write('

Constructor and Destructor:

\n') file.write('
\n');
			listBaseConstructor = element.get_all_sub_type(['constructor'])
			for elem in listBaseConstructor:
				ret = write_methode(elem, namespaceStack, displayLen)
				file.write(ret)
			listBaseDestructor = element.get_all_sub_type(['destructor'])
			for elem in listBaseDestructor:
				ret = write_methode(elem, namespaceStack, displayLen)
				file.write(ret)
			file.write('
\n'); file.write('
\n') if element.get_node_type() in ['library', 'application', 'namespace', 'class', 'struct']: listBaseMethode = element.get_all_sub_type(['methode']) if len(listBaseMethode) != 0: file.write('

Synopsis:

\n') file.write('
\n');
			displayLen = calculate_methode_size(listBaseMethode)
			for elem in listBaseMethode:
				ret = write_methode(elem, namespaceStack, displayLen)
				file.write(ret)
			file.write('
\n') file.write('
\n') # generate herirage list : if element.get_node_type() == 'class': parent = element.get_parents() child = None if parent != []: file.write('

Object Hierarchy:

\n') file.write('
\n');
			file.write(str(parent));
			file.write('
\n'); if len(listBase) != 0: # display all functions : file.write('

Detail:

\n') for subElement in listBase: file.write('

' + subElement['node'].get_name() + '

') file.write('
\n');
			file.write(write_methode(subElement, namespaceStack, link = False))
			file.write('
\n'); #debug.info(str(element['node'].get_doc())); file.write(parse_doxygen(subElement['node'].get_doc())); file.write('
\n'); file.write('
\n'); if element.get_node_type() == 'enum': myElementList = element.get_enum_list() elementSize = 0 for enumElement in myElementList: tmpLen = len(enumElement['name']) if tmpLen > elementSize: elementSize = tmpLen file.write('

Value list

\n') if len(myElementList) < 9: nbColumn = 1 else: nbColumn = 3 file.write('\n'); file.write("

Detail:

\n") isFirst = True for enumElement in myElementList: if isFirst == False: file.write('
\n'); isFirst = False file.write('' + enumElement['name']) file.write('
\n')
			file.write(enumElement['name'] + white_space(elementSize-len(enumElement['name'])) + ' = ' + enumElement['value'] + '')
			file.write('
\n') if enumElement['doc'] != "": file.write(parse_doxygen(enumElement['doc'])); if element.get_node_type() == 'union': file.write("TODO : the page ..."); file.write(footer) file.close(); def generate(myLutinDoc, outFolder) : myDoc = myLutinDoc.get_base_doc_node() monkTools.copy_file(monkTools.get_current_path(__file__)+"/theme/base.css", outFolder+"/base.css") monkTools.copy_file(monkTools.get_current_path(__file__)+"/theme/menu.css", outFolder+"/menu.css") # create common header genericHeader = '\n' genericHeader += '\n' genericHeader += '\n' genericHeader += ' \n' genericHeader += ' ' + myDoc.get_name() + ' Library\n' genericHeader += ' \n' genericHeader += ' \n' genericHeader += '\n' genericHeader += '\n' genericHeader += ' \n" genericHeader += "
\n" genericFooter = "
\n" genericFooter += "\n" genericFooter += "\n" # create index.hml : generate_stupid_index_page(outFolder, genericHeader, genericFooter, myLutinDoc) # create the namespace index properties : generate_page(outFolder, genericHeader, genericFooter, myDoc) for docInputName,outpath in myLutinDoc.listDocFile : debug.print_element("doc", myLutinDoc.name, "<==", docInputName) outputFileName = outFolder + "/" + outpath.replace('/','_') +".html" debug.debug("output file : " + outputFileName) monkTools.create_directory_of_file(outputFileName) inData = monkTools.file_read_data(docInputName) if inData == "": continue outData = genericHeader + codeBB.transcode(inData) + genericFooter monkTools.file_write_data(outputFileName, outData) for docInputName,outpath in myLutinDoc.listTutorialFile : debug.print_element("tutorial", myLutinDoc.name, "<==", docInputName) outputFileName = outFolder + "/" + outpath+".html" debug.debug("output file : " + outputFileName) monkTools.create_directory_of_file(outputFileName) inData = monkTools.file_read_data(docInputName) if inData == "": continue outData = genericHeader + codeBB.transcode(inData) + genericFooter monkTools.file_write_data(outputFileName, outData)