diff --git a/.gitignore b/.gitignore index 658fe2d026..4ec9186c7a 100644 --- a/.gitignore +++ b/.gitignore @@ -36,7 +36,7 @@ pvlib/spa_c_files/spa.h pvlib/spa_c_files/spa_tester.c # generated documentation -# pvlib/sphinx/Docs/build/ +docs/sphinx/source/generated/ # Installer logs pip-log.txt diff --git a/docs/sphinx/source/_static/.gitignore b/docs/sphinx/source/_static/.gitignore index e69de29bb2..e33609d251 100644 --- a/docs/sphinx/source/_static/.gitignore +++ b/docs/sphinx/source/_static/.gitignore @@ -0,0 +1 @@ +*.png diff --git a/docs/sphinx/source/_static/no_scrollbars.css b/docs/sphinx/source/_static/no_scrollbars.css new file mode 100644 index 0000000000..5177a66ac8 --- /dev/null +++ b/docs/sphinx/source/_static/no_scrollbars.css @@ -0,0 +1,11 @@ +/* override table width restrictions */ +/* as described in https://github.com/snide/sphinx_rtd_theme/issues/117 */ +.wy-table-responsive table td, .wy-table-responsive table th { + /* !important prevents the common CSS stylesheets from + overriding this as on RTD they are loaded after this stylesheet */ + white-space: normal !important; +} + +.wy-table-responsive { + overflow: visible !important; +} diff --git a/docs/sphinx/source/_templates/autosummary/class.rst b/docs/sphinx/source/_templates/autosummary/class.rst new file mode 100644 index 0000000000..398b40dd53 --- /dev/null +++ b/docs/sphinx/source/_templates/autosummary/class.rst @@ -0,0 +1,31 @@ +{{ fullname }} +{{ underline }} + +.. currentmodule:: {{ module }} + +.. autoclass:: {{ objname }} + + {% block methods %} + + {% if methods %} + .. rubric:: Methods + + .. autosummary:: + :toctree: {{ objname }} + {% for item in methods %} + ~{{ name }}.{{ item }} + {%- endfor %} + {% endif %} + {% endblock %} + + {% block attributes %} + {% if attributes %} + .. rubric:: Attributes + + .. autosummary:: + :toctree: {{ objname }} + {% for item in attributes %} + ~{{ name }}.{{ item }} + {%- endfor %} + {% endif %} + {% endblock %} diff --git a/docs/sphinx/source/_templates/autosummary/module.rst b/docs/sphinx/source/_templates/autosummary/module.rst new file mode 100644 index 0000000000..8ecda58605 --- /dev/null +++ b/docs/sphinx/source/_templates/autosummary/module.rst @@ -0,0 +1,40 @@ +{{ fullname }} +{{ underline }} + +.. automodule:: {{ fullname }} + + {% block functions %} + {% if functions %} + .. rubric:: Functions + + .. autosummary:: + :toctree: {{ objname }} + {% for item in functions %} + {{ item }} + {%- endfor %} + {% endif %} + {% endblock %} + + {% block classes %} + {% if classes %} + .. rubric:: Classes + + .. autosummary:: + :toctree: {{ objname }} + :template: autosummary/class.rst + {% for item in classes %} + {{ item }} + {%- endfor %} + {% endif %} + {% endblock %} + + {% block exceptions %} + {% if exceptions %} + .. rubric:: Exceptions + + .. autosummary:: + {% for item in exceptions %} + {{ item }} + {%- endfor %} + {% endif %} + {% endblock %} diff --git a/docs/sphinx/source/conf.py b/docs/sphinx/source/conf.py index cda390e293..6d48047388 100644 --- a/docs/sphinx/source/conf.py +++ b/docs/sphinx/source/conf.py @@ -126,6 +126,7 @@ def __getattr__(cls, name): # If true, keep warnings as "system message" paragraphs in the built documents. #keep_warnings = False +autosummary_generate = True # -- Options for HTML output ---------------------------------------------- @@ -219,6 +220,10 @@ def __getattr__(cls, name): # Output file base name for HTML help builder. htmlhelp_basename = 'PVLIB_Pythondoc' +# A workaround for the responsive tables always having annoying scrollbars. +def setup(app): + app.add_stylesheet("no_scrollbars.css") + # -- Options for LaTeX output --------------------------------------------- @@ -310,3 +315,151 @@ def __getattr__(cls, name): 'numpy': ('http://docs.scipy.org/doc/numpy/', None), } + +# Monkey patch sphinx autosummary to avoid +# https://github.com/sphinx-doc/sphinx/issues/1061 + +import sphinx.ext.autosummary.generate +from sphinx.ext.autosummary.generate import _simple_warn, _simple_info +from sphinx.ext.autosummary.generate import * + +def generate_autosummary_docs(sources, output_dir=None, suffix='.rst', + warn=_simple_warn, info=_simple_info, + base_path=None, builder=None, template_dir=None): + + showed_sources = list(sorted(sources)) + if len(showed_sources) > 20: + showed_sources = showed_sources[:10] + ['...'] + showed_sources[-10:] + info('[autosummary] generating autosummary for: %s' % + ', '.join(showed_sources)) + + if output_dir: + info('[autosummary] writing to %s' % output_dir) + + if base_path is not None: + sources = [os.path.join(base_path, filename) for filename in sources] + + # create our own templating environment + template_dirs = [os.path.join(package_dir, 'ext', + 'autosummary', 'templates')] + if builder is not None: + # allow the user to override the templates + template_loader = BuiltinTemplateLoader() + template_loader.init(builder, dirs=template_dirs) + else: + if template_dir: + template_dirs.insert(0, template_dir) + template_loader = FileSystemLoader(template_dirs) + template_env = SandboxedEnvironment(loader=template_loader) + + # read + items = find_autosummary_in_files(sources) + + # keep track of new files + new_files = [] + + # write + for name, path, template_name in sorted(set(items), key=str): + if path is None: + # The corresponding autosummary:: directive did not have + # a :toctree: option + continue + + path = output_dir or os.path.abspath(path) + ensuredir(path) + + try: + name, obj, parent, mod_name = import_by_name(name) + except ImportError as e: + warn('[autosummary] failed to import %r: %s' % (name, e)) + continue + + fn = os.path.join(path, name + suffix) + + # skip it if it exists + if os.path.isfile(fn): + continue + + new_files.append(fn) + + with open(fn, 'w') as f: + doc = get_documenter(obj, parent) + + if template_name is not None: + template = template_env.get_template(template_name) + else: + try: + template = template_env.get_template('autosummary/%s.rst' + % doc.objtype) + except TemplateNotFound: + template = template_env.get_template('autosummary/base.rst') + + def get_members(obj, typ, include_public=[], imported=False): + items = [] + for name in dir(obj): + try: + obj_name = safe_getattr(obj, name) + documenter = get_documenter(safe_getattr(obj, name), + obj) + except AttributeError: + continue + if documenter.objtype == typ: + try: + cond = ( + imported or + obj_name.__module__ == obj.__name__ + ) + except AttributeError: + cond = True + if cond: + items.append(name) + public = [x for x in items + if x in include_public or not x.startswith('_')] + return public, items + + ns = {} + + if doc.objtype == 'module': + ns['members'] = dir(obj) + ns['functions'], ns['all_functions'] = \ + get_members(obj, 'function') + ns['classes'], ns['all_classes'] = \ + get_members(obj, 'class') + ns['exceptions'], ns['all_exceptions'] = \ + get_members(obj, 'exception') + elif doc.objtype == 'class': + ns['members'] = dir(obj) + ns['methods'], ns['all_methods'] = \ + get_members(obj, 'method', ['__init__']) + ns['attributes'], ns['all_attributes'] = \ + get_members(obj, 'attribute') + + parts = name.split('.') + if doc.objtype in ('method', 'attribute'): + mod_name = '.'.join(parts[:-2]) + cls_name = parts[-2] + obj_name = '.'.join(parts[-2:]) + ns['class'] = cls_name + else: + mod_name, obj_name = '.'.join(parts[:-1]), parts[-1] + + ns['fullname'] = name + ns['module'] = mod_name + ns['objname'] = obj_name + ns['name'] = parts[-1] + + ns['objtype'] = doc.objtype + ns['underline'] = len(name) * '=' + + rendered = template.render(**ns) + f.write(rendered) + + # descend recursively to new files + if new_files: + generate_autosummary_docs(new_files, output_dir=output_dir, + suffix=suffix, warn=warn, info=info, + base_path=base_path, builder=builder, + template_dir=template_dir) + +sphinx.ext.autosummary.generate.generate_autosummary_docs = \ + generate_autosummary_docs diff --git a/docs/sphinx/source/index.rst b/docs/sphinx/source/index.rst index 45f10ecedf..ae8f7b554e 100644 --- a/docs/sphinx/source/index.rst +++ b/docs/sphinx/source/index.rst @@ -68,7 +68,7 @@ Contents ======== .. toctree:: - :maxdepth: 2 + :maxdepth: 4 package_overview whatsnew diff --git a/docs/sphinx/source/modules.rst b/docs/sphinx/source/modules.rst index e0a23ea8ac..9687193216 100644 --- a/docs/sphinx/source/modules.rst +++ b/docs/sphinx/source/modules.rst @@ -1,90 +1,18 @@ Modules ======= -atmosphere ------------------ - -.. automodule:: pvlib.atmosphere - :members: - :undoc-members: - :show-inheritance: - -clearsky ----------------- - -.. automodule:: pvlib.clearsky - :members: - :undoc-members: - :show-inheritance: - -forecast ----------------- - -.. automodule:: pvlib.forecast - :members: - :undoc-members: - :show-inheritance: - -irradiance ------------------ - -.. automodule:: pvlib.irradiance - :members: - :undoc-members: - :show-inheritance: - -location ---------------- - -.. automodule:: pvlib.location - :members: - :undoc-members: - :show-inheritance: - -modelchain ----------- - -.. automodule:: pvlib.modelchain - :members: - :undoc-members: - :show-inheritance: - -pvsystem ---------------- - -.. automodule:: pvlib.pvsystem - :members: - :undoc-members: - :show-inheritance: - -solarposition --------------------- - -.. automodule:: pvlib.solarposition - :members: - :undoc-members: - :show-inheritance: - -tmy --------------------- - -.. automodule:: pvlib.tmy - :members: - :undoc-members: - :show-inheritance: - -tracking --------------------- - -.. automodule:: pvlib.tracking - :members: - :undoc-members: - :show-inheritance: - -tools --------------------- - -.. automodule:: pvlib.tools - :members: - :undoc-members: - :show-inheritance: +.. autosummary:: + :toctree: generated + :template: autosummary/module.rst + + pvlib.atmosphere + pvlib.clearsky + pvlib.forecast + pvlib.irradiance + pvlib.location + pvlib.modelchain + pvlib.pvsystem + pvlib.solarposition + pvlib.tmy + pvlib.tools + pvlib.tracking