Hide keyboard shortcuts

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 Default values for the Sphinx configuration. 

5""" 

6import sys 

7import os 

8import datetime 

9import warnings 

10from .style_css_template import style_figure_notebook 

11 

12 

13def latex_preamble(): 

14 """ 

15 Default latex preamble. 

16 """ 

17 preamble = ''' 

18 %% addition by pyquickhelper(1) %% 

19 \\usepackage{etex} 

20 \\usepackage{fixltx2e} % LaTeX patches, \\textsubscript 

21 \\usepackage{cmap} % fix search and cut-and-paste in Acrobat 

22 \\usepackage[raccourcis]{fast-diagram} 

23 \\usepackage{titlesec} 

24 \\usepackage{amsmath} 

25 \\usepackage{amssymb} 

26 \\usepackage{amsfonts} 

27 \\usepackage{graphics} 

28 \\usepackage{epic} 

29 \\usepackage{eepic} 

30 \\usepackage{media9} 

31 %\\usepackage{pict2e} 

32 %%% Redefined titleformat 

33 \\setlength{\\parindent}{0cm} 

34 \\setlength{\\parskip}{1ex plus 0.5ex minus 0.2ex} 

35 \\newcommand{\\hsp}{\\hspace{20pt}} 

36 \\newcommand{\\acc}[1]{\\left\\{#1\\right\\}} 

37 \\newcommand{\\cro}[1]{\\left[#1\\right]} 

38 \\newcommand{\\pa}[1]{\\left(#1\\right)} 

39 \\newcommand{\\R}{\\mathbb{R}} 

40 \\newcommand{\\HRule}{\\rule{\\linewidth}{0.5mm}} 

41 %\\titleformat{\\chapter}[hang]{\\Huge\\bfseries\\sffamily}{\\thechapter\\hsp}{0pt}{\\Huge\\bfseries\\sffamily} 

42 

43 \\renewcommand{\\Verbatim}[1][1]{% 

44 \\bgroup\\parskip=0pt% 

45 \\smallskip% 

46 \\list{}{% 

47 \\setlength\\parskip{0pt}% 

48 \\setlength\\itemsep{0ex}% 

49 \\setlength\\topsep{0ex}% 

50 \\setlength\\partopsep{0pt}% 

51 \\setlength\\leftmargin{10pt}% 

52 }% 

53 \\item\\MakeFramed{\\FrameRestore}% 

54 \\tiny 

55 \\OriginalVerbatim[#1]% 

56 %% addition by pyquickhelper(1) %% 

57 } 

58 '''.replace(" ", "") 

59 return preamble 

60 

61 

62def get_epkg_dictionary(): 

63 """ 

64 Returns default dictionary for extension @see fn epkg_role. 

