1#!/usr/bin/env python3 2""" Adds links in the manual pages to implementations of the function 3 Also adds References section if any {cite} are found in the manual page 4""" 5 6import os 7import re 8 9def processfile(petsc_dir,dir,file,implsClassAll,subimplsClassAll,implsFuncAll): 10 #print('Processing '+os.path.join(dir,file)) 11 isclass = False 12 with open(os.path.join(dir,file),'r') as f: 13 text = f.read() 14 bibneeded = text.find('{cite}') > -1 15 isclass = text.find('typedef struct') > -1 16 if bibneeded: 17 with open(os.path.join(dir,file),'w') as f: 18 f.write(text[0:text.find('## See Also')]) 19 f.write('\n## References\n```{bibliography}\n:filter: docname in docnames\n```\n\n') 20 f.write(text[text.find('## See Also'):]) 21 22 itemName = file[0:-3] 23 if isclass: 24 iclass = list(filter(lambda x: x.find('_p_'+itemName+' ') > -1, implsClassAll)) 25 func = None 26 isubclass = list(filter(lambda x: x.find('} '+itemName+'_') > -1, subimplsClassAll)) 27 else: 28 iclass = None 29 isubclass = None 30 func = list(filter(lambda x: x.find(' '+itemName+'_') > -1, implsFuncAll)) 31 if func or iclass: 32 with open(os.path.join(dir,file),'a') as f: 33 f.write('\n## Implementations\n') 34 if func: 35 for str in func: 36 f.write(re.sub('(.*\.[ch]x*u*).*('+itemName+'.*)(\(.*\))','<A HREF=\"PETSC_DOC_OUT_ROOT_PLACEHOLDER/\\1.html#\\2\">\\2() in \\1</A><BR>',str,count=1)+'\n') 37 if iclass: 38 for str in iclass: 39 f.write(re.sub('(.*\.[ch]x*u*):.*struct.*(_p_'+itemName+').*{','<A HREF=\"PETSC_DOC_OUT_ROOT_PLACEHOLDER/\\1.html#\\2\">\\2 in \\1</A><BR>',str,count=1)+'\n') 40 if isubclass: 41 for str in isubclass: 42 f.write(re.sub('(.*\.[ch]x*u*):} ('+itemName+'_.*);','<A HREF=\"PETSC_DOC_OUT_ROOT_PLACEHOLDER/\\1.html#\\2\">\\2 in \\1</A><BR>',str,count=1)+'\n') 43 44def loadstructfunctions(petsc_dir): 45 '''Creates the list of structs and class functions''' 46 import subprocess 47 implsClassAll = subprocess.check_output(['git', 'grep', '-E', 'struct[[:space:]]+_[pn]_[^[:space:]]+.*\{', '--', '*.c', '*.cpp', '*.cu', '*.c', '*.h', '*.cxx'], cwd = petsc_dir).strip().decode('utf-8') 48 implsClassAll = list(filter(lambda x: not (x.find('/tests/') > -1 or x.find('/tutorials') > -1 or x.find(';') > -1), implsClassAll.split('\n'))) 49 50 subimplsClassAll = subprocess.check_output(['git', 'grep', '-E', '} [A-Z][A-Za-z]*_[A-Za-z]*;', '--', '*.c', '*.cpp', '*.cu', '*.c', '*.h', '*.cxx'], cwd = petsc_dir).strip().decode('utf-8') 51 subimplsClassAll = list(filter(lambda x: not (x.find('/tests/') > -1 or x.find('/tutorials') > -1), subimplsClassAll.split('\n'))) 52 53 implsFuncAll = subprocess.check_output(['git', 'grep', '-nE', '^(static )?(PETSC_EXTERN )?(PETSC_INTERN )?(extern )?PetscErrorCode +[^_ ]+_([^_ ]+|SuperLU_DIST|MKL_[C]{0,1}PARDISO)\(', '--', '*/impls/*.c', '*/impls/*.cpp', '*/impls/*.cu', '*/impls/*.c', '*/impls/*.h', '*/impls/*.cxx'], cwd = petsc_dir).strip().decode('utf-8') 54 implsFuncAll = list(filter(lambda x: not (x.find('_Private') > -1 or x.find('_private') > -1 or x.find(';') > -1), implsFuncAll.split('\n'))) 55 return (implsClassAll,subimplsClassAll,implsFuncAll) 56 57def main(petsc_dir): 58 (implsClassAll,subimplsClassAll,implsFuncAll) = loadstructfunctions(petsc_dir) 59 for dirpath, dirnames, filenames in os.walk(os.path.join(petsc_dir,'doc','manualpages'),topdown=True): 60 #print('Processing directory '+dirpath) 61 for file in filenames: 62 if file.endswith('.md'): processfile(petsc_dir,dirpath,file,implsClassAll,subimplsClassAll,implsFuncAll) 63 64if __name__ == "__main__": 65 main(os.path.abspath(os.environ['PETSC_DIR'])) 66