xref: /petsc/doc/build_c2html.py (revision be39004295a98ced168607de69334a8b204d0588)
1#!/usr/bin/env python3
2""" Builds the html files for all the source"""
3
4import os
5import re
6import subprocess
7import pathlib
8from itertools import chain
9
10def compute_make_np(i):
11  '''Number of cores to run make c2html on'''
12  f16 = .80
13  f32 = .65
14  f64 = .50
15  f99 = .30
16  if (i<=2):    return 2
17  elif (i<=4):  return i
18  elif (i<=16): return int(4+(i-4)*f16)
19  elif (i<=32): return int(4+12*f16+(i-16)*f32)
20  elif (i<=64): return int(4+12*f16+16*f32+(i-32)*f64)
21  else:         return int(4+12*f16+16*f32+32*f64+(i-64)*f99)
22
23def main(petsc_dir,build_dir,loc,c2html,mapnames):
24  os.chdir(petsc_dir)
25
26  # reformat file that maps manual pages to directory location and add MPI manual pages
27  with open('htmlmap.tmp', "w") as fdw, open(os.path.join(build_dir,'manualpages','htmlmap'), "r") as fd:
28    fdw.write(fd.read().replace('man+manualpages/','man+HTML_ROOT/manualpages/'))
29  with open('htmlmap.tmp', "a") as fdw, open(os.path.join(build_dir,'manualpages','mpi.www.index'), "r") as fd:
30    fdw.write(fd.read())
31
32  # walk directories generating list of all source code that needs processing and creating index.html for each directory
33  SKIPDIRS = set('public html benchmarks output arch doc binding config petsc-doc lib bin .git systems share mpiuni kernels khash valgrind interfaces data linter'.split())
34  SUFFIXES = set('.F90 .F .c .cxx .cpp .h .cu .hpp'.split())
35  allfiles = []
36  for root, dirs, files in chain.from_iterable(os.walk(path) for path in [petsc_dir]):
37    dirs[:] = [d for d in dirs if not any([s for s in SKIPDIRS if d.startswith(s)])]
38    root = root[len(petsc_dir)+1:]
39    if not root: continue
40    if not os.path.isdir(os.path.join(loc,root)): os.makedirs(os.path.join(loc,root))
41    allfiles.extend([os.path.join(loc,root,f+'.html') for f in files if any([s for s in SUFFIXES if f.endswith(s)])])
42
43    # create index.html file for each directory
44    with open(os.path.join(loc,root,'index.html'),'w') as fdw:
45      if root.startswith('src'):
46
47        # get MANSEC from the makefile and copy the MANSEC basic information into the index
48        # TODO: the text is actually .md so needs processing
49        if os.path.isfile(os.path.join(root,'makefile')):
50          with open(os.path.join(root,'makefile')) as mklines:
51            mansecl = [line for line in mklines if line.startswith('MANSEC')]
52            if mansecl:
53              mansec = re.sub('MANSEC[ ]*=[ ]*','',mansecl[0]).strip('\n').strip()
54              with open(os.path.join('doc','manualpages','MANSECHeaders',mansec)) as fd:
55                fdw.write(fd.read())
56
57      fdw.write('\n<p>\n')
58
59      # TODO: use HTML lists for the list below
60
61      # list examples
62      if root.find('/tests') > -1 or root.find('tutorials') > -1:
63        fdw.write('\n<p>\nExamples\n<p>')
64        for f in files:
65          if any([s for s in SUFFIXES if f.endswith(s)]):
66            with open(os.path.join(root,f)) as fd:
67              line = fd.readline()
68              l = line.find('char help[] = ')
69              if l > -1:
70                s = line.find('\\n')
71                line = line[l + 15:s]
72              else: line = ''
73              fdw.write('<a href="' + f + '.html">' + f + ': ' + line + '</a><br>\n')
74
75      # list source code
76      else:
77        if any([f for f in files if any([s for s in SUFFIXES if f.endswith(s)])]):
78          fdw.write('\n<p>\nSource files\n<p>')
79        for f in files:
80          if any([s for s in SUFFIXES if f.endswith(s)]):
81            fdw.write('<a href=\"' + f + '.html\">' + f + '</a><br>\n')
82
83      # list subdirectories
84      if dirs:
85        fdw.write('\n<p>\nDirectories\n<p>')
86      for d in dirs:
87        fdw.write('<a href="' + os.path.join(d,'index.html') + '">' + d + '</a><br>\n')
88
89  # create makefile that will run c2html on all source files in parallel
90  git_sha = subprocess.check_output(['git', 'rev-parse', 'HEAD'], text=True).rstrip()
91  with open(os.path.join(petsc_dir,'c2html.mk'),'w') as fd:
92    fd.write('files = ')
93    fd.write(' '.join(allfiles))
94    fd.write('\n')
95    fd.write('\n')
96    fd.write(os.path.join(loc,'%.html')+' : %\n')
97    fd.write('	@' + str(os.path.join(str(petsc_dir),'doc','build_c2html_file.py')) + ' ' + str(petsc_dir) + ' ' + str(loc) + ' '+ git_sha + ' ' + c2html + ' ' + mapnames + ' $< $@\n')
98    fd.write('\n')
99    fd.write('all: $(files)\n')
100
101  import multiprocessing
102  command = ['make', '-j', str(compute_make_np(multiprocessing.cpu_count())), '-f', 'c2html.mk', 'all']
103  subprocess.run(command, cwd=petsc_dir, check=True)
104
105  os.unlink('c2html.mk')
106  os.unlink('htmlmap.tmp')
107