Пример #1
0
    def preprocess(self, nb, resources):

        logging.info('adding ipub defaults to notebook')

        for keys, val in flatten(self.nb_defaults).items():
            dct = nb.metadata
            for key in keys[:-1]:
                if key not in dct:
                    dct[key] = NotebookNode({})
                dct = dct[key]
            if keys[-1] not in dct:
                dct[keys[-1]] = val
            elif self.overwrite:
                dct[keys[-1]] = val

        for cell in nb.cells:
            for keys, val in flatten(self.cell_defaults).items():
                dct = cell.metadata
                for key in keys[:-1]:
                    if key not in dct:
                        dct[key] = NotebookNode({})
                    dct = dct[key]
                if keys[-1] not in dct:
                    dct[keys[-1]] = val
                elif self.overwrite:
                    dct[keys[-1]] = val

        return nb, resources
Пример #2
0
 def postprocess_output(self, outputs):
     """
     Postprocesses output and maps mime types to ones accepted by R.
     """
     res = []
     for output in outputs:
         msg_type = output.output_type
         content = output
         out = NotebookNode(output_type=msg_type)
         if msg_type in ('display_data', 'execute_result'):
             for mime, data in content['data'].items():
                 try:
                     attr = self.MIME_MAP[mime]
                     if attr == 'text':
                         tmpval = RClansiconv(data)
                     else:
                         tmpval = data
                     setattr(out, attr, tmpval)
                 except KeyError:
                     raise NotImplementedError('unhandled mime type: %s' %
                                               mime)
         elif msg_type == 'stream':
             setattr(out, 'text', RClansiconv(content['text']))
         elif msg_type == 'error':
             setattr(out, 'html',
                     RClansiconv('\n'.join(content['traceback']) + '\n'))
         else:
             if _debugging: logging.info('Unsupported: ' + msg_type)
             raise NotImplementedError('unhandled result: %s' % msg_type)
         if _debugging:
             logging.info(
                 'Sending: msg_type: [{}]; HTML: [{}]; TEXT: [{}]'.format(
                     msg_type, out.get('html', ''), out.get('text', '')))
         res.append(out)
     return res  # upstream process will handle it [e.g. send as an oob message]
Пример #3
0
 def new_cell(idents, filename, lineno, source=None):
     cell_types = ['markdown', 'code']
     slide_types = ['slide', 'subslide', 'fragment']
     split_types = ['split']
     cell = {'metadata': {},
             'cell_type': 'markdown'}
     if source is not None:
         if source and source[-1] == "\n":
             source = source[:-1]
         cell['source'] = source
     for ident in idents:
         if ident in cell_types:
             cell['cell_type'] = ident
             if ident == 'code':
                 cell['outputs'] = []
                 cell['execution_count'] = None
         elif ident in slide_types:
             if 'slideshow' not in cell['metadata']:
                 cell['metadata']['slideshow'] = {}
             cell['metadata']['slideshow']['slide_type'] = ident
         elif ident in split_types:
             cell['metadata']['cell_style'] = ident
         else:
             print("{}:{} - ignored directive `{}' in separator"
                   .format(filename, lineno, ident))
     return NotebookNode(cell)
Пример #4
0
    def embed_html(self, cell, path):
        """ a new cell, based on embedded html file
        """
        logging.info('embedding html in notebook from: {}'.format(path))

        height = int(cell.metadata.ipub.embed_html.get('height', 0.5) * 100)
        width = int(cell.metadata.ipub.embed_html.get('width', 0.5) * 100)
        embed_code = """
        <iframe style="display:block; margin: 0 auto; height:{height}vh; width:{width}vw; overflow:auto; resize:both" {src}="{path}" frameborder="0" allowfullscreen></iframe>
        """.format(src=self.src_name, path=path, height=height, width=width)

        # add to the exising output or create a new one
        if cell.outputs:
            cell.outputs[0]["data"]["text/html"] = embed_code
        else:
            cell.outputs.append(
                NotebookNode({
                    "data": {
                        "text/html": embed_code
                    },
                    "execution_count": 0,
                    "metadata": {},
                    "output_type": "execute_result"
                }))

        return cell
