Skip to content

Conversation

AoifeHughes
Copy link
Contributor

@AoifeHughes AoifeHughes commented Sep 29, 2025

This was to try and fix #642 as I was afraid of a caching issue, please see that PR for previous discussions

Aoife and others added 29 commits September 18, 2025 13:31
@AoifeHughes AoifeHughes self-assigned this Sep 29, 2025
Copy link
Contributor

Preview the changes: https://turinglang.org/docs/pr-previews/652
Please avoid using the search feature and navigation bar in PR previews!

@AoifeHughes AoifeHughes marked this pull request as ready for review October 1, 2025 08:25
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds notebook generation and download functionality to the documentation site by creating Jupyter notebooks from Quarto .qmd files and providing download links in the rendered HTML pages.

  • Introduces a Python script to convert .qmd files to .ipynb format with proper cell structure
  • Adds shell scripts to generate notebooks and inject download links into HTML pages
  • Integrates notebook generation into both publish and preview GitHub workflows

Reviewed Changes

Copilot reviewed 5 out of 7 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
assets/scripts/qmd_to_ipynb.py Python converter that parses .qmd files and creates Jupyter notebooks with appropriate cell types
assets/scripts/generate_notebooks.sh Shell script that finds .qmd files and converts them to notebooks in the _site directory
assets/scripts/add_notebook_links.sh Shell script that adds download links to HTML pages using Perl regex replacement
.github/workflows/publish.yml Adds notebook generation and link injection steps to the publish workflow
.github/workflows/preview.yml Adds notebook generation and link injection steps to the preview workflow

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Comment on lines 136 to 138
"display_name": "Julia 1.11",
"language": "julia",
"name": self.kernel_name
Copy link
Preview

Copilot AI Oct 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The hardcoded display name 'Julia 1.11' doesn't match the dynamic kernel name when using Python. Consider making the display name dynamic based on the kernel.

Copilot uses AI. Check for mistakes.

Comment on lines 140 to 145
"language_info": {
"file_extension": ".jl",
"mimetype": "application/julia",
"name": "julia",
"version": "1.11.0"
}
Copy link
Preview

Copilot AI Oct 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The language_info is hardcoded for Julia even when the kernel is Python. This should be conditional based on the detected engine/kernel type.

Copilot uses AI. Check for mistakes.

echo "Generating Jupyter notebooks from .qmd files..."

# Find all .qmd files in tutorials, usage, and developers directories
find tutorials usage developers -name "index.qmd" | while read qmd_file; do
Copy link
Preview

Copilot AI Oct 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using 'while read' with 'find' can fail with filenames containing spaces or special characters. Use 'find ... -print0 | while IFS= read -r -d "" qmd_file; do' for safer file handling.

Suggested change
find tutorials usage developers -name "index.qmd" | while read qmd_file; do
find tutorials usage developers -name "index.qmd" -print0 | while IFS= read -r -d '' qmd_file; do

Copilot uses AI. Check for mistakes.

@AoifeHughes
Copy link
Contributor Author

Screenshot 2025-10-01 at 09 26 20

This PR adds a download button to get jupyter notebooks from the docs.

Some notes:

  • quarto doesn't like either using convert or the _quarto.yml config options to make notebooks as well as html
  • To avoid running each file 2x in the deployment I created a few scripts, the main of which is https://github.com/TuringLang/docs/pull/652/files#diff-fa790f7c53fe8322e42e5baf383fa2350e43f4f279c3ee25e4aeac1d4680f3a4 which handles the conversion and builds the notebooks
  • The CI has been updated to perform this
  • I would have much rather used quarto's built in solutions, but they're just not fit for purpose in this instance (please see the dozens of commits in which I tried every solution I could find before raising them as possible solutions @mhauru can attest to the numerous attempts I made in the last week).

@shravanngoswamii if you'd have some time to check these out, I'd appreciate it.

@AoifeHughes
Copy link
Contributor Author

I should also mention, I had a few issues with the CI versions of bash/posix vs deploying on my mac, so some of the scripting is done to appease github actions moreso than how users may run locally.

