xref: /petsc/doc/fix_man_page_edit_links.py (revision bcee047adeeb73090d7e36cc71e39fc287cdbb97) !
1#!/usr/bin/env python
2""" A brittle approach to making "Edit this Page" links work on man pages """
3
4import os
5import re
6import fileinput
7
8EDIT_URL_PATTERN = re.compile(
9    r'^<p><a.*href="(.*)">Edit on GitLab</a></p>')  # very brittle
10
11SHOW_SOURCE_PATTERN = re.compile(
12    r'(?s)<div class="toc-item">\s*<div class="tocsection sourcelink">.*<a href=.*>.*<i class="fa-solid fa-file-lines"></i> Show Source\s*</a>\s*</div>\s*</div>')
13
14
15def _get_edit_url(filename):
16    """ Get the edit URL for the source code for a manual page that was added by lib/petsc/bin/maint/wwwindex.py"""
17    with open(filename, "r") as f:
18        for line in f:
19            m = re.match(EDIT_URL_PATTERN, line)
20            if m:
21                return m.group(1)
22    return None
23
24
25def _check_edit_link(filename):
26    """ Return true if the file has an edit link to be updated """
27    found = False
28    with open(filename, "r") as f:
29        for line in f:
30            if line.lstrip().startswith("<div") and "editthispage" in line:
31                return True
32        return False
33
34
35def _update_edit_link(filename, url):
36    """ Change the URL for editthispage that Sphinx generates to the URL for GitLab repository location of the file
37        Remove the Edit on GitLab line added by lib/petsc/bin/maint/wwwindex.py since it is now a duplicate"""
38    with fileinput.FileInput(filename, inplace=True) as f:
39        replace_link_line = False
40        done = False
41        for line in f:
42            if done:
43                print(line, end="")  # prints to file
44            else:
45                if line.lstrip().startswith("<div") and "editthispage" in line:
46                    replace_link_line = True
47                if replace_link_line and line.lstrip().startswith("<a"):
48                    print("<a href=%s>" % url)  # prints to file
49                    done = True
50                elif not 'Edit on GitLab' in line:
51                    print(line, end="")  # prints to file
52
53def fix_man_page_edit_links(root):
54    base = os.path.join(root, "manualpages")
55    for root, dirs, filenames in os.walk(base):
56        for filename in filenames:
57            if filename.endswith(".html"):
58                filename_full = os.path.join(root, filename)
59                url = _get_edit_url(filename_full)
60                if url is not None and _check_edit_link(filename_full):
61                    _update_edit_link(filename_full, url)
62            # remove Show Source line
63            with open(filename_full) as f:
64                str = f.read()
65                newstr = re.sub(SHOW_SOURCE_PATTERN,'',str)
66            with open(filename_full,'w') as f:
67                f.write(newstr)
68