def xml2swig(header_name, xml_path, swig_working_dir, case_sense_names, docstrings_features, all_index): """For a given header file, creates swig (.i) file using xml outputs from doxygen (Driver : Doxy2SWIG) Parameters ---------- header_name : Path() Name of the header file (h or hpp) component_name : string component (numerics, kernel, ...) of interest xml_path : string absolute path to xml files. swig_working_dir : Path() Absolute path to siconos swig outputs case_sense_names : bool false if xml output files names are lower case only docstrings_features: dict all docstrings features (keys) with the header used to build them (values) all_index: dict class and files names (keys) with a short description (values) (in-out) Notes ----- * This function takes into account the value of CASE_SENSE_NAMES parameter in doxygen config. * .i file will be named as the xml input file, with .i as ext. * all latex formula are replaced with temporary strings and postprocess later) """ header_name = Path(header_name).resolve() # Get xml files related to current header allfiles = common.get_xml_files(header_name, xml_path, case_sense_names) # Build .i files for f in allfiles: common.filter_dot_in_xml_formulas(f) # Create doxy2swig parser ... p = SiconosDoxy2Swig(f, swig_working_dir) # And write p.swig_outputname, e.g. classX.i p.run() featname, kind, descr = p.get_xml_compound_infos() if kind in ('class', 'struct'): all_index[featname] = descr elif kind == 'file': all_index[header_name.name] = descr for feat in p.features: docstrings_features[feat] = header_name if not p.enums: docstrings_features['pydata_' + p.name] = p.enums # Look for namespaces files namespaces_files = [f for f in xml_path.glob('namespace*.xml')] # Build corresponding .i files for f in namespaces_files: namespace_name = f.stem.split('namespace')[-1] namespace_name = namespace_name.replace(r'_1_1', r'::') common.filter_dot_in_xml_formulas(f) # set output filename == xml file without extension + .i p = SiconosDoxy2Swig(f, swig_working_dir) p.run() hpp_name = p.get_specific_subnodes(p.xmldoc, 'location', recursive=4) hpp_name = Path(hpp_name[0].attributes['file'].value) featname, kind, descr = p.get_xml_compound_infos() if kind in ('class', 'struct'): all_index[featname] = descr elif kind == 'file': all_index[hpp_name.name] = descr for feat in p.features: docstrings_features[feat] = hpp_name if p.enums: docstrings_features['pydata_' + p.name] = p.enums
def xml2rst(headername, srcdir, component_name, sphinx_directory, doxyconf, all_index): """Generate rst file(s) from xml (doxygen outputs) for given C/C++ header Parameters ---------- headername : Path() name of the header (full path) srcdir : string absolute path to c/c++ sources (CMAKE_SOURCE_DIR) component_name : string component (numerics, kernel, ...) of interest (i.e. breathe project) sphinx_directory : string directory where rst files will be written doxyconf : dict dict describing xml/doxy conf. """ case_sense_names = doxyconf['CASE_SENSE_NAMES'] xml_path = doxyconf['XML_OUTPUT'] # First get list of xml files generated from current header by doxygen xml_files = common.get_xml_files(headername, xml_path, case_sense_names) # Then, for each xml, write sphinx header. # 3 cases : class, struct or file. for f in xml_files: common.filter_dot_in_xml_formulas(f) path = os.path.join(xml_path, f) root = ET.parse(path).getroot() f = f.as_posix() compounds = root.findall('compounddef') refname = sphinxref4headername(headername.as_posix(), srcdir) name, kind, descr = common.get_xml_compound_infos(compounds[0]) if f.find('class') > -1 or f.find('struct') > -1: assert len(compounds) == 1 all_index[name] = descr assert kind in ('struct', 'class') label = '.. _' + kind + '_' + name + ':\n\n' title = kind.title() + ' ' + name lenname = len(title) title = label + title + '\n' + lenname * '-' + '\n\n' pgm = 'Defined in :ref:`pgm' + refname + '`' + '\n\n' gen = title + pgm gen += '.. doxygen' + kind + ':: ' + name + '\n' gen += ' :project: ' + component_name + '\n' outputname = kind + headername.stem outputname = Path(sphinx_directory, outputname + '.rst') elif f.find('_8h') > -1: label = '.. _file' + refname + ':\n\n' shortname = headername.as_posix().split(srcdir)[-1] shortname = shortname.replace('/./', '/') if shortname[0] == '/': shortname = shortname[1:] title = 'File ' + shortname lenname = len(title) title = label + title + '\n' + lenname * '-' + '\n\n' pgm = ':ref:`Go to the source code of this file <pgm' pgm += refname + '>`' + '\n\n' gen = title + pgm # sphinx_root = Path(sphinx_directory, '../../') #relpath = os.path.relpath(srcdir, sphinx_root) #fname = os.path.join(relpath, shortname[1:]) gen += '.. doxygenfile:: ' + shortname + '\n' gen += ' :project: ' + component_name + '\n' outputname = 'file_' + headername.name.replace('.', '_') outputname = Path(sphinx_directory, outputname + '.rst') fname = shortname.split('/')[-1] all_index[fname] = descr else: # namespaces files. # Nothing to be done, breathe deal with those # directly from _8h file. continue with open(outputname, 'wt') as out: out.write(gen) out.write('\n') create_rst_for_program(headername.as_posix(), srcdir, sphinx_directory, True)