1e81fdcb135d0325e3bc22fae0583555d20aae280Brendan Jackman#    Copyright 2015-2017 ARM Limited
27712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh#    Copyright 2016 Google Inc. All Rights Reserved.
37712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh#
47712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh# Licensed under the Apache License, Version 2.0 (the "License");
57712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh# you may not use this file except in compliance with the License.
67712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh# You may obtain a copy of the License at
77712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh#
87712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh#     http://www.apache.org/licenses/LICENSE-2.0
97712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh#
107712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh# Unless required by applicable law or agreed to in writing, software
117712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh# distributed under the License is distributed on an "AS IS" BASIS,
127712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh# See the License for the specific language governing permissions and
147712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh# limitations under the License.
157712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh#
167712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh"""Preprocessor to remove Marked Lines from IPython Output Cells"""
177712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh
187712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh
190e6aa44c54f87cedb39fdee542ace0061f94f6f0Javi Merinofrom nbconvert.exporters.html import HTMLExporter
207712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singhfrom nbconvert.preprocessors import Preprocessor
217712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singhimport os
227712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singhimport re
237712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh
247712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar SinghREMOVE_START = '/* TRAPPY_PUBLISH_REMOVE_START */'
257712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar SinghREMOVE_STOP = '/* TRAPPY_PUBLISH_REMOVE_STOP */'
267712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar SinghREMOVE_LINE = '/* TRAPPY_PUBLISH_REMOVE_LINE */'
277712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar SinghIMPORT_SCRIPT = r'/\* TRAPPY_PUBLISH_IMPORT = "([^"]+)" \*/'
287712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar SinghSOURCE_LIB = r'<!-- TRAPPY_PUBLISH_SOURCE_LIB = "([^"]+)" -->'
297712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh
307712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh
310e6aa44c54f87cedb39fdee542ace0061f94f6f0Javi Merinoclass HTML(HTMLExporter):
320e6aa44c54f87cedb39fdee542ace0061f94f6f0Javi Merino    """HTML Exporter class for TRAPpy notebooks"""
330e6aa44c54f87cedb39fdee542ace0061f94f6f0Javi Merino
340e6aa44c54f87cedb39fdee542ace0061f94f6f0Javi Merino    def __init__(self, **kwargs):
350e6aa44c54f87cedb39fdee542ace0061f94f6f0Javi Merino        super(HTML, self).__init__(**kwargs)
360e6aa44c54f87cedb39fdee542ace0061f94f6f0Javi Merino        self.register_preprocessor(TrappyPlotterPreprocessor, enabled=True)
370e6aa44c54f87cedb39fdee542ace0061f94f6f0Javi Merino
380e6aa44c54f87cedb39fdee542ace0061f94f6f0Javi Merino
397712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singhclass TrappyPlotterPreprocessor(Preprocessor):
407712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh    """Preprocessor to remove Marked Lines from IPython Output Cells"""
417712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh
427712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh    def __init__(self, *args, **kwargs):
437712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh        super(Preprocessor, self).__init__(*args, **kwargs)
447712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh        self.inlined_files = []
457712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh        self.sourced_libs = []
467712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh
477712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh    def preprocess_cell(self, cell, resources, cell_index):
487712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh        """Check if cell has text/html output and filter it"""
497712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh
507712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh        if cell.cell_type == 'code' and hasattr(cell, "outputs"):
517712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh            for output in cell.outputs:
527712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh                if output.output_type == "display_data" and \
537712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh                   hasattr( output.data, "text/html"):
547712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh                    filtered =  self.filter_output(output.data["text/html"])
557712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh                    output.data["text/html"] = filtered
567712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh        return cell, resources
577712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh
587712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh    def filter_output(self, output):
597712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh        """Function to remove marked lines"""
607712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh
617712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh        lines = output.split('\n')
627712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh
637712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh        final_lines = []
647712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh        multi_line_remove = False
657712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh        for line in lines:
667712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh            if REMOVE_START in line:
677712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh                multi_line_remove = True
687712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh                continue
697712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh            if REMOVE_STOP in line:
707712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh                multi_line_remove = False
717712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh                continue
727712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh            if multi_line_remove or REMOVE_LINE in line:
737712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh                continue
747712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh
757712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh            import_match = re.search(IMPORT_SCRIPT, line)
767712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh            if import_match:
777712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh                trappy_base = os.path.dirname(os.path.dirname(__file__))
787712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh                import_file = os.path.join(trappy_base, import_match.group(1))
797712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh                if import_file in self.inlined_files:
807712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh                    continue
817712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh
827712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh                with open(import_file) as fin:
837712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh                    final_lines.extend([l[:-1] for l in fin.readlines()])
847712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh
857712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh                self.inlined_files.append(import_file)
867712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh                continue
877712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh
887712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh            source_match = re.search(SOURCE_LIB, line)
897712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh            if source_match:
907712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh                lib_url = source_match.group(1)
917712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh                if lib_url in self.sourced_libs:
927712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh                    continue
937712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh
947712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh                scl = '<script src="{}" type="text/javascript" charset="utf-8"></script>'.\
957712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh                      format(lib_url)
967712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh                final_lines.append(scl)
977712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh
987712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh                self.sourced_libs.append(lib_url)
997712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh                continue
1007712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh
1017712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh            final_lines.append(line)
1027712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh
1037712c8f14d2bac1d2fbdbe5ed78449d71fb75a96Kapileshwar Singh        return '\n'.join(final_lines)
104