Coverage for pyquickhelper/helpgen/sphinx_helper.py: 21%

48 statements  

« prev     ^ index     » next       coverage.py v7.2.7, created at 2023-06-03 02:21 +0200

1# -*- coding: utf-8 -*- 

2""" 

3@file 

4@brief Various helpers for Sphinx. 

5""" 

6import os 

7from ..filehelper import synchronize_folder, explore_folder_iterfile 

8from ..loghelper.flog import noLOG, fLOG 

9 

10 

11def everything_but_python(fullname): 

12 """ 

13 Returns True if ``__pycache__`` is not in filename. 

14 """ 

15 if "__pycache__" in fullname: 

16 return False 

17 return os.path.splitext(fullname)[-1] not in [".py", ".pyc"] 

18 

19 

20def sphinx_add_scripts(source, dest, filter=everything_but_python, fLOG=fLOG): 

21 """ 

22 copy additional scripts to a folder for sphinx documentation 

23 

24 @param source source 

25 @param dest destination folder (will be created if it does not exists) 

26 @param filter @see fn synchronize_folder 

27 @param fLOG logging function 

28 @return @see fn synchronize_folder 

29 """ 

30 

31 if not os.path.exists(dest): 

32 os.makedirs(dest) 

33 

34 res = synchronize_folder( 

35 source, dest, repo1=False, repo2=False, filter=filter, fLOG=fLOG) 

36 return res 

37 

38 

39def post_process_html_nb_output_static_file(build, fLOG=noLOG): 

40 """ 

41 post process the HTML files produced by Sphinx to adjust the static files 

42 in notebooks (IPython static files do have the same paths as 

43 Sphinx static files) 

44 

45 @param build build location 

46 @param fLOG logging function 

47 @return list of modified files 

48 

49 Static path in IPython start by ``/static``, they start by ``../_static`` 

50 or ``/_static`` in Sphinx. 

51 """ 

52 if not os.path.exists(build): 

53 raise FileNotFoundError( # pragma: no cover 

54 f"Unable to find {build!r}.") 

55 

56 tofind = ' src="/static/' 

57 torep = ' src="../_static/' 

58 

59 res = [] 

60 for full in explore_folder_iterfile(build, pattern=".*[.]html"): 

61 modif = False 

62 with open(full, "r", encoding="utf8") as f: 

63 try: 

64 content = f.read() 

65 except UnicodeDecodeError as e: # pragma: no cover 

66 # maybe it is Windows and the encoding is sometimes different 

67 with open(full, "r", encoding="cp1252") as g: 

68 try: 

69 content = g.read() 

70 content = content.replace( 

71 "charset=cp1252", "charset=utf-8") 

72 except UnicodeDecodeError: 

73 raise FileNotFoundError( 

74 f"Unable to load {full!r}\n{os.path.abspath(full)!r}") from e 

75 

76 if tofind in content: 

77 res.append(full) 

78 content = content.replace(tofind, torep) 

79 modif = True 

80 

81 # js 

82 repl = {'https://unpkg.com/@jupyter-widgets/html-manager@^0.20.0/dist/embed-amd.js': 

83 '../_static/embed-amd.js'} 

84 lines = content.split('\n') 

85 new_lines = [] 

86 for line in lines: 

87 if "https://cdnjs.cloudflare.com/ajax/libs/require.js" in line: 

88 if fLOG: 

89 fLOG( # pragma: no cover 

90 f"[post_process_html_nb_output_static_file] js: skip {line!r}") 

91 modif = True 

92 continue 

93 new_lines.append(line) 

94 content = "\n".join(new_lines) 

95 for k, v in repl.items(): 

96 if k in content: 

97 if fLOG: 

98 fLOG( 

99 f"[post_process_html_output] js: replace {k!r} -> {v!r}") 

100 content = content.replace(k, v) 

101 modif = True 

102 

103 if modif: 

104 fLOG(f"[post_process_html_nb_output_static_file] {full!r}") 

105 with open(full, "w", encoding="utf8") as f: 

106 f.write(content) 

107 

108 return res