Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Restructure docs #3303

Merged
merged 4 commits into from
Dec 18, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
*.sw[op]
examples/*.png
nb_examples/
nb_tutorials/
build/*
dist/*
*.egg-info/
Expand Down
4 changes: 4 additions & 0 deletions docs/source/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ help:
@echo " linkcheck to check all external links for integrity"
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
@echo " coverage to run coverage check of the documentation (if enabled)"
@echo " serve to launch a server from built html files"

clean:
rm -rf $(BUILDDIR)/*
Expand Down Expand Up @@ -190,3 +191,6 @@ pseudoxml:
$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
@echo
@echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."

serve: html
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i don't think http.server actually takes a --directory argument! (only confirmed on python 3.6.6)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm. Maybe they introduced it on python 3.7+. I will swap that with a simple cd.

cd $(BUILDDIR)/html && python -m http.server
9 changes: 5 additions & 4 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,10 +143,11 @@

html_theme_options = {
"navbar_links": [
("Quickstart", "intro"),
("API", "api"),
("Tutorials", "nb_tutorials/index"),
("Examples", "nb_examples/index"),
("Learn", "learn"),
("Books + Videos", "learn"),
("API", "api"),
("About PyMC3", "history")
],
# "fixed_sidebar": "false",
# "description": "Probabilistic Programming in Python: Bayesian Modeling and Probabilistic Machine Learning with Theano"
Expand Down Expand Up @@ -174,7 +175,7 @@
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ["_static", "nb_examples/_images"]
html_static_path = ["_static", "nb_tutorials/_images", "nb_examples/_images"]

# Add any extra paths that contain custom files (such as robots.txt or
# .htaccess) here, relative to this directory. These files are copied
Expand Down
6 changes: 6 additions & 0 deletions docs/source/intro.rst → docs/source/history.rst
Original file line number Diff line number Diff line change
Expand Up @@ -143,3 +143,9 @@ This example will generate 1000 posterior samples on each of two cores using the
The sample is returned as arrays inside of a ``MultiTrace`` object, which is then passed to a plotting function. The resulting graphic shows a forest plot of the random variables in the model, along with a convergence diagnostic (R-hat) that indicates our model has converged.

.. image:: ./images/forestplot.png

See also
========

* `Tutorials <nb_tutorials/index.html>`__
* `Examples <nb_examples/index.html>`__
12 changes: 9 additions & 3 deletions docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,12 @@
Gaussian processes to fit a regression model.</p>
</div>
<div class="eight wide right floated column">
<pre><code class="python">
X, y = linear_training_data()

.. code-block:: python

import pymc3 as pm

X, y = linear_training_data()
with pm.Model() as linear_model:
weights = pm.Normal('weights', mu=0, sd=1)
noise = pm.Gamma('noise', alpha=2, beta=1)
Expand All @@ -29,7 +32,10 @@

prior = pm.sample_prior_predictive()
posterior = pm.sample()
posterior_pred = pm.sample_posterior_predictive(posterior)</code></pre>
posterior_pred = pm.sample_posterior_predictive(posterior)

.. raw:: html

</div>
</div>
</div>
Expand Down
2 changes: 1 addition & 1 deletion docs/source/learn.rst
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.. title:: Learn
.. title:: Learning Resources

.. raw:: html

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,11 @@ Gallery.contents = {
"GP-TProcess": "Gaussian Processes",
"GP-slice-sampling": "Gaussian Processes",
"GP-smoothing": "Gaussian Processes",
"LKJ": "How-To",
"MvGaussianRandomWalk_demo": "Time Series",
"PyMC3_tips_and_heuristic": "How-To",
"SMC2_gaussians": "Other",
"api_quickstart": "How-To",
"bayes_param_survival_pymc3": "Survival Analysis",
"bayesian_neural_network_advi": "Variational Inference",
"bayesian_neural_network_with_sgfs": "Stochastic Gradients",
"blackbox_external_likelihood": "How-To",
"censored_data": "Survival Analysis",
"constant_stochastic_gradient": "Stochastic Gradients",
"convolutional_vae_keras_advi": "Variational Inference",
Expand All @@ -46,26 +42,16 @@ Gallery.contents = {
"gaussian-mixture-model-advi": "Mixture Models",
"gaussian_mixture_model": "Mixture Models",
"gaussian_process": "Gaussian Processes",
"getting_started": "How-To",
"hierarchical_partial_pooling": "GLMs",
"howto_debugging": "How-To",
"lasso_block_update": "How-To",
"lda-advi-aevb": "Variational Inference",
"live_sample_plots": "How-To",
"marginalized_gaussian_mixture_model": "Mixture Models",
"model_averaging": "How-To",
"model_comparison": "Diagnostics",
"multilevel_modeling": "Applied",
"normalizing_flows_overview": "Variational Inference",
"posterior_predictive": "Diagnostics",
"profiling": "How-To",
"rugby_analytics": "Applied",
"sampler-stats": "How-To",
"sampling_compound_step": "How-To",
"sgfs_simple_optimization": "Stochastic Gradients",
"stochastic_volatility": "Applied",
"survival_analysis": "Survival Analysis",
"updating_priors": "How-To",
"variational_api_quickstart": "Variational Inference",
"weibull_aft": "Survival Analysis"
}
16 changes: 16 additions & 0 deletions docs/source/notebooks/table_of_contents_tutorials.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
Gallery.contents = {
"api_quickstart": "Basics",
"getting_started": "Basics",
"sampler-stats": "Basics",
"sampling_compound_step": "Basics",
"howto_debugging": "Basics",
"live_sample_plots": "How-To",
"profiling": "How-To",
"updating_priors": "How-To",
"lasso_block_update": "How-To",
"model_averaging": "How-To",
"blackbox_external_likelihood": "How-To",
"LKJ": "How-To",
"variational_api_quickstart": "How-To",
"PyMC3_tips_and_heuristic": "How-To"
}
14 changes: 11 additions & 3 deletions docs/source/semantic_sphinx/layout.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
'_static/semantic.min.js',
]
%}
{% if pagename == 'nb_examples/index' %}
{% if pagename == 'nb_examples/index' or pagename == 'nb_tutorials/index' %}
{% set script_files = script_files + [
'_static/gallery.js',
]
Expand All @@ -18,9 +18,17 @@
<meta http-equiv='X-UA-Compatible' content='IE=edge,chrome=1'>
<meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1'>
<meta name="apple-mobile-web-app-capable" content="yes">
{% if pagename == 'nb_tutorials/index' %}
<script type="text/javascript">
jQuery(function () { Gallery.loadScript("{{ pathto('_static/gallery_tutorials_contents.js', 1) }}", "exampleloader"); });
</script>
{# this is used when loading the gallery index using $.ajax fails,
such as on Chrome for documents on localhost #}
<script type="text/javascript" id="exampleloader"></script>
{% endif %}
{% if pagename == 'nb_examples/index' %}
<script type="text/javascript">
jQuery(function () { Gallery.loadScript("{{ pathto('_static/gallery_contents.js', 1) }}", "exampleloader"); });
jQuery(function () { Gallery.loadScript("{{ pathto('_static/gallery_examples_contents.js', 1) }}", "exampleloader"); });
</script>
{# this is used when loading the gallery index using $.ajax fails,
such as on Chrome for documents on localhost #}
Expand Down Expand Up @@ -62,7 +70,7 @@
<div class="ui center aligned text container">
<img src="https://cdn.rawgit.com/pymc-devs/pymc3/master/docs/logos/svg/PyMC3_banner.svg" />
<h2>Probabilistic Programming in Python</h2>
<a href="intro.html">
<a href="notebooks/api_quickstart.html">
<div class="ui huge primary button">Quickstart <i class="right arrow icon"></i></div>
</a>
</div>
Expand Down
3 changes: 3 additions & 0 deletions docs/source/semantic_sphinx/static/gallery.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ var Gallery = {
categories["Other"].push(key)
}
})
if(categories["Other"].length === 0){
delete categories["Other"]
}
return categories
},

Expand Down
52 changes: 39 additions & 13 deletions docs/source/sphinxext/gallery_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import os
import glob
import shutil
import runpy

import matplotlib

Expand All @@ -17,16 +18,16 @@
from matplotlib import image

DOC_SRC = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
TABLE_OF_CONTENTS_FILENAME = "table_of_contents.js"
TABLE_OF_CONTENTS_FILENAME = "table_of_contents_{}.js"

INDEX_TEMPLATE = """
.. _{sphinx_tag}:

.. title:: example_notebooks
.. title:: {gallery}_notebooks

.. raw:: html

<h1 class="ui header">Example Notebooks</h1>
<h1 class="ui header">{Gallery} Notebooks</h1>
<div id="gallery" class="ui vertical segment">
</div>
"""
Expand Down Expand Up @@ -119,15 +120,30 @@ def gen_previews(self):
create_thumbnail(self.png_path)


def main(app):
class TableOfContentsJS(object):
"""Container to load table of contents JS file"""

def load(self, path):
"""Creates an attribute ``contents`` by running the JS file as a python
file.

"""
runpy.run_path(path, {"Gallery": self})


def build_gallery(srcdir, gallery):
working_dir = os.getcwd()
os.chdir(app.builder.srcdir)
static_dir = os.path.join(app.builder.srcdir, "_static")
target_dir = os.path.join(app.builder.srcdir, "nb_examples")
os.chdir(srcdir)
static_dir = os.path.join(srcdir, "_static")
target_dir = os.path.join(srcdir, "nb_{}".format(gallery))
image_dir = os.path.join(target_dir, "_images")
source_dir = os.path.abspath(
os.path.join(os.path.dirname(os.path.dirname(app.builder.srcdir)), "notebooks")
os.path.join(os.path.dirname(os.path.dirname(srcdir)), "notebooks")
)
table_of_contents_file = os.path.join(
source_dir, TABLE_OF_CONTENTS_FILENAME.format(gallery))
tocjs = TableOfContentsJS()
tocjs.load(table_of_contents_file)

if not os.path.exists(static_dir):
os.makedirs(static_dir)
Expand All @@ -143,16 +159,17 @@ def main(app):

# Write individual example files
data = {}
for filename in sorted(glob.glob(os.path.join(source_dir, "*.ipynb"))):
for basename in sorted(tocjs.contents):
filename = os.path.join(source_dir, basename + ".ipynb")
ex = NotebookGenerator(filename, target_dir)
data[ex.stripped_name] = {
"title": ex.pagetitle,
"url": os.path.join("/examples", ex.output_html),
"url": os.path.join(os.sep, gallery, ex.output_html),
"thumb": os.path.basename(ex.png_path),
}

js_file = os.path.join(image_dir, "gallery_contents.js")
with open(os.path.join(source_dir, TABLE_OF_CONTENTS_FILENAME), "r") as toc:
js_file = os.path.join(image_dir, "gallery_{}_contents.js".format(gallery))
with open(table_of_contents_file, "r") as toc:
table_of_contents = toc.read()

js_contents = "Gallery.examples = {}\n{}".format(
Expand All @@ -163,10 +180,19 @@ def main(app):
js.write(js_contents)

with open(os.path.join(target_dir, "index.rst"), "w") as index:
index.write(INDEX_TEMPLATE.format(sphinx_tag="notebook_gallery"))
index.write(INDEX_TEMPLATE.format(
sphinx_tag="notebook_gallery",
gallery=gallery,
Gallery=gallery.title().rstrip("s")
))

os.chdir(working_dir)


def main(app):
for gallery in ("tutorials", "examples"):
build_gallery(app.builder.srcdir, gallery)


def setup(app):
app.connect("builder-inited", main)