Пример #5
0
    def preprocess(self, nb, resources):
                
        logging.info('extracting caption cells') 
        
        # extract captions
        final_cells = []
        captions = {}
        for cell in nb.cells:
            if hasattr(cell.metadata, 'ipub'):
                
                if hasattr(cell.metadata.ipub.get('equation',False),'get'):
                    if hasattr(cell.metadata.ipub.equation.get('environment',False),'startswith'):
                        if cell.metadata.ipub.equation.environment.startswith('breqn'):
                            if "ipub" not in nb.metadata:
                                nb.metadata["ipub"] = NotebookNode({'enable_breqn':True})
                            else:
                                nb.metadata.ipub['enable_breqn'] = True
                
                if hasattr(cell.metadata.ipub, 'caption'):
                                        
                    if cell.cell_type == 'markdown':
                        capt = cell.source.split(r'\n')[0]
                        captions[cell.metadata.ipub.caption] = capt
                        continue
                    elif cell.cell_type == 'code':
                        if not cell.outputs:
                            pass
                        elif "text/latex" in cell.outputs[0].get('data',{}):
                            capt = cell.outputs[0].data["text/latex"].split(r'\n')[0]
                            captions[cell.metadata.ipub.caption] = capt
                            continue
                        elif "text/plain" in cell.outputs[0].get('data',{}):
                            capt = cell.outputs[0].data["text/plain"].split(r'\n')[0]
                            captions[cell.metadata.ipub.caption] = capt
                            continue

            final_cells.append(cell)
        nb.cells = final_cells  
        
        # replace captions
        for cell in nb.cells:
            if hasattr(cell.metadata, 'ipub'):
                for key in cell.metadata.ipub:
                    if hasattr(cell.metadata.ipub[key], 'label'):
                        if cell.metadata.ipub[key]['label'] in captions:
                            logging.debug('replacing caption for: {}'.format(cell.metadata.ipub[key]['label']))
                            cell.metadata.ipub[key]['caption'] = captions[cell.metadata.ipub[key]['label']]
                            
                    # add float type/number prefix to caption, if required
                    if self.add_prefix:
                        if hasattr(cell.metadata.ipub[key], 'caption'):
                            if hasattr(cell.metadata.ipub[key], 'caption_prefix'):                    
                                newcaption = cell.metadata.ipub[key].caption_prefix + cell.metadata.ipub[key].caption
                                cell.metadata.ipub[key].caption = newcaption
                    
        
        return nb, resources
Пример #6
0
 def mkdcell(self, source, metadata, slidetype):
     meta = copy.deepcopy(metadata)
     meta.ipyslides = slidetype
     self.append(
         NotebookNode({
             "cell_type": "markdown",
             "source": '\n'.join(source),
             "metadata": meta
         }))
Пример #7
0
    def preprocess_cell(self, cell, resources, cell_index):
        """Also extracts attachments"""
        from nbformat.notebooknode import NotebookNode

        attach_names = []

        # Just move the attachment into an output

        for k, attach in cell.get('attachments', {}).items():
            for mime_type in self.extract_output_types:
                if mime_type in attach:

                    if 'outputs' not in cell:
                        cell['outputs'] = []

                    o = NotebookNode({
                        'data': NotebookNode({mime_type: attach[mime_type]}),
                        'metadata': NotebookNode({
                            'filenames': {mime_type: k}  # Will get re-written
                        }),
                        'output_type': 'display_data'
                    })

                    cell['outputs'].append(o)

                    attach_names.append((mime_type, k))

        nb, resources = super().preprocess_cell(cell, resources, cell_index)

        output_names = list(resources.get('outputs', {}).keys())

        if attach_names:
            # We're going to assume that attachments are only on Markdown cells, and Markdown cells
            # can't generate output, so all of the outputs were added.

            # reverse + zip matches the last len(attach_names) elements from output_names

            for output_name, (mimetype, an) in zip(reversed(output_names), reversed(attach_names)):
                # We'll post process to set the final output directory
                cell.source = re.sub(r'\(attachment:{}\)'.format(an),
                                     '(__IMGDIR__/{})'.format(output_name), cell.source)

        return nb, resources
