xref: /petsc/doc/build_man_impls_links.py (revision daba9d70159ea2f6905738fcbec7404635487b2b)
11b37a2a7SPierre Jolivet#!/usr/bin/env python3
292b0751cSBarry Smith""" Adds links in the manual pages to implementations of the function
392b0751cSBarry Smith    Also adds References section if any {cite} are found in the manual page
492b0751cSBarry Smith"""
5fae261c0SBarry Smith
6fae261c0SBarry Smithimport os
7fae261c0SBarry Smithimport re
8fae261c0SBarry Smith
97f019730SBarry Smithdef processfile(petsc_dir,build_dir,dir,file,implsClassAll,subimplsClassAll,implsFuncAll):
10fae261c0SBarry Smith  #print('Processing '+os.path.join(dir,file))
1130ad25b6SBarry Smith  isclass = False
1292b0751cSBarry Smith  with open(os.path.join(dir,file),'r') as f:
1392b0751cSBarry Smith    text = f.read()
1492b0751cSBarry Smith    bibneeded = text.find('{cite}') > -1
1530ad25b6SBarry Smith    isclass = text.find('typedef struct') > -1
1692b0751cSBarry Smith  if bibneeded:
1792b0751cSBarry Smith    with open(os.path.join(dir,file),'w') as f:
1892b0751cSBarry Smith      f.write(text[0:text.find('## See Also')])
1992b0751cSBarry Smith      f.write('\n## References\n```{bibliography}\n:filter: docname in docnames\n```\n\n')
2092b0751cSBarry Smith      f.write(text[text.find('## See Also'):])
2130ad25b6SBarry Smith
22fae261c0SBarry Smith  itemName = file[0:-3]
2330ad25b6SBarry Smith  if isclass:
2430ad25b6SBarry Smith    iclass = list(filter(lambda x: x.find('_p_'+itemName+' ') > -1, implsClassAll))
2530ad25b6SBarry Smith    func = None
2630ad25b6SBarry Smith    isubclass = list(filter(lambda x: x.find('} '+itemName+'_') > -1, subimplsClassAll))
2730ad25b6SBarry Smith  else:
2830ad25b6SBarry Smith    iclass = None
2930ad25b6SBarry Smith    isubclass = None
3030ad25b6SBarry Smith    func = list(filter(lambda x: x.find(' '+itemName+'_') > -1, implsFuncAll))
31fae261c0SBarry Smith  if func or iclass:
32fae261c0SBarry Smith    with open(os.path.join(dir,file),'a') as f:
33fae261c0SBarry Smith      f.write('\n## Implementations\n')
34fae261c0SBarry Smith      if func:
35fae261c0SBarry Smith        for str in func:
36813bf178SBarry Smith          f.write(re.sub(r'(.*\.[ch]x*u*).*('+itemName+r'.*)(\(.*\))','<A HREF=\"PETSC_DOC_OUT_ROOT_PLACEHOLDER/\\1.html#\\2\">\\2() in \\1</A><BR>',str,count=1)+'\n')
37fae261c0SBarry Smith      if iclass:
38fae261c0SBarry Smith        for str in iclass:
3934c645fdSBarry Smith          f.write(re.sub(r'(.*\.[ch]x*u*):.*struct.*(_p_'+itemName+').*{','<A HREF=\"PETSC_DOC_OUT_ROOT_PLACEHOLDER/\\1.html#\\2\">\\2 in \\1</A><BR>',str,count=1)+'\n')
4030ad25b6SBarry Smith      if isubclass:
4130ad25b6SBarry Smith        for str in isubclass:
4234c645fdSBarry Smith          f.write(re.sub(r'(.*\.[ch]x*u*):} ('+itemName+'_.*);','<A HREF=\"PETSC_DOC_OUT_ROOT_PLACEHOLDER/\\1.html#\\2\">\\2 in \\1</A><BR>',str,count=1)+'\n')
4330ad25b6SBarry Smith
44fae261c0SBarry Smithdef loadstructfunctions(petsc_dir):
45fae261c0SBarry Smith  '''Creates the list of structs and class functions'''
46fae261c0SBarry Smith  import subprocess
47*d52a580bSJunchao Zhang  implsClassAll = subprocess.check_output(['git', 'grep', '-E', r'struct[[:space:]]+_[pn]_[^[:space:]]+.*\{', '--', '*.c', '*.cu', '*.c', '*.h', '*.cxx'], cwd = petsc_dir).strip().decode('utf-8')
48fae261c0SBarry Smith  implsClassAll = list(filter(lambda x: not (x.find('/tests/') > -1 or x.find('/tutorials') > -1 or x.find(';') > -1), implsClassAll.split('\n')))
49fae261c0SBarry Smith
50*d52a580bSJunchao Zhang  subimplsClassAll = subprocess.check_output(['git', 'grep', '-E', '} [A-Z][A-Za-z]*_[A-Za-z]*;', '--', '*.c', '*.cu', '*.c', '*.h', '*.cxx'], cwd = petsc_dir).strip().decode('utf-8')
5130ad25b6SBarry Smith  subimplsClassAll = list(filter(lambda x: not (x.find('/tests/') > -1 or x.find('/tutorials') > -1), subimplsClassAll.split('\n')))
5230ad25b6SBarry Smith
53*d52a580bSJunchao Zhang  implsFuncAll = subprocess.check_output(['git', 'grep', '-nE', r'^(static )?(PETSC_EXTERN )?(PETSC_INTERN )?(extern )?PetscErrorCode +[^_ ]+_([^_ ]+|SuperLU_DIST|MKL_[C]{0,1}PARDISO)\(', '--', '*/impls/*.c', '*/impls/*.cu', '*/impls/*.c', '*/impls/*.h', '*/impls/*.cxx'], cwd = petsc_dir).strip().decode('utf-8')
54fae261c0SBarry Smith  implsFuncAll = list(filter(lambda x: not (x.find('_Private') > -1 or x.find('_private') > -1 or x.find(';') > -1), implsFuncAll.split('\n')))
5530ad25b6SBarry Smith  return (implsClassAll,subimplsClassAll,implsFuncAll)
56fae261c0SBarry Smith
577f019730SBarry Smithdef main(petsc_dir,build_dir):
5830ad25b6SBarry Smith    (implsClassAll,subimplsClassAll,implsFuncAll) = loadstructfunctions(petsc_dir)
597f019730SBarry Smith    for dirpath, dirnames, filenames in os.walk(os.path.join(build_dir,'manualpages'),topdown=True):
60fae261c0SBarry Smith      #print('Processing directory '+dirpath)
61fae261c0SBarry Smith      for file in filenames:
627f019730SBarry Smith        if file.endswith('.md'): processfile(petsc_dir,build_dir,dirpath,file,implsClassAll,subimplsClassAll,implsFuncAll)
63