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