Home | History | Annotate | Download | only in nbexport
      1 #    Copyright 2015-2017 ARM Limited
      2 #    Copyright 2016 Google Inc. All Rights Reserved.
      3 #
      4 # Licensed under the Apache License, Version 2.0 (the "License");
      5 # you may not use this file except in compliance with the License.
      6 # You may obtain a copy of the License at
      7 #
      8 #     http://www.apache.org/licenses/LICENSE-2.0
      9 #
     10 # Unless required by applicable law or agreed to in writing, software
     11 # distributed under the License is distributed on an "AS IS" BASIS,
     12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13 # See the License for the specific language governing permissions and
     14 # limitations under the License.
     15 #
     16 """Preprocessor to remove Marked Lines from IPython Output Cells"""
     17 
     18 
     19 from nbconvert.exporters.html import HTMLExporter
     20 from nbconvert.preprocessors import Preprocessor
     21 import os
     22 import re
     23 
     24 REMOVE_START = '/* TRAPPY_PUBLISH_REMOVE_START */'
     25 REMOVE_STOP = '/* TRAPPY_PUBLISH_REMOVE_STOP */'
     26 REMOVE_LINE = '/* TRAPPY_PUBLISH_REMOVE_LINE */'
     27 IMPORT_SCRIPT = r'/\* TRAPPY_PUBLISH_IMPORT = "([^"]+)" \*/'
     28 SOURCE_LIB = r'<!-- TRAPPY_PUBLISH_SOURCE_LIB = "([^"]+)" -->'
     29 
     30 
     31 class HTML(HTMLExporter):
     32     """HTML Exporter class for TRAPpy notebooks"""
     33 
     34     def __init__(self, **kwargs):
     35         super(HTML, self).__init__(**kwargs)
     36         self.register_preprocessor(TrappyPlotterPreprocessor, enabled=True)
     37 
     38 
     39 class TrappyPlotterPreprocessor(Preprocessor):
     40     """Preprocessor to remove Marked Lines from IPython Output Cells"""
     41 
     42     def __init__(self, *args, **kwargs):
     43         super(Preprocessor, self).__init__(*args, **kwargs)
     44         self.inlined_files = []
     45         self.sourced_libs = []
     46 
     47     def preprocess_cell(self, cell, resources, cell_index):
     48         """Check if cell has text/html output and filter it"""
     49 
     50         if cell.cell_type == 'code' and hasattr(cell, "outputs"):
     51             for output in cell.outputs:
     52                 if output.output_type == "display_data" and \
     53                    hasattr( output.data, "text/html"):
     54                     filtered =  self.filter_output(output.data["text/html"])
     55                     output.data["text/html"] = filtered
     56         return cell, resources
     57 
     58     def filter_output(self, output):
     59         """Function to remove marked lines"""
     60 
     61         lines = output.split('\n')
     62 
     63         final_lines = []
     64         multi_line_remove = False
     65         for line in lines:
     66             if REMOVE_START in line:
     67                 multi_line_remove = True
     68                 continue
     69             if REMOVE_STOP in line:
     70                 multi_line_remove = False
     71                 continue
     72             if multi_line_remove or REMOVE_LINE in line:
     73                 continue
     74 
     75             import_match = re.search(IMPORT_SCRIPT, line)
     76             if import_match:
     77                 trappy_base = os.path.dirname(os.path.dirname(__file__))
     78                 import_file = os.path.join(trappy_base, import_match.group(1))
     79                 if import_file in self.inlined_files:
     80                     continue
     81 
     82                 with open(import_file) as fin:
     83                     final_lines.extend([l[:-1] for l in fin.readlines()])
     84 
     85                 self.inlined_files.append(import_file)
     86                 continue
     87 
     88             source_match = re.search(SOURCE_LIB, line)
     89             if source_match:
     90                 lib_url = source_match.group(1)
     91                 if lib_url in self.sourced_libs:
     92                     continue
     93 
     94                 scl = '<script src="{}" type="text/javascript" charset="utf-8"></script>'.\
     95                       format(lib_url)
     96                 final_lines.append(scl)
     97 
     98                 self.sourced_libs.append(lib_url)
     99                 continue
    100 
    101             final_lines.append(line)
    102 
    103         return '\n'.join(final_lines)
    104