Skip to content

Commit c6d446a

Browse files
committed
fixes #1410
1 parent 26728a1 commit c6d446a

File tree

3 files changed

+87
-35
lines changed

3 files changed

+87
-35
lines changed

nbdev/_modidx.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@
203203
'nbdev.processors.add_show_docs': ('api/processors.html#add_show_docs', 'nbdev/processors.py'),
204204
'nbdev.processors.add_show_docs.begin': ( 'api/processors.html#add_show_docs.begin',
205205
'nbdev/processors.py'),
206+
'nbdev.processors.boxify': ('api/processors.html#boxify', 'nbdev/processors.py'),
206207
'nbdev.processors.cell_lang': ('api/processors.html#cell_lang', 'nbdev/processors.py'),
207208
'nbdev.processors.clean_magics': ('api/processors.html#clean_magics', 'nbdev/processors.py'),
208209
'nbdev.processors.clean_show_doc': ('api/processors.html#clean_show_doc', 'nbdev/processors.py'),
@@ -212,6 +213,7 @@
212213
'nbdev.processors.exec_show_docs.begin': ( 'api/processors.html#exec_show_docs.begin',
213214
'nbdev/processors.py'),
214215
'nbdev.processors.exec_show_docs.end': ('api/processors.html#exec_show_docs.end', 'nbdev/processors.py'),
216+
'nbdev.processors.fdiv': ('api/processors.html#fdiv', 'nbdev/processors.py'),
215217
'nbdev.processors.filter_stream_': ('api/processors.html#filter_stream_', 'nbdev/processors.py'),
216218
'nbdev.processors.hide_': ('api/processors.html#hide_', 'nbdev/processors.py'),
217219
'nbdev.processors.hide_line': ('api/processors.html#hide_line', 'nbdev/processors.py'),

nbdev/processors.py

Lines changed: 37 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/api/10_processors.ipynb.
22

33
# %% auto 0
4-
__all__ = ['CARD_DIV', 'CLOSE_DIV', 'populate_language', 'insert_warning', 'cell_lang', 'add_show_docs', 'mv_exports',
5-
'add_links', 'add_fold', 'strip_ansi', 'strip_hidden_metadata', 'hide_', 'hide_line', 'filter_stream_',
6-
'clean_magics', 'rm_header_dash', 'rm_export', 'clean_show_doc', 'exec_show_docs', 'FilterDefaults']
4+
__all__ = ['populate_language', 'insert_warning', 'cell_lang', 'add_show_docs', 'fdiv', 'boxify', 'mv_exports', 'add_links',
5+
'add_fold', 'strip_ansi', 'strip_hidden_metadata', 'hide_', 'hide_line', 'filter_stream_', 'clean_magics',
6+
'rm_header_dash', 'rm_export', 'clean_show_doc', 'exec_show_docs', 'FilterDefaults']
77

88
# %% ../nbs/api/10_processors.ipynb 2
99
import ast
@@ -47,7 +47,7 @@ def begin(self): self.nb.cells.insert(1, mk_cell(self.content, 'markdown'))
4747
def _def_names(cell, shown):
4848
cellp = cell.parsed_()
4949
return [showdoc_nm(o) for o in concat(cellp)
50-
if isinstance(o,_def_types) and o.name not in shown and o.name[0]!='_'] if cellp else []
50+
if isinstance(o,_def_types) and o.name not in shown and (o.name[0]!='_' or o.name[:2]=='__')] if cellp else []
5151

5252
def _get_nm(tree):
5353
i = tree.value.args[0]
@@ -83,21 +83,32 @@ def begin(self):
8383
nb.has_docs_ = shown_docs or exports
8484

