quarto

Install and interact with Quarto from nbdev

Helpful background on how Quarto fits in here: https://nbdev.fast.ai/explanations/docs.html

Install


source

install_quarto

def install_quarto():

Install latest Quarto on macOS or Linux, prints instructions for Windows


source

install

def install():

Install Quarto and the current library

Render docs


source

refresh_quarto_yml

def refresh_quarto_yml():

Generate _quarto.yml from pyproject.toml.


source

nbdev_proc_nbs

def nbdev_proc_nbs(
    *, path:str='', # Path to notebooks
    n_workers:int=4, # Number of workers
    force:bool=False, # Ignore cache and build all
    file_glob:str='', # Only process notebooks matching glob (other files are always included)
    file_re:str='', # Only process notebooks matching regex (other files are always included)
    symlinks:bool=False, # Follow symlinks?
    path_glob:str=None, # Only include files whose full paths match glob (wildcards match separators)
    path_re:str=None, # Only include files whose full paths match regex
    folder_re:str=None, # Only enter folders matching regex
    skip_file_glob:str=None, # Skip files matching glob
    skip_file_re:str='^[_.]', # Skip files matching regex
    skip_folder_re:str='^[_.]', # Skip folders matching regex
):

Process notebooks in path for docs rendering


source

nbdev_readme

def nbdev_readme(
    path:str=None, # Path to notebooks (or project root)
    chk_time:bool=False, # Only build if out of date
):

Create README.md from readme_nb (index.ipynb by default). Skips if the file doesn’t exist.

nbdev-readme calls “quarto render,” which is explained in the Quarto guide here.

Pandoc’s gfm writer hard-wraps prose at 72 columns by default; -M wrap:preserve keeps each paragraph’s line breaks exactly as authored in the notebook instead.

Only the readme notebook itself is processed (plus non-notebook assets like images), so building the README never executes code from the project’s other notebooks; and if the readme notebook doesn’t exist, the command just returns.


source

nbdev_contributing

def nbdev_contributing(
    path:str=None, # Path to notebooks
    chk_time:bool=False, # Only build if out-of-date
):

Create CONTRIBUTING.md from contributing_nb (defaults to ‘contributing.ipynb’ if present). Skips if the file doesn’t exist.

Quarto’s quarto-nav.js rewrites /index.html links to / for clean URLs, but the regex is unanchored, so on a site’s index page it also mangles the “Other Formats” CommonMark link: index.html.md becomes .md (quarto-dev/quarto-cli#14667). _fix_quarto_nav anchors the regex in the rendered site’s copy of the script. Once quarto fixes it upstream, the pattern no longer matches and this becomes a no-op.

with tempfile.TemporaryDirectory() as d:
    nav = Path(d)/'site_libs/quarto-nav/quarto-nav.js'
    nav.parent.mkdir(parents=True)
    nav.write_text(r'x.replace(/\/index\.html/, "/");')
    _fix_quarto_nav(d)
    test_eq(nav.read_text(), r'x.replace(/\/index\.html(?=[?#]|$)/, "/");')
    _fix_quarto_nav(d)   # idempotent, and a no-op once quarto fixes the regex upstream
    test_eq(nav.read_text(), r'x.replace(/\/index\.html(?=[?#]|$)/, "/");')

source

nbdev_docs

def nbdev_docs(
    path:str=None, # Path to notebooks
    n_workers:int=4, # Preprocessing and Quarto workers (0 or 1: serial)
):

Create Quarto docs

nbdev-docs renders website pages in parallel. --n-workers defaults to the CPU count; use --n-workers 1 for serial rendering. Each worker renders a batch in its own project copy. The combined site retains page assets, navigation, search and sitemap entries. Books, Quarto-generated llms.txt, and projects with pre/post-render hooks use a single Quarto process.

The renderer lives in the hand-written nbdev/quarto_render.py. Its integration test uses real Quarto to compare serial and parallel sites and check incremental updates.

nbdev-docs builds only the website. It never regenerates README.md or CONTRIBUTING.md. Rendering the readme notebook again, as GitHub Markdown, would leave the site’s homepage without its HTML figures. nbdev-prepare, nbdev-readme and nbdev-contributing regenerate those files.


source

prepare

def prepare():

Export, test, and clean notebooks, and render README if needed

Preview

nbdev-preview keeps its own copy of the site in the _proc cache, rendering new or changed pages on startup and as you edit; it doesn’t change doc_path. When the cache has no site it starts from a copy of the one in doc_path, so unchanged pages from the last nbdev-docs run aren’t rendered again. With neither, it builds all pages in parallel using the same --n-workers setting as nbdev-docs. Use nbdev-preview --render to rebuild everything, including changes to shared configuration or filters.


source

fs_watchdog

def fs_watchdog(
    func, path, recursive:bool=True
):

File system watchdog dispatching to func


source

nbdev_preview

def nbdev_preview(
    path:str=None, # Path to notebooks
    port:int=None, # The port on which to run preview
    host:str=None, # The host on which to run preview
    no_browser:bool=False, # Do not open a browser
    render:bool=False, # Render all pages before previewing
    n_workers:int=4, # Preprocessing and Quarto workers (0 or 1: serial)
):

Preview docs locally