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