Skip to content

Commit fc523cc

Browse files
ashwinvisjunpenglao
authored andcommitted
Restructure docs (#3303)
* How-to -> Tutorials; Learn -> Resources (URL is the same) * Reorder navbar, change of names Details ------- Quickstart = API quickstart (no navbar link, linked big blue button + tutorials) Learn -> Books+Videos Quickstart(old) -> About PyMC3 * Added syntax highlighting to landing page code snippet * Added see also section at the end of About PyMC3 * Classified Tutorials into Basic and How-Tos * Incorporate @junpenglao 's comments * Final tweaks to doc restructure Backwards compatible `make serve`, no dangling "Other", "intro.rst" -> "history"
1 parent c54dcee commit fc523cc

File tree

11 files changed

+95
-38
lines changed

11 files changed

+95
-38
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
*.sw[op]
33
examples/*.png
44
nb_examples/
5+
nb_tutorials/
56
build/*
67
dist/*
78
*.egg-info/

docs/source/Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ help:
4747
@echo " linkcheck to check all external links for integrity"
4848
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
4949
@echo " coverage to run coverage check of the documentation (if enabled)"
50+
@echo " serve to launch a server from built html files"
5051

5152
clean:
5253
rm -rf $(BUILDDIR)/*
@@ -190,3 +191,6 @@ pseudoxml:
190191
$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
191192
@echo
192193
@echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."
194+
195+
serve: html
196+
cd $(BUILDDIR)/html && python -m http.server

docs/source/conf.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -143,10 +143,11 @@
143143

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

179180
# Add any extra paths that contain custom files (such as robots.txt or
180181
# .htaccess) here, relative to this directory. These files are copied

docs/source/intro.rst renamed to docs/source/history.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,3 +143,9 @@ This example will generate 1000 posterior samples on each of two cores using the
143143
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.
144144

145145
.. image:: ./images/forestplot.png
146+
147+
See also
148+
========
149+
150+
* `Tutorials <nb_tutorials/index.html>`__
151+
* `Examples <nb_examples/index.html>`__

docs/source/index.rst

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,12 @@
1616
Gaussian processes to fit a regression model.</p>
1717
</div>
1818
<div class="eight wide right floated column">
19-
<pre><code class="python">
20-
X, y = linear_training_data()
2119

20+
.. code-block:: python
21+
22+
import pymc3 as pm
23+
24+
X, y = linear_training_data()
2225
with pm.Model() as linear_model:
2326
weights = pm.Normal('weights', mu=0, sd=1)
2427
noise = pm.Gamma('noise', alpha=2, beta=1)
@@ -29,7 +32,10 @@
2932
3033
prior = pm.sample_prior_predictive()
3134
posterior = pm.sample()
32-
posterior_pred = pm.sample_posterior_predictive(posterior)</code></pre>
35+
posterior_pred = pm.sample_posterior_predictive(posterior)
36+
37+
.. raw:: html
38+
3339
</div>
3440
</div>
3541
</div>

docs/source/learn.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
.. title:: Learn
1+
.. title:: Learning Resources
22

33
.. raw:: html
44

docs/source/notebooks/table_of_contents.js renamed to docs/source/notebooks/table_of_contents_examples.js

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,11 @@ Gallery.contents = {
2626
"GP-TProcess": "Gaussian Processes",
2727
"GP-slice-sampling": "Gaussian Processes",
2828
"GP-smoothing": "Gaussian Processes",
29-
"LKJ": "How-To",
3029
"MvGaussianRandomWalk_demo": "Time Series",
31-
"PyMC3_tips_and_heuristic": "How-To",
3230
"SMC2_gaussians": "Other",
33-
"api_quickstart": "How-To",
3431
"bayes_param_survival_pymc3": "Survival Analysis",
3532
"bayesian_neural_network_advi": "Variational Inference",
3633
"bayesian_neural_network_with_sgfs": "Stochastic Gradients",
37-
"blackbox_external_likelihood": "How-To",
3834
"censored_data": "Survival Analysis",
3935
"constant_stochastic_gradient": "Stochastic Gradients",
4036
"convolutional_vae_keras_advi": "Variational Inference",
@@ -46,26 +42,16 @@ Gallery.contents = {
4642
"gaussian-mixture-model-advi": "Mixture Models",
4743
"gaussian_mixture_model": "Mixture Models",
4844
"gaussian_process": "Gaussian Processes",
49-
"getting_started": "How-To",
5045
"hierarchical_partial_pooling": "GLMs",
51-
"howto_debugging": "How-To",
52-
"lasso_block_update": "How-To",
5346
"lda-advi-aevb": "Variational Inference",
54-
"live_sample_plots": "How-To",
5547
"marginalized_gaussian_mixture_model": "Mixture Models",
56-
"model_averaging": "How-To",
5748
"model_comparison": "Diagnostics",
5849
"multilevel_modeling": "Applied",
5950
"normalizing_flows_overview": "Variational Inference",
6051
"posterior_predictive": "Diagnostics",
61-
"profiling": "How-To",
6252
"rugby_analytics": "Applied",
63-
"sampler-stats": "How-To",
64-
"sampling_compound_step": "How-To",
6553
"sgfs_simple_optimization": "Stochastic Gradients",
6654
"stochastic_volatility": "Applied",
6755
"survival_analysis": "Survival Analysis",
68-
"updating_priors": "How-To",
69-
"variational_api_quickstart": "Variational Inference",
7056
"weibull_aft": "Survival Analysis"
7157
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
Gallery.contents = {
2+
"api_quickstart": "Basics",
3+
"getting_started": "Basics",
4+
"sampler-stats": "Basics",
5+
"sampling_compound_step": "Basics",
6+
"howto_debugging": "Basics",
7+
"live_sample_plots": "How-To",
8+
"profiling": "How-To",
9+
"updating_priors": "How-To",
10+
"lasso_block_update": "How-To",
11+
"model_averaging": "How-To",
12+
"blackbox_external_likelihood": "How-To",
13+
"LKJ": "How-To",
14+
"variational_api_quickstart": "How-To",
15+
"PyMC3_tips_and_heuristic": "How-To"
16+
}

docs/source/semantic_sphinx/layout.html

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
'_static/semantic.min.js',
66
]
77
%}
8-
{% if pagename == 'nb_examples/index' %}
8+
{% if pagename == 'nb_examples/index' or pagename == 'nb_tutorials/index' %}
99
{% set script_files = script_files + [
1010
'_static/gallery.js',
1111
]
@@ -18,9 +18,17 @@
1818
<meta http-equiv='X-UA-Compatible' content='IE=edge,chrome=1'>
1919
<meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1'>
2020
<meta name="apple-mobile-web-app-capable" content="yes">
21+
{% if pagename == 'nb_tutorials/index' %}
22+
<script type="text/javascript">
23+
jQuery(function () { Gallery.loadScript("{{ pathto('_static/gallery_tutorials_contents.js', 1) }}", "exampleloader"); });
24+
</script>
25+
{# this is used when loading the gallery index using $.ajax fails,
26+
such as on Chrome for documents on localhost #}
27+
<script type="text/javascript" id="exampleloader"></script>
28+
{% endif %}
2129
{% if pagename == 'nb_examples/index' %}
2230
<script type="text/javascript">
23-
jQuery(function () { Gallery.loadScript("{{ pathto('_static/gallery_contents.js', 1) }}", "exampleloader"); });
31+
jQuery(function () { Gallery.loadScript("{{ pathto('_static/gallery_examples_contents.js', 1) }}", "exampleloader"); });
2432
</script>
2533
{# this is used when loading the gallery index using $.ajax fails,
2634
such as on Chrome for documents on localhost #}
@@ -62,7 +70,7 @@
6270
<div class="ui center aligned text container">
6371
<img src="https://cdn.rawgit.com/pymc-devs/pymc3/master/docs/logos/svg/PyMC3_banner.svg" />
6472
<h2>Probabilistic Programming in Python</h2>
65-
<a href="intro.html">
73+
<a href="notebooks/api_quickstart.html">
6674
<div class="ui huge primary button">Quickstart <i class="right arrow icon"></i></div>
6775
</a>
6876
</div>

docs/source/semantic_sphinx/static/gallery.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,9 @@ var Gallery = {
7070
categories["Other"].push(key)
7171
}
7272
})
73+
if(categories["Other"].length === 0){
74+
delete categories["Other"]
75+
}
7376
return categories
7477
},
7578

docs/source/sphinxext/gallery_generator.py

Lines changed: 39 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import os
99
import glob
1010
import shutil
11+
import runpy
1112

1213
import matplotlib
1314

@@ -17,16 +18,16 @@
1718
from matplotlib import image
1819

1920
DOC_SRC = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
20-
TABLE_OF_CONTENTS_FILENAME = "table_of_contents.js"
21+
TABLE_OF_CONTENTS_FILENAME = "table_of_contents_{}.js"
2122

2223
INDEX_TEMPLATE = """
2324
.. _{sphinx_tag}:
2425
25-
.. title:: example_notebooks
26+
.. title:: {gallery}_notebooks
2627
2728
.. raw:: html
2829
29-
<h1 class="ui header">Example Notebooks</h1>
30+
<h1 class="ui header">{Gallery} Notebooks</h1>
3031
<div id="gallery" class="ui vertical segment">
3132
</div>
3233
"""
@@ -119,15 +120,30 @@ def gen_previews(self):
119120
create_thumbnail(self.png_path)
120121

121122

122-
def main(app):
123+
class TableOfContentsJS(object):
124+
"""Container to load table of contents JS file"""
125+
126+
def load(self, path):
127+
"""Creates an attribute ``contents`` by running the JS file as a python
128+
file.
129+
130+
"""
131+
runpy.run_path(path, {"Gallery": self})
132+
133+
134+
def build_gallery(srcdir, gallery):
123135
working_dir = os.getcwd()
124-
os.chdir(app.builder.srcdir)
125-
static_dir = os.path.join(app.builder.srcdir, "_static")
126-
target_dir = os.path.join(app.builder.srcdir, "nb_examples")
136+
os.chdir(srcdir)
137+
static_dir = os.path.join(srcdir, "_static")
138+
target_dir = os.path.join(srcdir, "nb_{}".format(gallery))
127139
image_dir = os.path.join(target_dir, "_images")
128140
source_dir = os.path.abspath(
129-
os.path.join(os.path.dirname(os.path.dirname(app.builder.srcdir)), "notebooks")
141+
os.path.join(os.path.dirname(os.path.dirname(srcdir)), "notebooks")
130142
)
143+
table_of_contents_file = os.path.join(
144+
source_dir, TABLE_OF_CONTENTS_FILENAME.format(gallery))
145+
tocjs = TableOfContentsJS()
146+
tocjs.load(table_of_contents_file)
131147

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

144160
# Write individual example files
145161
data = {}
146-
for filename in sorted(glob.glob(os.path.join(source_dir, "*.ipynb"))):
162+
for basename in sorted(tocjs.contents):
163+
filename = os.path.join(source_dir, basename + ".ipynb")
147164
ex = NotebookGenerator(filename, target_dir)
148165
data[ex.stripped_name] = {
149166
"title": ex.pagetitle,
150-
"url": os.path.join("/examples", ex.output_html),
167+
"url": os.path.join(os.sep, gallery, ex.output_html),
151168
"thumb": os.path.basename(ex.png_path),
152169
}
153170

154-
js_file = os.path.join(image_dir, "gallery_contents.js")
155-
with open(os.path.join(source_dir, TABLE_OF_CONTENTS_FILENAME), "r") as toc:
171+
js_file = os.path.join(image_dir, "gallery_{}_contents.js".format(gallery))
172+
with open(table_of_contents_file, "r") as toc:
156173
table_of_contents = toc.read()
157174

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

165182
with open(os.path.join(target_dir, "index.rst"), "w") as index:
166-
index.write(INDEX_TEMPLATE.format(sphinx_tag="notebook_gallery"))
183+
index.write(INDEX_TEMPLATE.format(
184+
sphinx_tag="notebook_gallery",
185+
gallery=gallery,
186+
Gallery=gallery.title().rstrip("s")
187+
))
167188

168189
os.chdir(working_dir)
169190

170191

192+
def main(app):
193+
for gallery in ("tutorials", "examples"):
194+
build_gallery(app.builder.srcdir, gallery)
195+
196+
171197
def setup(app):
172198
app.connect("builder-inited", main)

0 commit comments

Comments
 (0)