Skip to content

Commit 08c0aae

Browse files
committed
Update docs
1 parent 8a42e3c commit 08c0aae

7 files changed

Lines changed: 141 additions & 63 deletions

File tree

‎nbs/api/01_config.ipynb‎

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -558,7 +558,11 @@
558558
"id": "78056483",
559559
"metadata": {},
560560
"source": [
561-
"You can customize nbdev for all your projects by creating a `~/.config/nbdev/config.toml` file (or following the [XDG specification](https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html)). Any `[tool.nbdev]` key can go there, with the project's own setting winning: for example, `jupyter_hooks = false` globally disables nbdev's Jupyter hooks, and `cell_timeout = 60` gives `nbdev-test` a default cell timeout. `nbdev-create-config` also reads `user`, `author`, and `author_email` from it when neither the arguments nor the git remote supply them."
561+
"Set defaults for all projects in `~/.config/nbdev/config.toml`, or its [XDG location](https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html). It accepts any `[tool.nbdev]` key. Project settings override these defaults.\n",
562+
"\n",
563+
"For example, `jupyter_hooks = false` disables the Jupyter hooks by default. `cell_timeout = 60` sets a 60-second default for `nbdev-test`.\n",
564+
"\n",
565+
"`nbdev-create-config` also reads `user`, `author` and `author_email` from this file when arguments and Git don't supply them."
562566
]
563567
},
564568
{
@@ -904,9 +908,11 @@
904908
"id": "f4a02289",
905909
"metadata": {},
906910
"source": [
907-
"An LLM (or person) asking `doc(pkg)` should learn which modules to read next, like a good `llms.txt`. The curation signal is the docstring itself: a module saying more than the default summary plus `Docs:` link has had documentation deliberately written for it, so it's meant to be independently useful. `pkg_mdoc` lists those modules, each with the first paragraph of its docstring, and `update_init_mdoc` writes the result as the package docstring in `__init__.py` (surgically: any code there is preserved). It runs as part of `add_init`, so plain `nbdev-export` keeps it current.\n",
911+
"The package docstring helps readers of `doc(pkg)` choose which modules to read next. `pkg_mdoc` lists modules whose docstrings extend beyond the default summary and `Docs:` link. Each entry uses the module docstring's first paragraph.\n",
908912
"\n",
909-
"Tools understand the same signal: pyskills' `doc()` treats a package with a substantive docstring as curated and elides its mechanical submodule listing, so the generated `Modules:` list is the whole answer rather than being repeated (e.g. `doc('pyskills')` itself)."
913+
"`update_init_mdoc` writes this documentation into `__init__.py` without changing its code. `nbdev-export` runs it through `add_init`.\n",
914+
"\n",
915+
"pyskills' `doc()` uses this package documentation instead of adding its usual submodule listing. For example, see `doc('pyskills')`."
910916
]
911917
},
912918
{
@@ -1004,7 +1010,9 @@
10041010
"id": "a56dfc74",
10051011
"metadata": {},
10061012
"source": [
1007-
"The same parts also make a spec-compliant [llms.txt](https://llmstxt.org): title, `> ` summary, the index-notebook intro, and a `## Modules` section linking each substantive module to its `.html.md` page (taken from the `Docs:` line of its docstring). `update_llms_txt` writes it to the notebooks folder, where Quarto copies it to the site root. A trailing HTML-comment marker identifies the file as generated: a hand-written `llms.txt` (no marker) is never overwritten."
1013+
"`pkg_llms` builds an [llms.txt](https://llmstxt.org) from the same documentation. It includes the title, summary, index-notebook introduction and module list. Module links use the `.html.md` URLs from their docstrings' `Docs:` lines.\n",
1014+
"\n",
1015+
"`update_llms_txt` writes the file to the notebooks folder for Quarto to copy to the site root. It marks generated files with an HTML comment. It never overwrites an existing file without that marker."
10081016
]
10091017
},
10101018
{

‎nbs/api/03_process.ipynb‎

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,9 @@
6060
"id": "cbe57d96",
6161
"metadata": {},
6262
"source": [
63-
"Special comments at the start of a cell provide information to `nbdev` about how to process it. The parsing primitives live in `fastcore.nbio` (the `langs` table, `nb_lang`, `first_code_ln`, and `NbCell`'s `directives` property and `remove_directives` method) and are available here via its re-exports; this module builds the notebook processing pipeline on top of them."
63+
"`NBProcessor` applies processors to notebook cells. Processors can handle every cell or respond to directives at the start of a cell.\n",
64+
"\n",
65+
"Directive parsing comes from `fastcore.nbio`. This module re-exports its `langs`, `nb_lang`, `first_code_ln` and `NbCell`. Cells provide the `directives` property and `remove_directives` method."
6466
]
6567
},
6668
{
@@ -161,7 +163,7 @@
161163
"id": "85874d36",
162164
"metadata": {},
163165
"source": [
164-
"Cell processors can be callables (e.g regular functions), in which case they are called for every cell (set a cell's source to `None` to remove the cell):"
166+
"A callable processor runs on every cell. To remove a cell, set its source to `None`:"
165167
]
166168
},
167169
{
@@ -199,15 +201,15 @@
199201
"id": "a8202589",
200202
"metadata": {},
201203
"source": [
202-
"Directives are put in a cell attribute `directives_` as a dictionary keyed by directive name, with the raw value string as each value (`''` for a bare directive). When a processor method receives a directive, the value is whitespace-split into positional arguments:"
204+
"`NBProcessor` saves each cell's directives in `directives_` before processing. This dictionary maps names to raw string values, with `''` for bare directives. Directive handlers get these values split on whitespace into positional arguments."
203205
]
204206
},
205207
{
206208
"cell_type": "markdown",
207209
"id": "8e160de8",
208210
"metadata": {},
209211
"source": [
210-
"Notebook-level directives can be stored in the notebook metadata, as a dict under an `nbdev` key: they are merged into the first code cell's `directives_`, so notebook-scope directives like `default_exp` need no cell to live in. A directive of the same name anywhere in a cell takes priority."
212+
"Notebook metadata can hold directives under an `nbdev` key. `NBProcessor` adds them to the first code cell's `directives_`. A directive with the same name in any cell takes precedence. For example, `default_exp` can go in notebook metadata without needing a dedicated cell:"
211213
]
212214
},
213215
{
@@ -254,7 +256,7 @@
254256
"id": "315106a7",
255257
"metadata": {},
256258
"source": [
257-
"However, a more convenient way to handle comment directives is to use a *class* as a processor, and include a method in your class with the same name as your directive, surrounded by underscores:"
259+
"To handle directives in a class, name each method after its directive with surrounding underscores:"
258260
]
259261
},
260262
{
@@ -283,7 +285,7 @@
283285
"id": "15c01642",
284286
"metadata": {},
285287
"source": [
286-
"In the case that your processor supports just one comment directive, you can just use a regular function, with the same name as your directive, but with an underscore appended -- here `printme_` is identical to `_PrintExample` above:"
288+
"For a single directive, a function with a trailing underscore works too. This `printme_` function does the same work as `_PrintExample`:"
287289
]
288290
},
289291
{
@@ -344,7 +346,13 @@
344346
"id": "2fb60713",
345347
"metadata": {},
346348
"source": [
347-
"For more complex behavior, inherit from `Processor`, and override one of more of `begin()` (called before any cells are processed), `cell()` (called for each cell), and `end()` (called after all cells are processed). You can also include comment directives (such as the `_printme` example above) in these subclasses. Subclasses will automatically have access to `self.nb`, containing the processed notebook."
349+
"A `Processor` subclass can keep state across cells. It has access to the notebook through `self.nb`. Override these methods as needed:\n",
350+
"\n",
351+
"- `begin()` runs before the cells.\n",
352+
"- `cell()` runs on each cell.\n",
353+
"- `end()` runs after the cells.\n",
354+
"\n",
355+
"Subclasses can also have directive handlers such as `_printme_`."
348356
]
349357
},
350358
{

‎nbs/api/07_merge.ipynb‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@
6767
"id": "85693d12",
6868
"metadata": {},
6969
"source": [
70-
"When working with jupyter notebooks (which are json files behind the scenes) and GitHub, it is very common that a merge conflict (that will add new lines in the notebook source file) will break some notebooks you are working on. This module defines the function `nbdev-fix` to fix those notebooks for you, and attempt to automatically merge standard conflicts. The remaining ones will be delimited by markdown cells like this:"
70+
"Git conflict markers make notebook JSON invalid. `nbdev-fix` creates a notebook you can open in Jupyter. It resolves metadata and output conflicts automatically. For conflicting cell contents, it keeps both versions between Markdown markers:"
7171
]
7272
},
7373
{
@@ -219,7 +219,7 @@
219219
"id": "427424b3",
220220
"metadata": {},
221221
"source": [
222-
"Note that in this example, the second conflict is easily solved: it just concerns the execution count of the second cell and can be solved by choosing either option without really impacting your notebook. This is the kind of conflict we will fix automatically. The first conflict is more complicated as it spans across two cells and there is a cell present in one version, not the other. Such a conflict (and generally the ones where the inputs of the cells change form one version to the other) aren't automatically fixed, but we will return a proper json file where the annotations introduced by git will be placed in markdown cells."
222+
"The second conflict affects an execution count. Either value works, so `nbdev-fix` can resolve it automatically. The first conflict spans two cells, including one missing from the other version. It needs a manual decision. `nbdev-fix` preserves both versions in a valid notebook."
223223
]
224224
},
225225
{
@@ -563,9 +563,9 @@
563563
"id": "dd5e9a07",
564564
"metadata": {},
565565
"source": [
566-
"This begins by optionally backing the notebook `fname` to `fname.bak` in case something goes wrong. Then it parses the broken json, solving conflicts in cells. Every conflict that only involves metadata or outputs of cells will be solved automatically by using the local (`theirs==False`) or the remote (`theirs==True`) branch. Otherwise, or for conflicts involving the inputs of cells, the json will be repaired by including the two version of the conflicted cell(s) with markdown cells indicating the conflicts. You will be able to open the notebook again and search for the conflicts (look for `<<<<<<<`) then fix them as you wish.\n",
566+
"By default, `nbdev-fix` keeps local outputs and metadata. Pass `theirs=True` to use the other branch's values. Conflicting source remains in separate cells. Open the repaired notebook and search for `<<<<<<<` to resolve these conflicts.\n",
567567
"\n",
568-
"A message will be printed indicating whether the notebook was fully merged or if conflicts remain."
568+
"Without `outname`, the command overwrites the input notebook. Set `nobackup=False` to keep a `.ipynb.bak` copy. The completion message says whether any conflicts remain."
569569
]
570570
},
571571
{
@@ -663,9 +663,9 @@
663663
"id": "db41a4b0",
664664
"metadata": {},
665665
"source": [
666-
"This implements a [git merge driver](https://git-scm.com/docs/gitattributes#_defining_a_custom_merge_driver) for notebooks that automatically resolves conflicting metadata and outputs, and splits remaining conflicts as separate cells so that the notebook can be viewed and fixed in Jupyter. The easiest way to install it is by running `nbdev-install-hooks`.\n",
666+
"Run `nbdev-install-hooks` to install the notebook [Git merge driver](https://git-scm.com/docs/gitattributes#_defining_a_custom_merge_driver). It first runs Git's standard merge, then calls `nbdev-fix` if conflicts remain.\n",
667667
"\n",
668-
"This works by first running Git's default merge driver, and then `nbdev-fix` if there are still conflicts. You can set `nbdev-fix`'s `theirs` argument using the `THEIRS` environment variable, for example:\n",
668+
"Set the `THEIRS` environment variable to choose the other branch's outputs and metadata:\n",
669669
"\n",
670670
" THEIRS=True git merge branch"
671671
]

‎nbs/api/11_clean.ipynb‎

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@
6060
"id": "3c669488",
6161
"metadata": {},
6262
"source": [
63-
"To avoid pointless conflicts while working with jupyter notebooks (with different execution counts or cell metadata), it is recommended to clean the notebooks before committing anything (done automatically if you install the git hooks with `nbdev-install-hooks`). The following functions are used to do that. Cleaning also adds cell `id`s if missing (required by nbformat 4.5+)."
63+
"Clean notebooks before committing to remove execution counts and metadata that cause unnecessary merge conflicts. Install the hooks with `nbdev-install-hooks` to clean notebooks automatically. Cleaning also adds missing cell IDs, which nbformat 4.5+ requires."
6464
]
6565
},
6666
{
@@ -237,8 +237,7 @@
237237
"id": "20e64f41",
238238
"metadata": {},
239239
"source": [
240-
"Jupyter adds a trailing <code>\\n</code> to images in cell outputs. Vscode-jupyter does not.\\\n",
241-
"Notebooks should be brought to a common style to avoid unnecessary diffs:"
240+
"Jupyter adds a trailing `\\n` to images in cell outputs. VS Code's Jupyter extension does not. In this PNG example, `clean_nb` removes the newline to avoid editor-dependent diffs:"
242241
]
243242
},
244243
{
@@ -259,7 +258,7 @@
259258
"id": "62dd6b38",
260259
"metadata": {},
261260
"source": [
262-
"The test notebook has metadata in both the main metadata section and contains cell level metadata in the second cell:"
261+
"The test notebook contains notebook metadata and metadata on its second cell:"
263262
]
264263
},
265264
{
@@ -280,7 +279,7 @@
280279
"id": "5261f00d",
281280
"metadata": {},
282281
"source": [
283-
"After cleaning the notebook, all extra metadata is removed, only some keys are allowed by default:"
282+
"`clean_nb` keeps the default allowed metadata keys and removes the others:"
284283
]
285284
},
286285
{
@@ -301,7 +300,7 @@
301300
"id": "5c387f44",
302301
"metadata": {},
303302
"source": [
304-
"`clean_nb` also repairs structural problems by default (via `repair_nb`), so notebooks that Jupyter would reject, such as a markdown cell carrying an `outputs` attr, are fixed on every clean:"
303+
"`clean_nb` calls `repair_nb` by default to fix invalid notebook structure. For example, Markdown cells must not have `outputs` or `execution_count` attributes:"
305304
]
306305
},
307306
{
@@ -367,7 +366,7 @@
367366
"id": "286cb214",
368367
"metadata": {},
369368
"source": [
370-
"Passing `clean_ids=True` removes `id`s from plaintext repr outputs, to avoid notebooks whose contents change on each run since they often lead to git merge conflicts. For example:\n",
369+
"`clean_ids=True` removes object memory addresses from text representations in outputs. These addresses can change between runs and cause unnecessary Git diffs and merge conflicts. For example:\n",
371370
"\n",
372371
"```\n",
373372
"<PIL.PngImagePlugin.PngImageFile image mode=L size=28x28 at 0x7FB4F8979690>\n",
@@ -385,7 +384,7 @@
385384
"id": "89d0a249",
386385
"metadata": {},
387386
"source": [
388-
"*Cell* IDs, on the other hand, are always added if missing"
387+
"`clean_nb` adds missing cell IDs:"
389388
]
390389
},
391390
{
@@ -460,7 +459,7 @@
460459
"source": [
461460
"## Directive migrations\n",
462461
"\n",
463-
"Deliberate, opt-in rewrites for moving to the directive conventions introduced in v3.3: directives can live in cell metadata (an `nbdev` dict key), notebook-scope directives like `default_exp` can live in notebook metadata, and comment spellings have one canonical form. None of these run by default; they're flags on `nbdev-clean` for one-off migration runs, so the git hook never triggers them."
462+
"`nbdev-clean` can rewrite directive comments and move directives into metadata. These migrations require explicit flags. Git hooks never run them."
464463
]
465464
},
466465
{
@@ -504,7 +503,7 @@
504503
"id": "233f7207",
505504
"metadata": {},
506505
"source": [
507-
"`_to_meta` and `_to_comments` move named directives between a cell's comments and its `nbdev` metadata key, preserving values through the same mapping the parser uses (bare directives become `true`, and so on):"
506+
"Move selected directives between comments and cell metadata without changing their meaning:"
508507
]
509508
},
510509
{
@@ -567,7 +566,7 @@
567566
"id": "bb81ec0f",
568567
"metadata": {},
569568
"source": [
570-
"`_canon_dirs` respells each directive line canonically without touching anything else, and `_hoist_nb_meta` moves `default_exp` to notebook metadata, deleting a first cell that held nothing but directives (a bare `#| hide` on an otherwise-empty cell hides nothing). `_dir_moves` bundles the migrations for the CLI, converting the raw loaded dict to `NbCell`s first:"
569+
"`_canon_dirs` rewrites directive comments in canonical form and leaves other source unchanged. `_hoist_nb_meta` moves `default_exp` into notebook metadata. It removes cells left empty by the move, including those containing only `#| hide`:"
571570
]
572571
},
573572
{
@@ -644,8 +643,13 @@
644643
"source": [
645644
"By default (`fname` left to `None`), all the notebooks in `config.nbs_path` are cleaned. You can opt in to fully clean the notebook by removing every bit of metadata and the cell outputs by passing `clear_all=True`.\n",
646645
"\n",
647-
"If you want to keep some keys in the main notebook metadata you can set `allowed_metadata_keys` in `[tool.nbdev]` in `pyproject.toml`.\n",
648-
"Similarly for cell level metadata use `allowed_cell_metadata_keys`, and for output metadata use `allowed_out_metadata_keys`. For example, to preserve both `k1` and `k2` at both the notebook and cell level add the following to `pyproject.toml`:\n",
646+
"To preserve extra metadata, use these settings under `[tool.nbdev]` in `pyproject.toml`:\n",
647+
"\n",
648+
"- `allowed_metadata_keys` preserves notebook metadata.\n",
649+
"- `allowed_cell_metadata_keys` preserves cell metadata.\n",
650+
"- `allowed_out_metadata_keys` preserves output metadata.\n",
651+
"\n",
652+
"This example preserves `k1` and `k2` at all three levels:\n",
649653
"```toml\n",
650654
"[tool.nbdev]\n",
651655
"allowed_metadata_keys = [\"k1\", \"k2\"]\n",
@@ -952,7 +956,11 @@
952956
"source": [
953957
"See `clean_jupyter` and `nbdev-merge` for more about how each hook works.\n",
954958
"\n",
955-
"Both git drivers are registered under the name `jupyternotebook`, the same name nbdime uses. Repo installs define them in a repo-local `.gitconfig` (wired in via `include.path`) and activate them in the committed `.gitattributes`; `--globally` instead defines them in `~/.gitconfig` and activates them in the global attributes file (`core.attributesFile`, defaulting to `~/.config/git/attributes`). Since the attribute lines just name a driver, a committed `.gitattributes` means \"use your preferred notebook driver\": whichever tool defined `jupyternotebook` last in a config git consults wins, so switching between nbdev and nbdime is just re-running either tool's enable command. Global installs skip the repo-only `post-merge` trust hook."
959+
"Both Git drivers use the name `jupyternotebook`, matching nbdime. The attributes file selects this name. Git configuration determines which program runs it. You can therefore commit `.gitattributes` while letting collaborators use their preferred driver.\n",
960+
"\n",
961+
"A repo installation defines the drivers in `.gitconfig`, included through `include.path`, and activates them in `.gitattributes`. With `--globally`, definitions go in `~/.gitconfig`. Attributes go in `core.attributesFile`, which defaults to `~/.config/git/attributes`.\n",
962+
"\n",
963+
"Re-running either tool's enable command changes its driver configuration. Git uses the definition with highest precedence. Global installations skip the repo's `post-merge` trust hook."
956964
]
957965
},
958966
{

0 commit comments

Comments
 (0)