8585
# %% ../nbs/api/10_processors.ipynb 17
86-
CARD_DIV = mk_cell('::: {.py-2 .px-3 .mb-4 fig-align="center" .border .rounded .shadow-sm}', cell_type='markdown')
87-
CLOSE_DIV = mk_cell(':::', cell_type='markdown')
86+
def fdiv(attrs=''):
87+
"Create a fenced div markdown cell in quarto"
88+
if attrs: attrs = ' {'+attrs+'}'
89+
return mk_cell(':::'+attrs, cell_type='markdown')
90+
91+
# %% ../nbs/api/10_processors.ipynb 19
92+
def boxify(cells):
93+
"Add a box around `cells`"
94+
if not isinstance(cells, list): cells = [cells]
95+
res = [fdiv('.py-2 .px-3 .mb-4 fig-align="center" .border .rounded .shadow-sm')]
96+
return res+cells+[fdiv()]
8897

98+
# %% ../nbs/api/10_processors.ipynb 20
8999
class mv_exports(Processor):
90100
"Move `exports` cells to after the `show_doc`"
91101
def begin(self):
92102
cells = self.nb.cells
93103
exports = L(c for c in cells if c.cell_type=='code' and 'exports' in c.directives_)
94104
for cell in reversed(exports):
95-
if getattr(cells[cell.idx_+1], 'has_sd', 0):
96-
cells.insert(cell.idx_+1, cells.pop(cell.idx_))
97-
cells.insert(cell.idx_, CARD_DIV)
98-
cells.insert(cell.idx_+3, CLOSE_DIV)
105+
idx = cell.idx_
106+
if getattr(cells[idx+1], 'has_sd', 0):
107+
doccell = cells.pop(idx+1)
108+
srccell = cells.pop(idx)
109+
cells[idx:idx] = boxify([doccell,srccell])
99110

100-
# %% ../nbs/api/10_processors.ipynb 18
111+
# %% ../nbs/api/10_processors.ipynb 21
101112
_re_defaultexp = re.compile(r'^\s*#\|\s*default_exp\s+(\S+)', flags=re.MULTILINE)
102113

103114
def _default_exp(nb):
@@ -106,7 +117,7 @@ def _default_exp(nb):
106117
default_exp = first(code_src.filter().map(_re_defaultexp.search).filter())
107118
return default_exp.group(1) if default_exp else None
108119

109-
# %% ../nbs/api/10_processors.ipynb 20
120+
# %% ../nbs/api/10_processors.ipynb 23
110121
def add_links(cell):
111122
"Add links to markdown cells"
112123
nl = NbdevLookup()
@@ -115,31 +126,31 @@ def add_links(cell):
115126
if hasattr(o, 'data') and hasattr(o['data'], 'text/markdown'):
116127
o.data['text/markdown'] = [nl.link_line(s) for s in o.data['text/markdown']]
117128

118-
# %% ../nbs/api/10_processors.ipynb 22
129+
# %% ../nbs/api/10_processors.ipynb 25
119130
def add_fold(cell):
120131
"Add `code-fold` to `exports` cells"
121132
if cell.cell_type != 'code' or 'exports' not in cell.directives_: return
122133
cell.source = f'#| code-fold: show\n#| code-summary: "Exported source"\n{cell.source}'
123134

124-
# %% ../nbs/api/10_processors.ipynb 25
135+
# %% ../nbs/api/10_processors.ipynb 28
125136
_re_ansi_escape = re.compile(r'\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])')
126137

127138
def strip_ansi(cell):
128139
"Strip Ansi Characters."
129140
for outp in cell.get('outputs', []):
130141
if outp.get('name')=='stdout': outp['text'] = [_re_ansi_escape.sub('', o) for o in outp.text]
131142

132-
# %% ../nbs/api/10_processors.ipynb 27
143+
# %% ../nbs/api/10_processors.ipynb 30
133144
def strip_hidden_metadata(cell):
134145
'''Strips "hidden" metadata property from code cells so it doesn't interfere with docs rendering'''
135146
if cell.cell_type == 'code' and 'metadata' in cell: cell.metadata.pop('hidden',None)
136147

137-
# %% ../nbs/api/10_processors.ipynb 28
148+
# %% ../nbs/api/10_processors.ipynb 31
138149
def hide_(cell):
139150
"Hide cell from output"
140151
del(cell['source'])
141152

142-
# %% ../nbs/api/10_processors.ipynb 30
153+
# %% ../nbs/api/10_processors.ipynb 33
143154
def _re_hideline(lang=None): return re.compile(fr'{langs[lang]}\|\s*hide_line\s*$', re.MULTILINE)
144155