Пример #8
0
    def preprocess(self, nb, resources):

        if not self.split:
            return nb, resources

        logging.info("splitting outputs into separate cells")

        final_cells = []
        for cell in nb.cells:

            if not cell.cell_type == "code":
                final_cells.append(cell)
                continue
            outputs = cell.pop("outputs")
            cell.outputs = []
            final_cells.append(cell)
            for output in outputs:
                meta = copy.deepcopy(cell.metadata)
                # don't need the code to output
                meta.get("ipub", NotebookNode({})).code = False
                # don't create a new slide for each output,
                # unless specified in output level metadata
                if "slide" in meta.get("ipub", NotebookNode({})):
                    if meta.ipub.slide == "new":
                        meta.ipub.slide = True
                    else:
                        meta.ipub.slide = meta.ipub.slide
                meta = merge(meta, output.get("metadata", {}))
                new = NotebookNode(
                    {
                        "cell_type": "code",
                        "source": "",
                        "execution_count": None,
                        "metadata": meta,
                        "outputs": [output],
                    }
                )
                final_cells.append(new)

        nb.cells = final_cells

        return nb, resources
Пример #9
0
    def preprocess(self, nb, resources):

        logging.info("adding ipub defaults to notebook")

        for keys, val in flatten(self.nb_defaults).items():
            dct = nb.metadata
            for key in keys[:-1]:
                if key not in dct:
                    dct[key] = NotebookNode({})
                dct = dct[key]
            if keys[-1] not in dct:
                dct[keys[-1]] = val
            elif self.overwrite:
                dct[keys[-1]] = val

        for cell in nb.cells:

            for keys, val in flatten(self.cell_defaults).items():
                dct = cell.metadata
                leaf_not_dict = False
                for key in keys[:-1]:
                    if key not in dct:
                        dct[key] = NotebookNode({})
                    elif dct[key] is False and self.overwrite:
                        dct[key] = NotebookNode({})
                    elif dct[key] is True:
                        dct[key] = NotebookNode({})
                    elif not hasattr(dct[key], "items"):
                        leaf_not_dict = True
                        break
                    dct = dct[key]

                if leaf_not_dict:
                    pass
                elif keys[-1] not in dct:
                    dct[keys[-1]] = val
                elif self.overwrite:
                    dct[keys[-1]] = val

        return nb, resources
Пример #10
0
    def preprocess_cell(self, cell, resources, cell_index, store_history=True):
        """
            Need to override preprocess_cell to check reply for errors
            """
        # Copied from nbconvert ExecutePreprocessor
        if cell.cell_type != 'code' or not cell.source.strip():
            return cell, resources

        reply, outputs = self.run_cell(cell, cell_index, store_history)
        # Backwards compatibility for processes that wrap run_cell
        cell.outputs = outputs

        cell_allows_errors = (self.allow_errors
                              or "raises-exception" in cell.metadata.get(
                                  "tags", []))

        if self.force_raise_errors or not cell_allows_errors:
            if (reply is not None) and reply['content']['status'] == 'error':
                raise CellExecutionError.from_cell_and_msg(
                    cell, reply['content'])

        # Ensure errors are recorded to prevent false positives when autograding
        if (reply is None) or reply['content']['status'] == 'error':
            error_recorded = False
            for output in cell.outputs:
                if output.output_type == 'error':
                    error_recorded = True
            if not error_recorded:
                error_output = NotebookNode(output_type='error')
                if reply is None:
                    # Occurs when
                    # IPython.core.interactiveshell.InteractiveShell.showtraceback
                    # = None
                    error_output.ename = "CellTimeoutError"
                    error_output.evalue = ""
                    error_output.traceback = ["ERROR: No reply from kernel"]
                else:
                    # Occurs when
                    # IPython.core.interactiveshell.InteractiveShell.showtraceback
                    # = lambda *args, **kwargs : None
                    error_output.ename = reply['content']['ename']
                    error_output.evalue = reply['content']['evalue']
                    error_output.traceback = reply['content']['traceback']
                    if error_output.traceback == []:
                        error_output.traceback = [
                            "ERROR: An error occurred while"
                            " showtraceback was disabled"
                        ]
                cell.outputs.append(error_output)

        return cell, resources
Пример #11
0
 def edit_notebook(self, nb):
     """
     Inject the code needed to setup and shutdown spark and sc magic variables.
     """
     from nbformat.notebooknode import NotebookNode
     from textwrap import dedent
     preamble_node = NotebookNode(cell_type="code",
                                  source=dedent("""
         from pyspark.sql import SparkSession
         spark = SparkSession.builder.appName("NotebookTestSuite").master("local[*]").getOrCreate()
         globals()["spark"] = spark
         globals()["sc"] = spark.sparkContext
         """))
     epilogue_node = NotebookNode(cell_type="code",
                                  source=dedent("""
         try:
             spark.stop()
         except:
             pass
         """))
     nb.cells.insert(0, preamble_node)
     nb.cells.append(epilogue_node)
     return nb