65 """ 

66 epkg_dictionary = { 

67 '7z': "https://www.7-zip.org/", 

68 'ASCII': "https://en.wikipedia.org/wiki/ASCII", 

69 'Anaconda': 'https://continuum.io/downloads', 

70 'appveyor': 'https://www.appveyor.com/', 

71 'autopep8': 'https://github.com/hhatto/autopep8', 

72 'azure pipeline': 'https://azure.microsoft.com/en-us/services/devops/pipelines/', 

73 'azure pipelines': 'https://azure.microsoft.com/en-us/services/devops/pipelines/', 

74 'Azure Pipelines': 'https://azure.microsoft.com/en-us/services/devops/pipelines/', 

75 'bokeh': 'https://bokeh.pydata.org/en/latest/', 

76 'builderapi': 'https://www.sphinx-doc.org/en/master/extdev/builderapi.html', 

77 'bz2': 'https://en.wikipedia.org/wiki/Bzip2', 

78 'cairosvg': 'https://github.com/Kozea/CairoSVG', 

79 'chrome': 'https://www.google.com/chrome/', 

80 'class Sphinx': 'https://github.com/sphinx-doc/sphinx/blob/master/sphinx/application.py#L107', 

81 'circleci': 'https://circleci.com/', 

82 'codecov': 'https://codecov.io/', 

83 'conda': 'https://github.com/conda/conda', 

84 'coverage': 'https://pypi.org/project/coverage', 

85 'cryptography': 'https://cryptography.readthedocs.org/', 

86 'cssselect2': 'https://cssselect2.readthedocs.io/en/latest/', 

87 'C++': 'https://en.wikipedia.org/wiki/C%2B%2B', 

88 'Cython': 'https://cython.org/', 

89 'dataframe': 'https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.html', 

90 'datetime': 'https://docs.python.org/3/library/datetime.html#datetime-objects', 

91 'docx': 'https://en.wikipedia.org/wiki/Office_Open_XML', 

92 'DOT': 'https://www.graphviz.org/doc/info/lang.html', 

93 'doxygen': 'https://www.doxygen.org/', 

94 'django': 'https://www.djangoproject.com/', 

95 'docutils': 'https://docutils.sourceforge.net/', 

96 'dvipng': 'https://ctan.org/pkg/dvipng?lang=en', 

97 'FastAPI': 'https://fastapi.tiangolo.com/', 

98 'format style': 'https://pyformat.info/>`_', 

99 'FTP': 'https://en.wikipedia.org/wiki/File_Transfer_Protocol', 

100 'getsitepackages': 'https://docs.python.org/3/library/site.html#site.getsitepackages', 

101 'GIT': 'https://git-scm.com/', 

102 'git': 'https://git-scm.com/', 

103 'Git': 'https://git-scm.com/', 

104 'github': 'https://github.com/', 

105 'GitHub': 'https://github.com/', 

106 'graphviz': 'https://www.graphviz.org/', 

107 'GraphViz': 'https://www.graphviz.org/', 

108 'Graphviz': 'https://www.graphviz.org/', 

109 'html': 'https://en.wikipedia.org/wiki/HTML', 

110 'HTML': 'https://en.wikipedia.org/wiki/HTML', 

111 'imgmath': 'https://www.sphinx-doc.org/en/master/usage/extensions/math.html#module-sphinx.ext.imgmath', 

112 'img2pdf': 'https://gitlab.mister-muffin.de/josch/img2pdf', 

113 'Inkscape': 'https://inkscape.org/', 

114 'InkScape': 'https://inkscape.org/', 

115 'IPython': 'https://en.wikipedia.org/wiki/IPython', 

116 'Java': 'https://www.java.com/fr/download/', 

117 'javascript': 'https://en.wikipedia.org/wiki/JavaScript', 

118 'Jenkins': 'https://jenkins-ci.org/', 

119 'Jenkins API': 'https://python-jenkins.readthedocs.org/en/latest/api.html', 

120 'jinja2': 'https://jinja.pocoo.org/docs/', 

121 'js2py': 'https://github.com/PiotrDabkowski/Js2Py', 

122 'json': 'https://docs.python.org/3/library/json.html', 

123 'JSON': 'https://en.wikipedia.org/wiki/JSON', 

124 'Jupyter': 'https://jupyter.org/', 

125 'jupyter': 'https://jupyter.org/', 

126 'JupyterLab': 'https://jupyterlab.readthedocs.io/en/stable/', 

127 'Jupyter Lab': 'https://jupyterlab.readthedocs.io/en/stable/', 

128 'jupyter_sphinx': 'https://jupyter-sphinx.readthedocs.io/en/latest/index.html', 

129 'keyring': 'https://github.com/jaraco/keyring', 

130 'keyrings.cryptfile': 'https://github.com/frispete/keyrings.cryptfile', 

131 'latex': 'https://en.wikipedia.org/wiki/LaTeX', 

132 'LaTeX': 'https://en.wikipedia.org/wiki/LaTeX', 

133 'LaTex': 'https://en.wikipedia.org/wiki/LaTeX', 

134 'Latex': 'https://en.wikipedia.org/wiki/LaTeX', 

135 'Linux': 'https://en.wikipedia.org/wiki/Linux', 

136 'linux': 'https://en.wikipedia.org/wiki/Linux', 

137 'mako': 'https://www.makotemplates.org/', 

138 "matplotlib": "https://matplotlib.org/index.html", 

139 'Markdown': 'https://en.wikipedia.org/wiki/Markdown', 

140 'markdown': 'https://en.wikipedia.org/wiki/Markdown', 

141 'mathjax': 'https://www.mathjax.org/', 

142 'MD': 'https://en.wikipedia.org/wiki/Markdown', 

143 'md': 'https://en.wikipedia.org/wiki/Markdown', 

144 'mistune': 'https://pypi.org/project/mistune', 

145 'MiKTeX': 'https://miktex.org/', 

146 'Miktex': 'https://miktex.org/', 

147 'miktex': 'https://miktex.org/', 

148 'MinGW': 'https://www.mingw.org/', 

149 'MyBinder': 'https://gke.mybinder.org/', 

150 'nbconvert': 'https://nbconvert.readthedocs.io/en/latest/', 

151 'nbpresent': 'https://github.com/Anaconda-Platform/nbpresent', 

152 'node.js': 'https://nodejs.org/en/', 

153 'notebook': 'https://jupyter-notebook.readthedocs.io/', 

154 'nose': 'https://pypi.org/project/nose', 

155 'npm': 'https://www.npmjs.com/', 

156 'numpy': ('https://www.numpy.org/', 

157 ('https://docs.scipy.org/doc/numpy/reference/generated/numpy.{0}.html', 1), 

158 ('https://docs.scipy.org/doc/numpy/reference/generated/numpy.{0}.{1}.html', 2)), 

159 'pandas': ('https://pandas.pydata.org/pandas-docs/stable/', 

160 ('https://pandas.pydata.org/pandas-docs/stable/generated/pandas.{0}.html', 1), 

161 ('https://pandas.pydata.org/pandas-docs/stable/generated/pandas.{0}.{1}.html', 2)), 

162 'pandoc': 'https://johnmacfarlane.net/pandoc/', 

163 'Pandoc': 'https://johnmacfarlane.net/pandoc/', 

164 'paramiko': 'https://www.paramiko.org/', 

165 'pdf': 'https://en.wikipedia.org/wiki/Portable_Document_Format', 

166 'pep8': 'https://www.python.org/dev/peps/pep-0008/', 

167 'PEP8': 'https://www.python.org/dev/peps/pep-0008/', 

168 "PEP8 codes": 'https://pep8.readthedocs.io/en/latest/intro.html#error-codes', 

169 'Pillow': 'https://pillow.readthedocs.io/', 

170 'PIL': 'https://pillow.readthedocs.io/', 

171 'pip': 'https://pip.pypa.io/en/stable/', 

172 'png': 'https://fr.wikipedia.org/wiki/Portable_Network_Graphics', 

173 'PNG': 'https://fr.wikipedia.org/wiki/Portable_Network_Graphics', 

174 'pycodestyle': 'https://pycodestyle.readthedocs.io/', 

175 'pycrypto': 'https://pypi.org/project/pycrypto', 

176 'pycryptodome': 'https://pypi.org/project/pycryptodome/', 

177 'pycryptodomex': 'https://pypi.org/project/pycryptodomex/', 

178 'pyformat.info': 'https://pyformat.info/>`_', 

179 'pygments': 'https://pygments.org/', 

180 'pyinstrument': 'https://github.com/joerick/pyinstrument', 

181 'pylzma': 'https://pypi.org/project/pylzma', 

182 'pylint': 'https://www.pylint.org/', 

183 'pylint error codes': 'https://pylint-messages.wikidot.com/all-codes', 

184 'pypi': 'https://pypi.org/project/', 

185 'PyPI': 'https://pypi.org/project/', 

186 'pysftp': 'https://pysftp.readthedocs.io/', 

187 'pytest': 'https://docs.pytest.org/en/latest/', 

188 'python': 'https://www.python.org/', 

189 'Python': 'https://www.python.org/', 

190 'python-jenkins': 'https://python-jenkins.readthedocs.org/en/latest/', 

191 'pywin32': 'https://sourceforge.net/projects/pywin32/', 

192 'REST': 'https://en.wikipedia.org/wiki/Representational_state_transfer', 

193 'reveal.js': 'https://github.com/hakimel/reveal.js/releases', 

194 'rst': 'https://en.wikipedia.org/wiki/ReStructuredText', 

195 'RST': 'https://en.wikipedia.org/wiki/ReStructuredText', 

196 'scikit-learn': 'https://scikit-learn.org/', 

197 'SciTe': 'https://www.scintilla.org/SciTE.html', 

198 'sklearn': ('https://scikit-learn.org/stable/', 

199 ('https://scikit-learn.org/stable/modules/generated/{0}.html', 1), 

200 ('https://scikit-learn.org/stable/modules/generated/{0}.{1}.html', 2)), 

201 'scipy': ('https://www.scipy.org/', 

202 ('https://docs.scipy.org/doc/scipy/reference/generated/scipy.{0}.html', 1), 

203 ('https://docs.scipy.org/doc/scipy/reference/generated/scipy.{0}.{1}.html', 2)), 

204 'SFTP': 'https://en.wikipedia.org/wiki/SSH_File_Transfer_Protocol', 

205 'sphinx': 'https://www.sphinx-doc.org/en/master/', 

206 'Sphinx': 'https://www.sphinx-doc.org/en/master/', 

207 'sphinx.ext.autodoc': 'https://www.sphinx-doc.org/en/master/ext/autodoc.html#module-sphinx.ext.autodoc', 

208 'sphinx.ext.intersphinx': 'https://www.sphinx-doc.org/en/master/usage/extensions/intersphinx.html', 

209 'sphinx-gallery': 'https://sphinx-gallery.readthedocs.io/en/latest/', 

210 'Sphinx application': 'https://www.sphinx-doc.org/en/master/_modules/sphinx/application.html', 

211 'svg': 'https://fr.wikipedia.org/wiki/Scalable_Vector_Graphics', 

212 'SVG': 'https://fr.wikipedia.org/wiki/Scalable_Vector_Graphics', 

213 'SVN': 'https://subversion.apache.org/', 

214 'svn': 'https://subversion.apache.org/', 

215 'tar.gz': 'https://en.wikipedia.org/wiki/Tar_(computing)', 

216 'toctree': 'https://www.sphinx-doc.org/en/master/markup/toctree.html', 

217 'TexnicCenter': 'https://www.texniccenter.org/', 

218 'tinycss2': 'https://pythonhosted.org/tinycss2/', 

219 'tkinter': 'https://docs.python.org/3/library/tkinter.html', 

220 'tornado': 'https://www.tornadoweb.org/en/stable/', 

221 'TortoiseSVN': 'https://tortoisesvn.net/', 

222 'travis': 'https://travis-ci.com/', 

223 'uvicorn': 'https://www.uvicorn.org/', 

224 'vis.js': 'https://visjs.org/', 

225 'viz.js': 'https://github.com/mdaines/viz.js/', 

226 'Visual Studio Community Edition 2015': 'https://imagine.microsoft.com/en-us/Catalog/Product/101', 

227 'Windows': 'https://en.wikipedia.org/wiki/Microsoft_Windows', 

228 'xml': 'https://docs.python.org/3/library/xml.etree.elementtree.html#module-xml.etree.ElementTree', 

229 'yaml': 'https://en.wikipedia.org/wiki/YAML', 

230 'YAML': 'https://en.wikipedia.org/wiki/YAML', 

231 'yml': 'https://en.wikipedia.org/wiki/YAML', 

232 'zip': 'https://en.wikipedia.org/wiki/Zip_(file_format)', 

233 '*py': ('https://docs.python.org/3/', 

234 ('https://docs.python.org/3/library/{0}.html', 1), 

235 ('https://docs.python.org/3/library/{0}.html#{0}.{1}', 2), 

236 ('https://docs.python.org/3/library/{0}.html#{0}.{1}.{2}', 3)), 

237 '*pyf': (('https://docs.python.org/3/library/functions.html#{0}', 1),), 

238 # Custom. 

239 'jyquickhelper': 'http://www.xavierdupre.fr/app/jyquickhelper/helpsphinx/index.html', 

240 'pymyinstall': 'http://www.xavierdupre.fr/app/pymyinstall/helpsphinx/index.html', 

241 'pyquickhelper': 'http://www.xavierdupre.fr/app/pyquickhelper/helpsphinx/index.html', 

242 'pyrsslocal': 'http://www.xavierdupre.fr/app/pyrsslocal/helpsphinx/index.html', 

243 'tkinterquickhelper': 'http://www.xavierdupre.fr/app/tkinterquickhelper/helpsphinx/index.html', 

244 # Specific. 

245 'datetime.datetime.strptime': 'https://docs.python.org/3/library/datetime.html#strftime-strptime-behavior', 

246 } 

247 return epkg_dictionary 

248 

249 

250def set_sphinx_variables(fileconf, module_name, author, year, theme, theme_path, ext_locals, 

251 add_extensions=None, bootswatch_theme="spacelab", bootswatch_navbar_links=None, 

252 description_latex="", use_mathjax=False, use_lunrsearch=False, 

253 enable_disabled_parts="enable_disabled_documented_pieces_of_code", 

254 sharepost="facebook-linkedin-twitter-20-body", custom_style=None, 

255 extlinks=None, github_user=None, github_repo=None, title=None, 

256 book=True, link_resolve=None, nblayout='classic', doc_version=None): 

257 """ 

