#!/usr/bin/env python3 """ Builds the html files for all the source""" import os import re import subprocess import pathlib from itertools import chain def compute_make_np(i): '''Number of cores to run make c2html on''' f16 = .80 f32 = .65 f64 = .50 f99 = .30 if (i<=2): return 2 elif (i<=4): return i elif (i<=16): return int(4+(i-4)*f16) elif (i<=32): return int(4+12*f16+(i-16)*f32) elif (i<=64): return int(4+12*f16+16*f32+(i-32)*f64) else: return int(4+12*f16+16*f32+32*f64+(i-64)*f99) def main(petsc_dir,build_dir,loc,c2html,mapnames): os.chdir(petsc_dir) # reformat file that maps manual pages to directory location and add MPI manual pages with open('htmlmap.tmp', "w") as fdw, open(os.path.join(build_dir,'manualpages','htmlmap'), "r") as fd: fdw.write(fd.read().replace('man+manualpages/','man+HTML_ROOT/manualpages/')) with open('htmlmap.tmp', "a") as fdw, open(os.path.join(build_dir,'manualpages','mpi.www.index'), "r") as fd: fdw.write(fd.read()) # walk directories generating list of all source code that needs processing and creating index.html for each directory SKIPDIRS = set('public html benchmarks output arch doc binding config petsc-doc lib bin .git systems share mpiuni kernels khash valgrind interfaces data linter'.split()) SUFFIXES = set('.F90 .F .c .cxx .cpp .h .cu .hpp'.split()) allfiles = [] for root, dirs, files in chain.from_iterable(os.walk(path) for path in [petsc_dir]): dirs[:] = [d for d in dirs if not any([s for s in SKIPDIRS if d.startswith(s)])] root = root[len(petsc_dir)+1:] if not root: continue if not os.path.isdir(os.path.join(loc,root)): os.makedirs(os.path.join(loc,root)) allfiles.extend([os.path.join(loc,root,f+'.html') for f in files if any([s for s in SUFFIXES if f.endswith(s)])]) # create index.html file for each directory with open(os.path.join(loc,root,'index.html'),'w') as fdw: if root.startswith('src'): # get MANSEC from the makefile and copy the MANSEC basic information into the index # TODO: the text is actually .md so needs processing if os.path.isfile(os.path.join(root,'makefile')): with open(os.path.join(root,'makefile')) as mklines: mansecl = [line for line in mklines if line.startswith('MANSEC')] if mansecl: mansec = re.sub('MANSEC[ ]*=[ ]*','',mansecl[0]).strip('\n').strip() with open(os.path.join('doc','manualpages','MANSECHeaders',mansec)) as fd: fdw.write(fd.read()) fdw.write('\n

\n') # TODO: use HTML lists for the list below # list examples if root.find('/tests') > -1 or root.find('tutorials') > -1: fdw.write('\n

\nExamples\n

') for f in files: if any([s for s in SUFFIXES if f.endswith(s)]): with open(os.path.join(root,f)) as fd: line = fd.readline() l = line.find('char help[] = ') if l > -1: s = line.find('\\n') line = line[l + 15:s] else: line = '' fdw.write('' + f + ': ' + line + '
\n') # list source code else: if any([f for f in files if any([s for s in SUFFIXES if f.endswith(s)])]): fdw.write('\n

\nSource files\n

') for f in files: if any([s for s in SUFFIXES if f.endswith(s)]): fdw.write('' + f + '
\n') # list subdirectories if dirs: fdw.write('\n

\nDirectories\n

') for d in dirs: fdw.write('' + d + '
\n') # create makefile that will run c2html on all source files in parallel git_sha = subprocess.check_output(['git', 'rev-parse', 'HEAD'], text=True).rstrip() with open(os.path.join(petsc_dir,'c2html.mk'),'w') as fd: fd.write('files = ') fd.write(' '.join(allfiles)) fd.write('\n') fd.write('\n') fd.write(os.path.join(loc,'%.html')+' : %\n') fd.write(' @' + str(os.path.join(str(petsc_dir),'doc','build_c2html_file.py')) + ' ' + str(petsc_dir) + ' ' + str(loc) + ' '+ git_sha + ' ' + c2html + ' ' + mapnames + ' $< $@\n') fd.write('\n') fd.write('all: $(files)\n') import multiprocessing command = ['make', '-j', str(compute_make_np(multiprocessing.cpu_count())), '-f', 'c2html.mk', 'all'] subprocess.run(command, cwd=petsc_dir, check=True) os.unlink('c2html.mk') os.unlink('htmlmap.tmp')