145156
def hide_line(cell):
@@ -148,22 +159,22 @@ def hide_line(cell):
148159
if cell.cell_type == 'code' and _re_hideline(lang).search(cell.source):
149160
cell.source = '\n'.join([c for c in cell.source.splitlines() if not _re_hideline(lang).search(c)])
150161

151-
# %% ../nbs/api/10_processors.ipynb 33
162+
# %% ../nbs/api/10_processors.ipynb 36
152163
def filter_stream_(cell, *words):
153164
"Remove output lines containing any of `words` in `cell` stream output"
154165
if not words: return
155166
for outp in cell.get('outputs', []):
156167
if outp.output_type == 'stream':
157168
outp['text'] = [l for l in outp.text if not re.search('|'.join(words), l)]
158169

159-
# %% ../nbs/api/10_processors.ipynb 35
170+
# %% ../nbs/api/10_processors.ipynb 38
160171
_magics_pattern = re.compile(r'^\s*(%%|%).*', re.MULTILINE)
161172

162173
def clean_magics(cell):
163174
"A preprocessor to remove cell magic commands"
164175
if cell.cell_type == 'code': cell.source = _magics_pattern.sub('', cell.source).strip()
165176

166-
# %% ../nbs/api/10_processors.ipynb 37
177+
# %% ../nbs/api/10_processors.ipynb 40
167178
_re_hdr_dash = re.compile(r'^#+\s+.*\s+-\s*$', re.MULTILINE)
168179

169180
def rm_header_dash(cell):
@@ -172,14 +183,14 @@ def rm_header_dash(cell):
172183
src = cell.source.strip()
173184
if cell.cell_type == 'markdown' and src.startswith('#') and src.endswith(' -'): del(cell['source'])
174185

175-
# %% ../nbs/api/10_processors.ipynb 39
186+
# %% ../nbs/api/10_processors.ipynb 42
176187
_hide_dirs = {'export','exporti', 'hide','default_exp'}
177188

178189
def rm_export(cell):
179190
"Remove cells that are exported or hidden"
180191
if cell.directives_ and (cell.directives_.keys() & _hide_dirs): del(cell['source'])
181192

182-
# %% ../nbs/api/10_processors.ipynb 41
193+
# %% ../nbs/api/10_processors.ipynb 44
183194
_re_showdoc = re.compile(r'^show_doc', re.MULTILINE)
184195
def _is_showdoc(cell): return cell['cell_type'] == 'code' and _re_showdoc.search(cell.source)
185196
def _add_directives(cell, d):
@@ -191,7 +202,7 @@ def clean_show_doc(cell):
191202
if not _is_showdoc(cell): return
192203
_add_directives(cell, {'output':'asis','echo':'false'})
193204

194-
# %% ../nbs/api/10_processors.ipynb 42
205+
# %% ../nbs/api/10_processors.ipynb 45
195206
def _ast_contains(trees, types):
196207
for tree in trees:
197208
for node in ast.walk(tree):
@@ -212,7 +223,7 @@ def _do_eval(cell):
212223
return True
213224
if _show_docs(trees): return True
214225

215-
# %% ../nbs/api/10_processors.ipynb 43
226+
# %% ../nbs/api/10_processors.ipynb 46
216227
class exec_show_docs(Processor):
217228
"Execute cells needed for `show_docs` output, including exported cells and imports"
218229
def begin(self):
@@ -239,13 +250,13 @@ def end(self):
239250
widgets = {**old, **new, 'state': {**old.get('state', {}), **new['state']}}
240251
self.nb.metadata['widgets'] = {mimetype: widgets}
241252

242-
# %% ../nbs/api/10_processors.ipynb 45
253+
# %% ../nbs/api/10_processors.ipynb 48
243254
def _import_obj(s):
244255
mod_nm, obj_nm = s.split(':')
245256
mod = importlib.import_module(mod_nm)
246257
return getattr(mod, obj_nm)
247258

