Skip to content

Commit

Permalink
Merge pull request #207 from rum1887/qutip-qip-tuts
Browse files Browse the repository at this point in the history
Automatically generating the tutorial list
  • Loading branch information
BoxiLi committed Jun 16, 2023
2 parents d6d1649 + 1c88c1a commit ecece1a
Show file tree
Hide file tree
Showing 8 changed files with 193 additions and 13 deletions.
5 changes: 5 additions & 0 deletions .github/workflows/build_documentation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ jobs:
name: Install Python
with:
python-version: '3.8'

- name: Install Pandoc
run: |
sudo apt update
sudo apt install -y pandoc
- name: Install documentation dependencies
run: |
Expand Down
8 changes: 8 additions & 0 deletions doc/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,11 @@ help:
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

create_tutorials:
python3 source/tutorials-website/create_tutorials_html.py

#Modify the html target to include create_tutorials as a prerequisite
html: create_tutorials
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

2 changes: 1 addition & 1 deletion doc/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ docutils==0.17.1
sphinxcontrib-bibtex==2.4.2
pyqir-generator==0.6.2
pyqir-parser==0.6.2
qiskit==0.37.2
qiskit==0.37.2
4 changes: 3 additions & 1 deletion doc/source/contribution-docs.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Contributing to the documentation
The user guide provides an overview of the package's functionality.
The guide is composed of individual reStructuredText (**.rst**)
files which each get rendered as a webpage.
Each page typically tackles one area of functionality.
Each page typically tackles one area of functionality. A few **.rst** files are generated runtime from **html** files using the `Pandoc <https://pandoc.org>`_ tool.
To learn more about how to write **.rst** files,
it is useful to follow the `sphinx guide <https://www.sphinx-doc.org/en/master/usage/index.html>`_.

Expand All @@ -32,6 +32,8 @@ To build and test the documentation, the following packages are required:
sphinx numpydoc sphinx_rtd_theme doctest
The generation of documentation also requires Pandoc. Follow this `link <https://pandoc.org/installing.html>`_ to install Pandoc for your operating system.

Under the ``doc`` directory, use

.. code-block:: bash
Expand Down
2 changes: 1 addition & 1 deletion doc/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ qutip-qip |version|: QuTiP quantum information processing
:maxdepth: 2
:caption: Tutorials

tutorials.rst
tutorials_v5.rst

.. toctree::
:maxdepth: 2
Expand Down
136 changes: 136 additions & 0 deletions doc/source/tutorials-website/create_tutorials_html.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
#Adapted from https://github.com/qutip/qutip-tutorials/blob/1d1da2fc623372fa11ad5370a4fcd19452aad8fa/website/create_index.py

import os
import re
from jinja2 import Environment, FileSystemLoader, select_autoescape
import shutil
import subprocess
import tempfile

def atoi(text):
return int(text) if text.isdigit() else text

def natural_keys(text):
return [atoi(c) for c in re.split('(\d+)', text)]

class notebook:
def __init__(self, path, title):
# remove ../ from path
self.path = path.replace('../', '')
self.title = title
# set url and update from markdown to ipynb
self.url = url_prefix + self.path.replace(".md", ".ipynb")
self.url=self.url.replace(cloned_repo_dir,"")

def get_title(filename):
""" Reads the title from a markdown notebook """
with open(filename, 'r') as f:
# get first row that starts with "# "
for line in f.readlines():
# trim leading/trailing whitespaces
line = line.lstrip().rstrip()
# check if line is the title
if line[0:2] == '# ':
# return title
return line[2:]

def sort_files_titles(files, titles):
""" Sorts the files and titles either by filenames or titles """
# identify numbered files and sort them
nfiles = [s for s in files if s.split('/')[-1][0].isdigit()]
nfiles = sorted(nfiles, key=natural_keys)
ntitles = [titles[files.index(s)] for s in nfiles]
# sort the files without numbering by the alphabetic order of the titles
atitles = [titles[files.index(s)] for s in files if s not in nfiles]
atitles = sorted(atitles, key=natural_keys)
afiles = [files[titles.index(s)] for s in atitles]
# merge the numbered and unnumbered sorting
return nfiles + afiles, ntitles + atitles

def get_notebooks(path):
""" Gets a list of all notebooks in a directory """
# get list of files and their titles
try:
files = [os.path.join(path, f) for f in os.listdir(path) if f.endswith('.md')]
except FileNotFoundError:
return {}
titles = [get_title(f) for f in files]
# sort the files and titles for display
files_sorted, titles_sorted = sort_files_titles(files, titles)
# generate notebook objects from the sorted lists and return
notebooks = [notebook(f, t) for f, t in zip(files_sorted, titles_sorted)]
return notebooks