Пример #12
0
    def ensure_title(self, licence, authors, logo_path):
        """
        make sure the first cell is a author + licence cell
        """

        # the title cell has 3 parts that are equidistant
        # xxx it looks like this <style> tag somehow gets
        # trimmed away when rendered inside of edx
        # so I had to add it in nbhosting's custom.css as well

        def title_cell(licence, authors, logo_path):
            cell = ''
            cell += f'<div class="licence">\n'
            cell += f'<span>{licence}</span>\n'
            if authors:
                cell += f'<span>{" &amp; ".join(authors)}</span>\n'
            if logo_path:
                cell += f'<span><img src="{logo_path}" /></span>\n'
            cell += f'</div>'
            return cell

        # a bit rustic but good enough
        def is_title_cell(cell):
            # for legacy - notebooks tweaked with older versions
            # of this tool, we want to consider first cells that have
            # Licence as being our title cell as well
            return cell['cell_type'] == 'markdown' \
                and (cell['source'].find("title-slide") >= 0
                     or cell['source'].lower().find("licence") >= 0)

        # when opened interactively and then saved again, this is how the result looks like
        expected_title_cell = title_cell(licence, authors, logo_path)
        title_lines = [line + "\n" for line in expected_title_cell.split("\n")]
        # remove last \n
        title_lines[-1] = title_lines[-1][:-1]

        first_cell = self.cells()[0]
        # cell.source is a list of strings
        if is_title_cell(first_cell):
            # licence cell already here, just overwrite contents to latest version
            first_cell['source'] = title_lines
        else:
            self.cells().insert(
                0,
                NotebookNode({
                    "cell_type": "markdown",
                    "metadata": {},
                    "source": title_lines,
                }))
Пример #13
0
    def run_cmd(self, cmd, kernel_name=None):
        """
        Runs python command string.
        """

        if _debugging:
            logging.info('Running command: ' + cmd + ' using kernel: ' +
                         kernel_name)
        notebook = nbformat.v4.new_notebook()
        my_cell = nbformat.v4.new_code_cell(source=cmd)
        notebook.cells = [my_cell]
        if kernel_name:
            notebook.metadata['kernelspec'] = {'name': kernel_name}

        try:
            self.executePreprocessor.preprocess(notebook,
                                                {'metadata': {
                                                    'path': '.'
                                                }})
            if _debugging:
                logging.info('Result notebook: ' +
                             nbformat.v4.writes_json(notebook))
            if len(notebook.cells) < 1 or len(notebook.cells[0].outputs) < 1:
                return None
            return self.postprocess_output(notebook.cells[0].outputs)
        except:
            exc_type, exc_obj, exc_tb = sys.exc_info()

            msg = None
            if _debugging:
                msg = '\n'.join(
                    traceback.format_exception_only(exc_type, exc_obj) +
                    traceback.format_tb(exc_tb))
            else:
                msg = '\n'.join(
                    traceback.format_exception_only(exc_type, exc_obj))

            out = NotebookNode(output_type='error',
                               html=RClansiconv(msg + '\n'))
            return [out]
Пример #14
0
    def on_cell_executed(self, **kwargs):

        cell = kwargs['cell']
        cell_index = kwargs['cell_index']
        reply = kwargs['execute_reply']
        if reply['content']['status'] == 'error':
            error_recorded = False
            for output in cell.outputs:
                if output.output_type == 'error':
                    error_recorded = True
            if not error_recorded:
                # Occurs when
                # IPython.core.interactiveshell.InteractiveShell.showtraceback
                # = lambda *args, **kwargs : None
                error_output = NotebookNode(output_type='error')
                error_output.ename = reply['content']['ename']
                error_output.evalue = reply['content']['evalue']
                error_output.traceback = reply['content']['traceback']
                if error_output.traceback == []:
                    error_output.traceback = ["ERROR: An error occurred while"
                                                " showtraceback was disabled"]
                cell.outputs.append(error_output)
