xref: /petsc/doc/build_man_examples_links.py (revision a16d7c54a90597f5c8be70e4d1d8614d0ec77e42)
11b37a2a7SPierre Jolivet#!/usr/bin/env python3
2e1124065SBarry Smith""" Adds links in the manual pages to tutorials that utilize the functions"""
3e1124065SBarry Smith
4e1124065SBarry Smithimport os
5e1124065SBarry Smith
6d279607cSBarry Smithdef processfile(petsc_dir,dir,file,keyre,mdict,uses):
7e1124065SBarry Smith  '''Find all functions used in the tutorial and add links to the manual page for the function'''
8e1124065SBarry Smith  #print('Processing '+os.path.join(dir,file))
9e1124065SBarry Smith  with open(os.path.join(dir,file),'r') as fd:
10e1124065SBarry Smith    text = fd.read()
11e1124065SBarry Smith  found = list(set(keyre.findall(text)))
12d279607cSBarry Smith  for i in found:
137f30e1acSBarry Smith    if len(uses[i[1:-1]]) < 10:
147f30e1acSBarry Smith      uses[i[1:-1]].append(os.path.join(dir,file))
15e1124065SBarry Smith
16d279607cSBarry Smithdef processdir(petsc_dir,dir,keyre,mdict,uses):
17e1124065SBarry Smith  '''Loop over tutorials, call processfile() on each'''
18d279607cSBarry Smith  #print('Processing '+dir)
19e1124065SBarry Smith  for file in os.listdir(dir):
20b3fd2b1aSPierre Jolivet    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)
21e1124065SBarry Smith
22*7f019730SBarry Smithdef loadmanualpagescit(petsc_dir,build_dir):
23e1124065SBarry Smith  '''Loads and parses the manualpages.cit file generated by Sowing doctext'''
24e1124065SBarry Smith  import re
25e1124065SBarry Smith  mdict = {}
26d279607cSBarry Smith  PATTERN = re.compile(r'man:\+(.*)\+\+(.*)\+\+\+\+man\+\.\./(.*)#.*')
27e1124065SBarry Smith  EXCLUDE_PATTERN = re.compile('PetscCall|Petsc[A-Z]*Int|PetscReal|PetscScalar|PetscBool|PetscComplex|PetscErrorCode|SETERR|PetscLog|PETSC_FALSE|PETSC_TRUE')
28*7f019730SBarry Smith  with open(os.path.join(build_dir,'manualpages','manualpages.cit'),'r') as fd:
29e1124065SBarry Smith    text = fd.read()
30e1124065SBarry Smith  for line in  text.split():
31e1124065SBarry Smith    m = re.match(PATTERN, line)
32e1124065SBarry Smith    # print('Manual page '+m.group(1)+' location '+m.group(3))
335a0a9f49SBarry Smith    if not m:
345a0a9f49SBarry Smith      raise RuntimeError('Cannot find PATTERN '+str(PATTERN)+' in manualpages.cit line '+line)
35e1124065SBarry Smith    if re.match(EXCLUDE_PATTERN,m.group(1)): continue
366f51e5adSBarry Smith    mdict[r' '+m.group(1)+r' '] = m.group(3)
376f51e5adSBarry Smith    mdict[r' '+m.group(1)+r'\)'] = m.group(3)
386f51e5adSBarry Smith    mdict[r' '+m.group(1)+r','] = m.group(3)
396f51e5adSBarry Smith    mdict[r'\('+m.group(1)+r'\('] = m.group(3)
40e1124065SBarry Smith  # sort to find enclosing names first
41e1124065SBarry Smith  mdict = dict(sorted(mdict.items(), key=lambda item: len(item[0]), reverse = True))
42e1124065SBarry Smith  keyre = re.compile('|'.join(list(mdict.keys())))
437f30e1acSBarry Smith  uses = {i[1:-1]: [] for i in mdict.keys()}
44d279607cSBarry Smith  return keyre,mdict,uses
45e1124065SBarry Smith
46*7f019730SBarry Smithdef main(petsc_dir,build_dir):
47*7f019730SBarry Smith    keyre,mdict,uses = loadmanualpagescit(petsc_dir,build_dir)
48e1124065SBarry Smith    for dirpath, dirnames, filenames in os.walk(os.path.join(petsc_dir,'src'),topdown=True):
496dd63270SBarry Smith      dirnames[:] = [d for d in dirnames if d not in ['output', 'ftn-custom', 'ftn-auto', 'ftn-mod', 'tests', 'binding']]
50e1124065SBarry Smith      if dirpath.endswith('tutorials'):
51d279607cSBarry Smith        processdir(petsc_dir,dirpath,keyre,mdict,uses)
52d279607cSBarry Smith
53d279607cSBarry Smith    for i in mdict:
547f30e1acSBarry Smith      if len(uses[i[1:-1]]) > 0:
55*7f019730SBarry Smith        manpage = os.path.join(build_dir,'manualpages',mdict[i])
56b0cd42eaSPierre Jolivet        set_uses = set(uses[i[1:-1]])
576f51e5adSBarry Smith        uses[i[1:-1]] = []
58d279607cSBarry Smith        with open(manpage,'a') as fd:
59d279607cSBarry Smith          fd.write('\n## Examples\n')
60b0cd42eaSPierre Jolivet          for j in set_uses:
61d279607cSBarry Smith            file = j.replace(petsc_dir+'/','')
62d279607cSBarry Smith            fd.write('<A HREF="PETSC_DOC_OUT_ROOT_PLACEHOLDER/'+file+'.html">'+file+'</A><BR>\n')
63