Voilà Notebook to PDF Converter

[5]:
# css box model: https://www.w3schools.com/css/css_boxmodel.asp
# box shadow: https://www.w3schools.com/cssref/css3_pr_box-shadow.asp
# adding css style to ipywidgets.Box: https://stackoverflow.com/questions/49863789/setting-background-color-of-a-box-in-ipywidgets
[2]:
%%html
<style>
.box_style{
    box-shadow: 5px 5px 18px #888888;
    padding: 50px;
    margin: 20px;
}
</style>
[3]:
from IPython.display import display, clear_output, Image, HTML
import ipywidgets as widgets
import subprocess, os, base64
import markdown

output = widgets.Output()
fileInput = widgets.FileUpload()
convertButton = widgets.Button(description='Convert')
loadingGifPath = 'https://upload.wikimedia.org/wikipedia/commons/a/a3/Lightness_rotate_36f_cw.gif'

def convert(b):
    with output:
        clear_output()
        display(Image(url=loadingGifPath, width=25, height=25))
        try:
            nbName = list(fileInput.value.keys())[0]
        except IndexError:
            clear_output()
            print()
            display(HTML('<p style="color:red">Have you uploaded a notebook file yet? </p>'))
            return
        pdfName = nbName.replace('ipynb', 'pdf')
        with open(nbName, 'w+b') as f:
            f.write(fileInput.data[0])
        proc = subprocess.run(['jupyter', 'nbconvert', nbName, '--to', 'pdf'])
        clear_output()
        if proc.returncode == 1:
            print()
            display(HTML('<p style="color:red">LaTeX compiling error! </p>'))
        else:
            with open(pdfName, "rb") as f:
                data = f.read()
                b64 = base64.b64encode(data)
                payload = b64.decode()
            display(HTML(f'''<a download="{pdfName}" href="data:text/csv;base64,{payload}" target="_blank">
                            <button class="p-Widget jupyter-widgets jupyter-button widget-button"> Download PDF </button>
                        </a>'''))

convertButton.on_click(convert)

# display(fileInput, convertButton, output)


text = '''
## 3 Easy Steps:
1. Upload your notebook (.ipynb) file. You may only convert one notebook at a time \n
* Hit Convert \n
* A Download button will show up when your PDF file is ready. Enjoy!
'''

footer = '''<br><br/><p>Powered by&emsp;<p/>
<img src="https://raw.githubusercontent.com/beginnerSC/misc/master/docs/source/ds/poweredby.png" alt="Binder, Jupyter, Voilà" width="250"/>
'''

box_layout = widgets.Layout(display='flex',
                flex_flow='column',
                align_items='center',
                width='100%')

form = widgets.VBox([
            widgets.HTML(markdown.markdown('# Notebook to PDF Converter')),
            widgets.HBox([widgets.HTML(markdown.markdown(text)), widgets.HTML('<p>&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;<p/>'),
                widgets.VBox([widgets.HTML('<br><br/>'), fileInput, convertButton, output])]),
            widgets.HTML(markdown.markdown(footer))
        ])
form.add_class('box_style')

widgets.HBox([form], layout=box_layout)