Пример #15
0
    def preprocess(self, nb, resources):

        logger.info("extracting caption cells")

        # extract captions
        final_cells = []
        captions = {}
        for cell in nb.cells:
            if hasattr(cell.metadata, "ipub"):

                if hasattr(cell.metadata.ipub.get("equation", False), "get"):
                    if hasattr(
                            cell.metadata.ipub.equation.get(
                                "environment", False),
                            "startswith",
                    ):
                        if cell.metadata.ipub.equation.environment.startswith(
                                "breqn"):  # noqa: E501
                            if "ipub" not in nb.metadata:
                                nb.metadata["ipub"] = NotebookNode(
                                    {"enable_breqn": True})
                            else:
                                nb.metadata.ipub["enable_breqn"] = True

                if hasattr(cell.metadata.ipub, "caption"):

                    if cell.cell_type == "markdown":
                        capt = cell.source.split(r"\n")[0]
                        captions[cell.metadata.ipub.caption] = capt
                        continue
                    elif cell.cell_type == "code":
                        if not cell.outputs:
                            pass
                        elif "text/latex" in cell.outputs[0].get("data", {}):
                            capt = cell.outputs[0].data["text/latex"].split(
                                r"\n")[0]
                            captions[cell.metadata.ipub.caption] = capt
                            continue
                        elif "text/plain" in cell.outputs[0].get("data", {}):
                            capt = cell.outputs[0].data["text/plain"].split(
                                r"\n")[0]
                            captions[cell.metadata.ipub.caption] = capt
                            continue

            final_cells.append(cell)
        nb.cells = final_cells

        # replace captions
        for cell in nb.cells:
            if hasattr(cell.metadata, "ipub"):
                for key in cell.metadata.ipub:
                    if hasattr(cell.metadata.ipub[key], "label"):
                        if cell.metadata.ipub[key]["label"] in captions:
                            logger.debug("replacing caption for: {}".format(
                                cell.metadata.ipub[key]["label"]))
                            cell.metadata.ipub[key]["caption"] = captions[
                                cell.metadata.ipub[key]["label"]]  # noqa: E501

                    # add float type/number prefix to caption, if required
                    if self.add_prefix:
                        if hasattr(cell.metadata.ipub[key], "caption"):
                            if hasattr(cell.metadata.ipub[key],
                                       "caption_prefix"):
                                newcaption = (
                                    cell.metadata.ipub[key].caption_prefix +
                                    cell.metadata.ipub[key].caption)
                                cell.metadata.ipub[key].caption = newcaption

        return nb, resources
