%%md 

# RustPython Notebook: python, javascript, css, markdown and math 

Python in the browser is fun 🤘. Python and Javascript working together is double
the fun 😜. Markdown and math are good for communicating ideas 💡(especially
scientific ones 🧠). Adding css to the mix, makes everything look pretty ✨. 

# Main

In the notebook, you can write markdown, math, javascript and python. 


%%math
H(t) \xrightarrow{write} \Big[A(t+1),\ H(t+1)\Big]

%%md 
It even highlights properly. You can multi-task with split view mode and create
python documents as you need to. In main, use `%%` then: 
- `%%md` for markdown
- `%%py` for python
- `%%js` for javascript
- `%%math` for math blocks

Use the other tabs to write functions that you can call out from main. CSS is automatically applied.

%%md 

# DEMO
Here is a run down of what is happening with this demo. The notebook:
- runs JS to create a user interface. 
- the reader can input data, you can do js validation on that input.
- the dynamically created HTML element (with JS) can execute a python function (on click for example)
- the data is passed from Javascript back to Python
- you can run analysis or simulation in python
- the results are displayed with python  or js
- or data can be interactively visualized quickly in the browser with a js vis library.
- everything is styled with css, neatly.
- everything runs in the browser, even on your phone, no servers.

%%js

// Javascript code goes here

injectPython({
    // injectPython functions take the positional arguments as
    // normal function args, and kwargs as the `this` variable
    add_text_input() {
        const input = document.createElement('input');
        pushNotebook(input);
        return () => input.value;
    },
    add_button(buttonText, cb) {
        const do_button = (callback) => {
            const btn = document.createElement('button');
            btn.innerHTML = buttonText;
            btn.addEventListener('click', () => {
                try {
                    // python functions passed to js have a signature
                    // of ([args...], {kwargs...}) => any
                    callback([], {});
                } catch (err) {
                    // puts the traceback in the error box
                    handlePyError(err);
                }
            });
            pushNotebook(btn);
        };

        if (cb == null) {
            // to allow using as a decorator
            return do_button;
        } else {
            do_button(cb);
        }
    },
    add_output() {
        const resultDiv = document.createElement('div');
        resultDiv.classList.add('result');
        pushNotebook(resultDiv);
        return (value) => {
            resultDiv.innerHTML = value;
        };
    },
});

%%py 

# Python code

# you have access to helpers for emitting p & h1-h6
h2("Calculator")
h3("Enter your lucky number")

inp1 = add_text_input()
inp2 = add_text_input()

@add_button("click me to add")
def run_model():
	a, b = int(inp1()), int(inp2())
	set_output(f"<pre>{a} + {b} = <b>{a + b}</b></pre>")

set_output = add_output()
