def build_docstrings(headers, component_name, doxygen_config_filename, siconos_swig_path): """Create docstrings (doxy2swig) in swig files from xml (doxygen) generated from headers. Parameters ---------- headers : list (cmake like) headers files to parse component_name : string component (numerics, kernel, ...) of interest doxygen_config_filename : string name (full path) of the doxygen configuration file siconos_swig_path : string path to swig outputs in binary dir (i.e. wrap) Note ---- * all swig files will be genereted into siconos_wig_path/tmp_component_name directory and concatenated into component_name-docstrings.i that will be the file really used by swig. """ doxyconf = parse_doxygen_config(doxygen_config_filename) case_sense_names = doxyconf['CASE_SENSE_NAMES'].find('YES') > -1 xml_path = os.path.join(doxyconf['OUTPUT_DIRECTORY'].lstrip(), doxyconf['XML_OUTPUT'].lstrip()) headers = bt.parse_cmake_list(headers) swig_working_dir = os.path.join(siconos_swig_path, 'tmp_' + component_name) if not os.path.exists(swig_working_dir): os.makedirs(swig_working_dir) docstrings_features = {} all_index = {} for hfile in headers: xml2swig(hfile, component_name, xml_path, swig_working_dir, case_sense_names, docstrings_features, all_index) # Save features info in pickle file pickle_filename = os.path.join(siconos_swig_path, component_name + '.pickle') with open(pickle_filename, 'wb') as currentfile: pickle.dump(docstrings_features, currentfile) # Save class and files names and descriptions (for toc) pickle_filename = os.path.join(siconos_swig_path, component_name + '_index.pickle') with open(pickle_filename, 'wb') as currentfile: pickle.dump(all_index, currentfile) outputfile = os.path.join(siconos_swig_path, component_name + '-docstrings.i') swigfiles = glob.glob(os.path.join(swig_working_dir, '*.i')) with open(outputfile, 'w') as outfile: for fname in swigfiles: with open(fname) as infile: for line in infile: outfile.write(line) msg = 'Generates file ' # + outputfile + ' for doctrings in swig.' print(msg)
def create_breathe_files(headers, srcdir, component_name, sphinx_directory, doxygen_config_filename): """Create rst files for sphinx from xml (doxygen) outputs generated from headers. Parameters ---------- headers : list (cmake like) headers files to parse srcdir : string absolute path to c/c++ sources (CMAKE_SOURCE_DIR) component_name : string component (numerics, kernel, ...) of interest sphinx_directory : string root directory for sphinx rst files doxygen_config_filename : string name (full path) of the doxygen configuration file Notes: * for each header, rst files (class, struct, file and source codes) will be generated * three other 'main' rst files will be produced : * breathe_api.rst, with the toctree for all classes and structs * files_list.rst, with the toctree for all files documentation * sources_list.rst with the toctree for all program listings This function is supposed to be called by a target created with cmake (make <component>-xml2rst) """ # Get all headers for the current component, as a list. headers = bt.parse_cmake_list(headers) rst_files = [] # Parse doxygen config (specific to the current component) doxyconf = common.parse_doxygen_config(doxygen_config_filename) xmlconf = {} # Output path for cpp api documentation sphinx_directory = Path(sphinx_directory, 'reference', 'cpp', component_name) if not sphinx_directory.exists(): os.makedirs(sphinx_directory) # Check if doxygen doc is case-sensitive xmlconf['CASE_SENSE_NAMES'] = doxyconf['CASE_SENSE_NAMES'].find('YES') > -1 # Get xml files path xmlconf['XML_OUTPUT'] = Path(doxyconf['OUTPUT_DIRECTORY'].lstrip(), doxyconf['XML_OUTPUT'].lstrip()) all_index = {} # -- Create rst for classes, structs and files found in xml directory -- for hfile in headers: xml2rst(Path(hfile), srcdir, component_name, sphinx_directory, xmlconf, all_index) # -- Create rst files to collect list of classes and files # (i.e. files created above) -- class_and_struct_files = [f for f in sphinx_directory.glob('class*.rst')] class_and_struct_files += [f for f in sphinx_directory.glob('struct*.rst')] class_and_struct_files.sort() pgm_files = [f for f in sphinx_directory.glob('pgm_*.rst')] pgm_files.sort() rst_files = [f for f in sphinx_directory.glob('file_*.rst')] rst_files.sort() all_files = class_and_struct_files + rst_files all_files.sort() # -- Name of the main rst files for the current component -- # usually : docs/sphinx/reference/cpp/component_name/autodoc_all.rst outputname = Path(sphinx_directory, 'autodoc_all.rst') autodoc_collect(outputname, all_files, all_index, component_name) # Classes and structs outputname = Path(sphinx_directory, 'autodoc_classes.rst') autodoc_collect(outputname, class_and_struct_files, all_index, component_name, subtitle='Classes and structs') # Files doc outputname = Path(sphinx_directory, 'autodoc_files.rst') autodoc_collect(outputname, rst_files, all_index, component_name, subtitle='Files documentation') # Programs listings autodoc_collect_pgm(pgm_files, component_name, sphinx_directory)
def create_breathe_files(headers, srcdir, component_name, sphinx_directory, doxygen_config_filename): """Create rst files for sphinx from xml (doxygen) outputs generated from headers. Parameters ---------- headers : list (cmake like) headers files to parse srcdir : string absolute path to c/c++ sources (CMAKE_SOURCE_DIR) component_name : string component (numerics, kernel, ...) of interest sphinx_directory : string directory where rst files will be written doxygen_config_filename : string name (full path) of the doxygen configuration file Notes: * for each header, rst files (class, struct, file and source codes) will be generated * three other 'main' rst files will be produced : * breathe_api.rst, with the toctree for all classes and structs * files_list.rst, with the toctree for all files documentation * sources_list.rst with the toctree for all program listings """ # Get all headers for the current component headers = bt.parse_cmake_list(headers) rst_files = [] rst_programs = [] # Parse doxygen config doxyconf = parse_doxygen_config(doxygen_config_filename) xmlconf = {} sphinx_directory = os.path.join(sphinx_directory, component_name) if not os.path.exists(sphinx_directory): os.makedirs(sphinx_directory) xmlconf['CASE_SENSE_NAMES'] = doxyconf['CASE_SENSE_NAMES'].find('YES') > -1 xmlconf['XML_OUTPUT'] = os.path.join(doxyconf['OUTPUT_DIRECTORY'].lstrip(), doxyconf['XML_OUTPUT'].lstrip()) all_index = {} # -- Create rst files for classes, structs and files found in xml directory -- for hfile in headers: xml2rst(hfile, srcdir, component_name, sphinx_directory, xmlconf, all_index) # -- Create rst files to collect list of classes and files (i.e. files just created above) -- class_and_struct_files = glob.glob( os.path.join(sphinx_directory, 'class*.rst')) class_and_struct_files += glob.glob( os.path.join(sphinx_directory, 'struct*.rst')) class_and_struct_files.sort() pgm_files = glob.glob(os.path.join(sphinx_directory, 'pgm_*.rst')) pgm_files.sort() rst_files = glob.glob(os.path.join(sphinx_directory, 'file_*.rst')) rst_files.sort() all_files = class_and_struct_files + rst_files all_files.sort() # -- Name of the main rst files for the current component -- # usually : docs/sphinx/reference/cpp/component_name/autodoc_all.rst outputname = os.path.join(sphinx_directory, 'autodoc_all.rst') #title = component_name + ' component\n' #title += len(title) * '=' + '\n\n' indent = 4 * ' ' basename = '/reference/cpp/' + component_name + '/' with open(outputname, 'wt') as out: opt = ':maxdepth: 4\n' for f in all_files: name = os.path.basename(f).split('.')[0] if name.find('class') > -1: shorttitle = name.split('class')[-1] text = '* :class:`' + shorttitle + '` : ' elif name.find('struct') > -1: shorttitle = name.split('struct')[-1] text = '* :class:`' + shorttitle + '` : ' elif name.find('file_') > -1: shorttitle = name.split('file_')[-1].replace('_', '.') name = basename + name text = '* :doc:`' + shorttitle + '<' + name + '>` : ' try: text += all_index[shorttitle] + '\n' except: text += '\n' name = basename + name #gen = textwrap.indent(text, 4 * ' ') out.write(text) out.write('\n\n') # Classes and structs outputname = os.path.join(sphinx_directory, 'autodoc_classes.rst') subtitle = 'Classes and structs' subtitle += '\n' + len(subtitle) * '-' + '\n\n' with open(outputname, 'wt') as out: #out.write(title) out.write(subtitle) #out.write('.. toctree::\n') opt = ':maxdepth: 4\n' #out.write(textwrap.indent(opt, indent)) #out.write('\n') for f in class_and_struct_files: name = os.path.basename(f).split('.')[0] if name.find('class') > -1: shorttitle = name.split('class')[-1] elif name.find('struct') > -1: shorttitle = name.split('struct')[-1] text = '* :class:`' + shorttitle + '` : ' try: text += all_index[shorttitle] + '\n' except: text += '\n' name = basename + name #gen = textwrap.indent(text, 4 * ' ') out.write(text) out.write('\n\n') # Files doc outputname = os.path.join(sphinx_directory, 'autodoc_files.rst') subtitle = 'Files documentation\n' subtitle += len(subtitle) * '-' + '\n\n' with open(outputname, 'wt') as out: out.write(subtitle) #out.write('.. toctree::\n :maxdepth: 2\n\n') for f in rst_files: name = os.path.basename(f).split('.')[0] shorttitle = name.split('file_')[-1].replace('_', '.') name = basename + name text = '* :doc:`' + shorttitle + '<' + name + '>` : ' try: text += all_index[shorttitle] + '\n' except: text += '\n' #gen = textwrap.indent(shorttitle + '<' + name + '>\n', 4 * ' ') out.write(text) out.write('\n\n') # Programs listings outputname = os.path.join(sphinx_directory, 'autodoc_pgm.rst') label = '.. _' + component_name + '_pgm_listings:\n\n' title = component_name.title() + ' programs listings\n' title += len(title) * '-' + '\n\n' title = label + title with open(outputname, 'wt') as out: out.write(title) out.write('.. toctree::\n :maxdepth: 2\n\n') for f in pgm_files: name = os.path.basename(f).split('.')[0] shorttitle = f.split(sphinx_directory)[-1].split('.')[0] splits = shorttitle.split('_') shorttitle = '/'.join(splits[2:-1]) + '.' + splits[-1] name = basename + name gen = textwrap.indent(shorttitle + '<' + name + '>\n', 4 * ' ') out.write(gen)