Пример #16
0
    def preprocess(self, nb, resources):

        logging.info(
            'creating slides based on markdown and existing slide tags')
        latexdoc_tags = [
            'code', 'error', 'table', 'equation', 'figure', 'text'
        ]
        # break up titles
        cells_in_slide = 0
        header_levels = []
        final_cells = FinalCells(self.header_slide)
        for i, cell in enumerate(nb.cells):

            # Make sure every cell has an ipub meta tag
            cell.metadata.ipub = cell.metadata.get('ipub', NotebookNode())

            if cell.metadata.ipub.get('ignore', False):
                cell.metadata.ipyslides = 'skip'
                final_cells.append(cell)
                continue

            if cell.metadata.ipub.get('slide', False) == 'notes':
                cell.metadata.ipyslides = 'notes'
                final_cells.append(cell)
                continue

            if not cell.cell_type == "markdown":
                # TODO this doesn't test if the data is actually available to be output
                if not any([
                        cell.metadata.ipub.get(typ, False)
                        for typ in latexdoc_tags
                ]):
                    cell.metadata.ipyslides = 'skip'
                    final_cells.append(cell)
                    continue

                if cells_in_slide > self.max_cells and self.max_cells:
                    cell.metadata.ipyslides = 'verticalbreak_after'
                    cells_in_slide = 1
                elif cell.metadata.ipub.get('slide', False) == 'new':
                    cell.metadata.ipyslides = 'verticalbreak_after'
                    cells_in_slide = 1
                else:
                    cell.metadata.ipyslides = 'normal'
                    cells_in_slide += 1
                final_cells.append(cell)
                continue

            nonheader_lines = []
            for line in cell.source.split('\n'):

                if is_header(line, 0) and self.autonumbering:
                    line, header_levels = number_title(line, header_levels[:])

                if is_header(line, self.column_level):
                    if nonheader_lines and cell.metadata.ipub.get(
                            'slide', False):
                        if (cells_in_slide > self.max_cells and self.max_cells
                            ) or cell.metadata.ipub.slide == 'new':
                            final_cells.mkdcell(nonheader_lines, cell.metadata,
                                                'verticalbreak_after')
                            cells_in_slide = 1
                        else:
                            cells_in_slide += 1
                            final_cells.mkdcell(nonheader_lines, cell.metadata,
                                                'normal')
                        current_lines = []

                    if self.header_slide:
                        final_cells.mkdcell(
                            [line], cell.metadata,
                            'horizontalbreak_after_plusvertical')
                    else:
                        final_cells.mkdcell([line], cell.metadata,
                                            'horizontalbreak_after')
                    cells_in_slide = 1

                elif is_header(line, self.row_level):
                    if nonheader_lines and cell.metadata.ipub.get(
                            'slide', False):
                        if (cells_in_slide > self.max_cells and self.max_cells
                            ) or cell.metadata.ipub.slide == 'new':
                            final_cells.mkdcell(nonheader_lines, cell.metadata,
                                                'verticalbreak_after')
                            cells_in_slide = 1
                        else:
                            cells_in_slide += 1
                            final_cells.mkdcell(nonheader_lines, cell.metadata,
                                                'normal')
                        current_lines = []

                    final_cells.mkdcell([line], cell.metadata,
                                        'verticalbreak_after')
                    cells_in_slide = 1
                else:
                    nonheader_lines.append(line)

            if nonheader_lines and cell.metadata.ipub.get('slide', False):
                if (cells_in_slide > self.max_cells and
                        self.max_cells) or cell.metadata.ipub.slide == 'new':
                    final_cells.mkdcell(nonheader_lines, cell.metadata,
                                        'verticalbreak_after')
                    cells_in_slide = 1
                else:
                    cells_in_slide += 1
                    final_cells.mkdcell(nonheader_lines, cell.metadata,
                                        'normal')

        if not final_cells.finalize():
            logging.warning('no cells available for slideshow')
        nb.cells = final_cells.cells

        return nb, resources
    def preprocess(self, nb, resources):

        logging.info(
            "creating slides based on markdown and existing slide tags")
        latexdoc_tags = [
            "code", "error", "table", "equation", "figure", "text"
        ]
        # break up titles
        cells_in_slide = 0
        final_cells = FinalCells(self.header_slide)

        header_levels = []
        try:
            base_numbering = nb.metadata.toc.base_numbering
            header_levels = list(
                map(lambda x: int(x), base_numbering.split(".")))
            header_levels[0] -= 1
            logging.debug("base_numbering = " + base_numbering)
            logging.debug("header_levels = " + str(header_levels))
        except ValueError:
            logging.warning("Invalid toc.base_numbering in notebook metadata")
        except AttributeError:
            logging.debug(
                "No toc.base_numbering in notebook metadata; starting at 1")

        for i, cell in enumerate(nb.cells):

            # Make sure every cell has an ipub meta tag
            cell.metadata.ipub = cell.metadata.get("ipub", NotebookNode())

            if cell.metadata.ipub.get("ignore", False):
                cell.metadata.ipyslides = "skip"
                final_cells.append(cell)
                continue

            if cell.metadata.ipub.get("slide", False) == "notes":
                cell.metadata.ipyslides = "notes"
                final_cells.append(cell)
                continue

            if not cell.cell_type == "markdown":
                # TODO this doesn't test if the data is actually available
                # to be output
                if not any([
                        cell.metadata.ipub.get(typ, False)
                        for typ in latexdoc_tags
                ]):
                    cell.metadata.ipyslides = "skip"
                    final_cells.append(cell)
                    continue

                if cells_in_slide > self.max_cells and self.max_cells:
                    cell.metadata.ipyslides = "verticalbreak_after"
                    cells_in_slide = 1
                elif cell.metadata.ipub.get("slide", False) == "new":
                    cell.metadata.ipyslides = "verticalbreak_after"
                    cells_in_slide = 1
                else:
                    cell.metadata.ipyslides = "normal"
                    cells_in_slide += 1
                final_cells.append(cell)
                continue

            nonheader_lines = []
            for line in cell.source.split("\n"):

                if is_header(line, 0) and self.autonumbering:
                    line, header_levels = number_title(line, header_levels[:])

                if is_header(line, self.column_level):
                    if nonheader_lines and cell.metadata.ipub.get(
                            "slide", False):
                        if (cells_in_slide > self.max_cells and self.max_cells
                            ) or cell.metadata.ipub.slide == "new":
                            final_cells.mkdcell(nonheader_lines, cell.metadata,
                                                "verticalbreak_after")
                            cells_in_slide = 1
                        else:
                            cells_in_slide += 1
                            final_cells.mkdcell(nonheader_lines, cell.metadata,
                                                "normal")
                        # current_lines = []

                    if self.header_slide:
                        final_cells.mkdcell(
                            [line], cell.metadata,
                            "horizontalbreak_after_plusvertical")
                    else:
                        final_cells.mkdcell([line], cell.metadata,
                                            "horizontalbreak_after")
                    cells_in_slide = 1

                elif is_header(line, self.row_level):
                    if nonheader_lines and cell.metadata.ipub.get(
                            "slide", False):
                        if (cells_in_slide > self.max_cells and self.max_cells
                            ) or cell.metadata.ipub.slide == "new":
                            final_cells.mkdcell(nonheader_lines, cell.metadata,
                                                "verticalbreak_after")
                            cells_in_slide = 1
                        else:
                            cells_in_slide += 1
                            final_cells.mkdcell(nonheader_lines, cell.metadata,
                                                "normal")
                        # current_lines = []

                    final_cells.mkdcell([line], cell.metadata,
                                        "verticalbreak_after")
                    cells_in_slide = 1
                else:
                    nonheader_lines.append(line)

            if nonheader_lines and cell.metadata.ipub.get("slide", False):
                if (cells_in_slide > self.max_cells and
                        self.max_cells) or cell.metadata.ipub.slide == "new":
                    final_cells.mkdcell(nonheader_lines, cell.metadata,
                                        "verticalbreak_after")
                    cells_in_slide = 1
                else:
                    cells_in_slide += 1
                    final_cells.mkdcell(nonheader_lines, cell.metadata,
                                        "normal")

        if not final_cells.finalize():
            logging.warning("no cells available for slideshow")
        nb.cells = final_cells.cells

        return nb, resources