258 Defines variables for :epkg:`Sphinx`. 

259 

260 @param fileconf location of the configuration file 

261 @param module_name name of the module 

262 @param author author 

263 @param year year 

264 @param theme theme to use 

265 @param theme_path theme path (sets ``html_theme_path``) 

266 @param ext_locals context (see `locals <https://docs.python.org/2/library/functions.html#locals>`_) 

267 @param add_extensions additional extensions 

268 @param bootswatch_theme for example, ``spacelab``, look at 

269 `spacelab <https://bootswatch.com/spacelab/>`_ 

270 @param bootswatch_navbar_links see `sphinx-bootstrap-theme <https://ryan-roemer.github.io/ 

271 sphinx-bootstrap-theme/README.html>`_ 

272 @param description_latex description latex 

273 @param use_mathjax set up the documentation to use mathjax, 

274 see `sphinx.ext.mathjax 

275 <https://www.sphinx-doc.org/en/master/usage/extensions/math.html>`_, 

276 default option is True 

277 @param use_lunrsearch suggest autocompletion in sphinx, 

278 see `sphinxcontrib-lunrsearch <https://github.com/rmcgibbo/ 

279 sphinxcontrib-lunrsearch>`_ 

280 @param enable_disabled_parts @see fn remove_undesired_part_for_documentation 