def generate_index_html(version_directory, tutorial_directories, title, version_note):
""" Generates the index HTML file from the given data """
# get tutorials from the different directories
tutorials = {}
for dir in tutorial_directories:
tutorials[dir] = get_notebooks(os.path.join(version_directory, dir))

# Load environment for Jinja and template
env = Environment(
loader=FileSystemLoader(os.path.join(os.path.dirname(__file__), "../")),
autoescape=select_autoescape()
)
template = env.get_template("tutorials-website/tutorials.html.jinja")

# render template and return
html = template.render(tutorials=tutorials, title=title, version_note=version_note)
return html

# Clone the qutip-tutorials repository
repo_url = 'https://github.com/qutip/qutip-tutorials.git'
cloned_repo_dir = tempfile.mkdtemp()
subprocess.run(['git', 'clone', repo_url, cloned_repo_dir])

# Set the necessary variables
url_prefix = "https://nbviewer.org/urls/qutip.org/qutip-tutorials"
tutorial_directories = [
'pulse-level-circuit-simulation',
'quantum-circuits',
]

# Perform the operations on the cloned repository
prefix = ""
suffix = ""
#with open('prefix.html', 'r') as f:
# prefix = f.read()
#with open('suffix.html', 'r') as f:
# suffix = f.read()

# Version 4 index file
title = 'Tutorials for QuTiP Version 4'
version_note = 'These are the tutorials for QuTiP Version 4. You can find the tutorials for QuTiP Version 5 <a href="./index-v5.html">here</a>.'
html = generate_index_html(os.path.join(cloned_repo_dir, 'tutorials-v4/'), tutorial_directories, title, version_note)
with open('source/tutorials-website/qutip-qip.html', 'w+') as f:
#f.write(prefix)
f.write(html)
#f.write(suffix)

# Version 5 index file
title = 'Tutorials for QuTiP Version 5'
version_note = 'These are the tutorials for QuTiP Version 5. You can find the tutorials for QuTiP Version 4 <a href="./index.html">here</a>.'
html = generate_index_html(os.path.join(cloned_repo_dir, 'tutorials-v5/'), tutorial_directories, title, version_note)
with open('source/tutorials-website/qutip-qip-v5.html', 'w+') as f:
#f.write(prefix)
f.write(html)
#f.write(suffix)

# Wipe off the cloned repository
shutil.rmtree(cloned_repo_dir)

def convert_html_to_rst(html_file_path, rst_file_path):
# Use the subprocess module to call the pandoc command-line tool
subprocess.run(['pandoc', html_file_path, '-o', rst_file_path])

html_file_path = 'source/tutorials-website/qutip-qip.html'
html_file_path_v5 = 'source/tutorials-website/qutip-qip-v5.html'

rst_file_path = 'source/tutorials.rst'
rst_file_path_v5 = 'source/tutorials_v5.rst'

#convert_html_to_rst(html_file_path, rst_file_path)
convert_html_to_rst(html_file_path_v5, rst_file_path_v5)


39 changes: 39 additions & 0 deletions doc/source/tutorials-website/tutorials.html.jinja
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<div class="row">
<div class="col-md-12">
<h1>{{ title }}</h1><br>
</div>
</div>

<h4 id="quantum-information-processing">Quantum information processing</h4>
<p>This section contains tutorials for QuTiP Version 5. You can find the tutorials for QuTiP Version 4 <a href="https://qutip.org/qutip-tutorials/">here</a>. To check the version of QuTiP, you can use the <code>qutip.about()</code> command.</p>

<h5 id="qip-circuits">Quantum circuits and algorithms</h5>
<ul>
{% for item in tutorials['quantum-circuits'] %}
<li><a href="{{ item.url }}">{{ item.title }}</a></li>
{% endfor %}
</ul>


<h5 id="qip-pulse-level">Pulse-level circuit simulation</h5>
<ul>
{% for item in tutorials['pulse-level-circuit-simulation'] %}
<li><a href="{{ item.url }}">{{ item.title }}</a></li>
{% endfor %}
</ul>

<div class="row">
<div class="col-md-12">
<h3 id="contributing">Contributing</h3>
<p>If you would like to contribute a notebook or report a bug, you may open
an issue or pull request in the
<a href="https://github.com/qutip/qutip-tutorials">qutip-tutorials</a>
GitHub repository.
</p>
<p>A few of the notebooks are still maintained in the repository
<a href="https://github.com/qutip/qutip-notebooks">qutip-notebooks</a> and
a complete archive of older versions of the tutorials is maintained there.
</p>

</div>
</div>
10 changes: 0 additions & 10 deletions doc/source/tutorials.rst

This file was deleted.

0 comments on commit ecece1a

Please sign in to comment.