from ipytangle import tangle

square = tangle(x=1, y=(1, lambda x: x*x))

print("square is", square)
square.x = 2
print("y is", square.y)

"""
Explanation: IPyTangle
 
Reactive narratives inspired by Tangle in the Jupyter Notebook.
IPyTangle makes plain markdown into an interactive part of your data-driven narrative.

Installation
Get the most recent release with:
bash
pip install ipytangle
Or the bleeding-edge version:
bash
pip install -e git+https://github.com/bollwyvl/ipytangle#egg=IPyTangle
Usage
In a Notebook, write this python...
```python
from ipytangle import tangle
tangle(cookies=3, calories=lambda cookies: cookies * 50)
```
And this markdown:
markdown
When you eat [`cookies` cookies](#:cookies), you consume [`calories` calories](#:calories).
And you would see something like this:

When you eat 2 cookies, you consume 150 calories.

And interacting with the links would cause the result to update.
Examples
Adapted from the originals from Tangle.

Cookies
California State Parks Proposition 21

Additionally, ipytangle comes with integration with IPython's interact, the easiest way to start using widgets.

Interacting with a tangle
Tangling up interact

Markdown
ipytangle implements most of the TangleKit baseline as markdown links. Because it adds no new notation, unrendered Tangle Markdown should still render in a useful way.
Generally, think of a link as:
markdown
[what the user sees](#:tangle types)
In the link text, backticks, `` are used to represent a JavaScript expression that will be updated on user interaction, cascading updates, or other updates from the kernel. In addition to any variables defined with ipytangle, some formatting libraries are provided. window globals should also work :wink:.
Only the generated code blocks will be transformed, the rest of the elements (if any) will be preserved. This means you can use images, inside the label of a control, for example.
Link Types
[&lt;stringy expression&gt;](#:)
just display a view
markdown
For [`years` years](#:) have I trained Jedi.
[&lt;stringy expression&gt;](#:&lt;variable&gt;)
display a view and update an integer based on dragging
markdown
[made the kessel run in `distance` parsecs](#:distance)
[&lt;booly expression&gt;](#:if) ... [ [&lt;booly expression&gt;](#elif)] ... [ [](#:else) ] ... [](#:endif)
mark some text (which may have other fields) to only display based on condition
markdown
What's more foolish? The [`fool_is_more_foolish`](#:if)fool[](#:else)the fool who follows him(#:endif).
you may also have an else and any number of elifs... because they are markdown span-level elements, you may use 
newlines for easier editing
markdown
[`feeling == "bad"`](#:if) I have a bad feeling about this.
[`feeling == "cautious"`](#:elif) You will never find a more wretched hive of scum and villainy.
[](#:else) Search your feelings.
[](#:endif)
Proposed Link Types
[&lt;stringy expression&gt;](#:&lt;variable&gt;:(int|float):&lt;min&gt;:&lt;max&gt;:&lt;step&gt;)
display a view and update some type of variable. Additionally, minimum maximum and step-size values can be specified.
[](#:&lt;variable&gt;:inline)
Replace the variable, for which a linked widget has been registered (TBD) with the widget itself inline. 

Needs research.

Widgets
At it's core, ipytangle provides Tangle, an IPython Widget. Because of this, a Tangle can connect to any other IPython widgets via traitlets and links. Unlike many widgets, a Tangle doesn't do much with its screen real estate, and might not be very interesting to put inside a layout. Yet.
There are several methods for creating a Tangle.
ipytangle.tangle
As in the above example, this tries to be the most pythonic approach.
End of explanation
"""


from IPython.html.widgets import IntSlider

x = IntSlider(1)
square = tangle(x=x,  y=(1, lambda x: x*x))

print("square is", square)
x.value = 2
print("y is", square.y)

"""
Explanation: Linking to other widgets
tangle makes working with other core and custom widgets easy, automatically copying trait information. If a widget implements value, as most of the core widgets do, you can reference it directly. Alternately, specify a tuple of (widget, "trait_name") to subscribe to that trait.
End of explanation
"""


from ipytangle import Tangle
from IPython.utils import traitlets

class Square(Tangle):
    x = traitlets.CInt(1, sync=True)
    y = traitlets.CInt(1, sync=True)
    
    def _x_changed(self):
        self.y = self.x * self.x

square = Square()

print("square is", square)
square.x = 2
print("y is", square.y)

"""
Explanation: ipytangle.Tangle
If you are already familiar with widgets, subclassing Tangle might be the most convenient:
End of explanation
"""


