File size: 2,911 Bytes
fa8cde6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# AUTOGENERATED! DO NOT EDIT! File to edit: curations/devtips/02_nbdev_quarto.ipynb.

# %% auto 0
__all__ = ['MyFrontmatterProc', 'filter_nb']

# %% curations/devtips/02_nbdev_quarto.ipynb 4
import sys
import nbformat
from nbdev.imports import *
from nbdev.process import *
from nbdev.processors import NBProcessor, mk_cell, populate_language, add_show_docs, insert_warning,\
                strip_ansi, hide_line, filter_stream_, rm_header_dash,\
                clean_show_doc, exec_show_docs, rm_export, clean_magics, hide_, add_links, strip_hidden_metadata
from pathlib import Path
import yaml
import re
from execnb.nbio import dict2nb,loads

# %% curations/devtips/02_nbdev_quarto.ipynb 5
_RE_FM_BASE=r'''^---\s*
(.*?\S+.*?)
---\s*'''

_re_fm_nb = re.compile(_RE_FM_BASE+'$', flags=re.DOTALL)
_re_fm_md = re.compile(_RE_FM_BASE, flags=re.DOTALL)

def _fm2dict(s:str, nb=True):
    "Load YAML frontmatter into a `dict`"
    re_fm = _re_fm_nb if nb else _re_fm_md
    match = re_fm.search(s.strip())
    return yaml.safe_load(match.group(1)) if match else {}

def _md2dict(s:str):
    "Convert H1 formatted markdown cell to frontmatter dict"
    if '#' not in s: return {}
    m = re.search(r'^#\s+(\S.*?)\s*$', s, flags=re.MULTILINE)
    if not m: return {}
    res = {'title': m.group(1)}
    m = re.search(r'^>\s+(\S.*?)\s*$', s, flags=re.MULTILINE)
    if m: res['description'] = m.group(1)
    r = re.findall(r'^-\s+(\S.*:.*\S)\s*$', s, flags=re.MULTILINE)
    if r:
        try: res.update(yaml.safe_load('\n'.join(r)))
        except Exception as e: warn(f'Failed to create YAML dict for:\n{r}\n\n{e}\n')
    return res

# %% curations/devtips/02_nbdev_quarto.ipynb 6
def _dict2fm(d): return f'---\n{yaml.dump(d)}\n---\n\n'
def _insertfm(nb, fm): nb.cells.insert(0, mk_cell(_dict2fm(fm), 'raw'))

class MyFrontmatterProc(Processor):
    "A YAML and formatted-markdown frontmatter processor"
    def begin(self): self.fm = getattr(self.nb, 'frontmatter_', {})

    def _update(self, f, cell):
        s = cell.get('source')
        if not s: return
        d = f(s)
        if not d: return
        self.fm.update(d)
        cell.source = None

    def cell(self, cell):
        if cell.cell_type=='raw': self._update(_fm2dict, cell)
        elif cell.cell_type=='markdown' and 'title' not in self.fm: self._update(_md2dict, cell)

    def end(self):
        self.nb.frontmatter_ = self.fm
        if not self.fm: return
        _insertfm(self.nb, self.fm)

# %% curations/devtips/02_nbdev_quarto.ipynb 7
def filter_nb():
    procs = [MyFrontmatterProc, populate_language, insert_warning,
                    strip_ansi, hide_line, filter_stream_, rm_header_dash,
                    clean_magics, hide_, strip_hidden_metadata]
    nb_txt = sys.stdin.read()
    nb = dict2nb(loads(nb_txt))
    nbp = NBProcessor(nb=nb, procs=procs)
    nbp.process()
    nbformat.write(nbp.nb, sys.stdout)

filter_nb()