#!/usr/bin/env python3
""" Adds links in the manual pages to tutorials that utilize the functions"""
import os
def processfile(petsc_dir,dir,file,keyre,mdict,uses):
'''Find all functions used in the tutorial and add links to the manual page for the function'''
#print('Processing '+os.path.join(dir,file))
with open(os.path.join(dir,file),'r') as fd:
text = fd.read()
found = list(set(keyre.findall(text)))
for i in found:
if len(uses[i[1:-1]]) < 10:
uses[i[1:-1]].append(os.path.join(dir,file))
def processdir(petsc_dir,dir,keyre,mdict,uses):
'''Loop over tutorials, call processfile() on each'''
#print('Processing '+dir)
for file in os.listdir(dir):
if os.path.isfile(os.path.join(dir,file)) and (file.endswith('.c') or file.endswith('.cxx') or file.endswith('.F90')): processfile(petsc_dir,dir,file,keyre,mdict,uses)
def loadmanualpagescit(petsc_dir,build_dir):
'''Loads and parses the manualpages.cit file generated by Sowing doctext'''
import re
mdict = {}
PATTERN = re.compile(r'man:\+(.*)\+\+(.*)\+\+\+\+man\+\.\./(.*)#.*')
EXCLUDE_PATTERN = re.compile('PetscCall|Petsc[A-Z]*Int|PetscReal|PetscScalar|PetscBool|PetscComplex|PetscErrorCode|SETERR|PetscLog|PETSC_FALSE|PETSC_TRUE')
with open(os.path.join(build_dir,'manualpages','manualpages.cit'),'r') as fd:
text = fd.read()
for line in text.split():
m = re.match(PATTERN, line)
# print('Manual page '+m.group(1)+' location '+m.group(3))
if not m:
raise RuntimeError('Cannot find PATTERN '+str(PATTERN)+' in manualpages.cit line '+line)
if re.match(EXCLUDE_PATTERN,m.group(1)): continue
mdict[r' '+m.group(1)+r' '] = m.group(3)
mdict[r' '+m.group(1)+r'\)'] = m.group(3)
mdict[r' '+m.group(1)+r','] = m.group(3)
mdict[r'\('+m.group(1)+r'\('] = m.group(3)
# sort to find enclosing names first
mdict = dict(sorted(mdict.items(), key=lambda item: len(item[0]), reverse = True))
keyre = re.compile('|'.join(list(mdict.keys())))
uses = {i[1:-1]: [] for i in mdict.keys()}
return keyre,mdict,uses
def main(petsc_dir,build_dir):
keyre,mdict,uses = loadmanualpagescit(petsc_dir,build_dir)
for dirpath, dirnames, filenames in os.walk(os.path.join(petsc_dir,'src'),topdown=True):
dirnames[:] = [d for d in dirnames if d not in ['output', 'ftn-custom', 'ftn-auto', 'ftn-mod', 'tests', 'binding']]
if dirpath.endswith('tutorials'):
processdir(petsc_dir,dirpath,keyre,mdict,uses)
for i in mdict:
if len(uses[i[1:-1]]) > 0:
manpage = os.path.join(build_dir,'manualpages',mdict[i])
set_uses = set(uses[i[1:-1]])
uses[i[1:-1]] = []
with open(manpage,'a') as fd:
fd.write('\n## Examples\n')
for j in set_uses:
file = j.replace(petsc_dir+'/','')
fd.write(''+file+'
\n')