Coverage for pyquickhelper/helpgen/sphinx_main_missing_html_files.py: 81%
97 statements
« prev ^ index » next coverage.py v7.2.7, created at 2023-06-03 02:21 +0200
« prev ^ index » next coverage.py v7.2.7, created at 2023-06-03 02:21 +0200
1"""
2@file
3@brief function around missing file for the documentation
4"""
5import os
6import shutil
7from ..texthelper.texts_language import TITLES
10def add_missing_files(root, conf, blog_list, fLOG):
11 """
12 Adds missing files for the documentation,
13 ``moduletoc.html``, ``blogtoc.html``, ``searchbox.html``.
15 @param root root
16 @param conf configuration module (to guess the template folder)
17 @param blog_list list of recent blog posts to add to the navigational bar (list)
18 or a name for a placeholder (such as ``__INSERT__``)
19 @param theme theme, missing files depend on it
20 @param fLOG logging function
21 @return list of modified files
23 The function considers the theme for the searchbox.
24 `sphinx_rtd_theme <https://github.com/rtfd/sphinx_rtd_theme>`_ has
25 a different style for the searchbox.
26 """
27 # settings
28 fold = conf.templates_path
29 if isinstance(fold, list):
30 fold = fold[0]
32 if hasattr(conf, "language"):
33 language = conf.language
34 else:
35 language = "en"
37 if hasattr(conf, "extensions"):
38 lunr = "sphinxcontrib.lunrsearch" in conf.extensions
39 else:
40 lunr = False
42 loc = os.path.join(root, "_doc", "sphinxdoc", "source", fold)
43 if not os.path.exists(loc):
44 os.makedirs(loc)
46 api_index = os.path.join(root, "_doc", "sphinxdoc",
47 "source", "api", "index.rst")
48 add_api_link = os.path.exists(api_index)
49 if add_api_link:
50 api_title = extract_first_title(api_index)
52 tocs = []
54 # link
55 link = '\n<li class="toctree-l1"><a class="reference internal" href="{0}">{1}</a></li>'
56 double_link = '\n<li class="toctree-l1"><a class="reference internal" href="{0}">{1}</a></li>' + \
57 '\n<li class="toctree-l1"><a class="reference internal" href="{2}">{3}</a></li>'
59 # moduletoc.html
60 mt = os.path.join(loc, "moduletoc.html")
61 if fLOG:
62 fLOG(f"[add_missing_files] create '{mt}'")
63 tocs.append(mt)
64 with open(mt, "w", encoding="utf8") as f:
65 f.write(f"\n<h3>{TITLES[language]['toc0']}</h3>")
66 f.write("\n<ul>")
67 f.write(link.format("{{ pathto('',1) }}/blog/main_0000.html", "Blog"))
68 f.write(link.format("{{ pathto('',1) }}/genindex.html", "Index"))
69 if add_api_link:
70 f.write(double_link.format("{{ pathto('',1) }}/py-modindex.html", "Module",
71 "{{ pathto('',1) }}/api/index.html", api_title))
72 else:
73 f.write(link.format(
74 "{{ pathto('',1) }}/py-modindex.html", "Module"))
75 # f.write("""{%- if prev or next %}<li class="toctree-l1">
76 # {%- if prev %}<a href="{{ prev.link|e }}"><--</a>{%- endif %}
77 # {%- if next %}<a href="{{ next.link|e }}">--></a>{%- endif %}
78 # </li>{%- endif %}""")
79 f.write("\n</ul>")
80 f.write(
81 '\n<h3><a href="{{ pathto(master_doc) }}">%s</a></h3>\n' % TITLES[language]["toc"])
82 f.write('{{ toctree() }}')
83 f.write(f"\n<h3>{TITLES[language]['toc1']}</h3>")
84 f.write("\n<ul>")
85 f.write(
86 link.format("{{ pathto('',1) }}/i_faq.html", TITLES[language]["FAQ"]))
87 f.write(
88 link.format("{{ pathto('',1) }}/glossary.html", TITLES[language]["glossary"]))
89 f.write(link.format("{{ pathto('',1) }}/README.html", "README"))
90 f.write(
91 link.format("{{ pathto('',1) }}/filechanges.html", TITLES[language]["changes"]))
92 f.write(
93 link.format("{{ pathto('',1) }}/license.html", TITLES[language]["license"]))
94 f.write("\n</ul>")
96 # blogtoc.html
97 mt = os.path.join(loc, "blogtoc.html")
98 if fLOG:
99 fLOG(f"[add_missing_files] create '{mt}'")
100 tocs.append(mt)
101 with open(mt, "w", encoding="utf8") as f:
102 f.write("""<a href="{{ pathto('',1) }}/genindex.html">Index</a>\n""")
103 f.write(
104 """<a href="{{ pathto('',1) }}/py-modindex.html">Module</a>\n""")
105 f.write(
106 """<h3><a href="{{ pathto('',1) }}/blog/main_0000.html">Blog</a></h3>\n""")
107 if isinstance(blog_list, str):
108 f.write(blog_list)
109 elif isinstance(blog_list, list):
110 f.write("\n<br />".join(blog_list))
111 else:
112 raise TypeError(type(blog_list))
114 # searchbox.html
115 theme = conf.theme
116 mt = os.path.join(loc, "searchbox.html")
117 if fLOG:
118 fLOG(f"[add_missing_files] create '{mt}'")
119 tocs.append(mt)
120 with open(mt, "w", encoding="utf8") as f:
121 if theme == "sphinx_rtd_theme":
122 text = """
123 {%- if builder != 'singlehtml' %}
124 <div role="search">
125 <form id="rtd-search-form" class="wy-form" action="{{ pathto('search') }}" method="get">
126 <input type="text" name="q" placeholder="{{ _('Search docs') }}" />
127 <input type="hidden" name="check_keywords" value="yes" />
128 <input type="hidden" name="area" value="default" />
129 </form>
130 </div>
131 <script type="text/javascript">$('#searchbox').show(0);</script>
132 {%- endif %}
133 """.replace(" ", "")
134 else:
135 text = """
136 {%- if pagename != "search" and builder != "singlehtml" %}
137 <div id="searchbox" style="display: none" role="search">
138 <form class="search" action="{{ pathto('search') }}" method="get">
139 <input type="text" name="q" />
140 <input type="submit" value="{{ _('Go') }}" />
141 <input type="hidden" name="check_keywords" value="yes" />
142 <input type="hidden" name="area" value="default" />
143 </form>
144 <p class="searchtip" style="font-size: 10%"> </p>
145 </div>
146 <script type="text/javascript">$('#searchbox').show(0);</script>
147 {%- endif %}
148 """.replace(" ", "")
149 f.write(text)
151 if lunr:
152 text = """
153 <script src="{{ pathto('_static/js/searchbox.js', 1) }}" type="text/javascript"></script>
154 <script type="text/javascript" id="lunrsearchindexloader"></script>
155 <form class="lunsearch" action="" method="get">
156 <input type="hidden" name="check_keywords" value="yes" />
157 <input type="hidden" name="area" value="default" />
158 <input type="hidden" id="ls_lunrsearch-highlight" value="{{ lunrsearch_highlight }}" />
159 <input type="hidden" id="ls_search-index-url" value="{{ pathto('searchindex.js', 1) }}"/>
160 <input type="text" class="search-field" id="ls_search-field" name="q" placeholder="Search API" />
161 <ul class="results" id="ls_search-results"></ul>
162 </form>
163 """.replace(" ", "")
164 f.write(text)
166 missings = [] # ['layout.html', 'page.html']
167 import sphinx
168 themes = os.path.join(os.path.dirname(sphinx.__file__), "themes", "basic")
169 for mis in missings:
170 mt = os.path.join(loc, mis)
171 if not os.path.exists(mt):
172 sr = os.path.join(themes, mis)
173 if os.path.exists(sr):
174 if fLOG:
175 fLOG(f"[add_missing_files] create '{mt}'")
176 shutil.copy(sr, loc)
177 return tocs
180def extract_first_title(filename, underline="="):
181 """
182 Extracts the first title (rst format) in a file.
184 @param filename filename
185 @param underline level of the title
186 @return title name (or raises an exception if not found)
187 """
188 if not os.path.exists(filename):
189 raise FileNotFoundError(filename)
190 with open(filename, "r", encoding="utf-8") as f:
191 lines = f.readlines()
192 look = {underline}
193 for i, line in enumerate(lines):
194 sline = line.strip("\t\r\n ")
195 car = set(sline)
196 if car == look and i > 0:
197 title = lines[i - 1]
198 return title.strip("\n\r\t ")
199 raise ValueError("Unable to find a title in '{0}'\nCONTENT\n{1}".format(
200 filename, "".join(lines)))