Пример #18
0
    def ensure_title(self, licence, authors, logo_path):
        """
        make sure the first cell is a author + licence cell
        """

        # the title cell has 3 parts that are equidistant
        # xxx it looks like this <style> tag somehow gets
        # trimmed away when rendered inside of edx
        # so I had to add it in nbhosting's custom.css as well
        title_style = '''<style>
div.title-slide {
    width: 100%;
    display: flex;
    flex-direction: row;            /* default value; can be omitted */
    flex-wrap: nowrap;              /* default value; can be omitted */
    justify-content: space-between;
}
</style>
'''

        title_format = '''<div class="title-slide">
<span style="float:left;">{licence}</span>
<span>{html_authors}</span>
<span>{html_image}</span>
</div>'''

        title_image_format = '<img src="{logo_path}" style="display:inline" />'
        html_image = "" if not logo_path else \
                      title_image_format.format(logo_path=logo_path)

        # a bit rustic but good enough

        def is_title_cell(cell):
            # for legacy - notebooks tweaked with older versions
            # of this tool, we want to consider first cells that have
            # Licence as being our title cell as well
            return cell['cell_type'] == 'markdown' \
                and (cell['source'].find("title-slide") >= 0
                     or cell['source'].find("Licence") >= 0)
        html_authors = "" if not authors \
                       else " &amp; ".join(authors)

        title_line = title_style.replace("\n", "") \
                       + title_format.format(
                           licence=licence,
                           html_authors=html_authors,
                           html_image=html_image)

        # when opened interactively and then saved again, this is how the result looks like
        title_lines = [line + "\n" for line in title_line.split("\n")]
        # remove last \n
        title_lines[-1] = title_lines[-1][:-1]

        first_cell = self.cells()[0]
        # cell.source is a list of strings
        if is_title_cell(first_cell):
            # licence cell already here, just overwrite contents to latest version
            first_cell['source'] = title_lines
        else:
            self.cells().insert(
                0,
                NotebookNode({
                    "cell_type": "markdown",
                    "metadata": {},
                    "source": title_lines,
                }))