Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -552,9 +552,10 @@ jobs:
run: |
set -x
cd docs
curl -O https://gist.githubusercontent.com/ritchie46/cac6b337ea52281aa23c049250a4ff03/raw/89a957ff3919d90e6ef2d34235e6bf22304f3366/pokemon.csv
curl -O https://d37ci6vzurychx.cloudfront.net/trip-data/yellow_tripdata_2021-01.parquet
uv run --no-project make html
# build.sh downloads the example data, registers the Jupyter kernel
# myst-nb needs, symlinks the data next to each executed page, and
# runs sphinx. Using it here keeps CI identical to a local build.
uv run --no-project bash ./build.sh

- name: Copy & push the generated HTML
if: github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref_type == 'tag')
Expand Down
4 changes: 2 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,9 @@ Every Python function must include a docstring with usage examples.
When adding or updating an aggregate or window function, ensure the corresponding
site documentation is kept in sync:

- **Aggregations**: `docs/source/user-guide/common-operations/aggregations.rst` —
- **Aggregations**: `docs/source/user-guide/common-operations/aggregations.md` —
add new aggregate functions to the "Aggregate Functions" list and include usage
examples if appropriate.
- **Window functions**: `docs/source/user-guide/common-operations/windows.rst` —
- **Window functions**: `docs/source/user-guide/common-operations/windows.md` —
add new window functions to the "Available Functions" list and include usage
examples if appropriate.
15 changes: 15 additions & 0 deletions docs/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,21 @@ rm -rf build 2> /dev/null
rm -rf temp 2> /dev/null
mkdir temp
cp -rf source/* temp/

# myst-nb executes each page as a notebook from the directory that page
# lives in, so the example data files must sit alongside every page that
# loads them by relative name (e.g. `ctx.read_csv("pokemon.csv")`). Symlink
# them into each directory that has such a page rather than copying the
# 20 MB parquet repeatedly.
for d in temp temp/user-guide temp/user-guide/common-operations; do
ln -sf "$script_dir/pokemon.csv" "$d/pokemon.csv"
ln -sf "$script_dir/yellow_tripdata_2021-01.parquet" "$d/yellow_tripdata_2021-01.parquet"
done

# myst-nb runs `{code-cell}` blocks against a Jupyter kernel named "python3".
# Register the active environment's interpreter as that kernel (idempotent).
python -m ipykernel install --sys-prefix --name python3 --display-name "Python 3"

make SOURCEDIR=`pwd`/temp html

cd "$original_dir" || exit
31 changes: 31 additions & 0 deletions docs/source/_static/images/original_dark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
45 changes: 45 additions & 0 deletions docs/source/_static/theme_overrides.css
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,48 @@ html[data-theme="dark"] .table tbody tr:nth-of-type(odd) {
white-space: normal !important;
}
}


/* Hideable right-hand "On this page" sidebar.
* toc-toggle.js adds the button and toggles `pst-secondary-hidden` on <body>;
* hiding the sidebar lets the flex article container reclaim the width. */

body.pst-secondary-hidden .bd-sidebar-secondary {
display: none;
}

/* Let the article use the freed space rather than just re-centering. */
body.pst-secondary-hidden .bd-article-container {
max-width: none;
}

/* Floating toggle button, pinned to the top-right under the navbar. */
#pst-secondary-toggle {
position: fixed;
top: 4.5rem;
right: 0.75rem;
z-index: 1020;
display: flex;
align-items: center;
justify-content: center;
width: 2rem;
height: 2rem;
padding: 0;
border: 1px solid var(--pst-color-border, #ccc);
border-radius: 0.25rem;
background-color: var(--pst-color-surface, #fff);
color: var(--pst-color-text-base, #333);
cursor: pointer;
}

#pst-secondary-toggle:hover {
color: rgb(var(--pst-color-link-hover));
}

/* The toggle is only meaningful where the sidebar is shown (wide screens);
* below the theme's lg breakpoint the sidebar is already collapsed away. */
@media (max-width: 959.98px) {
#pst-secondary-toggle {
display: none;
}
}
66 changes: 66 additions & 0 deletions docs/source/_static/toc-toggle.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

