Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# -*- coding: utf-8 -*-
2"""
3@file
4@brief Function to verify the files produced by Sphinx
5"""
6import os
7import re
8import warnings
9from ..loghelper.flog import noLOG
10from ..filehelper.synchelper import explore_folder_iterfile
13class SphinxVerificationException(Exception):
15 """
16 to format the error message
17 """
19 def __init__(self, errors):
20 """
21 @param errors errors met
22 """
23 stack = []
24 for name, line, m in errors:
25 message = '[sphinxerror]-4 {2}\n File "{0}", line {1}'.format(
26 name, line + 1, m)
27 stack.append(message)
28 Exception.__init__(self, "\n" + "\n".join(stack))
31def verification_html_format(folder, fLOG=noLOG, raise_above=0.1):
32 """
33 dig into folders abd subfolders to find HTML files
34 produced by Sphinx, does some verification to detect errors,
35 the function, the function raises an exception for all mistakes
37 @param folder folder to verifiy
38 @param fLOG logging function
39 @param raise_above raises an exception of the number of errors is above a given threshold
40 or a relative threshold if it is a float
41 @return list of errors
42 """
43 nbfile = 0
44 errors = []
45 for item in explore_folder_iterfile(folder, ".[.]html", fullname=True):
46 fLOG("[verification_html_format]", item)
47 if not os.path.exists(item):
48 fLOG(
49 "[verification_html_format] unable to find and check '{0}'".format(item))
50 continue
51 err = verification_html_file(item, fLOG=fLOG)
52 if len(err) > 0:
53 fitem = os.path.abspath(item)
54 if "html/coverage" in fitem.replace("\\", "/"):
55 # we skip as it comes from coverage report.
56 pass
57 else:
58 errors.extend((fitem, line, m) for line, m in err)
59 nbfile += 1
60 fLOG("[verification_html_format] checked:{0} errors:{1}".format(
61 nbfile, len(errors)))
62 if len(errors) > 0:
63 e = SphinxVerificationException(errors)
64 if isinstance(raise_above, int) and len(errors) >= raise_above:
65 raise e
66 if len(errors) * 1.0 / nbfile >= raise_above:
67 raise e
68 warnings.warn("Sphinx error {0}".format(e), UserWarning)
69 return errors
72def verification_html_file(item, fLOG=noLOG):
73 """
74 Verifies a file produced by :epkg:`sphinx` and checks basic mistakes.
76 @param item filename
77 @param fLOG logging function
78 @return list of errors (line, message)
80 The first line is 0.
81 """
82 with open(item, "r", encoding="utf8") as f:
83 content = f.read()
85 content = content.replace("\r", "").replace("\n", "_#!#_LINES_#_")
86 content = re.sub("<pre>(.*?)</pre>", "<pre></pre>", content)
87 content = content.replace("_#!#_LINES_#_", "\n")
88 lines = content.split("\n")
89 reg = re.compile("([.][.] _[-a-z_A-Z0-9][:.])")
91 errors = []
92 for i, line in enumerate(lines):
93 if "<h1>Source code for " in line or "<h1>Code source de " in line:
94 # no need to go further
95 # the source takes place after this substring
96 break
97 if ":ref:`" in line and ":ref:`{ref_name}`" not in line:
98 errors.append((i, "wrong :ref:` in " + line.strip("\n\r ")))
99 if ":func:`" in line:
100 errors.append((i, "wrong :func:` in " + line.strip("\n\r ")))
101 if ":class:`" in line:
102 errors.append((i, "wrong :class:` in " + line.strip("\n\r ")))
103 if ":meth:`" in line:
104 errors.append((i, "wrong :meth:` in " + line.strip("\n\r ")))
105 if ":method:`" in line:
106 errors.append((i, "wrong :method:` in " + line.strip("\n\r ")))
107 if ">`" in line and "`</span></a>-" not in line:
108 errors.append((i, "wrong >`, missing _ in " + line.strip("\n\r ")))
109 find = reg.findall(line)
110 if len(find) > 0:
111 errors.append(
112 (i, "label or index remaining: " + str(find) + " in " + line.strip("\n\r ")))
114 return errors