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