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.
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):
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:
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.
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:
class _PrintExample:def _printme_(self, cell, to_print): print(to_print)NBProcessor(everything_fn, _PrintExample()).process()
testing
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:
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.
class CountCellProcessor(Processor):def begin(self):print(f"First cell:\n{self.nb.cells[0].source}")self.count=0def cell(self, cell):if cell.cell_type=='code': self.count +=1def end(self): print(f"* There were {self.count} code cells")