xref: /petsc/doc/build_man_examples_links.py (revision cb3ff29fa5c880872e59c11fa7fc2fbe1f738e0e)
1#!/usr/bin/env python
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 re.match(EXCLUDE_PATTERN,m.group(1)): continue
34    mdict[' '+m.group(1)+' '] = m.group(3)
35    mdict['\('+m.group(1)+'\('] = m.group(3)
36  # sort to find enclosing names first
37  mdict = dict(sorted(mdict.items(), key=lambda item: len(item[0]), reverse = True))
38  keyre = re.compile('|'.join(list(mdict.keys())))
39  uses = {i[1:-1]: [] for i in mdict.keys()}
40  return keyre,mdict,uses
41
42def main(petsc_dir):
43    keyre,mdict,uses = loadmanualpagescit(petsc_dir)
44    for dirpath, dirnames, filenames in os.walk(os.path.join(petsc_dir,'src'),topdown=True):
45      dirnames[:] = [d for d in dirnames if d not in ['output', 'ftn-custom', 'f90-custom', 'ftn-auto', 'f90-mod', 'tests', 'binding']]
46      if dirpath.endswith('tutorials'):
47        processdir(petsc_dir,dirpath,keyre,mdict,uses)
48
49    for i in mdict:
50      if len(uses[i[1:-1]]) > 0:
51        manpage = os.path.join(petsc_dir,'doc','manualpages',mdict[i])
52        set_uses = set(uses[i[1:-1]])
53        with open(manpage,'a') as fd:
54          fd.write('\n## Examples\n')
55          for j in set_uses:
56            file = j.replace(petsc_dir+'/','')
57            fd.write('<A HREF="PETSC_DOC_OUT_ROOT_PLACEHOLDER/'+file+'.html">'+file+'</A><BR>\n')
58
59if __name__ == "__main__":
60   main(os.path.abspath(os.environ['PETSC_DIR']))
61