Question: I am documenting a python library with Sphinx. I have a couple of example scripts which I'd like to document in a narrative way, something like this: #: Import necessary package and define :meth:`make_grid` import numpy as np def make_grid(a,b): """ Make a grid for constant by piece functions """ x = np.linspace(0,np.pi) xmid = (x[:-1]+x[1:])/2 h = x[1:]-x[:-1] return xmid,h #: Interpolate a function xmid,h = make_grid(0,np.pi) y = np.sin(xmid) #: Calculate its integral I = np.sum(y*h) print ("Result %g" % I )  Those scripts should remain present as executable scripts in the repository, and I want to avoid duplicating their code into comments. I would like to generate the corresponding documentation, something like :  Is there any automated way to do so? This would allow me not to duplicate the example script in the documentation. It seems to me this was the object of this old question but in my hands viewcode extension doesn't interpret comments, it just produces an html page with quoted code, comments remain comments.

Answer: Take a look at the sphinx-gallery extension, which seems to do what you require. With this extension, if you have a Python script, you must start it with a header docstring, and then you can add comments that will be formatted as text rather than code using the # %% syntax, e.g., """ My example script. """ import numpy as np # %% # This will be a text block x = np.linspace(0, 10, 100) y = np.sin(2 * np.pi * x) # %% # Another block of text  More details of the syntax is described here, and various examples are, e.g., here. Alternative option If the sphinx-gallery option is not appropriate (i.e., you don't really want a thumbnail-style gallery page linking to the examples), you could instead make use of the nbsphinx extension and the jupytext package. You can write your example Python scripts in jupytext's percent format, and then generate the pages via an intermediate conversion to a Jupyter notebook. For example (after installing both nbsphinx and jupytext), if you had a package structure like: . ├── docs │ ├── Makefile │ ├── conf.py │ ├── examples -> ../src/examples/ │ ├── index.rst │ └── make.bat └── src └── examples └── narrative.py  where in this case I've symbolic linked the src/examples directory into the docs directory, you could edit your Sphinx conf.py file to contain:  # add nbsphinx to extensions extensions = [ ... "nbsphinx", ] # this converts .py files with the percent format to notebooks nbsphinx_custom_formats = { '.py': ['jupytext.reads', {'fmt': 'py:percent'}], } nbsphinx_output_prompt = "" nbsphinx_execute = "auto" templates_path = ['_templates'] # add conf.py to exclude_patterns exclude_patterns = [..., 'conf.py']  and have narrative.py looking like: # %% [markdown] # # A title # %% [raw] raw_mimetype="text/restructuredtext" # Import necessary package and define :meth:`make_grid` # %% import numpy as np def make_grid(a,b): """ Make a grid for constant by piece functions """ x = np.linspace(0,np.pi) xmid = (x[:-1]+x[1:])/2 h = x[1:]-x[:-1] return xmid,h # %% [markdown] # Interpolate a function # %% xmid,h = make_grid(0,np.pi) y = np.sin(xmid) # %% [markdown] # Calculate its integral # %% I = np.sum(y*h) print ("Result %g" % I )  then running make html should produce a narrative.html file like:  which you can link to from index.rst etc. Some things to note about the narrative.py file:  the start of the .py file has to contain a "Title" cell, which in this case, as I've set it as a Markdown cell, contains (after the initial comment string #) # A Title using the Markdown header syntax of #. If you don't have a title you won't be able to link to the output from other documents, e.g., index.rst; for most of the text cells, I have marked them as [markdown] format, i.e., they will be interpreted as containing Markdown syntax; for the cell containing restructured text, I have marked it as a [raw] cell with the meta data raw_mimetype="text/restructuredtext"; the input code cells will display with an input prompt by default [1]: etc. Turning off the input prompts requires using Custom CSS.