@AoifeHughes
Copy link
Contributor Author

I think this partially satisfies some of the points from #641 ~ it might be worth adding some note about these being available in the docs / have a quick way to export into online systems, as discussed in that issue.

def __init__(self, qmd_path: str):
self.qmd_path = Path(qmd_path)
self.cells: List[Dict[str, Any]] = []
self.kernel_name = "julia-1.11" # Default kernel
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generated notebooks don't work in Google Colab, or am I doing something wrong? I think the defined kernel might be the issue since Colab only supports the lts version of Julia by default. Also, we'll need to change this hardcoded version every time we update the docs to a new version. Maybe we should add a note in the README or change it to use the version from an env file or some variable that we can use everywhere.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think latest push should fix this. Lemme verify and confirm once it builds

@shravanngoswamii
Copy link
Member

Notebooks work fine with IJulia

Copy link
Member

@penelopeysm penelopeysm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall thoughts:

  1. Looks very nice! I like the little icon and it fits in thematically with the rest of the website very nicely.

  2. When you download the notebook, the first line is using Pkg; Pkg.instantiate(). I attempted to run this in a VSCode and this loads the global Julia environment. So if you subsequently run using Turing that will also add Turing to the global environment, which is probably not ideal for users.

Is it possible to modify the notebook generation such that the very top of the notebook contains a new code block saying using Pkg; Pkg.activate(; temp=true), before the call to instantiate()?

@AoifeHughes
Copy link
Contributor Author

Overall thoughts:

  1. Looks very nice! I like the little icon and it fits in thematically with the rest of the website very nicely.
  2. When you download the notebook, the first line is using Pkg; Pkg.instantiate(). I attempted to run this in a VSCode and this loads the global Julia environment. So if you subsequently run using Turing that will also add Turing to the global environment, which is probably not ideal for users.

Is it possible to modify the notebook generation such that the very top of the notebook contains a new code block saying using Pkg; Pkg.activate(; temp=true), before the call to instantiate()?

Yes! I'll need to modify the new file added assets/scripts/qmd_to_ipynb.py but that should be straight-forward. I'm also still pondering some of the other things about making it run in collab, so will make changes for that at the same time.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My main other question is: if the qmd-to-ipynb script is already in Python, why not write the Bash scripts in Python as well?

I don't mind the use of Python (it's way better for quick scripts than Julia is), but I think reducing the number of moving parts that need to work together will make for easier maintenance in the future. Especially because all of these scripts serve a common purpose and you're unlikely to want to run one without running the others.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eh, personally I find any bash stuff gets harder to read the more complex it gets, I can do that though, not a problem. Let me do the current changes and verify it works then I can explore this fully.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh yes bash is definitely hard to read but I meant moving the bash to python - not the other way round!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

aha, gotchu. tbh, I originally wrote the bash as a quick fix with the CI, it was only because the default convert didn't work that I did the python too.

Comment on lines 17 to 21
if ! grep -q 'Download notebook' "$html_file"; then
# Insert the notebook link AFTER the "Report an issue" link
# This ensures it goes in the right place in the sidebar toc-actions
# The download="index.ipynb" attribute forces browser to download instead of navigate
perl -i -pe 's/(<a href="[^"]*issues\/new"[^>]*><i class="bi[^"]*"><\/i>Report an issue<\/a><\/li>)/$1<li><a href="index.ipynb" class="toc-action" download="index.ipynb"><i class="bi bi-journal-code"><\/i>Download notebook<\/a><\/li>/g' "$html_file"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you make the string 'Download notebook' a variable?

@penelopeysm
Copy link
Member

Overall very excited about this, very happy that I clicked the download link and it just worked (tm) :)

@yebai
Copy link
Member

yebai commented Oct 6, 2025

Looks good -- it is very helpful to add an "Open in Colab" button too. URLs like

https://colab.research.google.com/github/TuringLang/docs/blob/gh-pages/pr-previews/652/usage/automatic-differentiation/index.ipynb

will automatically open a notebook from the given Github repo.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants