1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586 |
- """Utility functions for Jupyter Book.
- This is a mini-module to make testing easier."""
- import string
- import nbformat as nbf
- import os
- ALLOWED_CHARACTERS = string.ascii_letters + '-_/.' + string.digits
- def _split_yaml(lines):
- yaml0 = None
- for ii, iline in enumerate(lines):
- iline = iline.strip()
- if yaml0 is None:
- if iline == '---':
- yaml0 = ii
- elif iline:
- break
- elif iline == '---':
- return lines[yaml0 + 1:ii], lines[ii + 1:]
- return [], lines
- def _check_url_page(url_page, content_folder_name):
- """Check that the page URL matches certain conditions."""
- if not all(ii in ALLOWED_CHARACTERS for ii in url_page):
- raise ValueError("Found unsupported character in filename: {}".format(url_page))
- if '.' in os.path.splitext(url_page)[-1]:
- raise _error("A toc.yml entry links to a file directly. You should strip the file suffix.\n"
- "Please change {} to {}".format(url_page, os.path.splitext(url_page)[0]))
- if any(url_page.startswith(ii) for ii in [content_folder_name, os.sep+content_folder_name]):
- raise ValueError("It looks like you have a page URL that starts with your content folder's name."
- "page URLs should be *relative* to the content folder. Here is the page URL: {}".format(url_page))
-
- def _prepare_toc(toc):
- """Prepare the TOC for processing."""
- # Drop toc items w/o links
- toc = [ii for ii in toc if ii.get('url', None) is not None]
- # Un-nest the TOC so it's a flat list
- new_toc = []
- for ii in toc:
- sections = ii.pop('sections', None)
- new_toc.append(ii)
- if sections is None:
- continue
- for jj in sections:
- subsections = jj.pop('subsections', None)
- new_toc.append(jj)
- if subsections is None:
- continue
- for kk in subsections:
- new_toc.append(kk)
- return new_toc
- def _prepare_url(url):
- """Prep the formatting for a url."""
- # Strip suffixes and prefixes of the URL
- if not url.startswith('/'):
- url = '/' + url
- # Standardize the quotes character
- url = url.replace('"', "'")
- return url
- def _clean_notebook_cells(path_ntbk):
- """Clean up cell text of an nbformat NotebookNode."""
- ntbk = nbf.read(path_ntbk, nbf.NO_CONVERT)
- # Remove '#' from the end of markdown headers
- for cell in ntbk.cells:
- if cell.cell_type == "markdown":
- cell_lines = cell.source.split('\n')
- for ii, line in enumerate(cell_lines):
- if line.startswith('#'):
- cell_lines[ii] = line.rstrip('#').rstrip()
- cell.source = '\n'.join(cell_lines)
- nbf.write(ntbk, path_ntbk)
- def _error(msg):
- msg = '\n\n==========\n{}\n==========\n'.format(msg)
- raise ValueError(msg)
|