281 @param sharepost add share button to share blog post on usual networks 

282 @param custom_style custom style sheet 

283 @param extlinks parameter `extlinks <https://www.sphinx-doc.org/en/master/ext/extlinks.html#confval-extlinks>`_, 

284 example: ``{'issue': ('https://github.com/sdpython/pyquickhelper/issues/%s', 'issue ')}`` 

285 @param github_user git(hub) user 

286 @param github_repo git(hub) project 

287 @param title if not None, use *title* instead of *module_name* as a title 

288 @param book the output is a book 

289 @param link_resolve url where the documentation is published, 

290 used for parameter *linkcode_resolve* 

291 @param nblayout ``'classic'`` or ``'table'``, specifies the layout for 

292 the notebook gallery 

293 @param doc_version if not None, overwrites the current version 

294 

295 If the parameter *custom_style* is not None, it will call ``app.add_css_file(custom_style)`` 

296 in the setup. 

297 

298 .. exref:: 

299 :title: Simple configuration file for Sphinx 

300 

301 We assume a module is configurated using the same 

302 structure as `pyquickhelper <https://github.com/sdpython/pyquickhelper/>`_. 

303 The file ``conf.py`` could just contain: 

304 

305 :: 

306 

307 # -*- coding: utf-8 -*- 

308 import sys, os, datetime, re 

309 import solar_theme 

310 from pyquickhelper.helpgen.default_conf import set_sphinx_variables 

311 

312 sys.path.insert(0, os.path.abspath(os.path.join(os.path.split(__file__)[0]))) 

313 set_sphinx_variables(__file__, "pyquickhelper", "Xavier Dupré", 2014, 

314 "solar_theme", solar_theme.theme_path, locals()) 

315 

316 # custom settings 

317 ... 

318 

319 *setup.py* must contain a string such as ``__version__ = 3.4``. 

320 Close to the setup, there must be a file ``version.txt``. 

321 You overwrite a value by giving a variable another value after the fucntion is called. 

322 

323 Some parts of the code can be disabled before generating the documentation. 

324 Those parts are surrounded by:: 

325 

326 # -- HELP BEGIN EXCLUDE -- 

327 import module 

328 # -- HELP END EXCLUDE -- 

329 

330 If *enable_disabled_parts* is set to a string, these sections will become:: 

331 

332 # -- HELP BEGIN EXCLUDE -- 

333 if hasattr(sys, <enable_disabled_parts>) and sys.<enable_disabled_parts>: 

334 import module 

335 # -- HELP END EXCLUDE -- 

336 

337 This example shows what variables this functions sets. 

338 

339 .. runpython:: 

340 :showcode: 

341 

342 import alabaster 

343 from pyquickhelper.helpgen.default_conf import set_sphinx_variables 

344 

345 import pyquickhelper # replace by your module 

346 

347 ext_locals = {} 

348 set_sphinx_variables("this_file_conf.py", 

349 "pyquickhelper", # replace by your module 

350 "module_author", 2019, 

351 "readable", alabaster.get_path(), 

352 ext_locals, extlinks=dict( 

353 issue=('https://github.com/sdpython/module_name/issues/%s', 'issue')), 

354 title="module_name") 

355 

356 import pprint 

357 pprint.pprint(ext_locals) 

358 

359 .. versionchanged:: 1.9 

360 Uses ``jupyter_sphinx>=0.2``. 

361 """ 

362 # sphinx_gallery only supports matplotlib.use('agg') 

363 # and it must be done first. 

364 try: 

365 import sphinx_gallery 

366 import sphinx_gallery.gen_rst 

367 except ImportError: # pragma: no cover 

368 warnings.warn("ImportError: sphinx-gallery.", ImportWarning) 

369 except ValueError: # pragma: no cover 

370 warnings.warn( 

371 "ImportError: sphinx-gallery.get_rst fails.", ImportWarning) 

372 

373 # version .txt 

374 dirconf = os.path.abspath(os.path.dirname(fileconf)) 

375 version_file = os.path.join(dirconf, "..", "..", "..", "version.txt") 

376 if not os.path.exists(version_file): 

377 warnings.warn( 

378 "File '{0}' must contain the commit number (or last part of the version).".format( 

379 version_file), UserWarning) 

380 first_line = "0" 

381 else: 

382 first_line = get_first_line(version_file) 

383 

384 # language 

385 language = "en" 

386 

387 # main version 

388 if doc_version is None: 

389 mod = sys.modules.get(module_name, None) 

390 if mod is None: 

391 import importlib 

392 try: 

393 mod = importlib.import_module(module_name) 

394 except (ImportError, ModuleNotFoundError): # pragma: no cover 

395 mod = None 

396 if mod is None: 

397 raise RuntimeError( # pragma: no cover 

398 "Unknown module version. You should import '{0}' or specify " 

399 "'doc_version'.".format( 

400 module_name)) 

401 try: 

402 version = mod.__version__ 

403 except AttributeError: # pragma: no cover 

404 raise AttributeError("Unable to find attribute '__version__' in module '{}', " 

405 "__file__='{}'\n--PATH--\n{}".format( 

406 module_name, mod.__file__, "\n".join(sys.path))) 

407 else: 

408 version = doc_version # pragma: no cover 

409 

410 # settings sphinx 

411 pygments_style = 'sphinx' 

412 

413 # personnalization 

414 project_var_name = module_name # pylint: disable=W0127 

415 author = author # pylint: disable=W0127 

416 nblayout = nblayout # pylint: disable=W0127 

417 year = str(year) 

418 modindex_common_prefix = [project_var_name + ".", ] 

419 project = (project_var_name + ' documentation') if title is None else title 

420 copyright = str(year) + ", " + author 

421 release = (version if len(version.split('.')) < 3 

422 else "%s.%s" % (version, first_line)) 

423 html_title = ("%s %s" % (project_var_name, release) 

424 ) if title is None else title 

425 htmlhelp_basename = '%s_doc' % project_var_name 

426 enable_disabled_parts = enable_disabled_parts # pylint: disable=W0127 

427 

428 # personnalization latex 

429 _proj = project_var_name.replace("_", "\\_") 

430 latex_book = book 

431 latex_use_parts = False 

432 latex_documents = [('index', '%s_doc.tex' % project_var_name, 

433 _proj if title is None else title, 

434 author, 'manual', True), ] 

435 latex_docclass = dict(manual='report', howto='report') 

436 man_pages = [('index', '%s_doc' % project_var_name, 

437 ('%s Documentation' % _proj) if title is None else title, 

438 [author], 1)] 

439 texinfo_documents = [('index', 

440 ('%s documentation' % 

441 _proj) if title is None else title, 

442 ('%s' % _proj) if title is None else title, 

443 author, 

444 ('%s documentation' % 

445 _proj) if title is None else title, 

446 description_latex, 

447 'Miscellaneous'), 

448 ] 

449 latex_show_pagerefs = True 

450 

451 preamble = latex_preamble() 

452 latex_elements = { 

453 'papersize': 'a4', 

454 'pointsize': '10pt', 

455 'preamble': preamble, 

456 'docclass': 'book', 

457 'title': title} 

458 

459 # pyquickhelper automation 

460 auto_rst_generation = True 

461 

462 # latex_additional_files = ["mfgan-bw.sty", "_static/cover.png"] 

463 

464 # figure 

465 numfig = False 

466 

467 # theme 

468 html_theme = theme 

469 shtml_theme_options = {"bodyfont": "Calibri"} 

470 if theme_path is not None: 

471 if isinstance(theme_path, list): 

472 html_theme_path = theme_path # pragma: no cover 

473 else: 

474 html_theme_path = [theme_path] 

475 

476 # static files 

477 html_static_path = ['phdoc_static'] 

478 templates_path = ['phdoc_templates'] 

479 html_logo = os.path.join(html_static_path[0], "project_ico.png") 

480 html_favicon = os.path.join(html_static_path[0], "project_ico.ico") 

481 

482 # extensions, encoding 

483 source_suffix = '.rst' 

484 source_encoding = 'utf-8' 

485 master_doc = 'index' 

486 html_output_encoding = 'utf-8' 

487 

488 # blogs (custom parameter) 

489 blog_background = True 

490 blog_background_page = False 

491 sharepost = sharepost # pylint: disable=W0127 

492 

493 # jupyter_sphinx 

494 # See https://thebelab.readthedocs.io/en/latest/config_reference.html 

495 if github_user: 

496 jupyter_sphinx_thebelab_config = { # pragma: no cover 

497 'requestKernel': True, 

498 'binderOptions': { 

499 'repo': "sdpython/pyquickhelper/master?filepath=_doc" 

500 # 'repo': "{0}/{1}/master?filepath=_doc%2Fnotebooks".format( 

501 # github_user, module_name) 

502 }} 

503 else: 

504 jupyter_sphinx_thebelab_config = {'requestKernel': True} 

505 

506 # settings 

507 exclude_patterns = ["*.py", "**/*.py"] 

508 html_show_sphinx = False 

509 html_show_copyright = False 

510 __html_last_updated_fmt_dt = datetime.datetime.now() 

511 html_last_updated_fmt = '%04d-%02d-%02d' % ( 

512 __html_last_updated_fmt_dt.year, 

513 __html_last_updated_fmt_dt.month, 

514 __html_last_updated_fmt_dt.day) 

515 autoclass_content = 'both' 

516 autosummary_generate = True 

517 

518 # import helpers to find tools to build the documentation 

519 from .conf_path_tools import find_graphviz_dot, find_dvipng_path 

520 

521 # graphviz 

522 graphviz_output_format = "svg" 

523 graphviz_dot = find_graphviz_dot() 

524 

525 # todo, mathdef, blocref, faqref, exref, nbref 

526 todo_include_todos = True 

527 todoext_include_todosext = True 

528 mathdef_include_mathsext = True 

529 blocref_include_blocrefs = True 

530 faqref_include_faqrefs = True 

531 exref_include_exrefs = True 

532 nbref_include_nbrefs = True 

533 mathdef_link_number = "{first_letter}{number}" 

534 

535 # extensions 

536 extensions = [] 

537 try: 

538 import sphinx_gallery 

539 extensions.append('sphinx_gallery.gen_gallery') 

540 has_sphinx_gallery = True 

541 except ImportError: # pragma: no cover 

542 has_sphinx_gallery = False 

543 

544 if has_sphinx_gallery: 

545 try: 

546 import sphinx_gallery.gen_rst 

547 except ValueError as e: # pragma: no cover 

548 raise ValueError("Issue with sphinx-gallery.\n{0}".format(e)) 

549 

550 extensions.extend([ 

551 'sphinx.ext.autodoc', 'sphinx.ext.autosummary', 'sphinx.ext.coverage', 

552 'sphinx.ext.extlinks', 'sphinx.ext.graphviz', 'sphinx.ext.ifconfig', 

553 'sphinx.ext.inheritance_diagram', 'sphinx.ext.intersphinx', 

554 'sphinx.ext.mathjax' if use_mathjax else 'sphinx.ext.imgmath', 

555 'sphinx.ext.todo', 

556 'sphinxcontrib.imagesvg', 'jupyter_sphinx.execute', 

557 'pyquickhelper.sphinxext.sphinx_rst_builder', 

558 'pyquickhelper.sphinxext.sphinx_md_builder', 

559 'pyquickhelper.sphinxext.sphinx_latex_builder']) 

560 

561 try: 

562 import matplotlib.sphinxext 

563 assert matplotlib.sphinxext is not None 

564 extensions.append('matplotlib.sphinxext.plot_directive') 

565 plot_include_source = True 

566 plot_html_show_source_link = False 

567 except ImportError: # pragma: no cover 

568 # matplotlib is not installed. 

569 pass 

570 

571 if use_lunrsearch: # pragma: no cover 

572 extensions.append('sphinxcontrib.lunrsearch') 

573 

574 if not use_mathjax: 

575 # extensions.append('matplotlib.sphinxext.mathmpl') 

576 # this extension disables sphinx.ext.imgmath 

577 pass 

578 

579 if not use_mathjax: 

580 imgmath_latex, imgmath_dvipng, imgmath_dvisvgm = find_dvipng_path() 

581 imgmath_image_format = 'svg' 

582 

583 if add_extensions is not None: 

584 for a in add_extensions: 

585 if a not in extensions: 

586 extensions.append(a) 

587 

588 # add_function_parentheses = True 

589 # add_module_names = True 

590 # show_authors = False 

591 # html_sidebars = {} 

592 # html_additional_pages = {} 

593 # html_domain_indices = True 

594 # html_use_index = True 

595 # html_split_index = False 

596 # html_show_sourcelink = True 

597 # html_use_opensearch = '' 

598 # html_file_suffix = None 

599 # latex_logo = None 

600 latex_show_urls = 'footnote' 

601 # latex_appendices = [] 

602 # latex_domain_indices = True 

603 # texinfo_appendices = [] 

604 # texinfo_domain_indices = True 

605 # texinfo_show_urls = 'footnote' 

606 

607 # it modifies the set of things to display inside the sidebar 

608 # see https://www.sphinx-doc.org/en/master/config.html#confval-html_sidebars 

609 html_sidebars = { 

610 '[!blog]**': ['searchbox.html', 'moduletoc.html', 

611 'relations.html', 'sourcelink.html', ], 

612 'blog/**': ['searchbox.html', 'blogtoc.html', 

613 'localtoc.html', 'sourcelink.html', ], 

614 } 

615 

616 # tpl_role 

617 from ..sphinxext.documentation_link import python_link_doc 

618 tpl_template = {'py': python_link_doc} 

619 

620 # epkg_role 

621 epkg_dictionary = get_epkg_dictionary() 

622 

623 # latex 

624 math_number_all = False 

625 imgmath_latex_preamble = """ 

626 %% addition by pyquickhelper(2) %% 

627 \\usepackage{epic} 

628 \\newcommand{\\acc}[1]{\\left\\{#1\\right\\}} 

629 \\newcommand{\\cro}[1]{\\left[#1\\right]} 

630 \\newcommand{\\pa}[1]{\\left(#1\\right)} 

631 \\newcommand{\\R}{\\mathbb{R}} 

632 %% addition by pyquickhelper(2) %% 

633 """ 

634 # post processing of the full latex file 

635 # it should be a function, None by default 

636 custom_latex_processing = None 

637 

638 # github or git link 

639 if github_user: 

640 releases_issue_uri = "https://github.com/{0}/{1}/issues/%s".format( 

641 github_user, module_name) 

642 githublink_options = dict(user=github_user) 

643 github_anchor = "source on GitHub" 

644 else: 

645 githublink_options = None 

646 if github_repo: 

647 if githublink_options is None: 

648 githublink_options = {} 

649 value = github_repo.strip("/").split("/")[-1] 

650 if value.endswith(".git"): 

651 value = value[:-4] 

652 githublink_options['project'] = value 

653 

654 if 'anchor' not in githublink_options and "github" in github_repo.lower(): 

655 githublink_options['anchor'] = "source on GitHub" 

656 

657 if extlinks is None: 

658 extlinks = dict() 

659 elif 'issue' in extlinks: 

660 issue = extlinks['issue'][0].split('/') 

661 le = len(issue) 

662 if le > 0: 

663 user = issue[-4] 

664 project = issue[-3] 

665 if githublink_options is None: 

666 githublink_options = {} 

667 if 'user' not in githublink_options: 

668 githublink_options["user"] = user 

669 if 'project' not in githublink_options: 

670 githublink_options["project"] = project 

671 if 'anchor' not in githublink_options and 'github' in extlinks['issue'][0].lower(): 

672 githublink_options["anchor"] = 'source on GitHub' 

673 if not github_repo and extlinks['issue'][0].startswith("https://github.com"): 

674 github_repo = "https://github.com/{0}/{1}.git".format( 

675 user, project) 

676 

677 # themes 

678 if html_theme == "bootstrap": # pragma: no cover 

679 if bootswatch_navbar_links is None: 

680 bootswatch_navbar_links = [] 

681 html_logo = "project_ico_small.png" 

682 navbar_links = bootswatch_navbar_links 

683 html_theme_options = { 

684 'navbar_title': "home", 

685 'navbar_site_name': "Site", 

686 'navbar_links': navbar_links, 

687 'navbar_sidebarrel': True, 

688 'navbar_pagenav': True, 

689 'navbar_pagenav_name': "Page", 

690 'globaltoc_depth': 3, 

691 'globaltoc_includehidden': "true", 

692 'navbar_class': "navbar navbar-inverse", 

693 'navbar_fixed_top': "true", 

694 'source_link_position': "footer", 

695 'bootswatch_theme': bootswatch_theme, 

696 'bootstrap_version': "3", 

697 } 

698 elif html_theme == "guzzle_sphinx_theme": # pragma: no cover 

699 html_translator_class = 'guzzle_sphinx_theme.HTMLTranslator' 

700 if "guzzle_sphinx_theme" not in extensions: 

701 extensions.append('guzzle_sphinx_theme') 

702 html_theme_options = { 

703 "project_nav_name": module_name, 

704 # specified, then no sitemap will be built. 

705 # "base_url": "" 

706 # "homepage": "index", 

707 # "projectlink": "https://myproject.url", 

708 } 

709 elif html_theme == "foundation_sphinx_theme": # pragma: no cover 

710 import foundation_sphinx_theme # pylint: disable=E0401 

711 html_theme_path = foundation_sphinx_theme.HTML_THEME_PATH 

712 if "foundation_sphinx_theme" not in extensions: 

713 extensions.append('foundation_sphinx_theme') 

714 html_theme_options = { 

715 'logo_screen': 'project_ico.png', 

716 'logo_mobile': 'project_ico.ico', 

717 'favicon': 'project_ico.ico', 

718 'github_user': github_user, 

719 'github_repo': github_repo, 

720 } 

721 pygments_style = 'monokai' 

722 

723 # mapping 

724 

725 intersphinx_mapping = { 

726 'joblib': ('https://joblib.readthedocs.io/en/latest/', None), 

727 'matplotlib': ('https://matplotlib.org/', None), 

728 'numpy': ('https://docs.scipy.org/doc/numpy/', None), 

729 'pandas': ('https://pandas.pydata.org/pandas-docs/stable/', None), 

730 'pyquickhelper': ( 

731 'http://www.xavierdupre.fr/app/pyquickhelper/helpsphinx/', None), 

732 'python': ('https://docs.python.org/{.major}'.format( 

733 sys.version_info), None), 

734 'scikit-learn': ('https://scikit-learn.org/stable/', None), 

735 'scipy': ('https://docs.scipy.org/doc/scipy/reference', None), 

736 'sklearn': ('https://scikit-learn.org/stable/', None)} 

737 

738 # information about code 

739 def linkcode_resolve_function(domain, info): 

740 if link_resolve is None: 

741 return None 

742 if domain != 'py': 

743 return None 

744 if not info['module']: 

745 return None 

746 filename = info['module'].replace('.', '/') 

747 return "%s/%s.py" % (link_resolve, filename) 

748 

749 if link_resolve is not None: 

750 linkcode_resolve = linkcode_resolve_function 

751 extensions.append("sphinx.ext.linkcode") 

752 

753 # commit modification 

754 def modify_commit_function(nbch, date, author, comment): 

755 if author is not None and "@" in author: 

756 author = author.split("@")[0] 

757 return nbch, date, author, comment 

758 

759 modify_commit = modify_commit_function 

760 

761 # sphinx gallery 

762 backreferences_dir = "modules/generated" 

763 dirname = os.path.dirname(fileconf) 

764 exa = os.path.join(dirname, "..", "..", "..", "_doc", "examples") 

765 if os.path.exists(exa): 

766 exa = os.path.normpath(exa) 

767 import pathlib 

768 pp = pathlib.Path(exa) 

769 readmes = pp.glob("**/README.txt") 

770 examples_dirs = [] 

771 gallery_dirs = [] 

772 for res in readmes: 

773 if not has_sphinx_gallery: 

774 raise ImportError( # pragma: no cover 

775 "sphinx_gallery is not present for gallery '{0}'".format(exa)) 

776 last = res.parts[-2] 

777 if last.startswith("temp_"): 

778 continue # pragma: no cover 

779 parts = last.replace("\\", "/").split("/") 

780 if any(filter(lambda x: x.startswith("temp_"), parts)): 

781 continue # pragma: no cover 

782 nn = res.parent 

783 

784 # We check that a readme.txt is not present in the parent folder. 

785 nn_parent_read = os.path.join(os.path.split(nn)[0], "README.txt") 

786 if os.path.exists(nn_parent_read): 

787 continue # pragma: no cover 

788 

789 # Main gallery. 

790 examples_dirs.append(str(nn)) 

791 if last in ("notebooks", "examples"): 

792 last = "gy" + last 

793 dest = os.path.join(dirname, last) 

794 if dest in gallery_dirs: 

795 raise ValueError( # pragma: no cover 

796 "Gallery '{0}' already exists (source='{1}', last={2}).".format(dest, nn, last)) 

797 gallery_dirs.append(dest) 

798 if len(examples_dirs) == 0: 

799 raise ValueError( # pragma: no cover 

800 "Unable to find any 'README.txt' in '{0}'.".format(exa)) 

801 reference_url = {k: v[0] for k, v in intersphinx_mapping.items()} 

802 example_dir = os.path.join(dirname, "gallery") 

803 if not os.path.exists(example_dir): 

804 os.makedirs(example_dir) 

805 sphinx_gallery_conf = { 

806 'doc_module': (module_name), 

807 'examples_dirs': examples_dirs, 

808 'gallery_dirs': gallery_dirs, 

809 'backreferences_dir': example_dir, 

810 'expected_failing_examples': [], 

811 'capture_repr': ('_repr_html_', '__repr__'), 

812 'ignore_repr_types': r'matplotlib[text, axes]', 

813 'inspect_global_variables': False, 

814 'remove_config_comments': True, 

815 } 

816 

817 if github_repo is not None and github_user is not None: 

818 sphinx_gallery_conf['binder'] = { 

819 'org': github_user, 

820 'repo': github_repo, 

821 'binderhub_url': 'https://mybinder.org', 

822 'branch': 'master', 

823 'dependencies': os.path.abspath( 

824 os.path.join(os.path.dirname(version_file), 'requirements.txt')), 

825 'use_jupyter_lab': True, 

826 } 

827 

828 sphinx_gallery_conf['show_memory'] = False 

829 else: 

830 skipset = {"sphinx_gallery.gen_gallery"} 

831 extensions = [_ for _ in extensions if _ not in skipset] 

832 

833 # notebooks replacements (post-process) 

834 notebook_replacements = {'html': [('\\mathbb{1}_', '\\mathbf{1\\!\\!1}_')]} 

835 

836 # notebooks snippets 

837 notebook_custom_snippet_folder = 'notebooks_snippets' 

838 

839 ########################### 

840 # collect local variables 

841 ########################### 

842 # do not add anything after this 

843 loc = locals() 

844 for k, v in loc.items(): 

845 if not k.startswith("_") and k not in {'app', 'ext_locals', 'domains'}: 

846 ext_locals[k] = v 

847 

848 if custom_style is not None: 

849 ex = False 

850 for st in html_static_path: 

851 full = os.path.join(dirconf, st, custom_style) 

852 if os.path.exists(full): 

853 ex = True 

854 break 

855 if not ex: 

856 raise FileNotFoundError("unable to find {0} in\n{1}\nand\n{2}".format( 

857 custom_style, dirconf, "\n".join(html_static_path))) 

858 

859 def this_setup(app): 

860 if custom_style is not None: 

861 app.add_css_file(custom_style) 

862 return custom_setup(app, author) 

863 

864 ext_locals["setup"] = this_setup 

865 

866 

867################# 

868# custom functions 

869################# 

870 

871 

872def get_first_line(filename): 

873 """ 

874 Expects to find a text file with a line, 

875 the function extracts and returns this line. 

876 """ 

877 try: 

878 with open(filename, "r") as ff: 

879 first_line = ff.readlines()[0].strip(" \n\r") 

880 except FileNotFoundError: # pragma: no cover 

881 first_line = "xxx" 

882 return first_line 

883 

884 

885################# 

886# sphinx functions 

887################# 

888 

889 

890def _skip(app, what, name, obj, skip, options): 

891 """ 

892 To skip some functions, 

893 see `Skipping members 

894 <https://www.sphinx-doc.org/en/master/usage/extensions/autodoc.html>`_. 

895 """ 

896 if name.startswith("_") and name not in \ 

897 ["__qualname__", 

898 "__module__", 

899 "__dict__", 

900 "__doc__", 

901 "__weakref__", 

902 ]: 

903 return False 

904 return skip 

905 

906 

907def custom_setup(app, author): 

908 """ 

909 See `Sphinx core events <https://www.sphinx-doc.org/en/master/#sphinx-core-events>`_. 

910 """ 

911 from ..sphinxext.sphinx_bigger_extension import setup as setup_bigger 

912 from ..sphinxext.sphinx_githublink_extension import setup as setup_githublink 

913 from ..sphinxext.sphinx_blog_extension import setup as setup_blogpost 

914 from ..sphinxext.sphinx_blocref_extension import setup as setup_blocref 

915 from ..sphinxext.sphinx_exref_extension import setup as setup_exref 

916 from ..sphinxext.sphinx_faqref_extension import setup as setup_faqref 

917 from ..sphinxext.sphinx_gitlog_extension import setup as setup_gitlog 

918 from ..sphinxext.sphinx_mathdef_extension import setup as setup_mathdef 

919 from ..sphinxext.sphinx_quote_extension import setup as setup_quote 

920 from ..sphinxext.sphinx_nbref_extension import setup as setup_nbref 

921 from ..sphinxext.sphinx_runpython_extension import setup as setup_runpython 

922 from ..sphinxext.sphinx_downloadlink_extension import setup as setup_downloadlink 

923 from ..sphinxext.sphinx_video_extension import setup as setup_video 

924 from ..sphinxext.sphinx_image_extension import setup as setup_simpleimage 

925 from ..sphinxext.sphinx_todoext_extension import setup as setup_todoext 

926 from ..sphinxext.sphinx_docassert_extension import setup as setup_docassert 

927 from ..sphinxext.sphinx_autosignature import setup as setup_signature 

928 from ..sphinxext.sphinx_template_extension import setup as setup_tpl 

929 from ..sphinxext.sphinx_cmdref_extension import setup as setup_cmdref 

930 from ..sphinxext.sphinx_postcontents_extension import setup as setup_postcontents 

931 from ..sphinxext.sphinx_tocdelay_extension import setup as setup_tocdelay 

932 from ..sphinxext.sphinx_sharenet_extension import setup as setup_sharenet 

933 from ..sphinxext.sphinx_youtube_extension import setup as setup_youtube 

934 from ..sphinxext.sphinx_epkg_extension import setup as setup_epkg 

935 from ..sphinxext import setup_image 

936 from ..sphinxext.sphinx_toctree_extension import setup as setup_toctree 

937 from ..sphinxext.sphinx_collapse_extension import setup as setup_collapse 

938 from ..sphinxext.sphinx_gdot_extension import setup as setup_gdot 

939 

940 # delayed import to speed up import time 

941 from sphinx.errors import ExtensionError 

942 from sphinx.extension import Extension 

943 

944 try: 

945 app.connect("autodoc-skip-member", _skip) 

946 except ExtensionError as e: # pragma: no cover 

947 # No event autodoc-skip-member. 

948 warnings.warn("Sphinx extension error {0}".format(e), RuntimeError) 

949 if 'author' not in app.config.values: 

950 app.add_config_value('author', author, True) 

951 

952 exts = [setup_toctree, setup_runpython, setup_bigger, 

953 setup_githublink, setup_sharenet, setup_video, 

954 setup_simpleimage, setup_todoext, setup_blogpost, 

955 setup_mathdef, setup_blocref, setup_exref, 

956 setup_faqref, setup_nbref, setup_cmdref, 

957 setup_signature, setup_docassert, setup_postcontents, 

958 setup_tocdelay, setup_youtube, setup_tpl, 

959 setup_epkg, setup_image, setup_collapse, setup_gdot, 

960 setup_downloadlink, setup_quote, setup_gitlog] 

961 

962 for ext in exts: 

963 meta = ext(app) 

964 name = ext.__name__.rsplit('.', maxsplit=1)[-1].replace("setup_", "") 

965 if name == "image": 

966 name = "pyquickhelper.sphinxext.sphinximages.sphinxtrib.images" 

967 else: 

968 name = 'pyquickhelper.sphinxext.sphinx_%s_extension' % name 

969 app.extensions[name] = Extension(name, ext.__module__, **meta) 

970 

971 try: 

972 import bokeh 

973 assert bokeh is not None 

974 from ..sphinxext.bokeh.bokeh_plot import setup as setup_bokeh 

975 setup_bokeh(app) 

976 name = "pyquickhelper.sphinxext.bokeh.bokeh_plot" 

977 app.extensions[name] = Extension(name, setup_bokeh.__module__) 

978 except ImportError: # pragma: no cover 

979 # bokeh is not installed. 

980 pass 

981 

982 # from sphinx.util.texescape import tex_replacements 

983 # tex_replacements += [('oe', '\\oe '), ] 

984 app.add_js_file("require.js") 

985 

986 # style for notebooks 

987 app.add_css_file(style_figure_notebook[0]) 

988 return app 

989 

990 

991def get_default_stylesheet(css=None): 

992 """ 

993 Returns the style of additional style sheets. 

994 

995 @param css additional css files 

996 @return list of files 

997 """ 

998 # delayed import to speed up time 

999 from sphinx.builders.html import Stylesheet 

1000 rel = "_static/" + style_figure_notebook[0] 

1001 res = [Stylesheet(rel="stylesheet", filename=rel)] 

1002 if css is not None: 

1003 for cs in css: 

1004 res.append(Stylesheet(rel="stylesheet", filename=cs)) 

1005 return res 

1006 

1007 

1008def get_default_javascript(): 

1009 """ 

1010 Returns the style of additional style sheets 

1011 

1012 @return list of files 

1013 """ 

1014 return ["_static/require.js"]