nbdev 2.3.27__py3-none-any.whl → 2.3.29__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- nbdev/__init__.py +1 -1
- nbdev/_modidx.py +2 -0
- nbdev/clean.py +17 -15
- nbdev/cli.py +14 -19
- nbdev/config.py +21 -26
- nbdev/doclinks.py +16 -14
- nbdev/export.py +22 -15
- nbdev/frontmatter.py +5 -3
- nbdev/maker.py +28 -26
- nbdev/merge.py +11 -9
- nbdev/migrate.py +19 -17
- nbdev/process.py +16 -14
- nbdev/processors.py +39 -27
- nbdev/qmd.py +9 -7
- nbdev/quarto.py +25 -21
- nbdev/release.py +30 -28
- nbdev/serve.py +6 -4
- nbdev/showdoc.py +17 -15
- nbdev/sync.py +10 -8
- nbdev/test.py +6 -4
- {nbdev-2.3.27.dist-info → nbdev-2.3.29.dist-info}/METADATA +3 -2
- nbdev-2.3.29.dist-info/RECORD +29 -0
- nbdev-2.3.27.dist-info/RECORD +0 -29
- {nbdev-2.3.27.dist-info → nbdev-2.3.29.dist-info}/LICENSE +0 -0
- {nbdev-2.3.27.dist-info → nbdev-2.3.29.dist-info}/WHEEL +0 -0
- {nbdev-2.3.27.dist-info → nbdev-2.3.29.dist-info}/entry_points.txt +0 -0
- {nbdev-2.3.27.dist-info → nbdev-2.3.29.dist-info}/top_level.txt +0 -0
nbdev/processors.py
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
|
+
"""Some processors for NBProcessor"""
|
|
2
|
+
|
|
1
3
|
# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/api/10_processors.ipynb.
|
|
2
4
|
|
|
3
5
|
# %% auto 0
|
|
4
6
|
__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_', '
|
|
6
|
-
'rm_header_dash', 'rm_export', 'clean_show_doc', 'exec_show_docs', 'FilterDefaults']
|
|
7
|
+
'add_fold', 'strip_ansi', 'strip_hidden_metadata', 'hide_', 'hide_line', 'filter_stream_', 'ai_magics',
|
|
8
|
+
'clean_magics', 'rm_header_dash', 'rm_export', 'clean_show_doc', 'exec_show_docs', 'FilterDefaults']
|
|
7
9
|
|
|
8
|
-
# %% ../nbs/api/10_processors.ipynb
|
|
10
|
+
# %% ../nbs/api/10_processors.ipynb
|
|
9
11
|
import ast
|
|
10
12
|
import importlib
|
|
11
13
|
|
|
@@ -23,7 +25,7 @@ from fastcore.imports import *
|
|
|
23
25
|
from fastcore.xtras import *
|
|
24
26
|
import sys,yaml
|
|
25
27
|
|
|
26
|
-
# %% ../nbs/api/10_processors.ipynb
|
|
28
|
+
# %% ../nbs/api/10_processors.ipynb
|
|
27
29
|
_langs = 'bash|html|javascript|js|latex|markdown|perl|ruby|sh|svg'
|
|
28
30
|
_lang_pattern = re.compile(rf'^\s*%%\s*({_langs})\s*$', flags=re.MULTILINE)
|
|
29
31
|
|
|
@@ -36,13 +38,13 @@ class populate_language(Processor):
|
|
|
36
38
|
if lang: cell.metadata.language = lang[0]
|
|
37
39
|
else: cell.metadata.language = self.language
|
|
38
40
|
|
|
39
|
-
# %% ../nbs/api/10_processors.ipynb
|
|
41
|
+
# %% ../nbs/api/10_processors.ipynb
|
|
40
42
|
class insert_warning(Processor):
|
|
41
43
|
"Insert Autogenerated Warning Into Notebook after the first cell."
|
|
42
44
|
content = "<!-- WARNING: THIS FILE WAS AUTOGENERATED! DO NOT EDIT! -->"
|
|
43
45
|
def begin(self): self.nb.cells.insert(1, mk_cell(self.content, 'markdown'))
|
|
44
46
|
|
|
45
|
-
# %% ../nbs/api/10_processors.ipynb
|
|
47
|
+
# %% ../nbs/api/10_processors.ipynb
|
|
46
48
|
_def_types = (ast.FunctionDef,ast.AsyncFunctionDef,ast.ClassDef)
|
|
47
49
|
def _def_names(cell, shown):
|
|
48
50
|
cellp = cell.parsed_()
|
|
@@ -55,7 +57,7 @@ def _get_nm(tree):
|
|
|
55
57
|
else: val = try_attrs(i.value, 'id', 'func', 'attr')
|
|
56
58
|
return f'{val}.{i.attr}' if isinstance(i, ast.Attribute) else i.id
|
|
57
59
|
|
|
58
|
-
# %% ../nbs/api/10_processors.ipynb
|
|
60
|
+
# %% ../nbs/api/10_processors.ipynb
|
|
59
61
|
def _show_docs(trees):
|
|
60
62
|
return [t for t in trees if isinstance(t,ast.Expr) and nested_attr(t, 'value.func.id')=='show_doc']
|
|
61
63
|
|
|
@@ -82,20 +84,20 @@ class add_show_docs(Processor):
|
|
|
82
84
|
nb.cells.insert(cell.idx_+1, new_cell)
|
|
83
85
|
nb.has_docs_ = shown_docs or exports
|
|
84
86
|
|
|
85
|
-
# %% ../nbs/api/10_processors.ipynb
|
|
87
|
+
# %% ../nbs/api/10_processors.ipynb
|
|
86
88
|
def fdiv(attrs=''):
|
|
87
89
|
"Create a fenced div markdown cell in quarto"
|
|
88
90
|
if attrs: attrs = ' {'+attrs+'}'
|
|
89
91
|
return mk_cell(':::'+attrs, cell_type='markdown')
|
|
90
92
|
|
|
91
|
-
# %% ../nbs/api/10_processors.ipynb
|
|
93
|
+
# %% ../nbs/api/10_processors.ipynb
|
|
92
94
|
def boxify(cells):
|
|
93
95
|
"Add a box around `cells`"
|
|
94
96
|
if not isinstance(cells, list): cells = [cells]
|
|
95
97
|
res = [fdiv('.py-2 .px-3 .mb-4 fig-align="center" .border .rounded .shadow-sm')]
|
|
96
98
|
return res+cells+[fdiv()]
|
|
97
99
|
|
|
98
|
-
# %% ../nbs/api/10_processors.ipynb
|
|
100
|
+
# %% ../nbs/api/10_processors.ipynb
|
|
99
101
|
class mv_exports(Processor):
|
|
100
102
|
"Move `exports` cells to after the `show_doc`"
|
|
101
103
|
def begin(self):
|
|
@@ -108,7 +110,7 @@ class mv_exports(Processor):
|
|
|
108
110
|
srccell = cells.pop(idx)
|
|
109
111
|
cells[idx:idx] = [doccell,srccell]
|
|
110
112
|
|
|
111
|
-
# %% ../nbs/api/10_processors.ipynb
|
|
113
|
+
# %% ../nbs/api/10_processors.ipynb
|
|
112
114
|
_re_defaultexp = re.compile(r'^\s*#\|\s*default_exp\s+(\S+)', flags=re.MULTILINE)
|
|
113
115
|
|
|
114
116
|
def _default_exp(nb):
|
|
@@ -117,7 +119,7 @@ def _default_exp(nb):
|
|
|
117
119
|
default_exp = first(code_src.filter().map(_re_defaultexp.search).filter())
|
|
118
120
|
return default_exp.group(1) if default_exp else None
|
|
119
121
|
|
|
120
|
-
# %% ../nbs/api/10_processors.ipynb
|
|
122
|
+
# %% ../nbs/api/10_processors.ipynb
|
|
121
123
|
def add_links(cell):
|
|
122
124
|
"Add links to markdown cells"
|
|
123
125
|
nl = NbdevLookup()
|
|
@@ -126,13 +128,13 @@ def add_links(cell):
|
|
|
126
128
|
if hasattr(o, 'data') and hasattr(o['data'], 'text/markdown'):
|
|
127
129
|
o.data['text/markdown'] = [nl.link_line(s) for s in o.data['text/markdown']]
|
|
128
130
|
|
|
129
|
-
# %% ../nbs/api/10_processors.ipynb
|
|
131
|
+
# %% ../nbs/api/10_processors.ipynb
|
|
130
132
|
def add_fold(cell):
|
|
131
133
|
"Add `code-fold` to `exports` cells"
|
|
132
134
|
if cell.cell_type != 'code' or 'exports' not in cell.directives_: return
|
|
133
135
|
cell.source = f'#| code-fold: show\n#| code-summary: "Exported source"\n{cell.source}'
|
|
134
136
|
|
|
135
|
-
# %% ../nbs/api/10_processors.ipynb
|
|
137
|
+
# %% ../nbs/api/10_processors.ipynb
|
|
136
138
|
_re_ansi_escape = re.compile(r'\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])')
|
|
137
139
|
|
|
138
140
|
def strip_ansi(cell):
|
|
@@ -140,17 +142,17 @@ def strip_ansi(cell):
|
|
|
140
142
|
for outp in cell.get('outputs', []):
|
|
141
143
|
if outp.get('name')=='stdout': outp['text'] = [_re_ansi_escape.sub('', o) for o in outp.text]
|
|
142
144
|
|
|
143
|
-
# %% ../nbs/api/10_processors.ipynb
|
|
145
|
+
# %% ../nbs/api/10_processors.ipynb
|
|
144
146
|
def strip_hidden_metadata(cell):
|
|
145
147
|
'''Strips "hidden" metadata property from code cells so it doesn't interfere with docs rendering'''
|
|
146
148
|
if cell.cell_type == 'code' and 'metadata' in cell: cell.metadata.pop('hidden',None)
|
|
147
149
|
|
|
148
|
-
# %% ../nbs/api/10_processors.ipynb
|
|
150
|
+
# %% ../nbs/api/10_processors.ipynb
|
|
149
151
|
def hide_(cell):
|
|
150
152
|
"Hide cell from output"
|
|
151
153
|
del(cell['source'])
|
|
152
154
|
|
|
153
|
-
# %% ../nbs/api/10_processors.ipynb
|
|
155
|
+
# %% ../nbs/api/10_processors.ipynb
|
|
154
156
|
def _re_hideline(lang=None): return re.compile(fr'{langs[lang]}\|\s*hide_line\s*$', re.MULTILINE)
|
|
155
157
|
|
|
156
158
|
def hide_line(cell):
|
|
@@ -159,7 +161,7 @@ def hide_line(cell):
|
|
|
159
161
|
if cell.cell_type == 'code' and _re_hideline(lang).search(cell.source):
|
|
160
162
|
cell.source = '\n'.join([c for c in cell.source.splitlines() if not _re_hideline(lang).search(c)])
|
|
161
163
|
|
|
162
|
-
# %% ../nbs/api/10_processors.ipynb
|
|
164
|
+
# %% ../nbs/api/10_processors.ipynb
|
|
163
165
|
def filter_stream_(cell, *words):
|
|
164
166
|
"Remove output lines containing any of `words` in `cell` stream output"
|
|
165
167
|
if not words: return
|
|
@@ -167,14 +169,23 @@ def filter_stream_(cell, *words):
|
|
|
167
169
|
if outp.output_type == 'stream':
|
|
168
170
|
outp['text'] = [l for l in outp.text if not re.search('|'.join(words), l)]
|
|
169
171
|
|
|
170
|
-
# %% ../nbs/api/10_processors.ipynb
|
|
172
|
+
# %% ../nbs/api/10_processors.ipynb
|
|
173
|
+
_aimagics_pattern = re.compile(r'^\s*(%%ai.? |%%ai.?$)', re.MULTILINE)
|
|
174
|
+
|
|
175
|
+
def ai_magics(cell):
|
|
176
|
+
"A preprocessor to convert AI magics to markdown"
|
|
177
|
+
if cell.cell_type == 'code' and _aimagics_pattern.search(cell.source):
|
|
178
|
+
cell.cell_type ='markdown'
|
|
179
|
+
cell.source = '\n'.join(cell.source.splitlines()[1:])
|
|
180
|
+
|
|
181
|
+
# %% ../nbs/api/10_processors.ipynb
|
|
171
182
|
_magics_pattern = re.compile(r'^\s*(%%|%).*', re.MULTILINE)
|
|
172
183
|
|
|
173
184
|
def clean_magics(cell):
|
|
174
185
|
"A preprocessor to remove cell magic commands"
|
|
175
186
|
if cell.cell_type == 'code': cell.source = _magics_pattern.sub('', cell.source).strip()
|
|
176
187
|
|
|
177
|
-
# %% ../nbs/api/10_processors.ipynb
|
|
188
|
+
# %% ../nbs/api/10_processors.ipynb
|
|
178
189
|
_re_hdr_dash = re.compile(r'^#+\s+.*\s+-\s*$', re.MULTILINE)
|
|
179
190
|
|
|
180
191
|
def rm_header_dash(cell):
|
|
@@ -183,14 +194,14 @@ def rm_header_dash(cell):
|
|
|
183
194
|
src = cell.source.strip()
|
|
184
195
|
if cell.cell_type == 'markdown' and src.startswith('#') and src.endswith(' -'): del(cell['source'])
|
|
185
196
|
|
|
186
|
-
# %% ../nbs/api/10_processors.ipynb
|
|
197
|
+
# %% ../nbs/api/10_processors.ipynb
|
|
187
198
|
_hide_dirs = {'export','exporti', 'hide','default_exp'}
|
|
188
199
|
|
|
189
200
|
def rm_export(cell):
|
|
190
201
|
"Remove cells that are exported or hidden"
|
|
191
202
|
if cell.directives_ and (cell.directives_.keys() & _hide_dirs): del(cell['source'])
|
|
192
203
|
|
|
193
|
-
# %% ../nbs/api/10_processors.ipynb
|
|
204
|
+
# %% ../nbs/api/10_processors.ipynb
|
|
194
205
|
_re_showdoc = re.compile(r'^show_doc', re.MULTILINE)
|
|
195
206
|
def _is_showdoc(cell): return cell['cell_type'] == 'code' and _re_showdoc.search(cell.source)
|
|
196
207
|
def _add_directives(cell, d):
|
|
@@ -202,7 +213,7 @@ def clean_show_doc(cell):
|
|
|
202
213
|
if not _is_showdoc(cell): return
|
|
203
214
|
_add_directives(cell, {'output':'asis','echo':'false'})
|
|
204
215
|
|
|
205
|
-
# %% ../nbs/api/10_processors.ipynb
|
|
216
|
+
# %% ../nbs/api/10_processors.ipynb
|
|
206
217
|
def _ast_contains(trees, types):
|
|
207
218
|
for tree in trees:
|
|
208
219
|
for node in ast.walk(tree):
|
|
@@ -223,7 +234,7 @@ def _do_eval(cell):
|
|
|
223
234
|
return True
|
|
224
235
|
if _show_docs(trees): return True
|
|
225
236
|
|
|
226
|
-
# %% ../nbs/api/10_processors.ipynb
|
|
237
|
+
# %% ../nbs/api/10_processors.ipynb
|
|
227
238
|
class exec_show_docs(Processor):
|
|
228
239
|
"Execute cells needed for `show_docs` output, including exported cells and imports"
|
|
229
240
|
def begin(self):
|
|
@@ -250,13 +261,13 @@ class exec_show_docs(Processor):
|
|
|
250
261
|
widgets = {**old, **new, 'state': {**old.get('state', {}), **new['state']}}
|
|
251
262
|
self.nb.metadata['widgets'] = {mimetype: widgets}
|
|
252
263
|
|
|
253
|
-
# %% ../nbs/api/10_processors.ipynb
|
|
264
|
+
# %% ../nbs/api/10_processors.ipynb
|
|
254
265
|
def _import_obj(s):
|
|
255
266
|
mod_nm, obj_nm = s.split(':')
|
|
256
267
|
mod = importlib.import_module(mod_nm)
|
|
257
268
|
return getattr(mod, obj_nm)
|
|
258
269
|
|
|
259
|
-
# %% ../nbs/api/10_processors.ipynb
|
|
270
|
+
# %% ../nbs/api/10_processors.ipynb
|
|
260
271
|
class FilterDefaults:
|
|
261
272
|
"Override `FilterDefaults` to change which notebook processors are used"
|
|
262
273
|
def xtra_procs(self):
|
|
@@ -266,7 +277,8 @@ class FilterDefaults:
|
|
|
266
277
|
def base_procs(self):
|
|
267
278
|
return [FrontmatterProc, populate_language, add_show_docs, insert_warning,
|
|
268
279
|
strip_ansi, hide_line, filter_stream_, rm_header_dash,
|
|
269
|
-
clean_show_doc, exec_show_docs, rm_export, clean_magics, hide_, add_links,
|
|
280
|
+
clean_show_doc, exec_show_docs, rm_export, ai_magics, clean_magics, hide_, add_links,
|
|
281
|
+
add_fold, mv_exports, strip_hidden_metadata]
|
|
270
282
|
|
|
271
283
|
def procs(self):
|
|
272
284
|
"Processors for export"
|
nbdev/qmd.py
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
"""Basic qmd generation helpers (experimental)"""
|
|
2
|
+
|
|
1
3
|
# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/api/15_qmd.ipynb.
|
|
2
4
|
|
|
3
5
|
# %% ../nbs/api/15_qmd.ipynb 2
|
|
@@ -10,7 +12,7 @@ from fastcore.meta import delegates
|
|
|
10
12
|
# %% auto 0
|
|
11
13
|
__all__ = ['meta', 'div', 'img', 'btn', 'tbl_row', 'tbl_sep']
|
|
12
14
|
|
|
13
|
-
# %% ../nbs/api/15_qmd.ipynb
|
|
15
|
+
# %% ../nbs/api/15_qmd.ipynb
|
|
14
16
|
def meta(md, # Markdown to add meta to
|
|
15
17
|
classes=None, # List of CSS classes to add
|
|
16
18
|
style=None, # Dict of CSS styles to add
|
|
@@ -25,7 +27,7 @@ def meta(md, # Markdown to add meta to
|
|
|
25
27
|
meta = ' '.join(meta)
|
|
26
28
|
return md + ("{" + meta + "}" if meta else "")
|
|
27
29
|
|
|
28
|
-
# %% ../nbs/api/15_qmd.ipynb
|
|
30
|
+
# %% ../nbs/api/15_qmd.ipynb
|
|
29
31
|
def div(txt, # Markdown to add meta to
|
|
30
32
|
classes=None, # List of CSS classes to add
|
|
31
33
|
style=None, # Dict of CSS styles to add
|
|
@@ -33,7 +35,7 @@ def div(txt, # Markdown to add meta to
|
|
|
33
35
|
"A qmd div with optional metadata section"
|
|
34
36
|
return meta("::: ", classes=classes, style=style, **kwargs) + f"\n\n{txt}\n\n:::\n\n"
|
|
35
37
|
|
|
36
|
-
# %% ../nbs/api/15_qmd.ipynb
|
|
38
|
+
# %% ../nbs/api/15_qmd.ipynb
|
|
37
39
|
def img(fname, # Image to link to
|
|
38
40
|
classes=None, # List of CSS classes to add
|
|
39
41
|
style=None, # Dict of CSS styles to add
|
|
@@ -51,7 +53,7 @@ def img(fname, # Image to link to
|
|
|
51
53
|
res = meta(f'', classes=classes, style=style, **kwargs)
|
|
52
54
|
return f'[{res}]({fname})' if link else res
|
|
53
55
|
|
|
54
|
-
# %% ../nbs/api/15_qmd.ipynb
|
|
56
|
+
# %% ../nbs/api/15_qmd.ipynb
|
|
55
57
|
def btn(txt, # Button text
|
|
56
58
|
link, # Button link URL
|
|
57
59
|
classes=None, # List of CSS classes to add
|
|
@@ -60,20 +62,20 @@ def btn(txt, # Button text
|
|
|
60
62
|
"A qmd button"
|
|
61
63
|
return meta(f'[{txt}]({link})', classes=classes, style=style, role="button")
|
|
62
64
|
|
|
63
|
-
# %% ../nbs/api/15_qmd.ipynb
|
|
65
|
+
# %% ../nbs/api/15_qmd.ipynb
|
|
64
66
|
def tbl_row(cols:list, # Auto-stringified columns to show in the row
|
|
65
67
|
):
|
|
66
68
|
"Create a markdown table row from `cols`"
|
|
67
69
|
return '|' + '|'.join(str(c or '') for c in cols) + '|'
|
|
68
70
|
|
|
69
|
-
# %% ../nbs/api/15_qmd.ipynb
|
|
71
|
+
# %% ../nbs/api/15_qmd.ipynb
|
|
70
72
|
def tbl_sep(sizes:int|list=3 # List of column sizes, or single `int` if all sizes the same
|
|
71
73
|
):
|
|
72
74
|
"Create a markdown table separator with relative column size `sizes`"
|
|
73
75
|
if isinstance(sizes,int): sizes = [3]*sizes
|
|
74
76
|
return tbl_row('-'*s for s in sizes)
|
|
75
77
|
|
|
76
|
-
# %% ../nbs/api/15_qmd.ipynb
|
|
78
|
+
# %% ../nbs/api/15_qmd.ipynb
|
|
77
79
|
def _install_nbdev():
|
|
78
80
|
return div('''#### pip
|
|
79
81
|
|
nbdev/quarto.py
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
"""Install and interact with Quarto from nbdev"""
|
|
2
|
+
|
|
1
3
|
# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/api/14_quarto.ipynb.
|
|
2
4
|
|
|
3
5
|
# %% ../nbs/api/14_quarto.ipynb 3
|
|
@@ -21,12 +23,12 @@ import yaml
|
|
|
21
23
|
__all__ = ['BASE_QUARTO_URL', 'install_quarto', 'install', 'IndentDumper', 'nbdev_sidebar', 'refresh_quarto_yml',
|
|
22
24
|
'nbdev_proc_nbs', 'nbdev_readme', 'nbdev_docs', 'prepare', 'fs_watchdog', 'nbdev_preview']
|
|
23
25
|
|
|
24
|
-
# %% ../nbs/api/14_quarto.ipynb
|
|
26
|
+
# %% ../nbs/api/14_quarto.ipynb
|
|
25
27
|
def _sprun(cmd):
|
|
26
28
|
try: subprocess.check_output(cmd, shell=True)
|
|
27
29
|
except subprocess.CalledProcessError as cpe: sys.exit(cpe.returncode)
|
|
28
30
|
|
|
29
|
-
# %% ../nbs/api/14_quarto.ipynb
|
|
31
|
+
# %% ../nbs/api/14_quarto.ipynb
|
|
30
32
|
BASE_QUARTO_URL='https://www.quarto.org/download/latest/'
|
|
31
33
|
|
|
32
34
|
def _install_linux():
|
|
@@ -53,7 +55,7 @@ def install_quarto():
|
|
|
53
55
|
elif 'linux' in sys.platform: _install_linux()
|
|
54
56
|
finally: system('sudo rm -f .installing')
|
|
55
57
|
|
|
56
|
-
# %% ../nbs/api/14_quarto.ipynb
|
|
58
|
+
# %% ../nbs/api/14_quarto.ipynb
|
|
57
59
|
@call_parse
|
|
58
60
|
def install():
|
|
59
61
|
"Install Quarto and the current library"
|
|
@@ -61,7 +63,7 @@ def install():
|
|
|
61
63
|
d = get_config().lib_path
|
|
62
64
|
if (d/'__init__.py').exists(): system(f'pip install -e "{d.parent}[dev]"')
|
|
63
65
|
|
|
64
|
-
# %% ../nbs/api/14_quarto.ipynb
|
|
66
|
+
# %% ../nbs/api/14_quarto.ipynb
|
|
65
67
|
def _pre(p,b=True): return ' ' * (len(p.parts)) + ('- ' if b else ' ')
|
|
66
68
|
def _sort(a):
|
|
67
69
|
x,y = a
|
|
@@ -78,7 +80,7 @@ def _nbglob_docs(
|
|
|
78
80
|
**kwargs):
|
|
79
81
|
return nbglob(path, file_glob=file_glob, file_re=file_re, **kwargs)
|
|
80
82
|
|
|
81
|
-
# %% ../nbs/api/14_quarto.ipynb
|
|
83
|
+
# %% ../nbs/api/14_quarto.ipynb
|
|
82
84
|
def _recursive_parser(
|
|
83
85
|
dir_dict: dict, # Directory structure as a dict.
|
|
84
86
|
contents: list, # `contents` list from `sidebar.yaml` template dict.
|
|
@@ -101,7 +103,7 @@ class IndentDumper(yaml.Dumper):
|
|
|
101
103
|
def increase_indent(self, flow=False, indentless=False):
|
|
102
104
|
return super(IndentDumper, self).increase_indent(flow, False)
|
|
103
105
|
|
|
104
|
-
# %% ../nbs/api/14_quarto.ipynb
|
|
106
|
+
# %% ../nbs/api/14_quarto.ipynb
|
|
105
107
|
@call_parse
|
|
106
108
|
@delegates(_nbglob_docs)
|
|
107
109
|
def nbdev_sidebar(
|
|
@@ -136,7 +138,7 @@ def nbdev_sidebar(
|
|
|
136
138
|
if printit: return print(yml)
|
|
137
139
|
yml_path.write_text(yml)
|
|
138
140
|
|
|
139
|
-
# %% ../nbs/api/14_quarto.ipynb
|
|
141
|
+
# %% ../nbs/api/14_quarto.ipynb
|
|
140
142
|
_quarto_yml="""project:
|
|
141
143
|
type: website
|
|
142
144
|
|
|
@@ -145,6 +147,8 @@ format:
|
|
|
145
147
|
theme: cosmo
|
|
146
148
|
css: styles.css
|
|
147
149
|
toc: true
|
|
150
|
+
keep-md: true
|
|
151
|
+
commonmark: default
|
|
148
152
|
|
|
149
153
|
website:
|
|
150
154
|
twitter-card: true
|
|
@@ -158,7 +162,7 @@ website:
|
|
|
158
162
|
|
|
159
163
|
metadata-files: [nbdev.yml, sidebar.yml]"""
|
|
160
164
|
|
|
161
|
-
# %% ../nbs/api/14_quarto.ipynb
|
|
165
|
+
# %% ../nbs/api/14_quarto.ipynb
|
|
162
166
|
_nbdev_yml="""project:
|
|
163
167
|
output-dir: {doc_path}
|
|
164
168
|
|
|
@@ -170,7 +174,7 @@ website:
|
|
|
170
174
|
repo-url: "{git_url}"
|
|
171
175
|
"""
|
|
172
176
|
|
|
173
|
-
# %% ../nbs/api/14_quarto.ipynb
|
|
177
|
+
# %% ../nbs/api/14_quarto.ipynb
|
|
174
178
|
def refresh_quarto_yml():
|
|
175
179
|
"Generate `_quarto.yml` from `settings.ini`."
|
|
176
180
|
cfg = get_config()
|
|
@@ -184,13 +188,13 @@ def refresh_quarto_yml():
|
|
|
184
188
|
if qy.exists() and not str2bool(cfg.get('custom_quarto_yml', True)): qy.unlink()
|
|
185
189
|
if not qy.exists(): qy.write_text(_quarto_yml)
|
|
186
190
|
|
|
187
|
-
# %% ../nbs/api/14_quarto.ipynb
|
|
191
|
+
# %% ../nbs/api/14_quarto.ipynb
|
|
188
192
|
def _ensure_quarto():
|
|
189
193
|
if shutil.which('quarto'): return
|
|
190
194
|
print("Quarto is not installed. We will download and install it for you.")
|
|
191
195
|
install.__wrapped__()
|
|
192
196
|
|
|
193
|
-
# %% ../nbs/api/14_quarto.ipynb
|
|
197
|
+
# %% ../nbs/api/14_quarto.ipynb
|
|
194
198
|
def _pre_docs(path=None, n_workers:int=defaults.cpus, **kwargs):
|
|
195
199
|
cfg = get_config()
|
|
196
200
|
path = Path(path) if path else cfg.nbs_path
|
|
@@ -202,21 +206,21 @@ def _pre_docs(path=None, n_workers:int=defaults.cpus, **kwargs):
|
|
|
202
206
|
cache = proc_nbs(path, n_workers=n_workers, **kwargs)
|
|
203
207
|
return cache,cfg,path
|
|
204
208
|
|
|
205
|
-
# %% ../nbs/api/14_quarto.ipynb
|
|
209
|
+
# %% ../nbs/api/14_quarto.ipynb
|
|
206
210
|
@call_parse
|
|
207
211
|
@delegates(proc_nbs)
|
|
208
212
|
def nbdev_proc_nbs(**kwargs):
|
|
209
213
|
"Process notebooks in `path` for docs rendering"
|
|
210
214
|
_pre_docs(**kwargs)[0]
|
|
211
215
|
|
|
212
|
-
# %% ../nbs/api/14_quarto.ipynb
|
|
216
|
+
# %% ../nbs/api/14_quarto.ipynb
|
|
213
217
|
def _readme_mtime_not_older(readme_path, readme_nb_path):
|
|
214
218
|
if not readme_nb_path.exists():
|
|
215
219
|
print(f"Could not find {readme_nb_path}")
|
|
216
220
|
return True
|
|
217
221
|
return readme_path.exists() and readme_path.stat().st_mtime>=readme_nb_path.stat().st_mtime
|
|
218
222
|
|
|
219
|
-
# %% ../nbs/api/14_quarto.ipynb
|
|
223
|
+
# %% ../nbs/api/14_quarto.ipynb
|
|
220
224
|
class _SidebarYmlRemoved:
|
|
221
225
|
"Context manager for `nbdev_readme` to avoid rendering whole docs website"
|
|
222
226
|
def __init__(self,path): self._path=path
|
|
@@ -229,14 +233,14 @@ class _SidebarYmlRemoved:
|
|
|
229
233
|
def __exit__(self, exc_type, exc_value, exc_tb):
|
|
230
234
|
if self._moved: (self._path/'sidebar.yml.bak').rename(self._yml_path)
|
|
231
235
|
|
|
232
|
-
# %% ../nbs/api/14_quarto.ipynb
|
|
236
|
+
# %% ../nbs/api/14_quarto.ipynb
|
|
233
237
|
def _copytree(a,b):
|
|
234
238
|
if sys.version_info.major >=3 and sys.version_info.minor >=8: copytree(a, b, dirs_exist_ok=True)
|
|
235
239
|
else:
|
|
236
240
|
from distutils.dir_util import copy_tree
|
|
237
241
|
copy_tree(a, b)
|
|
238
242
|
|
|
239
|
-
# %% ../nbs/api/14_quarto.ipynb
|
|
243
|
+
# %% ../nbs/api/14_quarto.ipynb
|
|
240
244
|
def _save_cached_readme(cache, cfg):
|
|
241
245
|
tmp_doc_path = cache/cfg.doc_path.name
|
|
242
246
|
readme = tmp_doc_path/'README.md'
|
|
@@ -247,7 +251,7 @@ def _save_cached_readme(cache, cfg):
|
|
|
247
251
|
_rdmi = tmp_doc_path/((cache/cfg.readme_nb).stem + '_files') # Supporting files for README
|
|
248
252
|
if _rdmi.exists(): _copytree(_rdmi, cfg.config_path/_rdmi.name)
|
|
249
253
|
|
|
250
|
-
# %% ../nbs/api/14_quarto.ipynb
|
|
254
|
+
# %% ../nbs/api/14_quarto.ipynb
|
|
251
255
|
@call_parse
|
|
252
256
|
def nbdev_readme(
|
|
253
257
|
path:str=None, # Path to notebooks
|
|
@@ -263,7 +267,7 @@ def nbdev_readme(
|
|
|
263
267
|
|
|
264
268
|
_save_cached_readme(cache, cfg)
|
|
265
269
|
|
|
266
|
-
# %% ../nbs/api/14_quarto.ipynb
|
|
270
|
+
# %% ../nbs/api/14_quarto.ipynb
|
|
267
271
|
@call_parse
|
|
268
272
|
@delegates(_nbglob_docs)
|
|
269
273
|
def nbdev_docs(
|
|
@@ -277,7 +281,7 @@ def nbdev_docs(
|
|
|
277
281
|
shutil.rmtree(cfg.doc_path, ignore_errors=True)
|
|
278
282
|
move(cache/cfg.doc_path.name, cfg.config_path)
|
|
279
283
|
|
|
280
|
-
# %% ../nbs/api/14_quarto.ipynb
|
|
284
|
+
# %% ../nbs/api/14_quarto.ipynb
|
|
281
285
|
@call_parse
|
|
282
286
|
def prepare():
|
|
283
287
|
"Export, test, and clean notebooks, and render README if needed"
|
|
@@ -288,7 +292,7 @@ def prepare():
|
|
|
288
292
|
refresh_quarto_yml()
|
|
289
293
|
nbdev_readme.__wrapped__(chk_time=True)
|
|
290
294
|
|
|
291
|
-
# %% ../nbs/api/14_quarto.ipynb
|
|
295
|
+
# %% ../nbs/api/14_quarto.ipynb
|
|
292
296
|
@contextmanager
|
|
293
297
|
def fs_watchdog(func, path, recursive:bool=True):
|
|
294
298
|
"File system watchdog dispatching to `func`"
|
|
@@ -304,7 +308,7 @@ def fs_watchdog(func, path, recursive:bool=True):
|
|
|
304
308
|
observer.stop()
|
|
305
309
|
observer.join()
|
|
306
310
|
|
|
307
|
-
# %% ../nbs/api/14_quarto.ipynb
|
|
311
|
+
# %% ../nbs/api/14_quarto.ipynb
|
|
308
312
|
@call_parse
|
|
309
313
|
@delegates(_nbglob_docs)
|
|
310
314
|
def nbdev_preview(
|