1#!/usr/bin/env python3 2""" Adds links in the manual pages to tutorials that utilize the functions""" 3 4import os 5 6def processfile(petsc_dir,dir,file,keyre,mdict,uses): 7 '''Find all functions used in the tutorial and add links to the manual page for the function''' 8 #print('Processing '+os.path.join(dir,file)) 9 with open(os.path.join(dir,file),'r') as fd: 10 text = fd.read() 11 found = list(set(keyre.findall(text))) 12 for i in found: 13 if len(uses[i[1:-1]]) < 10: 14 uses[i[1:-1]].append(os.path.join(dir,file)) 15 16def processdir(petsc_dir,dir,keyre,mdict,uses): 17 '''Loop over tutorials, call processfile() on each''' 18 #print('Processing '+dir) 19 for file in os.listdir(dir): 20 if os.path.isfile(os.path.join(dir,file)) and (file.endswith('.c') or file.endswith('.cxx')): processfile(petsc_dir,dir,file,keyre,mdict,uses) 21 22def loadmanualpagescit(petsc_dir): 23 '''Loads and parses the manualpages.cit file generated by Sowing doctext''' 24 import re 25 mdict = {} 26 PATTERN = re.compile(r'man:\+(.*)\+\+(.*)\+\+\+\+man\+\.\./(.*)#.*') 27 EXCLUDE_PATTERN = re.compile('PetscCall|Petsc[A-Z]*Int|PetscReal|PetscScalar|PetscBool|PetscComplex|PetscErrorCode|SETERR|PetscLog|PETSC_FALSE|PETSC_TRUE') 28 with open(os.path.join(petsc_dir,'doc','manualpages','manualpages.cit'),'r') as fd: 29 text = fd.read() 30 for line in text.split(): 31 m = re.match(PATTERN, line) 32 # print('Manual page '+m.group(1)+' location '+m.group(3)) 33 if not m: 34 raise RuntimeError('Cannot find PATTERN '+str(PATTERN)+' in manualpages.cit line '+line) 35 if re.match(EXCLUDE_PATTERN,m.group(1)): continue 36 mdict[' '+m.group(1)+' '] = m.group(3) 37 mdict['\('+m.group(1)+'\('] = m.group(3) 38 # sort to find enclosing names first 39 mdict = dict(sorted(mdict.items(), key=lambda item: len(item[0]), reverse = True)) 40 keyre = re.compile('|'.join(list(mdict.keys()))) 41 uses = {i[1:-1]: [] for i in mdict.keys()} 42 return keyre,mdict,uses 43 44def main(petsc_dir): 45 keyre,mdict,uses = loadmanualpagescit(petsc_dir) 46 for dirpath, dirnames, filenames in os.walk(os.path.join(petsc_dir,'src'),topdown=True): 47 dirnames[:] = [d for d in dirnames if d not in ['output', 'ftn-custom', 'f90-custom', 'ftn-auto', 'f90-mod', 'tests', 'binding']] 48 if dirpath.endswith('tutorials'): 49 processdir(petsc_dir,dirpath,keyre,mdict,uses) 50 51 for i in mdict: 52 if len(uses[i[1:-1]]) > 0: 53 manpage = os.path.join(petsc_dir,'doc','manualpages',mdict[i]) 54 set_uses = set(uses[i[1:-1]]) 55 with open(manpage,'a') as fd: 56 fd.write('\n## Examples\n') 57 for j in set_uses: 58 file = j.replace(petsc_dir+'/','') 59 fd.write('<A HREF="PETSC_DOC_OUT_ROOT_PLACEHOLDER/'+file+'.html">'+file+'</A><BR>\n') 60 61if __name__ == "__main__": 62 main(os.path.abspath(os.environ['PETSC_DIR'])) 63