/* Adds a button that hides the right-hand "On this page" sidebar so the
* article can use the full page width. The choice is remembered across
* pages via localStorage. */
(function () {
"use strict";
var KEY = "pst-secondary-hidden";

function apply(hidden, btn) {
document.body.classList.toggle("pst-secondary-hidden", hidden);
if (btn) {
btn.setAttribute("aria-pressed", String(hidden));
btn.title = hidden ? "Show page contents" : "Hide page contents";
}
}

document.addEventListener("DOMContentLoaded", function () {
// Only offer the toggle on pages that actually have the sidebar.
if (!document.querySelector(".bd-sidebar-secondary")) {
return;
}

var btn = document.createElement("button");
btn.id = "pst-secondary-toggle";
btn.type = "button";
btn.setAttribute("aria-label", "Toggle page contents sidebar");
btn.innerHTML = '<i class="fa-solid fa-list" aria-hidden="true"></i>';
document.body.appendChild(btn);

btn.addEventListener("click", function () {
var hidden = !document.body.classList.contains("pst-secondary-hidden");
try {
localStorage.setItem(KEY, hidden ? "1" : "0");
} catch (e) {
/* localStorage may be unavailable; toggle still works for this page. */
}
apply(hidden, btn);
});

var stored = null;
try {
stored = localStorage.getItem(KEY);
} catch (e) {
/* ignore */
}
apply(stored === "1", btn);
});
})();
49 changes: 42 additions & 7 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,16 +48,40 @@
extensions = [
"sphinx.ext.mathjax",
"sphinx.ext.napoleon",
"myst_parser",
"IPython.sphinxext.ipython_directive",
# myst_nb is a superset of myst_parser: it provides the MyST markdown
# parser plus executable `{code-cell}` notebook directives. Do NOT also
# list "myst_parser" — myst_nb activates it internally and listing both
# raises an extension conflict.
"myst_nb",
"autoapi.extension",
]

# NOTE: .rst stays alongside .md because sphinx-autoapi generates RST
# under autoapi/ and Sphinx needs the suffix to parse it. The human-
# authored docs are all MyST .md now. ".md" is routed through myst-nb so
# pages carrying jupytext/kernelspec front matter execute their
# `{code-cell}` blocks; pages without that front matter render as plain
# MyST markdown. The ".rst" entry is only for the autoapi build artifacts.
source_suffix = {
".rst": "restructuredtext",
".md": "markdown",
".md": "myst-nb",
}

# Execute notebook code cells at build time and fail the build if any cell
# raises — this replaces the old IPython sphinx directive, whose executed
# examples are now `{code-cell}` blocks. "force" re-executes every build so
# stale cached output can never ship.
nb_execution_mode = "force"
nb_execution_timeout = 120
nb_execution_raise_on_error = True

# Prefer the plain-text repr of a cell's last expression over its rich
# `_repr_html_`. A DataFrame's HTML repr is a self-contained widget (inline
# styles + an injected <script>) built for Jupyter; in the docs theme it
# renders at the wrong width. The text repr is the readable table the old
# IPython directive showed and is stable across datafusion versions.
nb_mime_priority_overrides = [("html", "text/plain", 0)]

# Add any paths that contain templates here, relative to this directory.
templates_path = ["_templates"]

Expand Down Expand Up @@ -120,7 +144,7 @@ def setup(sphinx) -> None:
"show_toc_level": 2,
"logo": {
"image_light": "_static/images/original.svg",
"image_dark": "_static/images/original.svg",
"image_dark": "_static/images/original_dark.svg",
"alt_text": "Apache DataFusion in Python",
},
"navbar_start": ["navbar-logo"],
Expand All @@ -138,7 +162,10 @@ def setup(sphinx) -> None:
"icon": "fa-brands fa-rust",
},
],
"secondary_sidebar_items": [],
# Right-hand "On this page" TOC. A toggle button (added by
# _static/toc-toggle.js) lets the reader hide the whole sidebar and give
# the article full width.
"secondary_sidebar_items": ["page-toc"],
"collapse_navigation": True,
"show_nav_level": 2,
}
Expand All @@ -164,12 +191,20 @@ def setup(sphinx) -> None:

html_css_files = ["theme_overrides.css"]

# Adds a button that hides the right-hand "On this page" sidebar so the
# article can use the full width (see _static/toc-toggle.js).
html_js_files = ["toc-toggle.js"]

html_sidebars = {
"**": ["sidebar-globaltoc.html"],
}

# tell myst_parser to auto-generate anchor links for headers h1, h2, h3
myst_heading_anchors = 3

# enable nice rendering of checkboxes for the task lists
myst_enable_extensions = ["tasklist"]
# MyST extensions:
# - tasklist: GitHub-style `- [x]` checkboxes
# - colon_fence: `:::{directive}` blocks (needed by execution-metrics.md
# after the RST -> MyST conversion)
# - deflist: definition lists (used in a couple of converted pages)
myst_enable_extensions = ["tasklist", "colon_fence", "deflist"]
Loading