"""
Script for running notebooks and output nbconverted html files from the
command line, by @damianavila
To be replaced by IPython.nbconvert execute preprocessor in the future:
https://github.com/ipython/ipython/pull/5639
"""
from __future__ import print_function

import io
import os
import sys

from six import iteritems

try:
    from queue import Empty
except ImportError:
    from Queue import Empty

from IPython.kernel import KernelManager
from IPython.nbformat.current import read, NotebookNode
from IPython.nbconvert.exporters import HTMLExporter

from bokeh.utils import encode_utf8


def run_cell(kc, cell):
    iopub = kc.iopub_channel
    shell = kc.shell_channel

    kc.execute(cell.input)
    shell.get_msg(timeout=20)

    outs = []

    while True:
        try:
            msg = iopub.get_msg(timeout=0.2)
        except Empty:
            break

        msg_type = msg['msg_type']

        if msg_type in ('status', 'pyin'):
            continue
        elif msg_type == 'clear_output':
            outs = []
            continue

        content = msg['content']
        out = NotebookNode(output_type=msg_type)

        if msg_type == 'stream':
            out.stream = content['name']
            out.text = content['data']
        elif msg_type in ('display_data', 'execute_result'):
            for mime, data in iteritems(content['data']):
                attr = mime.split('/')[-1].lower()
                # this gets most right, but fix svg+html, plain
                attr = attr.replace('+xml', '').replace('plain', 'text')
                setattr(out, attr, data)
            if msg_type == 'execute_result':
                out.prompt_number = content['execution_count']
        elif msg_type == 'error':
            out.ename = content['ename']
            out.evalue = content['evalue']
            out.traceback = content['traceback']
        elif msg_type == 'execute_input':
            pass
        else:
            print("unhandled iopub msg:", msg_type)

        outs.append(out)
    return outs


def test_notebook(nb):
    km = KernelManager()
    km.start_kernel(extra_arguments=[], stderr=open(os.devnull, 'w'))
    kc = km.client()
    kc.start_channels()
    kc.kernel_info()

    while True:
        try:
            kc.iopub_channel.get_msg(timeout=1)
        except Empty:
            break

    errors = 0
    cells = 0
    for ws in nb.worksheets:
        for cell in ws.cells:
            if cell.cell_type != 'code':
                continue
            cells += 1
            try:
                outs = run_cell(kc, cell)
            except Exception as e:
                print("failed to run cell:", repr(e))
                print(cell.input)
                errors += 1
                continue
            cell.outputs = outs

    if errors:
        print("    %3i cells failed to complete" % errors)
    if cells:
        print("%i code cells from notebook %s" % (cells, nb.metadata.name))

    kc.stop_channels()
    km.shutdown_kernel()
    del km


def main(ipynb):
    print("running %s" % ipynb)
    with io.open(ipynb, encoding='utf8') as f:
        nb = read(f, 'json')
    test_notebook(nb)
    base, ext = os.path.splitext(ipynb)

    outfile = base + ".html"

    exportHtml = HTMLExporter()
    (body, resources) = exportHtml.from_notebook_node(nb)

    open(outfile, 'w').write(encode_utf8(body))
    print("wrote %s" % outfile)

if __name__ == '__main__':
    for ipynb in sys.argv[1:]:
        main(ipynb)

@@ -466,16 +466,8 @@
 rmat
-.current
  imp
@@ -475,16 +475,28 @@
 rt read,
+ NO_CONVERT,
  Noteboo
@@ -592,17 +592,16 @@
 e_utf8%0A%0A
-%0A
 def run_
@@ -691,29 +691,30 @@
 xecute(cell.
-input
+source
 )%0A    shell.
@@ -2036,17 +2036,16 @@
 n outs%0A%0A
-%0A
 def test
@@ -2372,41 +2372,8 @@
 = 0%0A
-    for ws in nb.worksheets:%0A    
     
@@ -2388,10 +2388,10 @@
  in 
-ws
+nb
 .cel
@@ -2402,20 +2402,16 @@
         
-  
-  
 if cell.
@@ -2435,36 +2435,32 @@
 e':%0A            
-    
 continue%0A       
@@ -2444,36 +2444,32 @@
        continue%0A
-    
         cells +=
@@ -2475,37 +2475,29 @@
 = 1%0A        
-  
-  
 try:%0A
-    
             
@@ -2526,28 +2526,24 @@
 ll)%0A        
-    
 except Excep
@@ -2561,28 +2561,24 @@
             
-   
- 
 print(%22faile
@@ -2595,18 +2595,16 @@
 ell:
-%22, repr(e)
+ %25r%22 %25 e
 )%0A  
@@ -2609,28 +2609,24 @@
             
-    
 print(cell.i
@@ -2624,21 +2624,22 @@
 nt(cell.
-input
+source
 )%0A      
@@ -2644,20 +2644,16 @@
         
-    
 errors +
@@ -2660,36 +2660,32 @@
 = 1%0A            
-    
 continue%0A       
@@ -2673,28 +2673,24 @@
    continue%0A
-    
         cell
@@ -2863,16 +2863,27 @@
 etadata.
+kernelspec.
 name))%0A%0A
@@ -2942,17 +2942,16 @@
 del km%0A%0A
-%0A
 def main
@@ -3063,14 +3063,18 @@
 (f, 
-'json'
+NO_CONVERT
 )%0A  
@@ -3138,38 +3138,8 @@
 b)%0A%0A
-    outfile = base + %22.html%22%0A%0A
     
@@ -3221,24 +3221,54 @@
 k_node(nb)%0A%0A
+    outfile = ipynb + %22.html%22%0A
     open(out

Update nbexecuter.py to nbformat v4