xref: /petsc/doc/build_man_pages.py (revision 3564227f45de1db6f03b7db00bc5cba98ef65d6b)
1*3564227fSBarry Smith#!/usr/bin/env python
2*3564227fSBarry Smith""" Loops through all the source using doctext to generate the manual pages"""
3*3564227fSBarry Smith
4*3564227fSBarry Smithimport os
5*3564227fSBarry Smithimport re
6*3564227fSBarry Smithimport subprocess
7*3564227fSBarry Smithimport pathlib
8*3564227fSBarry Smith
9*3564227fSBarry Smithdef findlmansec(file):
10*3564227fSBarry Smith    mansec = None
11*3564227fSBarry Smith    submansec = None
12*3564227fSBarry Smith    with open(file) as mklines:
13*3564227fSBarry Smith      #print(file)
14*3564227fSBarry Smith      submansecl = [line for line in mklines if line.find('SUBMANSEC') > -1]
15*3564227fSBarry Smith      if submansecl:
16*3564227fSBarry Smith        submansec = re.sub('[ ]*/\* [ ]*SUBMANSEC[ ]*=[ ]*','',submansecl[0]).strip('\n').strip('*/').strip()
17*3564227fSBarry Smith        if submansec == submansecl[0].strip('\n'):
18*3564227fSBarry Smith          submansec = re.sub('SUBMANSEC[ ]*=[ ]*','',submansecl[0]).strip('\n').strip()
19*3564227fSBarry Smith        #print(':SUBMANSEC:'+submansec)
20*3564227fSBarry Smith        return submansec
21*3564227fSBarry Smith    with open(file) as mklines:
22*3564227fSBarry Smith      mansecl = [line for line in mklines if line.startswith('MANSEC')]
23*3564227fSBarry Smith      if mansecl:
24*3564227fSBarry Smith        mansec = re.sub('MANSEC[ ]*=[ ]*','',mansecl[0]).strip('\n').strip()
25*3564227fSBarry Smith        #print(':MANSEC:'+mansec)
26*3564227fSBarry Smith        return mansec
27*3564227fSBarry Smith    return None
28*3564227fSBarry Smith
29*3564227fSBarry Smithdef processdir(petsc_dir, dir, doctext):
30*3564227fSBarry Smith  '''Runs doctext on each source file in the directory'''
31*3564227fSBarry Smith  #print('Processing '+dir)
32*3564227fSBarry Smith  #print('build_man_pages: Using doctext '+doctext)
33*3564227fSBarry Smith  loc = os.path.join(petsc_dir,'doc')
34*3564227fSBarry Smith  doctext_path = os.path.join(petsc_dir,'doc','manualpages','doctext')
35*3564227fSBarry Smith  lmansec = None
36*3564227fSBarry Smith  if os.path.isfile(os.path.join(dir,'makefile')):
37*3564227fSBarry Smith    lmansec = findlmansec(os.path.join(dir,'makefile'))
38*3564227fSBarry Smith
39*3564227fSBarry Smith  for file in os.listdir(dir):
40*3564227fSBarry Smith    llmansec = lmansec
41*3564227fSBarry Smith    if os.path.isfile(os.path.join(dir,file)) and pathlib.Path(file).suffix in ['.c', '.cxx', '.h', '.cu', '.cpp', '.hpp']:
42*3564227fSBarry Smith      #print('Processing '+file)
43*3564227fSBarry Smith      if not llmansec:
44*3564227fSBarry Smith        llmansec = findlmansec(os.path.join(dir,file))
45*3564227fSBarry Smith        if not llmansec: continue
46*3564227fSBarry Smith      if not os.path.isdir(os.path.join(loc,'manualpages',llmansec)): os.mkdir(os.path.join(loc,'manualpages',llmansec))
47*3564227fSBarry Smith
48*3564227fSBarry Smith      command = [doctext,
49*3564227fSBarry Smith                 '-myst',
50*3564227fSBarry Smith                 '-mpath',    os.path.join(loc,'manualpages',llmansec),
51*3564227fSBarry Smith                 '-heading',  'PETSc',
52*3564227fSBarry Smith                 '-defn',     os.path.join(loc,'manualpages','doctext','myst.def'),
53*3564227fSBarry Smith                 '-indexdir', '../'+llmansec,
54*3564227fSBarry Smith                 '-index',    os.path.join(loc,'manualpages','manualpages.cit'),
55*3564227fSBarry Smith                 '-locdir',   dir[len(petsc_dir)+1:]+'/',
56*3564227fSBarry Smith                 '-Wargdesc', os.path.join(loc,'manualpages','doctext','doctextcommon.txt'),
57*3564227fSBarry Smith                 file]
58*3564227fSBarry Smith      #print(command)
59*3564227fSBarry Smith      subprocess.run(command, cwd=dir, check=True)
60*3564227fSBarry Smith
61*3564227fSBarry Smithdef processkhash(T, t, KeyType, ValType, text):
62*3564227fSBarry Smith  '''Replaces T, t, KeyType, and ValType in text (from include/petsc/private/hashset.txt) with a set of supported values'''
63*3564227fSBarry Smith  import re
64*3564227fSBarry Smith  return re.sub('<ValType>',ValType,re.sub('<KeyType>',KeyType,re.sub('<t>',t,re.sub('<T>',T,text))))
65*3564227fSBarry Smith
66*3564227fSBarry Smithdef main(petsc_dir, doctext):
67*3564227fSBarry Smith  # generate source code for manual pages for PETSc khash functions
68*3564227fSBarry Smith  text = ''
69*3564227fSBarry Smith  for f in ['hashset.txt', 'hashmap.txt']:
70*3564227fSBarry Smith    with open(os.path.join(petsc_dir,'include','petsc','private',f)) as mklines:
71*3564227fSBarry Smith      text = mklines.read()
72*3564227fSBarry Smith      with open(os.path.join(petsc_dir,'include','petsc','private',f+'.h'),mode='w') as khash:
73*3564227fSBarry Smith        khash.write(processkhash('I','i','PetscInt','',text))
74*3564227fSBarry Smith        khash.write(processkhash('IJ','ij','struct {PetscInt i, j;}','',text))
75*3564227fSBarry Smith        khash.write(processkhash('I','i','PetscInt','PetscInt',text))
76*3564227fSBarry Smith        khash.write(processkhash('IJ','ij','struct {PetscInt i, j;}','PetscInt',text))
77*3564227fSBarry Smith        khash.write(processkhash('IJ','ij','struct {PetscInt i, j;}','PetscScalar',text))
78*3564227fSBarry Smith        khash.write(processkhash('IV','iv','PetscInt','PetscScalar',text))
79*3564227fSBarry Smith        khash.write(processkhash('Obj','obj','PetscInt64','PetscObject',text))
80*3564227fSBarry Smith
81*3564227fSBarry Smith  # generate the .md files for the manual pages from all the PETSc source code
82*3564227fSBarry Smith  for dirpath, dirnames, filenames in os.walk(os.path.join(petsc_dir),topdown=True):
83*3564227fSBarry Smith    dirnames[:] = [d for d in dirnames if d not in ['tests', 'tutorials', 'doc', 'output', 'ftn-custom', 'f90-custom', 'ftn-auto', 'f90-mod', 'binding', 'binding', 'config', 'lib', '.git', 'share', 'systems'] and not d.startswith('arch')]
84*3564227fSBarry Smith    processdir(petsc_dir,dirpath,doctext)
85*3564227fSBarry Smith
86*3564227fSBarry Smith  # generate list of all manual pages
87*3564227fSBarry Smith  with open(os.path.join(petsc_dir,'doc','manualpages','htmlmap'),mode='w') as map:
88*3564227fSBarry Smith    with open(os.path.join(petsc_dir,'doc','manualpages','manualpages.cit')) as cit:
89*3564227fSBarry Smith      map.write(re.sub('man\+../','man+manualpages/',cit.read()))
90*3564227fSBarry Smith    with open(os.path.join(petsc_dir,'doc','manualpages','mpi.www.index')) as mpi:
91*3564227fSBarry Smith      map.write(mpi.read())
92*3564227fSBarry Smith
93*3564227fSBarry Smithif __name__ == "__main__":
94*3564227fSBarry Smith  # TODO Accept doctext from command line
95*3564227fSBarry Smith  main(os.path.abspath(os.environ['PETSC_DIR']))
96