Skip to content

fix: backtick-stripping regex in nb2md()#268

Merged
danielfrg merged 6 commits intodanielfrg:mainfrom
gialmisi:main
Mar 5, 2026
Merged

fix: backtick-stripping regex in nb2md()#268
danielfrg merged 6 commits intodanielfrg:mainfrom
gialmisi:main

Conversation

@gialmisi
Copy link
Copy Markdown
Contributor

@gialmisi gialmisi commented Mar 5, 2026

This fix addresses a problem with generating table of contents based on notebook files that have backtick (`) heavy content. I noticed that some of the notebooks we convert in our documentation just mysteriously drop sections suddenly in the generated ToC. The tests in test_toc.py are all still passing.

Here is a minimal example of the issue this PR addressed:

## Section A                                                                                                                                                   
                                                      
Here is some text with `code`.                                                                                                                                 
                                                                                                                                                               
## Section B                                        

A table or code output might produce a lone backtick: `

## Section C

More text with `inline code` here.

## Section D

Final section.

Old regex:

  • The lone backtick at the end of Section B has no closing backtick on its line.
  • [.\s\S]*? matches across newlines, scanning forward until it finds the next backtick, which is in Section C...
  • This swallows \n\n## Section C\n\nMore text with , destroying the Section C heading.
  • ToC loses "Section C" entirely.

New regex:

  • [^\n]*` cannot cross newlines, all sections are included.
  • Should handle single backtick blocks with #include as well (noticed this while testing after the fix in the first commit).

Notebook conversion (nb2html + nb2md for TOC) runs on every build,
even when notebooks haven't changed. This adds a SHA-256 content+config
cache that skips conversion entirely on cache hit.

New plugin config options:
- cache (bool, default: True): enable/disable caching
- cache_dir (str, default: ".cache/mkdocs-jupyter"): cache location

The cache key incorporates the notebook file content and all config
options that affect output (execute, kernel_name, theme, show_input,
no_input, remove_tag_config, highlight_extra_classes, include_requirejs,
custom_mathjax_url, toc_depth). Changing any of these invalidates the
cache for that notebook, which triggers a rebuild.

Refactors get_nb_toc() to extract _get_nb_toc_tokens() so raw TOC
tokens can be serialized to the cache without a redundant nb2md() call.

Adds 9 tests: unit tests for cache key determinism and invalidation,
and integration tests verifying cache population, cache hit (nb2html
not called on second build), and cache-disabled behavior.

Closes danielfrg#161
- Add allow_errors to cache key config options
- Hash resolved exec_nb value instead of config["execute"] so
  notebooks matching execute_ignore get a distinct cache key
- Use repr() for config values in cache key for deterministic
  hashing of dicts
- Add stale cache eviction via on_post_build: tracks used cache
  paths during build and removes orphaned .json files
- Add tests for execute_ignore key sensitivity and stale eviction
- Fixes truncated Table of Contents for notebooks with inline code in
  markdown cells
- The regex `[.\s\S]*?` in backquote_text_regex matches any character
  including newlines, causing it to span across lines and destroy
  markdown headings used for TOC generation
- Replace with `[^`\n]*` to restrict matching to single lines
- The previously committed backtick fix was stripping #include which
  resulted in failing tests. Fixed.
@danielfrg danielfrg merged commit 136080e into danielfrg:main Mar 5, 2026
6 of 8 checks passed
@danielfrg
Copy link
Copy Markdown
Owner

ty!

@github-actions
Copy link
Copy Markdown

github-actions bot commented Mar 5, 2026

Preview deployment

Name Link
Deploy Preview Url https://fb97b1e9.mkdocs-jupyter-danielfrg-com.pages.dev
Latest deploy log https://github.com/danielfrg/mkdocs-jupyter/actions/runs/22724406648
Latest commit 136080e
Environment production

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.

2 participants