Belle II Software  release-05-01-25
conf.py
1 #!/usr/bin/env python3
2 # -*- coding: utf-8 -*-
3 #
4 # basf2 documentation build configuration file, created by
5 # sphinx-quickstart on Mon May 23 17:26:16 2016.
6 #
7 # This file is execfile()d with the current directory set to its
8 # containing dir.
9 #
10 # Note that not all possible configuration values are present in this
11 # autogenerated file.
12 #
13 # All configuration values have a default; values that are commented out
14 # serve to show the default.
15 
16 import sys
17 import os
18 import re
19 import glob
20 import shutil
21 import subprocess
22 import jupytext
23 
24 sys.path.insert(0, os.path.abspath("extensions"))
25 
26 # If extensions (or modules to document with autodoc) are in another directory,
27 # add these directories to sys.path here. If the directory is relative to the
28 # documentation root, use os.path.abspath to make it absolute, like shown here.
29 # sys.path.insert(0, os.path.abspath('....'))
30 
31 # -- General configuration ------------------------------------------------
32 
33 # If your documentation needs a minimal Sphinx version, state it here.
34 # needs_sphinx = '1.0'
35 
36 # Add any Sphinx extension module names here, as strings. They can be
37 # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
38 # ones.
39 extensions = [
40  'sphinx.ext.intersphinx',
41  'sphinx.ext.autodoc',
42  # 'sphinx.ext.autosummary',
43  'sphinx.ext.mathjax',
44  'sphinx.ext.napoleon',
45  'sphinx.ext.viewcode',
46  'sphinx.ext.autosectionlabel',
47  'sphinxarg.ext',
48  'basf2ext',
49  'nbsphinx',
50  'IPython.sphinxext.ipython_console_highlighting',
51 ]
52 
53 nbsphinx_allow_errors = True
54 # Anything that ends with .jupy.py will be understood as a jupyter
55 # notebook converted to a plain python file with jupytext. During the sphinx
56 # build, jupytext will converted it back to a .ipynb file and nbsphinx will
57 # build the HTML
58 nbsphinx_custom_formats = {
59  '.doc.jupy.py': lambda s: jupytext.reads(s, '.py'),
60 }
61 
62 # autosummary_generate = True
63 
64 # prefix each section with the name of the document it is in followed by a
65 # colon
66 autosectionlabel_prefix_document = True
67 
68 # Add any paths that contain templates here, relative to this directory.
69 templates_path = ['_sphinxtemplates']
70 
71 # The suffix(es) of source filenames.
72 # You can specify multiple suffix as a list of string:
73 # source_suffix = ['.rst', '.md']
74 source_suffix = '.rst'
75 
76 # The encoding of source files.
77 # source_encoding = 'utf-8-sig'
78 
79 # The master toctree document.
80 master_doc = 'index'
81 
82 # General information about the project.
83 project = 'basf2'
84 copyright = '2010-2019, Belle II Collaboration'
85 author = 'Belle2 Software Group'
86 
87 # The version info for the project you're documenting, acts as replacement for
88 # |version| and |release|, also used in various other places throughout the
89 # built documents.
90 #
91 # The short X.Y version.
92 version = subprocess.check_output(["git", "rev-parse", "--short", "HEAD"]).decode().strip()
93 # Used for links to the repository
94 basf2_repository = "https://stash.desy.de/projects/B2/repos/software"
95 basf2_commitid = subprocess.check_output(["git", "rev-parse", "HEAD"]).decode().strip()
96 basf2_jira = "https://agira.desy.de"
97 
98 # The full version, including alpha/beta/rc tags.
99 release = os.environ.get('BELLE2_RELEASE', 'development')
100 if release == 'head':
101  release = 'development'
102 
103 # Add warnings in the code if this is not a release
104 keep_warnings = release == "development"
105 nitpicky = keep_warnings
106 
107 # The language for content autogenerated by Sphinx. Refer to documentation
108 # for a list of supported languages.
109 #
110 # This is also used if you do content translation via gettext catalogs.
111 # Usually you set "language" from the command line for these cases.
112 language = None
113 
114 # There are two options for replacing |today|: either, you set today to some
115 # non-false value, then it is used:
116 # today = ''
117 # Else, today_fmt is used as the format for a strftime call.
118 # today_fmt = '%B %d, %Y'
119 
120 # List of patterns, relative to source directory, that match files and
121 # directories to ignore when looking for source files.
122 # This patterns also effect to html_static_path and html_extra_path
123 exclude_patterns = ['.*', '_sphinxbuild', 'Thumbs.db', 'build', 'include', 'lib', 'bin', 'modules', 'data', 'site_scons']
124 # If we want to create the light release documentation then we need t exclude anything not in the light release.
125 if tags.has('light'):
126  light_packages = set([entry.strip('/') for entry in open('../../.light').read().split() if entry.endswith('/')])
127  for entry in os.listdir("../../"):
128  if entry.find('.') > -1 or os.path.isfile(entry) or entry in exclude_patterns or entry in light_packages:
129  continue
130  exclude_patterns.append(entry)
131  del light_packages
132 
133 # now we need to exclude everything in the build dir except for the tools_doc
134 # sub dir but there's no negative exclusion pattern so do it manually
135 exclude_patterns.remove("build")
136 exclude_patterns += ['build/html', 'build/latex', 'build/json', 'build/Linux*']
137 # Ignore jupyter notebooks by default, we only want the ones meant for documentation
138 exclude_patterns += ['**/*.ipynb', '*.ipynb']
139 
140 # The reST default role (used for this markup: `text`) to use for all
141 # documents. :any: allows easy linking to functions/classes/modules
142 default_role = 'any'
143 
144 # If true, '()' will be appended to :func: etc. cross-reference text.
145 # add_function_parentheses = True
146 
147 # If true, the current module name will be prepended to all description
148 # unit titles (such as .. function::).
149 # add_module_names = True
150 
151 # If true, sectionauthor and moduleauthor directives will be shown in the
152 # output. They are ignored by default.
153 # show_authors = False
154 
155 # The name of the Pygments (syntax highlighting) style to use.
156 pygments_style = 'sphinx'
157 
158 # A list of ignored prefixes for module index sorting.
159 # modindex_common_prefix = []
160 
161 # If true, keep warnings as "system message" paragraphs in the built documents.
162 # keep_warnings = False
163 
164 # If true, `todo` and `todoList` produce output, else they produce nothing.
165 todo_include_todos = False
166 
167 # If true, figures with captions automatically get figure numbers included at the start of the caption.
168 # Also the :numref: role is allowed for figures. Referencing figures/sections etc in this way
169 # will insert a reference to the reference number instead of the reference text/caption.
170 numfig = True
171 
172 # -- Options for HTML output ----------------------------------------------
173 
174 # The theme to use for HTML and HTML Help pages. See the documentation for
175 # a list of builtin themes.
176 html_theme = 'sphinx_rtd_theme'
177 
178 # Theme options are theme-specific and customize the look and feel of a theme
179 # further. For a list of options available for each theme, see the
180 # documentation.
181 html_theme_options = {'stickysidebar': True}
182 
183 # Add any paths that contain custom themes here, relative to this directory.
184 html_theme_path = ["_themes", ]
185 
186 # The name for this set of Sphinx documents.
187 # "<project> v<release> documentation" by default.
188 # html_title = 'basf2 vhead'
189 
190 # A shorter title for the navigation bar. Default is the same as html_title.
191 # html_short_title = None
192 
193 # The name of an image file (relative to this directory) to place at the top
194 # of the sidebar.
195 html_logo = "b2logo.svg"
196 
197 # The name of an image file (relative to this directory) to use as a favicon of
198 # the docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
199 # pixels large.
200 # html_favicon = None
201 
202 # Add any paths that contain custom static files (such as style sheets) here,
203 # relative to this directory. They are copied after the builtin static files,
204 # so a file named "default.css" will overwrite the builtin "default.css".
205 html_static_path = ['_sphinxstatic']
206 
207 # Add any extra paths that contain custom files (such as robots.txt or
208 # .htaccess) here, relative to this directory. These files are copied
209 # directly to the root of the documentation.
210 # html_extra_path = []
211 
212 # If not None, a 'Last updated on:' timestamp is inserted at every page
213 # bottom, using the given strftime format.
214 # The empty string is equivalent to '%b %d, %Y'.
215 # html_last_updated_fmt = None
216 
217 # If true, SmartyPants will be used to convert quotes and dashes to
218 # typographically correct entities.
219 # html_use_smartypants = True
220 
221 # Custom sidebar templates, maps document names to template names.
222 # html_sidebars = {}
223 
224 # Additional templates that should be rendered to pages, maps page names to
225 # template names.
226 # html_additional_pages = {}
227 
228 # If false, no module index is generated.
229 # html_domain_indices = True
230 
231 # If false, no index is generated.
232 # html_use_index = True
233 
234 # If true, the index is split into individual pages for each letter.
235 # html_split_index = False
236 
237 # If true, links to the reST sources are added to the pages.
238 # html_show_sourcelink = True
239 
240 # If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
241 # html_show_sphinx = True
242 
243 # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
244 # html_show_copyright = True
245 
246 # If true, an OpenSearch description file will be output, and all pages will
247 # contain a <link> tag referring to it. The value of this option must be the
248 # base URL from which the finished HTML is served.
249 # html_use_opensearch = ''
250 
251 # This is the file name suffix for HTML files (e.g. ".xhtml").
252 # html_file_suffix = None
253 
254 # Language to be used for generating the HTML full-text search index.
255 # Sphinx supports the following languages:
256 # 'da', 'de', 'en', 'es', 'fi', 'fr', 'h', 'it', 'ja'
257 # 'nl', 'no', 'pt', 'ro', 'r', 'sv', 'tr', 'zh'
258 # html_search_language = 'en'
259 
260 # A dictionary with options for the search language support, empty by default.
261 # 'ja' uses this config value.
262 # 'zh' user can custom change `jieba` dictionary path.
263 # html_search_options = {'type': 'default'}
264 
265 # The name of a javascript file (relative to the configuration directory) that
266 # implements a search results scorer. If empty, the default will be used.
267 # html_search_scorer = 'scorer.js'
268 
269 # Output file base name for HTML help builder.
270 htmlhelp_basename = 'basf2doc'
271 
272 # -- Options for LaTeX output ---------------------------------------------
273 
274 latex_elements = {
275  # The paper size ('letterpaper' or 'a4paper').
276  'papersize': 'a4paper',
277 
278  # The font size ('10pt', '11pt' or '12pt').
279  'pointsize': '10pt',
280 
281  # Additional stuff for the LaTeX preamble.
282  'preamble': r'\setcounter{tocdepth}{2}',
283 
284  # Latex figure (float) alignment
285  # 'figure_align': 'htbp',
286 }
287 
288 # Grouping the document tree into LaTeX files. List of tuples
289 # (source start file, target name, title,
290 # author, documentclass [howto, manual, or own class]).
291 latex_documents = [
292  (master_doc, 'basf2.tex', 'Belle 2 Software Documentation',
293  author, 'manual'),
294 ]
295 
296 # The name of an image file (relative to this directory) to place at the top of
297 # the title page.
298 latex_logo = "belle2-logo.pdf"
299 
300 # For "manual" documents, if this is true, then toplevel headings are parts,
301 # not chapters.
302 latex_use_parts = True
303 latex_show_urls = 'footnote'
304 latex_show_pagerefs = True
305 
306 # If true, show page references after internal links.
307 # latex_show_pagerefs = False
308 
309 # If true, show URL addresses after external links.
310 # latex_show_urls = False
311 
312 # Documents to append as an appendix to all manuals.
313 # latex_appendices = []
314 
315 # If false, no module index is generated.
316 # latex_domain_indices = True
317 
318 
319 # -- Options for manual page output ---------------------------------------
320 
321 # One entry per manual page. List of tuples
322 # (source start file, name, description, authors, manual section).
323 man_pages = [
324  (master_doc, 'basf2', 'basf2 Documentation',
325  [author], 1)
326 ]
327 
328 # If true, show URL addresses after external links.
329 # man_show_urls = False
330 
331 
332 # -- Options for Texinfo output -------------------------------------------
333 
334 # Grouping the document tree into Texinfo files. List of tuples
335 # (source start file, target name, title, author,
336 # dir menu entry, description, category)
337 texinfo_documents = [
338  (master_doc, 'basf2', 'basf2 Documentation',
339  author, 'basf2', 'One line description of project.',
340  'Miscellaneous'),
341 ]
342 
343 # Documents to append as an appendix to all manuals.
344 # texinfo_appendices = []
345 
346 # If false, no module index is generated.
347 # texinfo_domain_indices = True
348 
349 # How to display URL addresses: 'footnote', 'no', or 'inline'.
350 # texinfo_show_urls = 'footnote'
351 
352 # If true, do not generate a @detailmenu in the "Top" node's menu.
353 # texinfo_no_detailmenu = False
354 
355 # allow to have links to python documentation
356 intersphinx_mapping = {'python': ('https://docs.python.org/3.6', None)}
357 
358 
359 def process_sig(app, what, name, obj, options, signature, return_annotation):
360  """
361  remove unhelpful 'self' arguments from methods.
362  """
363  if what == 'method' and signature:
364  reg = re.compile(r'^\( \(.*\)arg1')
365  signature = reg.sub('(', signature)
366  return (signature, return_annotation)
367 
368 
369 def improve_docstring(obj):
370  """
371  Enhances docstrings of PyROOT objects/classes.
372 
373  >>> improve_docstring(Belle2.Variable.Manager)
374 
375  or
376 
377  >>> variables = ROOT.Belle2.Variable.Manager
378  >>> improve_docstring(variables)
379  """
380  try:
381  # is this a ..._meta object?
382  classname = obj.__name__
383  pyclass = obj
384  except AttributeError:
385  classname = obj.__class__.__name__
386  pyclass = obj.__class__
387 
388  if '::' not in classname:
389  return # not a ROOT class?
390  pos = classname.find('Belle2::')
391  classname = classname[pos:]
392  if pyclass.__doc__ is None:
393  pyclass.__doc__ = ''
394 
395  pyclass.__name__ = 'Belle2.' + classname
396 
397  from ROOT import TClass
398  tclass = TClass(classname)
399  # if tclass:
400  # pyclass.__doc__ += '\n' + tclass.GetTitle()
401 
402  doxygen_url = 'https://b2-master.belle2.org/software/development/class'
403  doxygen_url += '_1_1'.join(classname.split('::'))
404  doxygen_url += '.html'
405  pyclass.__doc__ += '\n`Doxygen page for %s <%s>`_' % (classname, doxygen_url)
406 
407  # TODO put this into the member docstrings directly? (sadly, readonly)
408  members = tclass.GetListOfMethods()
409  if members.GetEntries() > 0:
410  pyclass.__doc__ += '\n\nMember functions:'
411  for f in members:
412  # getattr(pyclass, f.GetName()).__doc__ = "test"
413  pyclass.__doc__ += '\n * %s %s%s' % (f.GetReturnTypeName(), f.GetName(), f.GetSignature())
414  title = f.GetTitle()
415  if title:
416  pyclass.__doc__ += ' (%s)' % (title)
417 
418  members = tclass.GetListOfAllPublicDataMembers()
419  if members.GetEntries() > 0:
420  pyclass.__doc__ += '\n\nPublic data members'
421  for f in members:
422  pyclass.__doc__ += '\n * %s' % (f.GetName())
423  title = f.GetTitle()
424  if title:
425  pyclass.__doc__ += ' (%s)' % (title)
426 
427 
428 def skipmember(app, what, name, obj, skip, options):
429  """
430  This is executed before docstring processing,
431  so try improving them a bit.
432  """
433  try:
434  improve_docstring(obj)
435  except AttributeError:
436  pass
437  return skip
438 
439 
440 def process_docstring(app, what, name, obj, options, lines):
441  """
442  convert doxygen syntax to sphinx
443  """
444  substitutions = {
445  re.compile(r'^( *)@param (.*?):? '): r':param \2: ',
446  re.compile(r'^( *)@returns? '): r':return: ',
447  }
448  newlines = []
449  for l in lines:
450  new = l
451  for reg, sub in substitutions.items():
452  new = reg.sub(sub, new)
453  if new != l:
454  # Sphinx wants a new paragraph before these, so let's add one
455  newlines += ['']
456  newlines += [new]
457  lines[:] = newlines
458 
459 
460 def setup(app):
461  """
462  Install some event handlers to improve output.
463  """
464  app.connect('autodoc-process-signature', process_sig)
465  app.connect('autodoc-process-docstring', process_docstring)
466  app.connect('autodoc-skip-member', skipmember)
467  app.add_css_file('css/custom.css')
setup