248-
# %% ../nbs/api/10_processors.ipynb 46
259+
# %% ../nbs/api/10_processors.ipynb 49
249260
class FilterDefaults:
250261
"Override `FilterDefaults` to change which notebook processors are used"
251262
def xtra_procs(self):

nbs/api/10_processors.ipynb

Lines changed: 48 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@
179179
"def _def_names(cell, shown):\n",
180180
" cellp = cell.parsed_()\n",
181181
" return [showdoc_nm(o) for o in concat(cellp)\n",
182-
" if isinstance(o,_def_types) and o.name not in shown and o.name[0]!='_'] if cellp else []\n",
182+
" if isinstance(o,_def_types) and o.name not in shown and (o.name[0]!='_' or o.name[:2]=='__')] if cellp else []\n",
183183
"\n",
184184
"def _get_nm(tree):\n",
185185
" i = tree.value.args[0]\n",
@@ -257,19 +257,58 @@
257257
"outputs": [],
258258
"source": [
259259
"#| export\n",
260-
"CARD_DIV = mk_cell('::: {.py-2 .px-3 .mb-4 fig-align=\"center\" .border .rounded .shadow-sm}', cell_type='markdown')\n",
261-
"CLOSE_DIV = mk_cell(':::', cell_type='markdown')\n",
262-
"\n",
260+
"def fdiv(attrs=''):\n",
261+
" \"Create a fenced div markdown cell in quarto\"\n",
262+
" if attrs: attrs = ' {'+attrs+'}'\n",
263+
" return mk_cell(':::'+attrs, cell_type='markdown')"
264+
]
265+
},
266+
{
267+
"cell_type": "code",
268+
"execution_count": null,
269+
"id": "09a0be27",
270+
"metadata": {},
271+
"outputs": [],
272+
"source": [
273+
"a = fdiv('.py-2')\n",
274+
"test_eq(a.cell_type, 'markdown')\n",
275+
"test_eq(a.source, '::: {.py-2}')"
276+
]
277+
},
278+
{
279+
"cell_type": "code",
280+
"execution_count": null,
281+
"id": "27bc8ad4",
282+
"metadata": {},
283+
"outputs": [],
284+
"source": [
285+
"#| export\n",
286+
"def boxify(cells):\n",
287+
" \"Add a box around `cells`\"\n",
288+
" if not isinstance(cells, list): cells = [cells]\n",
289+
" res = [fdiv('.py-2 .px-3 .mb-4 fig-align=\"center\" .border .rounded .shadow-sm')]\n",
290+
" return res+cells+[fdiv()]"
291+
]
292+
},
293+
{
294+
"cell_type": "code",
295+
"execution_count": null,
296+
"id": "0a7127ef",
297+
"metadata": {},
298+
"outputs": [],
299+
"source": [
300+
"#| export\n",
263301
"class mv_exports(Processor):\n",
264302
" \"Move `exports` cells to after the `show_doc`\"\n",
265303
" def begin(self):\n",
266304
" cells = self.nb.cells\n",
267305
" exports = L(c for c in cells if c.cell_type=='code' and 'exports' in c.directives_)\n",
268306
" for cell in reversed(exports):\n",
269-
" if getattr(cells[cell.idx_+1], 'has_sd', 0): \n",
270-
" cells.insert(cell.idx_+1, cells.pop(cell.idx_))\n",
271-
" cells.insert(cell.idx_, CARD_DIV)\n",
272-
" cells.insert(cell.idx_+3, CLOSE_DIV)"
307+
" idx = cell.idx_\n",
308+
" if getattr(cells[idx+1], 'has_sd', 0):\n",
309+
" doccell = cells.pop(idx+1)\n",
310+
" srccell = cells.pop(idx)\n",
311+
" cells[idx:idx] = boxify([doccell,srccell])"
273312
]
274313
},
275314
{
@@ -750,7 +789,7 @@
750789
],
751790
"metadata": {
752791
"kernelspec": {
753-
"display_name": "python3",
792+
"display_name": "Python 3 (ipykernel)",
754793
"language": "python",
755794
"name": "python3"
756795
}

0 commit comments

Comments
 (0)