1 1
import copy
2 1
import logging
3

4 1
import traitlets as traits
5 1
from nbconvert.preprocessors import Preprocessor
6 1
from nbformat.notebooknode import NotebookNode
7

8

9 1
def merge(a, b, path=None, overwrite=True):
10
    """merges b into a
11

12
    Examples
13
    --------
14
    >>> from pprint import pprint
15
    >>> pprint(merge({'a':{'b':1},'c':3},{'a':{'b':2}}))
16
    {'a': {'b': 2}, 'c': 3}
17

18
    """
19 1
    if path is None:
20 1
        path = []
21 1
    for key in b:
22 1
        if key in a:
23 1
            if isinstance(a[key], dict) and isinstance(b[key], dict):
24 1
                merge(a[key], b[key], path + [str(key)], overwrite)
25 1
            elif a[key] == b[key]:
26 0
                pass  # same leaf value
27 1
            elif overwrite:
28 1
                a[key] = b[key]  # overwrite leaf value
29
            else:
30 0
                raise Exception("Conflict at %s" % ".".join(path + [str(key)]))
31
        else:
32 1
            a[key] = b[key]
33 1
    return a
34

35

36 1
class SplitOutputs(Preprocessor):
37
    """ a preprocessor to split outputs into separate cells,
38
    merging the cell and output metadata, with output metadata taking priority
39

40
    """
41

42 1
    split = traits.Bool(True, help="whether to split outputs").tag(config=True)
43

44 1
    def preprocess(self, nb, resources):
45

46 1
        if not self.split:
47 0
            return nb, resources
48

49 1
        logging.info("splitting outputs into separate cells")
50

51 1
        final_cells = []
52 1
        for cell in nb.cells:
53

54 1
            if not cell.cell_type == "code":
55 1
                final_cells.append(cell)
56 1
                continue
57 1
            outputs = cell.pop("outputs")
58 1
            cell.outputs = []
59 1
            final_cells.append(cell)
60 1
            for output in outputs:
61 1
                meta = copy.deepcopy(cell.metadata)
62
                # don't need the code to output
63 1
                meta.get("ipub", NotebookNode({})).code = False
64
                # don't create a new slide for each output,
65
                # unless specified in output level metadata
66 1
                if "slide" in meta.get("ipub", NotebookNode({})):
67 1
                    if meta.ipub.slide == "new":
68 0
                        meta.ipub.slide = True
69
                    else:
70 1
                        meta.ipub.slide = meta.ipub.slide
71 1
                meta = merge(meta, output.get("metadata", {}))
72 1
                new = NotebookNode(
73
                    {
74
                        "cell_type": "code",
75
                        "source": "",
76
                        "execution_count": None,
77
                        "metadata": meta,
78
                        "outputs": [output],
79
                    }
80
                )
81 1
                final_cells.append(new)
82

83 1
        nb.cells = final_cells
84

85 1
        return nb, resources

Read our documentation on viewing source code .

Loading