mirror of
https://github.com/IHaskell/IHaskell.git
synced 2025-04-16 11:26:08 +00:00
Merge master
This commit is contained in:
commit
6d3afb9e66
@ -44,10 +44,8 @@ install:
|
||||
# Here starts the actual work to be performed for the package under test; any command which exits with a non-zero exit code causes the build to fail.
|
||||
script:
|
||||
- |
|
||||
if [ ${GHCVER%.*} = "7.8" ]; then
|
||||
if [[ ${GHCVER%.*} == "7.8" || ${GHCVER%.*} == "7.10" ]]; then
|
||||
travis_retry ./build.sh all
|
||||
elif [ ${GHCVER%.*} = "7.10" ]; then
|
||||
travis_retry ./build.sh all no-widgets
|
||||
else
|
||||
travis_retry ./build.sh ihaskell
|
||||
fi
|
||||
|
34
README.md
34
README.md
@ -29,6 +29,8 @@ install instructions.
|
||||
|
||||
**How to get help:** Feel free to open an issue [on Github](https://github.com/gibiansky/IHaskell/issues?direction=desc&sort=updated&state=open) or join the [Gitter channel](https://gitter.im/gibiansky/IHaskell?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge).
|
||||
|
||||
Arch Linux has a package for IHaskell: https://aur.archlinux.org/packages/ihaskell-git/
|
||||
|
||||
### Install Using Installation Scripts
|
||||
|
||||
#### Ubuntu:
|
||||
@ -63,17 +65,23 @@ Once this is done, running `ipython --version` should print out `3.0` or above.
|
||||
Note that IHaskell *requires* 3.0 or above; IHaskell *will not work* with IPython 2 or earlier.
|
||||
|
||||
#### Install Haskell
|
||||
Install GHC and Cabal. You must have appropriate versions of both:
|
||||
|
||||
You can let [Stack](http://www.stackage.org/) take care of everything by running `stack setup` from within the IHaskell folder. Stack can also be used to build IHaskell later and will manage dependencies better than cabal (like in issue #578).
|
||||
|
||||
Or you can install GHC and Cabal manually. You must have appropriate versions of both:
|
||||
```bash
|
||||
ghc --numeric-version # Should be 7.6.* or 7.8.*
|
||||
ghc --numeric-version # Should be 7.6.* or 7.8.* or 7.10.*
|
||||
cabal --version # Should be 1.18.* or newer
|
||||
```
|
||||
These may be installed in a number of ways, including the [Haskell Platform](http://www.haskell.org/platform/), as a [standalone Mac app](https://github.com/ghcformacosx/ghc-dot-app), via Homebrew with `brew install ghc cabal-install`, and so on.
|
||||
GHC and Cabal may be installed in a number of other ways, including the [Haskell Platform](http://www.haskell.org/platform/), as a [standalone Mac app](https://github.com/ghcformacosx/ghc-dot-app), via Homebrew with `brew install ghc cabal-install`, and so on.
|
||||
|
||||
|
||||
#### Install ZeroMQ
|
||||
Install ZeroMQ, a library IHaskell uses for asynchronous communication.
|
||||
|
||||
- **Mac OS X**: With [Homebrew](http://brew.sh/) installed, run `brew install zeromq`. (If using 32-bit Haskell Platform, you *may* need to use `brew install zeromq --universal`. YMMV.)
|
||||
- **Mac OS X**:
|
||||
- With [Homebrew](http://brew.sh/) installed, run `brew install zeromq`. (If using 32-bit Haskell Platform, you *may* need to use `brew install zeromq --universal`. YMMV.)
|
||||
- With [MacPorts](https://www.macports.org/) installed, run `ports install zmq`
|
||||
- **Ubuntu**: Run `sudo apt-get install libzmq3-dev`.
|
||||
- **Other**: You can install ZeroMQ from source or use another package manager:
|
||||
```bash
|
||||
@ -87,6 +95,9 @@ sudo ldconfig
|
||||
If your own platform has a package and I haven't included instructions for it, feel free to send me an email or a PR on this README.
|
||||
|
||||
#### Install Haskell Tools
|
||||
|
||||
*(This section can be skipped when using stack)*
|
||||
|
||||
First, make sure that executables installed by `cabal` are on your shell `PATH`:
|
||||
```bash
|
||||
# If you have a ~/.cabal/bin folder:
|
||||
@ -102,7 +113,12 @@ cabal install happy cpphs
|
||||
```
|
||||
|
||||
#### Build IHaskell
|
||||
Install IHaskell! You may install it from Hackage via `cabal install`:
|
||||
Install IHaskell! You may install it from Stackage via `stack install` (check the latest version on [http://www.stackage.org/lts-3.8]:
|
||||
```bash
|
||||
stack install ihaskell-0.6.5.0
|
||||
```
|
||||
|
||||
Or you may install it from Hackage via `cabal install`:
|
||||
```bash
|
||||
cabal install ihaskell --reorder-goals
|
||||
```
|
||||
@ -144,6 +160,14 @@ The above will install `ihaskell`, all support libraries (specified in `stack.ya
|
||||
stack install ihaskell ihaskell-aeson ihaskell-diagrams
|
||||
```
|
||||
|
||||
Mac OS X users using MacPorts may run into an [issue involving libiconv](http://blog.omega-prime.co.uk/?p=96). A solution is to add the following lines in the file stack.yaml:
|
||||
```
|
||||
extra-lib-dirs:
|
||||
- /usr/lib
|
||||
extra-include-dirs:
|
||||
- /usr/include
|
||||
```
|
||||
|
||||
#### Run IHaskell
|
||||
Run IHaskell:
|
||||
- `ihaskell install` to install the IHaskell kernel into Jupyter.
|
||||
|
56
build.sh
56
build.sh
@ -32,9 +32,6 @@ fi
|
||||
# What to install.
|
||||
INSTALLS=""
|
||||
|
||||
# Remove my kernelspec
|
||||
rm -rf ~/.ipython/kernels/haskell
|
||||
|
||||
# Compile dependencies.
|
||||
if [ $# -gt 0 ]; then
|
||||
if [ $1 = "all" ] || [ $1 = "ihaskell" ]; then
|
||||
@ -47,7 +44,7 @@ INSTALLS="$INSTALLS ."
|
||||
|
||||
# Install ihaskell-display packages.
|
||||
if [ $# -gt 0 ]; then
|
||||
if [ $1 = "display" ] || [ $1 = "all" ]; then
|
||||
if [ $1 = "display" ] || [ $1 = "all" ]; then
|
||||
# Install all the display libraries
|
||||
cd ihaskell-display
|
||||
for dir in `ls | grep -v ihaskell-widgets`
|
||||
@ -58,25 +55,46 @@ if [ $# -gt 0 ]; then
|
||||
fi
|
||||
fi
|
||||
|
||||
# Clean all required directories, just in case.
|
||||
TOP=`pwd`
|
||||
for pkg in $INSTALLS
|
||||
do
|
||||
cd ./$pkg
|
||||
cabal clean
|
||||
cd $TOP
|
||||
done
|
||||
cleanup () {
|
||||
# Remove old kernelspec
|
||||
rm -rf ~/.ipython/kernels/haskell
|
||||
|
||||
# Stick a "./" before everything.
|
||||
INSTALL_DIRS=`echo $INSTALLS | tr ' ' '\n' | sed 's#^#./#' | tr ' ' '\n'`
|
||||
# Clean all required directories, just in case.
|
||||
TOP=`pwd`
|
||||
for pkg in $INSTALLS
|
||||
do
|
||||
cd ./$pkg
|
||||
cabal clean
|
||||
cd $TOP
|
||||
done
|
||||
}
|
||||
|
||||
echo CMD: cabal install --constraint "arithmoi -llvm" -j $INSTALL_DIRS --force-reinstalls --max-backjumps=-1 --reorder-goals
|
||||
cabal install --constraint "arithmoi -llvm" -j $INSTALL_DIRS --force-reinstalls --max-backjumps=-1 --reorder-goals
|
||||
install_selected () {
|
||||
# Stick a "./" before everything.
|
||||
INSTALL_DIRS=`echo $INSTALLS | tr ' ' '\n' | sed 's#^#./#' | tr ' ' '\n'`
|
||||
|
||||
if [ $2 = "no-widgets" ]; then
|
||||
echo 'Not installing ihaskell-widgets'
|
||||
elif [ $1 = "display" ] || [ $1 = "all" ]; then
|
||||
echo CMD: cabal install --constraint "arithmoi -llvm" -j $INSTALL_DIRS --force-reinstalls --max-backjumps=-1 --reorder-goals
|
||||
cabal install --constraint "arithmoi -llvm" -j $INSTALL_DIRS --force-reinstalls --max-backjumps=-1 --reorder-goals
|
||||
}
|
||||
|
||||
install_widgets () {
|
||||
echo CMD: cabal install ihaskell-display/ihaskell-widgets
|
||||
cabal install ihaskell-display/ihaskell-widgets
|
||||
}
|
||||
|
||||
# Check if arguments are correct, and proceed as required
|
||||
if [ -z $2 ]; then
|
||||
cleanup
|
||||
install_selected
|
||||
if [ $1 = "display" ] || [ $1 = "all" ]; then
|
||||
install_widgets
|
||||
fi
|
||||
elif [ $2 = "no-widgets" ]; then
|
||||
cleanup
|
||||
install_selected
|
||||
else
|
||||
print_help
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if hash ihaskell 2>/dev/null; then
|
||||
|
@ -1,5 +1,5 @@
|
||||
import Distribution.Simple
|
||||
import System.Cmd
|
||||
import System.Process
|
||||
|
||||
main = defaultMainWithHooks
|
||||
simpleUserHooks { preConf = \args confFlags -> do
|
||||
|
@ -7,7 +7,7 @@ name: ihaskell-diagrams
|
||||
-- PVP summary: +-+------- breaking API changes
|
||||
-- | | +----- non-breaking API additions
|
||||
-- | | | +--- code changes with no API change
|
||||
version: 0.3.0.0
|
||||
version: 0.3.1.0
|
||||
|
||||
-- A short (one-line) description of the package.
|
||||
synopsis: IHaskell display instances for diagram types
|
||||
|
@ -1,52 +0,0 @@
|
||||
{-# LANGUAGE TypeSynonymInstances, QuasiQuotes, FlexibleInstances, OverloadedStrings #-}
|
||||
|
||||
module IHaskell.Display.Parsec () where
|
||||
|
||||
import System.Random
|
||||
import Data.String.Here
|
||||
import Data.HashMap.Strict as Map
|
||||
import Control.Applicative ((<$>))
|
||||
|
||||
import qualified Data.Text as T
|
||||
import Data.Text (Text)
|
||||
|
||||
import Text.Parsec (parse, sourceLine, sourceColumn)
|
||||
import Text.Parsec.String (Parser)
|
||||
import Text.Parsec.Error (errorPos, ParseError)
|
||||
|
||||
import Data.Aeson
|
||||
|
||||
import IHaskell.Display
|
||||
|
||||
instance Show a => IHaskellDisplay (Parser a) where
|
||||
display renderable = return $ many [Display [javascript js], Display [html dom]]
|
||||
where
|
||||
dom = [hereFile|widget.html|]
|
||||
js = [hereFile|widget.js|]
|
||||
|
||||
-- | Text to parse.
|
||||
data ParseText = ParseText String
|
||||
|
||||
instance FromJSON ParseText where
|
||||
parseJSON (Object v) = ParseText <$> v .: "text"
|
||||
parseJSON _ = fail "Expecting object"
|
||||
|
||||
-- | Output of parsing.
|
||||
instance Show a => ToJSON (Either ParseError a) where
|
||||
toJSON (Left err) = object
|
||||
[ "status" .= ("error" :: String)
|
||||
, "line" .= sourceLine (errorPos err)
|
||||
, "col" .= sourceColumn (errorPos err)
|
||||
, "msg" .= show err
|
||||
]
|
||||
toJSON (Right result) = object ["status" .= ("success" :: String), "result" .= show result]
|
||||
|
||||
instance Show a => IHaskellWidget (Parser a) where
|
||||
-- Name for this widget.
|
||||
targetName _ = "parsec"
|
||||
-- When we rece
|
||||
comm widget (Object dict) publisher = do
|
||||
let key = "text" :: Text
|
||||
Just (String text) = Map.lookup key dict
|
||||
result = parse widget "<interactive>" $ T.unpack text
|
||||
publisher $ toJSON result
|
@ -1,20 +0,0 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013 Andrew Gibiansky
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
@ -1,3 +0,0 @@
|
||||
import Distribution.Simple
|
||||
|
||||
main = defaultMain
|
@ -1,74 +0,0 @@
|
||||
-- The name of the package.
|
||||
name: ihaskell-parsec
|
||||
|
||||
-- The package version. See the Haskell package versioning policy (PVP)
|
||||
-- for standards guiding when and how versions should be incremented.
|
||||
-- http://www.haskell.org/haskellwiki/Package_versioning_policy
|
||||
-- PVP summary: +-+------- breaking API changes
|
||||
-- | | +----- non-breaking API additions
|
||||
-- | | | +--- code changes with no API change
|
||||
version: 0.3.0.0
|
||||
|
||||
-- A short (one-line) description of the package.
|
||||
synopsis: IHaskell display instances for Parsec
|
||||
|
||||
-- A longer description of the package.
|
||||
-- description:
|
||||
|
||||
-- URL for the project homepage or repository.
|
||||
homepage: http://www.github.com/gibiansky/ihaskell
|
||||
|
||||
-- The license under which the package is released.
|
||||
license: MIT
|
||||
|
||||
-- The file containing the license text.
|
||||
license-file: LICENSE
|
||||
|
||||
-- The package author(s).
|
||||
author: Andrew Gibiansky
|
||||
|
||||
-- An email address to which users can send suggestions, bug reports, and
|
||||
-- patches.
|
||||
maintainer: andrew.gibiansky@gmail.com
|
||||
|
||||
-- A copyright notice.
|
||||
-- copyright:
|
||||
|
||||
category: Development
|
||||
|
||||
build-type: Simple
|
||||
|
||||
extra-source-files: widget.html, widget.js
|
||||
-- Extra files to be distributed with the package, such as examples or a
|
||||
-- README.
|
||||
-- extra-source-files:
|
||||
|
||||
-- Constraint on the version of Cabal needed to build this package.
|
||||
cabal-version: >=1.16
|
||||
|
||||
library
|
||||
-- Modules exported by the library.
|
||||
exposed-modules: IHaskell.Display.Parsec
|
||||
|
||||
-- Modules included in this library but not exported.
|
||||
-- other-modules:
|
||||
|
||||
-- Language extensions.
|
||||
default-extensions: DoAndIfThenElse
|
||||
OverloadedStrings
|
||||
|
||||
-- Other library packages from which modules are imported.
|
||||
build-depends: base >=4.6 && <4.9,
|
||||
aeson >=0.7 && <0.10,
|
||||
text,
|
||||
unordered-containers,
|
||||
random >= 1,
|
||||
parsec,
|
||||
here,
|
||||
ihaskell >= 0.5
|
||||
|
||||
-- Directories containing source files.
|
||||
-- hs-source-dirs:
|
||||
|
||||
-- Base language which the package is written in.
|
||||
default-language: Haskell2010
|
@ -1,6 +0,0 @@
|
||||
<!-- CodeMirror component -->
|
||||
<link rel="stylesheet" href="/static/components/codemirror/addon/lint/lint.css">
|
||||
|
||||
<!-- Parsec widget DOM -->
|
||||
<form><textarea id="parsec-editor">Insert parser text here...</textarea></form>
|
||||
<pre id="parsec-output"></pre>
|
@ -1,288 +0,0 @@
|
||||
// Only load this script once.
|
||||
var kernel = IPython.notebook.kernel;
|
||||
var initialized = kernel !== undefined && kernel != null;
|
||||
console.log("Initialized", initialized);
|
||||
if (initialized && window.parsecWidgetRegistered === undefined) {
|
||||
|
||||
// Do not load this script again.
|
||||
window.parsecWidgetRegistered = true;
|
||||
|
||||
// Codemirror lint.js
|
||||
// Must be included here, otherwise linting cannot happen the first time the widget is loaded.
|
||||
(function() {
|
||||
"use strict";
|
||||
var GUTTER_ID = "CodeMirror-lint-markers";
|
||||
var SEVERITIES = /^(?:error|warning)$/;
|
||||
|
||||
function showTooltip(e, content) {
|
||||
var tt = document.createElement("div");
|
||||
tt.className = "CodeMirror-lint-tooltip";
|
||||
tt.appendChild(content.cloneNode(true));
|
||||
document.body.appendChild(tt);
|
||||
|
||||
function position(e) {
|
||||
if (!tt.parentNode) return CodeMirror.off(document, "mousemove", position);
|
||||
tt.style.top = Math.max(0, e.clientY - tt.offsetHeight - 5) + "px";
|
||||
tt.style.left = (e.clientX + 5) + "px";
|
||||
}
|
||||
CodeMirror.on(document, "mousemove", position);
|
||||
position(e);
|
||||
if (tt.style.opacity != null) tt.style.opacity = 1;
|
||||
return tt;
|
||||
}
|
||||
function rm(elt) {
|
||||
if (elt.parentNode) elt.parentNode.removeChild(elt);
|
||||
}
|
||||
function hideTooltip(tt) {
|
||||
if (!tt.parentNode) return;
|
||||
if (tt.style.opacity == null) rm(tt);
|
||||
tt.style.opacity = 0;
|
||||
setTimeout(function() { rm(tt); }, 600);
|
||||
}
|
||||
|
||||
function showTooltipFor(e, content, node) {
|
||||
var tooltip = showTooltip(e, content);
|
||||
function hide() {
|
||||
CodeMirror.off(node, "mouseout", hide);
|
||||
if (tooltip) { hideTooltip(tooltip); tooltip = null; }
|
||||
}
|
||||
var poll = setInterval(function() {
|
||||
if (tooltip) for (var n = node;; n = n.parentNode) {
|
||||
if (n == document.body) return;
|
||||
if (!n) { hide(); break; }
|
||||
}
|
||||
if (!tooltip) return clearInterval(poll);
|
||||
}, 400);
|
||||
CodeMirror.on(node, "mouseout", hide);
|
||||
}
|
||||
|
||||
function LintState(cm, options, hasGutter) {
|
||||
this.marked = [];
|
||||
this.options = options;
|
||||
this.timeout = null;
|
||||
this.hasGutter = hasGutter;
|
||||
this.onMouseOver = function(e) { onMouseOver(cm, e); };
|
||||
}
|
||||
|
||||
function parseOptions(cm, options) {
|
||||
if (options instanceof Function) return {getAnnotations: options};
|
||||
if (!options || options === true) options = {};
|
||||
if (!options.getAnnotations) options.getAnnotations = cm.getHelper(CodeMirror.Pos(0, 0), "lint");
|
||||
if (!options.getAnnotations) throw new Error("Required option 'getAnnotations' missing (lint addon)");
|
||||
return options;
|
||||
}
|
||||
|
||||
function clearMarks(cm) {
|
||||
var state = cm.state.lint;
|
||||
if (state.hasGutter) cm.clearGutter(GUTTER_ID);
|
||||
for (var i = 0; i < state.marked.length; ++i)
|
||||
state.marked[i].clear();
|
||||
state.marked.length = 0;
|
||||
}
|
||||
|
||||
function makeMarker(labels, severity, multiple, tooltips) {
|
||||
var marker = document.createElement("div"), inner = marker;
|
||||
marker.className = "CodeMirror-lint-marker-" + severity;
|
||||
if (multiple) {
|
||||
inner = marker.appendChild(document.createElement("div"));
|
||||
inner.className = "CodeMirror-lint-marker-multiple";
|
||||
}
|
||||
|
||||
if (tooltips != false) CodeMirror.on(inner, "mouseover", function(e) {
|
||||
showTooltipFor(e, labels, inner);
|
||||
});
|
||||
|
||||
return marker;
|
||||
}
|
||||
|
||||
function getMaxSeverity(a, b) {
|
||||
if (a == "error") return a;
|
||||
else return b;
|
||||
}
|
||||
|
||||
function groupByLine(annotations) {
|
||||
var lines = [];
|
||||
for (var i = 0; i < annotations.length; ++i) {
|
||||
var ann = annotations[i], line = ann.from.line;
|
||||
(lines[line] || (lines[line] = [])).push(ann);
|
||||
}
|
||||
return lines;
|
||||
}
|
||||
|
||||
function annotationTooltip(ann) {
|
||||
var severity = ann.severity;
|
||||
if (!SEVERITIES.test(severity)) severity = "error";
|
||||
var tip = document.createElement("div");
|
||||
tip.className = "CodeMirror-lint-message-" + severity;
|
||||
tip.appendChild(document.createTextNode(ann.message));
|
||||
return tip;
|
||||
}
|
||||
|
||||
function startLinting(cm) {
|
||||
var state = cm.state.lint, options = state.options;
|
||||
if (options.async)
|
||||
options.getAnnotations(cm, updateLinting, options);
|
||||
else
|
||||
updateLinting(cm, options.getAnnotations(cm.getValue(), options.options));
|
||||
}
|
||||
|
||||
function updateLinting(cm, annotationsNotSorted) {
|
||||
clearMarks(cm);
|
||||
var state = cm.state.lint, options = state.options;
|
||||
|
||||
var annotations = groupByLine(annotationsNotSorted);
|
||||
|
||||
for (var line = 0; line < annotations.length; ++line) {
|
||||
var anns = annotations[line];
|
||||
if (!anns) continue;
|
||||
|
||||
var maxSeverity = null;
|
||||
var tipLabel = state.hasGutter && document.createDocumentFragment();
|
||||
|
||||
for (var i = 0; i < anns.length; ++i) {
|
||||
var ann = anns[i];
|
||||
var severity = ann.severity;
|
||||
if (!SEVERITIES.test(severity)) severity = "error";
|
||||
maxSeverity = getMaxSeverity(maxSeverity, severity);
|
||||
|
||||
if (options.formatAnnotation) ann = options.formatAnnotation(ann);
|
||||
if (state.hasGutter) tipLabel.appendChild(annotationTooltip(ann));
|
||||
|
||||
if (ann.to) state.marked.push(cm.markText(ann.from, ann.to, {
|
||||
className: "CodeMirror-lint-mark-" + severity,
|
||||
__annotation: ann
|
||||
}));
|
||||
}
|
||||
|
||||
if (state.hasGutter)
|
||||
cm.setGutterMarker(line, GUTTER_ID, makeMarker(tipLabel, maxSeverity, anns.length > 1,
|
||||
state.options.tooltips));
|
||||
}
|
||||
if (options.onUpdateLinting) options.onUpdateLinting(annotationsNotSorted, annotations, cm);
|
||||
}
|
||||
|
||||
function onChange(cm) {
|
||||
var state = cm.state.lint;
|
||||
clearTimeout(state.timeout);
|
||||
state.timeout = setTimeout(function(){startLinting(cm);}, state.options.delay || 500);
|
||||
}
|
||||
|
||||
function popupSpanTooltip(ann, e) {
|
||||
var target = e.target || e.srcElement;
|
||||
showTooltipFor(e, annotationTooltip(ann), target);
|
||||
}
|
||||
|
||||
// When the mouseover fires, the cursor might not actually be over
|
||||
// the character itself yet. These pairs of x,y offsets are used to
|
||||
// probe a few nearby points when no suitable marked range is found.
|
||||
var nearby = [0, 0, 0, 5, 0, -5, 5, 0, -5, 0];
|
||||
|
||||
function onMouseOver(cm, e) {
|
||||
if (!/\bCodeMirror-lint-mark-/.test((e.target || e.srcElement).className)) return;
|
||||
for (var i = 0; i < nearby.length; i += 2) {
|
||||
var spans = cm.findMarksAt(cm.coordsChar({left: e.clientX + nearby[i],
|
||||
top: e.clientY + nearby[i + 1]}));
|
||||
for (var j = 0; j < spans.length; ++j) {
|
||||
var span = spans[j], ann = span.__annotation;
|
||||
if (ann) return popupSpanTooltip(ann, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function optionHandler(cm, val, old) {
|
||||
if (old && old != CodeMirror.Init) {
|
||||
clearMarks(cm);
|
||||
cm.off("change", onChange);
|
||||
CodeMirror.off(cm.getWrapperElement(), "mouseover", cm.state.lint.onMouseOver);
|
||||
delete cm.state.lint;
|
||||
}
|
||||
|
||||
if (val) {
|
||||
var gutters = cm.getOption("gutters"), hasLintGutter = false;
|
||||
for (var i = 0; i < gutters.length; ++i) if (gutters[i] == GUTTER_ID) hasLintGutter = true;
|
||||
var state = cm.state.lint = new LintState(cm, parseOptions(cm, val), hasLintGutter);
|
||||
cm.on("change", onChange);
|
||||
if (state.options.tooltips != false)
|
||||
CodeMirror.on(cm.getWrapperElement(), "mouseover", state.onMouseOver);
|
||||
|
||||
startLinting(cm);
|
||||
}
|
||||
}
|
||||
|
||||
CodeMirror.defineOption("lintWith", false, optionHandler); // deprecated
|
||||
CodeMirror.defineOption("lint", false, optionHandler); // deprecated
|
||||
})();
|
||||
|
||||
var parsecWidgetCounter = 0;
|
||||
|
||||
// Register the comm target.
|
||||
var ParsecWidget = function (comm) {
|
||||
this.comm = comm;
|
||||
this.comm.on_msg($.proxy(this.handler, this));
|
||||
|
||||
// Get the cell that was probably executed.
|
||||
// The msg_id:cell mapping will make this possible without guessing.
|
||||
this.cell = IPython.notebook.get_cell(IPython.notebook.get_selected_index()-1);
|
||||
|
||||
// Store this widget so we can use it from callbacks.
|
||||
var widget = this;
|
||||
|
||||
// Editor options.
|
||||
var options = {
|
||||
lineNumbers: true,
|
||||
// Show parsec errors as lint errors.
|
||||
gutters: ["CodeMirror-lint-markers"],
|
||||
lintWith: {
|
||||
"getAnnotations": function(cm, update, opts) {
|
||||
var errs = [];
|
||||
if (widget.hasError) {
|
||||
var col = widget.error["col"];
|
||||
var line = widget.error["line"];
|
||||
errs = [{
|
||||
from: CodeMirror.Pos(line - 1, col - 1),
|
||||
to: CodeMirror.Pos(line - 1, col),
|
||||
message: widget.error["msg"],
|
||||
severity: "error"
|
||||
}];
|
||||
}
|
||||
update(cm, errs);
|
||||
},
|
||||
"async": true,
|
||||
}
|
||||
};
|
||||
|
||||
// Create the editor.
|
||||
var out = this.cell.output_area.element;
|
||||
this.textarea = out.find("#parsec-editor")[0];
|
||||
this.output = out.find("#parsec-output")[0];
|
||||
// Give the elements a different name.
|
||||
this.textarea.id += parsecWidgetCounter;
|
||||
this.output.id += parsecWidgetCounter;
|
||||
parsecWidgetCounter++;
|
||||
|
||||
var editor = CodeMirror.fromTextArea(this.textarea, options);
|
||||
var editor = editor;
|
||||
|
||||
// Update every key press.
|
||||
editor.on("keyup", function() {
|
||||
var text = editor.getDoc().getValue();
|
||||
comm.send({"text": text});
|
||||
});
|
||||
};
|
||||
|
||||
ParsecWidget.prototype.handler = function(msg) {
|
||||
var data = msg.content.data;
|
||||
this.hasError = (data["status"] == "error");
|
||||
console.log(this.hasError);
|
||||
if (this.hasError) {
|
||||
this.output.innerHTML = data["msg"];
|
||||
this.error = data;
|
||||
} else {
|
||||
this.output.innerHTML = data["result"];
|
||||
}
|
||||
};
|
||||
|
||||
// Register this widget.
|
||||
IPython.notebook.kernel.comm_manager.register_target('parsec', IPython.utils.always_new(ParsecWidget));
|
||||
console.log("Registering Parsec widget.");
|
||||
}
|
@ -61,6 +61,7 @@ library
|
||||
build-depends: base >=4.6 && <4.9,
|
||||
plot,
|
||||
bytestring,
|
||||
hmatrix >= 0.10,
|
||||
ihaskell >= 0.6.2
|
||||
|
||||
-- Directories containing source files.
|
||||
|
23
ihaskell-display/ihaskell-widgets/ChangeLog.md
Normal file
23
ihaskell-display/ihaskell-widgets/ChangeLog.md
Normal file
@ -0,0 +1,23 @@
|
||||
# ChangeLog for `ihaskell-widgets`
|
||||
|
||||
## `v0.2.2.1`
|
||||
|
||||
+ The `properties` function now prints types associated with widget fields.
|
||||
|
||||
## `v0.2.2.0`
|
||||
|
||||
+ Bump aeson upper bound to `<0.11`.
|
||||
|
||||
## `v0.2.0.0`
|
||||
|
||||
> Complete version with full fleshed out API.
|
||||
|
||||
Major additions:
|
||||
|
||||
+ Added `interactive` support under `IHaskell.Display.Widgets.Interactive`.
|
||||
+ Add `PlaceProxy`, `Proxy` and `Valid` widgets.
|
||||
+ Support for IPython 4.0.
|
||||
|
||||
## `v0.1.*.*` (Experimental)
|
||||
|
||||
> All IPython widgets and related functionality, but no support for `interactive`.
|
@ -22,13 +22,14 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": true
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"{-# LANGUAGE OverloadedStrings #-}\n",
|
||||
"{-# LANGUAGE FlexibleContexts #-}\n",
|
||||
"import IHaskell.Display.Widgets\n",
|
||||
"import Data.Text (pack, unpack)\n",
|
||||
"import Text.Printf (printf)"
|
||||
@ -43,18 +44,20 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"-- Constructors\n",
|
||||
"-- Check box\n",
|
||||
"chk <- mkCheckBox\n",
|
||||
"\n",
|
||||
"-- Toggle button\n",
|
||||
"tgb <- mkToggleButton\n",
|
||||
"\n",
|
||||
"-- For demonstration\n",
|
||||
"o <- mkHTMLWidget"
|
||||
"-- Valid widget: Displaying booleans conveniently\n",
|
||||
"vld <- mkValidWidget"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -66,16 +69,16 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"-- Display\n",
|
||||
"-- Display the widgets\n",
|
||||
"chk\n",
|
||||
"tgb\n",
|
||||
"o"
|
||||
"vld"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -87,38 +90,23 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": []
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"setField chk Description \"Bool 1: \"\n",
|
||||
"setField tgb Description \"Bool 2\"\n",
|
||||
"\n",
|
||||
"-- Helper function\n",
|
||||
"refresh b =\n",
|
||||
" let stat = if b then \"green\" else \"red\"\n",
|
||||
" fmt = \"<div style=\\\"background:%s;color:#ffffff\\\"><b>%s</b></div>\"\n",
|
||||
" in setField o StringValue $ pack $ printf fmt stat (show b)\n",
|
||||
"\n",
|
||||
" -- Cosmetic changes\n",
|
||||
"setField o Description \"Bool 1 && Bool 2\"\n",
|
||||
"setField o Padding 10\n",
|
||||
"setField vld Description \"Bool 1 && Bool 2\"\n",
|
||||
"\n",
|
||||
" -- And (&&) the two values, and send output to html widget\n",
|
||||
"setHandler w = setField w ChangeHandler $ do\n",
|
||||
" b1 <- getField chk BoolValue\n",
|
||||
" b2 <- getField tgb BoolValue\n",
|
||||
" refresh (b1 && b2)\n",
|
||||
" setField vld BoolValue (b1 && b2)\n",
|
||||
"\n",
|
||||
"setHandler chk\n",
|
||||
"setHandler tgb"
|
||||
@ -142,7 +130,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
@ -163,19 +151,11 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": []
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"sign <- mkCheckBox\n",
|
||||
"bits <- replicateM 7 mkToggleButton\n",
|
||||
@ -195,19 +175,11 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": []
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"box <- mkFlexBox\n",
|
||||
"out <- mkHTMLWidget\n",
|
||||
@ -248,19 +220,11 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": []
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import Control.Arrow (first, second)\n",
|
||||
"\n",
|
||||
@ -295,6 +259,12 @@
|
||||
"display_name": "Haskell",
|
||||
"language": "haskell",
|
||||
"name": "haskell"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": "ihaskell",
|
||||
"file_extension": ".hs",
|
||||
"name": "haskell",
|
||||
"version": "7.10.2"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
|
@ -23,7 +23,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": true
|
||||
},
|
||||
@ -42,121 +42,12 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false,
|
||||
"scrolled": true
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<style>/*\n",
|
||||
"Custom IHaskell CSS.\n",
|
||||
"*/\n",
|
||||
"\n",
|
||||
"/* Styles used for the Hoogle display in the pager */\n",
|
||||
".hoogle-doc {\n",
|
||||
" display: block;\n",
|
||||
" padding-bottom: 1.3em;\n",
|
||||
" padding-left: 0.4em;\n",
|
||||
"}\n",
|
||||
".hoogle-code {\n",
|
||||
" display: block;\n",
|
||||
" font-family: monospace;\n",
|
||||
" white-space: pre;\n",
|
||||
"}\n",
|
||||
".hoogle-text {\n",
|
||||
" display: block;\n",
|
||||
"}\n",
|
||||
".hoogle-name {\n",
|
||||
" color: green;\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
".hoogle-head {\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
".hoogle-sub {\n",
|
||||
" display: block;\n",
|
||||
" margin-left: 0.4em;\n",
|
||||
"}\n",
|
||||
".hoogle-package {\n",
|
||||
" font-weight: bold;\n",
|
||||
" font-style: italic;\n",
|
||||
"}\n",
|
||||
".hoogle-module {\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
".hoogle-class {\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"/* Styles used for basic displays */\n",
|
||||
".get-type {\n",
|
||||
" color: green;\n",
|
||||
" font-weight: bold;\n",
|
||||
" font-family: monospace;\n",
|
||||
" display: block;\n",
|
||||
" white-space: pre-wrap;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
".show-type {\n",
|
||||
" color: green;\n",
|
||||
" font-weight: bold;\n",
|
||||
" font-family: monospace;\n",
|
||||
" margin-left: 1em;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
".mono {\n",
|
||||
" font-family: monospace;\n",
|
||||
" display: block;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
".err-msg {\n",
|
||||
" color: red;\n",
|
||||
" font-style: italic;\n",
|
||||
" font-family: monospace;\n",
|
||||
" white-space: pre;\n",
|
||||
" display: block;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"#unshowable {\n",
|
||||
" color: red;\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
".err-msg.in.collapse {\n",
|
||||
" padding-top: 0.7em;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"/* Code that will get highlighted before it is highlighted */\n",
|
||||
".highlight-code {\n",
|
||||
" white-space: pre;\n",
|
||||
" font-family: monospace;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"/* Hlint styles */\n",
|
||||
".suggestion-warning { \n",
|
||||
" font-weight: bold;\n",
|
||||
" color: rgb(200, 130, 0);\n",
|
||||
"}\n",
|
||||
".suggestion-error { \n",
|
||||
" font-weight: bold;\n",
|
||||
" color: red;\n",
|
||||
"}\n",
|
||||
".suggestion-name {\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
"</style><span class='get-type'>ChildWidget :: forall (w :: WidgetType). (RecAll Attr (WidgetFields w) ToPairs) => IPythonWidget w -> ChildWidget</span>"
|
||||
],
|
||||
"text/plain": [
|
||||
"ChildWidget :: forall (w :: WidgetType). (RecAll Attr (WidgetFields w) ToPairs) => IPythonWidget w -> ChildWidget"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"source": [
|
||||
":t ChildWidget"
|
||||
]
|
||||
@ -170,7 +61,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
@ -190,19 +81,11 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": []
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import Control.Monad (replicateM)\n",
|
||||
"\n",
|
||||
@ -236,125 +119,12 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false,
|
||||
"scrolled": true
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<style>/*\n",
|
||||
"Custom IHaskell CSS.\n",
|
||||
"*/\n",
|
||||
"\n",
|
||||
"/* Styles used for the Hoogle display in the pager */\n",
|
||||
".hoogle-doc {\n",
|
||||
" display: block;\n",
|
||||
" padding-bottom: 1.3em;\n",
|
||||
" padding-left: 0.4em;\n",
|
||||
"}\n",
|
||||
".hoogle-code {\n",
|
||||
" display: block;\n",
|
||||
" font-family: monospace;\n",
|
||||
" white-space: pre;\n",
|
||||
"}\n",
|
||||
".hoogle-text {\n",
|
||||
" display: block;\n",
|
||||
"}\n",
|
||||
".hoogle-name {\n",
|
||||
" color: green;\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
".hoogle-head {\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
".hoogle-sub {\n",
|
||||
" display: block;\n",
|
||||
" margin-left: 0.4em;\n",
|
||||
"}\n",
|
||||
".hoogle-package {\n",
|
||||
" font-weight: bold;\n",
|
||||
" font-style: italic;\n",
|
||||
"}\n",
|
||||
".hoogle-module {\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
".hoogle-class {\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"/* Styles used for basic displays */\n",
|
||||
".get-type {\n",
|
||||
" color: green;\n",
|
||||
" font-weight: bold;\n",
|
||||
" font-family: monospace;\n",
|
||||
" display: block;\n",
|
||||
" white-space: pre-wrap;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
".show-type {\n",
|
||||
" color: green;\n",
|
||||
" font-weight: bold;\n",
|
||||
" font-family: monospace;\n",
|
||||
" margin-left: 1em;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
".mono {\n",
|
||||
" font-family: monospace;\n",
|
||||
" display: block;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
".err-msg {\n",
|
||||
" color: red;\n",
|
||||
" font-style: italic;\n",
|
||||
" font-family: monospace;\n",
|
||||
" white-space: pre;\n",
|
||||
" display: block;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"#unshowable {\n",
|
||||
" color: red;\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
".err-msg.in.collapse {\n",
|
||||
" padding-top: 0.7em;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"/* Code that will get highlighted before it is highlighted */\n",
|
||||
".highlight-code {\n",
|
||||
" white-space: pre;\n",
|
||||
" font-family: monospace;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"/* Hlint styles */\n",
|
||||
".suggestion-warning { \n",
|
||||
" font-weight: bold;\n",
|
||||
" color: rgb(200, 130, 0);\n",
|
||||
"}\n",
|
||||
".suggestion-error { \n",
|
||||
" font-weight: bold;\n",
|
||||
" color: red;\n",
|
||||
"}\n",
|
||||
".suggestion-name {\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
"</style><span class='err-msg'>No instance for (Data.Vinyl.Lens.RElem<br/> 'ihaskell-widgets-0.1.0.0:IHaskell.Display.Widgets.Singletons.Orientation '[] (Data.Vinyl.TypeLevel.RIndex 'ihaskell-widgets-0.1.0.0:IHaskell.Display.Widgets.Singletons.Orientation '[]))<br/> arising from a use of ‘setField’<br/>In the expression: setField box Orientation VerticalOrientation<br/>In an equation for ‘it’: it = setField box Orientation VerticalOrientation</span>"
|
||||
],
|
||||
"text/plain": [
|
||||
"No instance for (Data.Vinyl.Lens.RElem\n",
|
||||
" 'ihaskell-widgets-0.1.0.0:IHaskell.Display.Widgets.Singletons.Orientation '[] (Data.Vinyl.TypeLevel.RIndex 'ihaskell-widgets-0.1.0.0:IHaskell.Display.Widgets.Singletons.Orientation '[]))\n",
|
||||
" arising from a use of ‘setField’\n",
|
||||
"In the expression: setField box Orientation VerticalOrientation\n",
|
||||
"In an equation for ‘it’: it = setField box Orientation VerticalOrientation"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"-- Trying to set orientation for Boxes\n",
|
||||
"setField box Orientation VerticalOrientation"
|
||||
@ -369,24 +139,115 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": []
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"-- Trying to set orientation for FlexBox\n",
|
||||
"setField flx Orientation VerticalOrientation"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### ProxyWidget and PlaceProxy"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"The `ProxyWidget` widget allows for zero-or-one widgets to be placed inside it.\n",
|
||||
"\n",
|
||||
"From the IHaskell perspective, this is similar to the `Output` widget, but supports only widgets inside it."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"[b1, b2, b3] <- replicateM 3 mkButton\n",
|
||||
"\n",
|
||||
"setField b1 Description \"Button 1\"\n",
|
||||
"setField b2 Description \"Button 2\"\n",
|
||||
"setField b3 Description \"Button 3\"\n",
|
||||
"\n",
|
||||
"-- A proxy widget to display one button at a time\n",
|
||||
"proxy <- mkProxyWidget\n",
|
||||
"\n",
|
||||
"-- b1 ~> b2\n",
|
||||
"setField b1 ClickHandler $ setField proxy Child (Just $ ChildWidget b2)\n",
|
||||
"\n",
|
||||
"-- b2 ~> b3\n",
|
||||
"setField b2 ClickHandler $ setField proxy Child (Just $ ChildWidget b3)\n",
|
||||
"\n",
|
||||
"-- b3 ~> b1\n",
|
||||
"setField b3 ClickHandler $ setField proxy Child (Just $ ChildWidget b1)\n",
|
||||
"\n",
|
||||
"-- Set initial child, and display\n",
|
||||
"setField proxy Child (Just $ ChildWidget b1)\n",
|
||||
"\n",
|
||||
"proxy"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"The `PlaceProxy` widget allows for more flexible use-cases involving arbitrary widgets. It is similar to `ProxyWidget`, but allows more control over where the widget is displayed.\n",
|
||||
"\n",
|
||||
"This widget can be used to display widgets inside markdown cells, among other places such as custom widgets or custom html elements. For example, we can create a html `div` inside this markdown cell, and cause the child widget to display in it using its CSS selector.\n",
|
||||
"\n",
|
||||
"`<div id=\"widget_out\"></div>`\n",
|
||||
"\n",
|
||||
"<div id=\"widget_out\"></div>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false,
|
||||
"scrolled": false
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"pp <- mkPlaceProxy\n",
|
||||
"button <- mkButton\n",
|
||||
"setField button Description \"(0,0)\"\n",
|
||||
"\n",
|
||||
"-- Put button inside the place proxy widget\n",
|
||||
"setField pp Child (Just $ ChildWidget button)\n",
|
||||
"\n",
|
||||
"-- Output to the div created above\n",
|
||||
"setField pp Selector \"#widget_out\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"The widget doesn't yet display, but when we try to display it, the child widget shows in the div as expected."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": true
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"pp"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
@ -403,7 +264,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": true
|
||||
},
|
||||
@ -422,19 +283,11 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": []
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"buttons' <- replicateM 5 mkButton\n",
|
||||
"\n",
|
||||
@ -460,6 +313,12 @@
|
||||
"display_name": "Haskell",
|
||||
"language": "haskell",
|
||||
"name": "haskell"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": "ihaskell",
|
||||
"file_extension": ".hs",
|
||||
"name": "haskell",
|
||||
"version": "7.10.2"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
|
@ -68,7 +68,7 @@
|
||||
"jpg <- get \"http://imgs.xkcd.com/comics/functional.png\"\n",
|
||||
"\n",
|
||||
"img <- mkImageWidget\n",
|
||||
"setField img SB64Value (encode64 jpg)\n",
|
||||
"setField img B64Value (encode64 jpg)\n",
|
||||
"img"
|
||||
]
|
||||
},
|
||||
@ -104,6 +104,12 @@
|
||||
"display_name": "Haskell",
|
||||
"language": "haskell",
|
||||
"name": "haskell"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": "ihaskell",
|
||||
"file_extension": ".hs",
|
||||
"name": "haskell",
|
||||
"version": "7.10.2"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
|
@ -103,7 +103,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": true
|
||||
},
|
||||
@ -139,120 +139,11 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<style>/*\n",
|
||||
"Custom IHaskell CSS.\n",
|
||||
"*/\n",
|
||||
"\n",
|
||||
"/* Styles used for the Hoogle display in the pager */\n",
|
||||
".hoogle-doc {\n",
|
||||
" display: block;\n",
|
||||
" padding-bottom: 1.3em;\n",
|
||||
" padding-left: 0.4em;\n",
|
||||
"}\n",
|
||||
".hoogle-code {\n",
|
||||
" display: block;\n",
|
||||
" font-family: monospace;\n",
|
||||
" white-space: pre;\n",
|
||||
"}\n",
|
||||
".hoogle-text {\n",
|
||||
" display: block;\n",
|
||||
"}\n",
|
||||
".hoogle-name {\n",
|
||||
" color: green;\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
".hoogle-head {\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
".hoogle-sub {\n",
|
||||
" display: block;\n",
|
||||
" margin-left: 0.4em;\n",
|
||||
"}\n",
|
||||
".hoogle-package {\n",
|
||||
" font-weight: bold;\n",
|
||||
" font-style: italic;\n",
|
||||
"}\n",
|
||||
".hoogle-module {\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
".hoogle-class {\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"/* Styles used for basic displays */\n",
|
||||
".get-type {\n",
|
||||
" color: green;\n",
|
||||
" font-weight: bold;\n",
|
||||
" font-family: monospace;\n",
|
||||
" display: block;\n",
|
||||
" white-space: pre-wrap;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
".show-type {\n",
|
||||
" color: green;\n",
|
||||
" font-weight: bold;\n",
|
||||
" font-family: monospace;\n",
|
||||
" margin-left: 1em;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
".mono {\n",
|
||||
" font-family: monospace;\n",
|
||||
" display: block;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
".err-msg {\n",
|
||||
" color: red;\n",
|
||||
" font-style: italic;\n",
|
||||
" font-family: monospace;\n",
|
||||
" white-space: pre;\n",
|
||||
" display: block;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"#unshowable {\n",
|
||||
" color: red;\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
".err-msg.in.collapse {\n",
|
||||
" padding-top: 0.7em;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"/* Code that will get highlighted before it is highlighted */\n",
|
||||
".highlight-code {\n",
|
||||
" white-space: pre;\n",
|
||||
" font-family: monospace;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"/* Hlint styles */\n",
|
||||
".suggestion-warning { \n",
|
||||
" font-weight: bold;\n",
|
||||
" color: rgb(200, 130, 0);\n",
|
||||
"}\n",
|
||||
".suggestion-error { \n",
|
||||
" font-weight: bold;\n",
|
||||
" color: red;\n",
|
||||
"}\n",
|
||||
".suggestion-name {\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
"</style><span class='get-type'>setField :: forall (w :: WidgetType) (f :: Field). (RElem f (WidgetFields w) (RIndex f (WidgetFields w)), ToPairs (Attr f), IHaskellWidget (IPythonWidget w)) => IPythonWidget w -> SField f -> FieldType f -> IO ()</span>"
|
||||
],
|
||||
"text/plain": [
|
||||
"setField :: forall (w :: WidgetType) (f :: Field). (RElem f (WidgetFields w) (RIndex f (WidgetFields w)), ToPairs (Attr f), IHaskellWidget (IPythonWidget w)) => IPythonWidget w -> SField f -> FieldType f -> IO ()"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"source": [
|
||||
":t setField"
|
||||
]
|
||||
@ -270,121 +161,12 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false,
|
||||
"scrolled": true
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<style>/*\n",
|
||||
"Custom IHaskell CSS.\n",
|
||||
"*/\n",
|
||||
"\n",
|
||||
"/* Styles used for the Hoogle display in the pager */\n",
|
||||
".hoogle-doc {\n",
|
||||
" display: block;\n",
|
||||
" padding-bottom: 1.3em;\n",
|
||||
" padding-left: 0.4em;\n",
|
||||
"}\n",
|
||||
".hoogle-code {\n",
|
||||
" display: block;\n",
|
||||
" font-family: monospace;\n",
|
||||
" white-space: pre;\n",
|
||||
"}\n",
|
||||
".hoogle-text {\n",
|
||||
" display: block;\n",
|
||||
"}\n",
|
||||
".hoogle-name {\n",
|
||||
" color: green;\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
".hoogle-head {\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
".hoogle-sub {\n",
|
||||
" display: block;\n",
|
||||
" margin-left: 0.4em;\n",
|
||||
"}\n",
|
||||
".hoogle-package {\n",
|
||||
" font-weight: bold;\n",
|
||||
" font-style: italic;\n",
|
||||
"}\n",
|
||||
".hoogle-module {\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
".hoogle-class {\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"/* Styles used for basic displays */\n",
|
||||
".get-type {\n",
|
||||
" color: green;\n",
|
||||
" font-weight: bold;\n",
|
||||
" font-family: monospace;\n",
|
||||
" display: block;\n",
|
||||
" white-space: pre-wrap;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
".show-type {\n",
|
||||
" color: green;\n",
|
||||
" font-weight: bold;\n",
|
||||
" font-family: monospace;\n",
|
||||
" margin-left: 1em;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
".mono {\n",
|
||||
" font-family: monospace;\n",
|
||||
" display: block;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
".err-msg {\n",
|
||||
" color: red;\n",
|
||||
" font-style: italic;\n",
|
||||
" font-family: monospace;\n",
|
||||
" white-space: pre;\n",
|
||||
" display: block;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"#unshowable {\n",
|
||||
" color: red;\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
".err-msg.in.collapse {\n",
|
||||
" padding-top: 0.7em;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"/* Code that will get highlighted before it is highlighted */\n",
|
||||
".highlight-code {\n",
|
||||
" white-space: pre;\n",
|
||||
" font-family: monospace;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"/* Hlint styles */\n",
|
||||
".suggestion-warning { \n",
|
||||
" font-weight: bold;\n",
|
||||
" color: rgb(200, 130, 0);\n",
|
||||
"}\n",
|
||||
".suggestion-error { \n",
|
||||
" font-weight: bold;\n",
|
||||
" color: red;\n",
|
||||
"}\n",
|
||||
".suggestion-name {\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
"</style><span class='get-type'>getField :: forall (w :: WidgetType) (f :: Field). RElem f (WidgetFields w) (RIndex f (WidgetFields w)) => IPythonWidget w -> SField f -> IO (FieldType f)</span>"
|
||||
],
|
||||
"text/plain": [
|
||||
"getField :: forall (w :: WidgetType) (f :: Field). RElem f (WidgetFields w) (RIndex f (WidgetFields w)) => IPythonWidget w -> SField f -> IO (FieldType f)"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"source": [
|
||||
":t getField"
|
||||
]
|
||||
@ -405,120 +187,11 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<style>/*\n",
|
||||
"Custom IHaskell CSS.\n",
|
||||
"*/\n",
|
||||
"\n",
|
||||
"/* Styles used for the Hoogle display in the pager */\n",
|
||||
".hoogle-doc {\n",
|
||||
" display: block;\n",
|
||||
" padding-bottom: 1.3em;\n",
|
||||
" padding-left: 0.4em;\n",
|
||||
"}\n",
|
||||
".hoogle-code {\n",
|
||||
" display: block;\n",
|
||||
" font-family: monospace;\n",
|
||||
" white-space: pre;\n",
|
||||
"}\n",
|
||||
".hoogle-text {\n",
|
||||
" display: block;\n",
|
||||
"}\n",
|
||||
".hoogle-name {\n",
|
||||
" color: green;\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
".hoogle-head {\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
".hoogle-sub {\n",
|
||||
" display: block;\n",
|
||||
" margin-left: 0.4em;\n",
|
||||
"}\n",
|
||||
".hoogle-package {\n",
|
||||
" font-weight: bold;\n",
|
||||
" font-style: italic;\n",
|
||||
"}\n",
|
||||
".hoogle-module {\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
".hoogle-class {\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"/* Styles used for basic displays */\n",
|
||||
".get-type {\n",
|
||||
" color: green;\n",
|
||||
" font-weight: bold;\n",
|
||||
" font-family: monospace;\n",
|
||||
" display: block;\n",
|
||||
" white-space: pre-wrap;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
".show-type {\n",
|
||||
" color: green;\n",
|
||||
" font-weight: bold;\n",
|
||||
" font-family: monospace;\n",
|
||||
" margin-left: 1em;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
".mono {\n",
|
||||
" font-family: monospace;\n",
|
||||
" display: block;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
".err-msg {\n",
|
||||
" color: red;\n",
|
||||
" font-style: italic;\n",
|
||||
" font-family: monospace;\n",
|
||||
" white-space: pre;\n",
|
||||
" display: block;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"#unshowable {\n",
|
||||
" color: red;\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
".err-msg.in.collapse {\n",
|
||||
" padding-top: 0.7em;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"/* Code that will get highlighted before it is highlighted */\n",
|
||||
".highlight-code {\n",
|
||||
" white-space: pre;\n",
|
||||
" font-family: monospace;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"/* Hlint styles */\n",
|
||||
".suggestion-warning { \n",
|
||||
" font-weight: bold;\n",
|
||||
" color: rgb(200, 130, 0);\n",
|
||||
"}\n",
|
||||
".suggestion-error { \n",
|
||||
" font-weight: bold;\n",
|
||||
" color: red;\n",
|
||||
"}\n",
|
||||
".suggestion-name {\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
"</style><span class='get-type'>properties :: forall (w :: WidgetType). IPythonWidget w -> IO ()</span>"
|
||||
],
|
||||
"text/plain": [
|
||||
"properties :: forall (w :: WidgetType). IPythonWidget w -> IO ()"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"source": [
|
||||
":t properties"
|
||||
]
|
||||
@ -534,30 +207,11 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"3"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"\"abc\""
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"-- Showables\n",
|
||||
"1 + 2\n",
|
||||
@ -573,120 +227,11 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<style>/*\n",
|
||||
"Custom IHaskell CSS.\n",
|
||||
"*/\n",
|
||||
"\n",
|
||||
"/* Styles used for the Hoogle display in the pager */\n",
|
||||
".hoogle-doc {\n",
|
||||
" display: block;\n",
|
||||
" padding-bottom: 1.3em;\n",
|
||||
" padding-left: 0.4em;\n",
|
||||
"}\n",
|
||||
".hoogle-code {\n",
|
||||
" display: block;\n",
|
||||
" font-family: monospace;\n",
|
||||
" white-space: pre;\n",
|
||||
"}\n",
|
||||
".hoogle-text {\n",
|
||||
" display: block;\n",
|
||||
"}\n",
|
||||
".hoogle-name {\n",
|
||||
" color: green;\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
".hoogle-head {\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
".hoogle-sub {\n",
|
||||
" display: block;\n",
|
||||
" margin-left: 0.4em;\n",
|
||||
"}\n",
|
||||
".hoogle-package {\n",
|
||||
" font-weight: bold;\n",
|
||||
" font-style: italic;\n",
|
||||
"}\n",
|
||||
".hoogle-module {\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
".hoogle-class {\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"/* Styles used for basic displays */\n",
|
||||
".get-type {\n",
|
||||
" color: green;\n",
|
||||
" font-weight: bold;\n",
|
||||
" font-family: monospace;\n",
|
||||
" display: block;\n",
|
||||
" white-space: pre-wrap;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
".show-type {\n",
|
||||
" color: green;\n",
|
||||
" font-weight: bold;\n",
|
||||
" font-family: monospace;\n",
|
||||
" margin-left: 1em;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
".mono {\n",
|
||||
" font-family: monospace;\n",
|
||||
" display: block;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
".err-msg {\n",
|
||||
" color: red;\n",
|
||||
" font-style: italic;\n",
|
||||
" font-family: monospace;\n",
|
||||
" white-space: pre;\n",
|
||||
" display: block;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"#unshowable {\n",
|
||||
" color: red;\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
".err-msg.in.collapse {\n",
|
||||
" padding-top: 0.7em;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"/* Code that will get highlighted before it is highlighted */\n",
|
||||
".highlight-code {\n",
|
||||
" white-space: pre;\n",
|
||||
" font-family: monospace;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"/* Hlint styles */\n",
|
||||
".suggestion-warning { \n",
|
||||
" font-weight: bold;\n",
|
||||
" color: rgb(200, 130, 0);\n",
|
||||
"}\n",
|
||||
".suggestion-error { \n",
|
||||
" font-weight: bold;\n",
|
||||
" color: red;\n",
|
||||
"}\n",
|
||||
".suggestion-name {\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
"</style><span class='get-type'>display :: forall a. IHaskellDisplay a => a -> IO Display</span>"
|
||||
],
|
||||
"text/plain": [
|
||||
"display :: forall a. IHaskellDisplay a => a -> IO Display"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import IHaskell.Display\n",
|
||||
":t display"
|
||||
@ -714,120 +259,11 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<style>/*\n",
|
||||
"Custom IHaskell CSS.\n",
|
||||
"*/\n",
|
||||
"\n",
|
||||
"/* Styles used for the Hoogle display in the pager */\n",
|
||||
".hoogle-doc {\n",
|
||||
" display: block;\n",
|
||||
" padding-bottom: 1.3em;\n",
|
||||
" padding-left: 0.4em;\n",
|
||||
"}\n",
|
||||
".hoogle-code {\n",
|
||||
" display: block;\n",
|
||||
" font-family: monospace;\n",
|
||||
" white-space: pre;\n",
|
||||
"}\n",
|
||||
".hoogle-text {\n",
|
||||
" display: block;\n",
|
||||
"}\n",
|
||||
".hoogle-name {\n",
|
||||
" color: green;\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
".hoogle-head {\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
".hoogle-sub {\n",
|
||||
" display: block;\n",
|
||||
" margin-left: 0.4em;\n",
|
||||
"}\n",
|
||||
".hoogle-package {\n",
|
||||
" font-weight: bold;\n",
|
||||
" font-style: italic;\n",
|
||||
"}\n",
|
||||
".hoogle-module {\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
".hoogle-class {\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"/* Styles used for basic displays */\n",
|
||||
".get-type {\n",
|
||||
" color: green;\n",
|
||||
" font-weight: bold;\n",
|
||||
" font-family: monospace;\n",
|
||||
" display: block;\n",
|
||||
" white-space: pre-wrap;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
".show-type {\n",
|
||||
" color: green;\n",
|
||||
" font-weight: bold;\n",
|
||||
" font-family: monospace;\n",
|
||||
" margin-left: 1em;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
".mono {\n",
|
||||
" font-family: monospace;\n",
|
||||
" display: block;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
".err-msg {\n",
|
||||
" color: red;\n",
|
||||
" font-style: italic;\n",
|
||||
" font-family: monospace;\n",
|
||||
" white-space: pre;\n",
|
||||
" display: block;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"#unshowable {\n",
|
||||
" color: red;\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
".err-msg.in.collapse {\n",
|
||||
" padding-top: 0.7em;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"/* Code that will get highlighted before it is highlighted */\n",
|
||||
".highlight-code {\n",
|
||||
" white-space: pre;\n",
|
||||
" font-family: monospace;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"/* Hlint styles */\n",
|
||||
".suggestion-warning { \n",
|
||||
" font-weight: bold;\n",
|
||||
" color: rgb(200, 130, 0);\n",
|
||||
"}\n",
|
||||
".suggestion-error { \n",
|
||||
" font-weight: bold;\n",
|
||||
" color: red;\n",
|
||||
"}\n",
|
||||
".suggestion-name {\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
"</style><span class='get-type'>closeWidget :: forall w. IHaskellWidget w => w -> IO ()</span>"
|
||||
],
|
||||
"text/plain": [
|
||||
"closeWidget :: forall w. IHaskellWidget w => w -> IO ()"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"source": [
|
||||
":t closeWidget"
|
||||
]
|
||||
@ -850,120 +286,11 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<style>/*\n",
|
||||
"Custom IHaskell CSS.\n",
|
||||
"*/\n",
|
||||
"\n",
|
||||
"/* Styles used for the Hoogle display in the pager */\n",
|
||||
".hoogle-doc {\n",
|
||||
" display: block;\n",
|
||||
" padding-bottom: 1.3em;\n",
|
||||
" padding-left: 0.4em;\n",
|
||||
"}\n",
|
||||
".hoogle-code {\n",
|
||||
" display: block;\n",
|
||||
" font-family: monospace;\n",
|
||||
" white-space: pre;\n",
|
||||
"}\n",
|
||||
".hoogle-text {\n",
|
||||
" display: block;\n",
|
||||
"}\n",
|
||||
".hoogle-name {\n",
|
||||
" color: green;\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
".hoogle-head {\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
".hoogle-sub {\n",
|
||||
" display: block;\n",
|
||||
" margin-left: 0.4em;\n",
|
||||
"}\n",
|
||||
".hoogle-package {\n",
|
||||
" font-weight: bold;\n",
|
||||
" font-style: italic;\n",
|
||||
"}\n",
|
||||
".hoogle-module {\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
".hoogle-class {\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"/* Styles used for basic displays */\n",
|
||||
".get-type {\n",
|
||||
" color: green;\n",
|
||||
" font-weight: bold;\n",
|
||||
" font-family: monospace;\n",
|
||||
" display: block;\n",
|
||||
" white-space: pre-wrap;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
".show-type {\n",
|
||||
" color: green;\n",
|
||||
" font-weight: bold;\n",
|
||||
" font-family: monospace;\n",
|
||||
" margin-left: 1em;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
".mono {\n",
|
||||
" font-family: monospace;\n",
|
||||
" display: block;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
".err-msg {\n",
|
||||
" color: red;\n",
|
||||
" font-style: italic;\n",
|
||||
" font-family: monospace;\n",
|
||||
" white-space: pre;\n",
|
||||
" display: block;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"#unshowable {\n",
|
||||
" color: red;\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
".err-msg.in.collapse {\n",
|
||||
" padding-top: 0.7em;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"/* Code that will get highlighted before it is highlighted */\n",
|
||||
".highlight-code {\n",
|
||||
" white-space: pre;\n",
|
||||
" font-family: monospace;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"/* Hlint styles */\n",
|
||||
".suggestion-warning { \n",
|
||||
" font-weight: bold;\n",
|
||||
" color: rgb(200, 130, 0);\n",
|
||||
"}\n",
|
||||
".suggestion-error { \n",
|
||||
" font-weight: bold;\n",
|
||||
" color: red;\n",
|
||||
"}\n",
|
||||
".suggestion-name {\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
"</style><span class='get-type'>button :: Button</span>"
|
||||
],
|
||||
"text/plain": [
|
||||
"button :: Button"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"button <- mkButton -- Construct a Button\n",
|
||||
":t button"
|
||||
@ -978,7 +305,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 9,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
@ -991,54 +318,17 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"To view a widget's properties, we use the `properties` function:"
|
||||
"To view a widget's properties, we use the `properties` function. It also shows the type represented by the `Field`, which generally are not visible in type signatures due to high levels of type-hackery."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 10,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false,
|
||||
"scrolled": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"ViewModule\n",
|
||||
"ViewName\n",
|
||||
"MsgThrottle\n",
|
||||
"Version\n",
|
||||
"DisplayHandler\n",
|
||||
"Visible\n",
|
||||
"CSS\n",
|
||||
"DOMClasses\n",
|
||||
"Width\n",
|
||||
"Height\n",
|
||||
"Padding\n",
|
||||
"Margin\n",
|
||||
"Color\n",
|
||||
"BackgroundColor\n",
|
||||
"BorderColor\n",
|
||||
"BorderWidth\n",
|
||||
"BorderRadius\n",
|
||||
"BorderStyle\n",
|
||||
"FontStyle\n",
|
||||
"FontWeight\n",
|
||||
"FontSize\n",
|
||||
"FontFamily\n",
|
||||
"Description\n",
|
||||
"Tooltip\n",
|
||||
"Disabled\n",
|
||||
"Icon\n",
|
||||
"ButtonStyle\n",
|
||||
"ClickHandler"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"-- The button widget has many properties.\n",
|
||||
"properties button"
|
||||
@ -1053,19 +343,11 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 11,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": []
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"-- 250 pixels wide\n",
|
||||
"setField button Width 250"
|
||||
@ -1080,20 +362,12 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 12,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false,
|
||||
"scrolled": true
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": []
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"setField button Description \"Click Me (._.\\\")\"\n",
|
||||
"setField button ButtonStyle SuccessButton\n",
|
||||
@ -1115,19 +389,11 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 13,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": []
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"setField button ClickHandler $ putStrLn \"fO_o\"\n",
|
||||
"button -- Displaying again for convenience"
|
||||
@ -1142,19 +408,11 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 14,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": []
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"setField button ClickHandler $ getLine >>= putStrLn"
|
||||
]
|
||||
@ -1165,6 +423,12 @@
|
||||
"display_name": "Haskell",
|
||||
"language": "haskell",
|
||||
"name": "haskell"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": "ihaskell",
|
||||
"file_extension": ".hs",
|
||||
"name": "haskell",
|
||||
"version": "7.10.2"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
|
@ -27,7 +27,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": true
|
||||
},
|
||||
@ -46,9 +46,9 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": true
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
@ -58,7 +58,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
@ -77,19 +77,11 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": []
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"setField bit MaxInt 20\n",
|
||||
"setField bit MinInt 10\n",
|
||||
@ -119,7 +111,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": true
|
||||
},
|
||||
@ -131,7 +123,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
@ -143,21 +135,11 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"(25,75)"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"getField irs IntPairValue"
|
||||
]
|
||||
@ -178,7 +160,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": true
|
||||
},
|
||||
@ -190,19 +172,11 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 9,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": []
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"setField inp IntValue 42"
|
||||
]
|
||||
@ -213,6 +187,12 @@
|
||||
"display_name": "Haskell",
|
||||
"language": "haskell",
|
||||
"name": "haskell"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": "ihaskell",
|
||||
"file_extension": ".hs",
|
||||
"name": "haskell",
|
||||
"version": "7.10.2"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
|
@ -16,769 +16,12 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false,
|
||||
"scrolled": true
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<style>/*\n",
|
||||
"Custom IHaskell CSS.\n",
|
||||
"*/\n",
|
||||
"\n",
|
||||
"/* Styles used for the Hoogle display in the pager */\n",
|
||||
".hoogle-doc {\n",
|
||||
" display: block;\n",
|
||||
" padding-bottom: 1.3em;\n",
|
||||
" padding-left: 0.4em;\n",
|
||||
"}\n",
|
||||
".hoogle-code {\n",
|
||||
" display: block;\n",
|
||||
" font-family: monospace;\n",
|
||||
" white-space: pre;\n",
|
||||
"}\n",
|
||||
".hoogle-text {\n",
|
||||
" display: block;\n",
|
||||
"}\n",
|
||||
".hoogle-name {\n",
|
||||
" color: green;\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
".hoogle-head {\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
".hoogle-sub {\n",
|
||||
" display: block;\n",
|
||||
" margin-left: 0.4em;\n",
|
||||
"}\n",
|
||||
".hoogle-package {\n",
|
||||
" font-weight: bold;\n",
|
||||
" font-style: italic;\n",
|
||||
"}\n",
|
||||
".hoogle-module {\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
".hoogle-class {\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"/* Styles used for basic displays */\n",
|
||||
".get-type {\n",
|
||||
" color: green;\n",
|
||||
" font-weight: bold;\n",
|
||||
" font-family: monospace;\n",
|
||||
" display: block;\n",
|
||||
" white-space: pre-wrap;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
".show-type {\n",
|
||||
" color: green;\n",
|
||||
" font-weight: bold;\n",
|
||||
" font-family: monospace;\n",
|
||||
" margin-left: 1em;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
".mono {\n",
|
||||
" font-family: monospace;\n",
|
||||
" display: block;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
".err-msg {\n",
|
||||
" color: red;\n",
|
||||
" font-style: italic;\n",
|
||||
" font-family: monospace;\n",
|
||||
" white-space: pre;\n",
|
||||
" display: block;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"#unshowable {\n",
|
||||
" color: red;\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
".err-msg.in.collapse {\n",
|
||||
" padding-top: 0.7em;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"/* Code that will get highlighted before it is highlighted */\n",
|
||||
".highlight-code {\n",
|
||||
" white-space: pre;\n",
|
||||
" font-family: monospace;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"/* Hlint styles */\n",
|
||||
".suggestion-warning { \n",
|
||||
" font-weight: bold;\n",
|
||||
" color: rgb(200, 130, 0);\n",
|
||||
"}\n",
|
||||
".suggestion-error { \n",
|
||||
" font-weight: bold;\n",
|
||||
" color: red;\n",
|
||||
"}\n",
|
||||
".suggestion-name {\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
"</style><span class='get-type'>plain :: String -> DisplayData</span>"
|
||||
],
|
||||
"text/plain": [
|
||||
"plain :: String -> DisplayData"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<style>/*\n",
|
||||
"Custom IHaskell CSS.\n",
|
||||
"*/\n",
|
||||
"\n",
|
||||
"/* Styles used for the Hoogle display in the pager */\n",
|
||||
".hoogle-doc {\n",
|
||||
" display: block;\n",
|
||||
" padding-bottom: 1.3em;\n",
|
||||
" padding-left: 0.4em;\n",
|
||||
"}\n",
|
||||
".hoogle-code {\n",
|
||||
" display: block;\n",
|
||||
" font-family: monospace;\n",
|
||||
" white-space: pre;\n",
|
||||
"}\n",
|
||||
".hoogle-text {\n",
|
||||
" display: block;\n",
|
||||
"}\n",
|
||||
".hoogle-name {\n",
|
||||
" color: green;\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
".hoogle-head {\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
".hoogle-sub {\n",
|
||||
" display: block;\n",
|
||||
" margin-left: 0.4em;\n",
|
||||
"}\n",
|
||||
".hoogle-package {\n",
|
||||
" font-weight: bold;\n",
|
||||
" font-style: italic;\n",
|
||||
"}\n",
|
||||
".hoogle-module {\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
".hoogle-class {\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"/* Styles used for basic displays */\n",
|
||||
".get-type {\n",
|
||||
" color: green;\n",
|
||||
" font-weight: bold;\n",
|
||||
" font-family: monospace;\n",
|
||||
" display: block;\n",
|
||||
" white-space: pre-wrap;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
".show-type {\n",
|
||||
" color: green;\n",
|
||||
" font-weight: bold;\n",
|
||||
" font-family: monospace;\n",
|
||||
" margin-left: 1em;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
".mono {\n",
|
||||
" font-family: monospace;\n",
|
||||
" display: block;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
".err-msg {\n",
|
||||
" color: red;\n",
|
||||
" font-style: italic;\n",
|
||||
" font-family: monospace;\n",
|
||||
" white-space: pre;\n",
|
||||
" display: block;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"#unshowable {\n",
|
||||
" color: red;\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
".err-msg.in.collapse {\n",
|
||||
" padding-top: 0.7em;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"/* Code that will get highlighted before it is highlighted */\n",
|
||||
".highlight-code {\n",
|
||||
" white-space: pre;\n",
|
||||
" font-family: monospace;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"/* Hlint styles */\n",
|
||||
".suggestion-warning { \n",
|
||||
" font-weight: bold;\n",
|
||||
" color: rgb(200, 130, 0);\n",
|
||||
"}\n",
|
||||
".suggestion-error { \n",
|
||||
" font-weight: bold;\n",
|
||||
" color: red;\n",
|
||||
"}\n",
|
||||
".suggestion-name {\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
"</style><span class='get-type'>html :: String -> DisplayData</span>"
|
||||
],
|
||||
"text/plain": [
|
||||
"html :: String -> DisplayData"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<style>/*\n",
|
||||
"Custom IHaskell CSS.\n",
|
||||
"*/\n",
|
||||
"\n",
|
||||
"/* Styles used for the Hoogle display in the pager */\n",
|
||||
".hoogle-doc {\n",
|
||||
" display: block;\n",
|
||||
" padding-bottom: 1.3em;\n",
|
||||
" padding-left: 0.4em;\n",
|
||||
"}\n",
|
||||
".hoogle-code {\n",
|
||||
" display: block;\n",
|
||||
" font-family: monospace;\n",
|
||||
" white-space: pre;\n",
|
||||
"}\n",
|
||||
".hoogle-text {\n",
|
||||
" display: block;\n",
|
||||
"}\n",
|
||||
".hoogle-name {\n",
|
||||
" color: green;\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
".hoogle-head {\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
".hoogle-sub {\n",
|
||||
" display: block;\n",
|
||||
" margin-left: 0.4em;\n",
|
||||
"}\n",
|
||||
".hoogle-package {\n",
|
||||
" font-weight: bold;\n",
|
||||
" font-style: italic;\n",
|
||||
"}\n",
|
||||
".hoogle-module {\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
".hoogle-class {\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"/* Styles used for basic displays */\n",
|
||||
".get-type {\n",
|
||||
" color: green;\n",
|
||||
" font-weight: bold;\n",
|
||||
" font-family: monospace;\n",
|
||||
" display: block;\n",
|
||||
" white-space: pre-wrap;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
".show-type {\n",
|
||||
" color: green;\n",
|
||||
" font-weight: bold;\n",
|
||||
" font-family: monospace;\n",
|
||||
" margin-left: 1em;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
".mono {\n",
|
||||
" font-family: monospace;\n",
|
||||
" display: block;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
".err-msg {\n",
|
||||
" color: red;\n",
|
||||
" font-style: italic;\n",
|
||||
" font-family: monospace;\n",
|
||||
" white-space: pre;\n",
|
||||
" display: block;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"#unshowable {\n",
|
||||
" color: red;\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
".err-msg.in.collapse {\n",
|
||||
" padding-top: 0.7em;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"/* Code that will get highlighted before it is highlighted */\n",
|
||||
".highlight-code {\n",
|
||||
" white-space: pre;\n",
|
||||
" font-family: monospace;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"/* Hlint styles */\n",
|
||||
".suggestion-warning { \n",
|
||||
" font-weight: bold;\n",
|
||||
" color: rgb(200, 130, 0);\n",
|
||||
"}\n",
|
||||
".suggestion-error { \n",
|
||||
" font-weight: bold;\n",
|
||||
" color: red;\n",
|
||||
"}\n",
|
||||
".suggestion-name {\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
"</style><span class='get-type'>jpg :: Width -> Height -> Base64 -> DisplayData</span>"
|
||||
],
|
||||
"text/plain": [
|
||||
"jpg :: Width -> Height -> Base64 -> DisplayData"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<style>/*\n",
|
||||
"Custom IHaskell CSS.\n",
|
||||
"*/\n",
|
||||
"\n",
|
||||
"/* Styles used for the Hoogle display in the pager */\n",
|
||||
".hoogle-doc {\n",
|
||||
" display: block;\n",
|
||||
" padding-bottom: 1.3em;\n",
|
||||
" padding-left: 0.4em;\n",
|
||||
"}\n",
|
||||
".hoogle-code {\n",
|
||||
" display: block;\n",
|
||||
" font-family: monospace;\n",
|
||||
" white-space: pre;\n",
|
||||
"}\n",
|
||||
".hoogle-text {\n",
|
||||
" display: block;\n",
|
||||
"}\n",
|
||||
".hoogle-name {\n",
|
||||
" color: green;\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
".hoogle-head {\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
".hoogle-sub {\n",
|
||||
" display: block;\n",
|
||||
" margin-left: 0.4em;\n",
|
||||
"}\n",
|
||||
".hoogle-package {\n",
|
||||
" font-weight: bold;\n",
|
||||
" font-style: italic;\n",
|
||||
"}\n",
|
||||
".hoogle-module {\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
".hoogle-class {\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"/* Styles used for basic displays */\n",
|
||||
".get-type {\n",
|
||||
" color: green;\n",
|
||||
" font-weight: bold;\n",
|
||||
" font-family: monospace;\n",
|
||||
" display: block;\n",
|
||||
" white-space: pre-wrap;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
".show-type {\n",
|
||||
" color: green;\n",
|
||||
" font-weight: bold;\n",
|
||||
" font-family: monospace;\n",
|
||||
" margin-left: 1em;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
".mono {\n",
|
||||
" font-family: monospace;\n",
|
||||
" display: block;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
".err-msg {\n",
|
||||
" color: red;\n",
|
||||
" font-style: italic;\n",
|
||||
" font-family: monospace;\n",
|
||||
" white-space: pre;\n",
|
||||
" display: block;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"#unshowable {\n",
|
||||
" color: red;\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
".err-msg.in.collapse {\n",
|
||||
" padding-top: 0.7em;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"/* Code that will get highlighted before it is highlighted */\n",
|
||||
".highlight-code {\n",
|
||||
" white-space: pre;\n",
|
||||
" font-family: monospace;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"/* Hlint styles */\n",
|
||||
".suggestion-warning { \n",
|
||||
" font-weight: bold;\n",
|
||||
" color: rgb(200, 130, 0);\n",
|
||||
"}\n",
|
||||
".suggestion-error { \n",
|
||||
" font-weight: bold;\n",
|
||||
" color: red;\n",
|
||||
"}\n",
|
||||
".suggestion-name {\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
"</style><span class='get-type'>svg :: String -> DisplayData</span>"
|
||||
],
|
||||
"text/plain": [
|
||||
"svg :: String -> DisplayData"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<style>/*\n",
|
||||
"Custom IHaskell CSS.\n",
|
||||
"*/\n",
|
||||
"\n",
|
||||
"/* Styles used for the Hoogle display in the pager */\n",
|
||||
".hoogle-doc {\n",
|
||||
" display: block;\n",
|
||||
" padding-bottom: 1.3em;\n",
|
||||
" padding-left: 0.4em;\n",
|
||||
"}\n",
|
||||
".hoogle-code {\n",
|
||||
" display: block;\n",
|
||||
" font-family: monospace;\n",
|
||||
" white-space: pre;\n",
|
||||
"}\n",
|
||||
".hoogle-text {\n",
|
||||
" display: block;\n",
|
||||
"}\n",
|
||||
".hoogle-name {\n",
|
||||
" color: green;\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
".hoogle-head {\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
".hoogle-sub {\n",
|
||||
" display: block;\n",
|
||||
" margin-left: 0.4em;\n",
|
||||
"}\n",
|
||||
".hoogle-package {\n",
|
||||
" font-weight: bold;\n",
|
||||
" font-style: italic;\n",
|
||||
"}\n",
|
||||
".hoogle-module {\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
".hoogle-class {\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"/* Styles used for basic displays */\n",
|
||||
".get-type {\n",
|
||||
" color: green;\n",
|
||||
" font-weight: bold;\n",
|
||||
" font-family: monospace;\n",
|
||||
" display: block;\n",
|
||||
" white-space: pre-wrap;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
".show-type {\n",
|
||||
" color: green;\n",
|
||||
" font-weight: bold;\n",
|
||||
" font-family: monospace;\n",
|
||||
" margin-left: 1em;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
".mono {\n",
|
||||
" font-family: monospace;\n",
|
||||
" display: block;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
".err-msg {\n",
|
||||
" color: red;\n",
|
||||
" font-style: italic;\n",
|
||||
" font-family: monospace;\n",
|
||||
" white-space: pre;\n",
|
||||
" display: block;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"#unshowable {\n",
|
||||
" color: red;\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
".err-msg.in.collapse {\n",
|
||||
" padding-top: 0.7em;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"/* Code that will get highlighted before it is highlighted */\n",
|
||||
".highlight-code {\n",
|
||||
" white-space: pre;\n",
|
||||
" font-family: monospace;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"/* Hlint styles */\n",
|
||||
".suggestion-warning { \n",
|
||||
" font-weight: bold;\n",
|
||||
" color: rgb(200, 130, 0);\n",
|
||||
"}\n",
|
||||
".suggestion-error { \n",
|
||||
" font-weight: bold;\n",
|
||||
" color: red;\n",
|
||||
"}\n",
|
||||
".suggestion-name {\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
"</style><span class='get-type'>latex :: String -> DisplayData</span>"
|
||||
],
|
||||
"text/plain": [
|
||||
"latex :: String -> DisplayData"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<style>/*\n",
|
||||
"Custom IHaskell CSS.\n",
|
||||
"*/\n",
|
||||
"\n",
|
||||
"/* Styles used for the Hoogle display in the pager */\n",
|
||||
".hoogle-doc {\n",
|
||||
" display: block;\n",
|
||||
" padding-bottom: 1.3em;\n",
|
||||
" padding-left: 0.4em;\n",
|
||||
"}\n",
|
||||
".hoogle-code {\n",
|
||||
" display: block;\n",
|
||||
" font-family: monospace;\n",
|
||||
" white-space: pre;\n",
|
||||
"}\n",
|
||||
".hoogle-text {\n",
|
||||
" display: block;\n",
|
||||
"}\n",
|
||||
".hoogle-name {\n",
|
||||
" color: green;\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
".hoogle-head {\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
".hoogle-sub {\n",
|
||||
" display: block;\n",
|
||||
" margin-left: 0.4em;\n",
|
||||
"}\n",
|
||||
".hoogle-package {\n",
|
||||
" font-weight: bold;\n",
|
||||
" font-style: italic;\n",
|
||||
"}\n",
|
||||
".hoogle-module {\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
".hoogle-class {\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"/* Styles used for basic displays */\n",
|
||||
".get-type {\n",
|
||||
" color: green;\n",
|
||||
" font-weight: bold;\n",
|
||||
" font-family: monospace;\n",
|
||||
" display: block;\n",
|
||||
" white-space: pre-wrap;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
".show-type {\n",
|
||||
" color: green;\n",
|
||||
" font-weight: bold;\n",
|
||||
" font-family: monospace;\n",
|
||||
" margin-left: 1em;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
".mono {\n",
|
||||
" font-family: monospace;\n",
|
||||
" display: block;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
".err-msg {\n",
|
||||
" color: red;\n",
|
||||
" font-style: italic;\n",
|
||||
" font-family: monospace;\n",
|
||||
" white-space: pre;\n",
|
||||
" display: block;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"#unshowable {\n",
|
||||
" color: red;\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
".err-msg.in.collapse {\n",
|
||||
" padding-top: 0.7em;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"/* Code that will get highlighted before it is highlighted */\n",
|
||||
".highlight-code {\n",
|
||||
" white-space: pre;\n",
|
||||
" font-family: monospace;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"/* Hlint styles */\n",
|
||||
".suggestion-warning { \n",
|
||||
" font-weight: bold;\n",
|
||||
" color: rgb(200, 130, 0);\n",
|
||||
"}\n",
|
||||
".suggestion-error { \n",
|
||||
" font-weight: bold;\n",
|
||||
" color: red;\n",
|
||||
"}\n",
|
||||
".suggestion-name {\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
"</style><span class='get-type'>javascript :: String -> DisplayData</span>"
|
||||
],
|
||||
"text/plain": [
|
||||
"javascript :: String -> DisplayData"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<style>/*\n",
|
||||
"Custom IHaskell CSS.\n",
|
||||
"*/\n",
|
||||
"\n",
|
||||
"/* Styles used for the Hoogle display in the pager */\n",
|
||||
".hoogle-doc {\n",
|
||||
" display: block;\n",
|
||||
" padding-bottom: 1.3em;\n",
|
||||
" padding-left: 0.4em;\n",
|
||||
"}\n",
|
||||
".hoogle-code {\n",
|
||||
" display: block;\n",
|
||||
" font-family: monospace;\n",
|
||||
" white-space: pre;\n",
|
||||
"}\n",
|
||||
".hoogle-text {\n",
|
||||
" display: block;\n",
|
||||
"}\n",
|
||||
".hoogle-name {\n",
|
||||
" color: green;\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
".hoogle-head {\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
".hoogle-sub {\n",
|
||||
" display: block;\n",
|
||||
" margin-left: 0.4em;\n",
|
||||
"}\n",
|
||||
".hoogle-package {\n",
|
||||
" font-weight: bold;\n",
|
||||
" font-style: italic;\n",
|
||||
"}\n",
|
||||
".hoogle-module {\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
".hoogle-class {\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"/* Styles used for basic displays */\n",
|
||||
".get-type {\n",
|
||||
" color: green;\n",
|
||||
" font-weight: bold;\n",
|
||||
" font-family: monospace;\n",
|
||||
" display: block;\n",
|
||||
" white-space: pre-wrap;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
".show-type {\n",
|
||||
" color: green;\n",
|
||||
" font-weight: bold;\n",
|
||||
" font-family: monospace;\n",
|
||||
" margin-left: 1em;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
".mono {\n",
|
||||
" font-family: monospace;\n",
|
||||
" display: block;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
".err-msg {\n",
|
||||
" color: red;\n",
|
||||
" font-style: italic;\n",
|
||||
" font-family: monospace;\n",
|
||||
" white-space: pre;\n",
|
||||
" display: block;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"#unshowable {\n",
|
||||
" color: red;\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
".err-msg.in.collapse {\n",
|
||||
" padding-top: 0.7em;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"/* Code that will get highlighted before it is highlighted */\n",
|
||||
".highlight-code {\n",
|
||||
" white-space: pre;\n",
|
||||
" font-family: monospace;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"/* Hlint styles */\n",
|
||||
".suggestion-warning { \n",
|
||||
" font-weight: bold;\n",
|
||||
" color: rgb(200, 130, 0);\n",
|
||||
"}\n",
|
||||
".suggestion-error { \n",
|
||||
" font-weight: bold;\n",
|
||||
" color: red;\n",
|
||||
"}\n",
|
||||
".suggestion-name {\n",
|
||||
" font-weight: bold;\n",
|
||||
"}\n",
|
||||
"</style><span class='get-type'>many :: [Display] -> Display</span>"
|
||||
],
|
||||
"text/plain": [
|
||||
"many :: [Display] -> Display"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"{-# LANGUAGE OverloadedStrings #-}\n",
|
||||
"import IHaskell.Display.Widgets\n",
|
||||
@ -806,7 +49,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
@ -838,6 +81,12 @@
|
||||
"display_name": "Haskell",
|
||||
"language": "haskell",
|
||||
"name": "haskell"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": "ihaskell",
|
||||
"file_extension": ".hs",
|
||||
"name": "haskell",
|
||||
"version": "7.10.2"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
|
@ -13,13 +13,14 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": true
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"{-# LANGUAGE OverloadedStrings #-}\n",
|
||||
"{-# LANGUAGE FlexibleContexts #-}\n",
|
||||
"import IHaskell.Display.Widgets"
|
||||
]
|
||||
},
|
||||
@ -32,7 +33,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
@ -83,19 +84,11 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": []
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import Data.IORef\n",
|
||||
"import Graphics.Rendering.Chart.Easy hiding (tan)\n",
|
||||
@ -164,19 +157,11 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": []
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"divBox <- mkFlexBox\n",
|
||||
"setField divBox Orientation HorizontalOrientation\n",
|
||||
@ -204,20 +189,12 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false,
|
||||
"scrolled": true
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": []
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"slBox <- mkFlexBox\n",
|
||||
"\n",
|
||||
@ -244,19 +221,11 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": []
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"-- The four FlexBox widgets.\n",
|
||||
"import Control.Monad (replicateM, forM_)\n",
|
||||
@ -302,19 +271,11 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": []
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"-- A FlexBox with ToggleButtons\n",
|
||||
"buttonBox <- mkFlexBox\n",
|
||||
@ -339,19 +300,11 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": []
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import Control.Arrow (first, second)\n",
|
||||
"\n",
|
||||
@ -384,19 +337,11 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 9,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": []
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"setField tlBox Children $ map ChildWidget $ boxes ++ [buttonBox] ++ rangeBoxes"
|
||||
]
|
||||
@ -410,19 +355,11 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 10,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": []
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"setField tlBox Titles [\"Plot title\", \"X-Label\", \"Y-Label\", \"Grid\", \"X-range\", \"Y-range\"]"
|
||||
]
|
||||
@ -436,19 +373,11 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 11,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": []
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"let syncVal widget value fieldGetter = readIORef plotState >>= setField widget value . fieldGetter\n",
|
||||
" in do\n",
|
||||
@ -478,7 +407,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 12,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
@ -500,22 +429,11 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 13,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
},
|
||||
{
|
||||
"data": {},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"-- Spurious update to display empty plot instead of empty image initially\n",
|
||||
"update return\n",
|
||||
@ -532,7 +450,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 14,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": true
|
||||
},
|
||||
@ -543,7 +461,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 15,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
@ -554,7 +472,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 16,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": true
|
||||
},
|
||||
@ -569,6 +487,12 @@
|
||||
"display_name": "Haskell",
|
||||
"language": "haskell",
|
||||
"name": "haskell"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": "ihaskell",
|
||||
"file_extension": ".hs",
|
||||
"name": "haskell",
|
||||
"version": "7.10.2"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
|
@ -22,7 +22,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": true
|
||||
},
|
||||
@ -34,7 +34,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
@ -49,19 +49,11 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": []
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"setField msel Description \"Functions to show (One or more)\"\n",
|
||||
"setField msel Options (OptionLabels [\"sin\", \"cos\"])\n",
|
||||
@ -79,20 +71,12 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false,
|
||||
"scrolled": true
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": []
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import Graphics.Rendering.Chart.Easy hiding (tan)\n",
|
||||
"import Graphics.Rendering.Chart.Backend.Cairo\n",
|
||||
@ -140,92 +124,11 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
},
|
||||
{
|
||||
"data": {},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
},
|
||||
{
|
||||
"data": {},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
},
|
||||
{
|
||||
"data": {},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
},
|
||||
{
|
||||
"data": {},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
},
|
||||
{
|
||||
"data": {},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
},
|
||||
{
|
||||
"data": {},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
},
|
||||
{
|
||||
"data": {},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
},
|
||||
{
|
||||
"data": {},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
},
|
||||
{
|
||||
"data": {},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
},
|
||||
{
|
||||
"data": {},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
},
|
||||
{
|
||||
"data": {},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
},
|
||||
{
|
||||
"data": {},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
},
|
||||
{
|
||||
"data": {},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
},
|
||||
{
|
||||
"data": {},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
},
|
||||
{
|
||||
"data": {},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"-- Display the widgets\n",
|
||||
"msel\n",
|
||||
@ -246,6 +149,12 @@
|
||||
"display_name": "Haskell",
|
||||
"language": "haskell",
|
||||
"name": "haskell"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": "ihaskell",
|
||||
"file_extension": ".hs",
|
||||
"name": "haskell",
|
||||
"version": "7.10.2"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
|
@ -21,19 +21,20 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": true
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"{-# LANGUAGE OverloadedStrings #-}\n",
|
||||
"{-# LANGUAGE FlexibleContexts #-}\n",
|
||||
"import IHaskell.Display.Widgets"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
@ -69,7 +70,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": true
|
||||
},
|
||||
@ -82,7 +83,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
@ -94,7 +95,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
@ -116,7 +117,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
@ -142,7 +143,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
@ -154,20 +155,12 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false,
|
||||
"scrolled": true
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": []
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"-- Some padding\n",
|
||||
"setField text Padding 5"
|
||||
@ -182,19 +175,11 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 9,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": []
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"setField text Placeholder \"Enter your text here...\"\n",
|
||||
"setField area Placeholder \"Parsed output will appear here...\""
|
||||
@ -216,7 +201,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 10,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": true
|
||||
},
|
||||
@ -239,7 +224,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 11,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": true
|
||||
},
|
||||
@ -300,19 +285,11 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 12,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": []
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"setField text ChangeHandler $ do\n",
|
||||
" input <- unpack <$> getField text StringValue\n",
|
||||
@ -338,7 +315,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 13,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": true
|
||||
},
|
||||
@ -354,6 +331,12 @@
|
||||
"display_name": "Haskell",
|
||||
"language": "haskell",
|
||||
"name": "haskell"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": "ihaskell",
|
||||
"file_extension": ".hs",
|
||||
"name": "haskell",
|
||||
"version": "7.10.2"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
|
@ -8,26 +8,17 @@
|
||||
## Creating widgets
|
||||
|
||||
Let's say the user types in some code, and the only effect of that code is the creation of a widget.
|
||||
The kernel will open a comm for the widget, and store a reference to that comm inside it. Then, to
|
||||
notify the frontend about the creation of a widget, an initial state update is sent on the widget's
|
||||
comm.
|
||||
The kernel will open a comm for the widget, and store a reference to that comm. The comm_open message
|
||||
also holds the initial state of the widget in it, which is used by the frontend to create a model for
|
||||
the widget.
|
||||
|
||||
> The comm should be opened with a `target_name` of `"ipython.widget"`.
|
||||
|
||||
The initial state update message looks like this:
|
||||
|
||||
```json
|
||||
{
|
||||
"method": "update",
|
||||
"state": { "<some/all widget properties>" }
|
||||
}
|
||||
```
|
||||
|
||||
Any *numeric* property initialized with the empty string is provided the default value by the
|
||||
frontend. Some numbers need to be sent as actual numbers (when non-null), whereas some (especially
|
||||
those used by sliders) need to be sent as strings.
|
||||
frontend. Some numbers need to be sent as actual numbers (when non-null), whereas the ones representing
|
||||
lengths in CSS units need to be sent as strings.
|
||||
|
||||
The initial state update must *at least* have the following fields:
|
||||
The initial state must *at least* have the following fields:
|
||||
|
||||
- `msg_throttle` (default 3): To prevent the kernel from flooding with messages, the messages from
|
||||
the widget to the kernel are throttled. If `msg_throttle` messages were sent, and all are still
|
||||
@ -43,8 +34,8 @@ The initial state update must *at least* have the following fields:
|
||||
|
||||
- Rest of the properties as required initially.
|
||||
|
||||
This state update is also used with fragments of the overall state to sync changes between the
|
||||
frontend and the kernel.
|
||||
This state is also used with fragments of the overall state to sync changes between the frontend and
|
||||
the kernel.
|
||||
|
||||
## Displaying widgets
|
||||
|
||||
@ -111,7 +102,7 @@ If this were not so, the frontend would not be able to determine under which cel
|
||||
input widget, when an `input_request` is received.
|
||||
|
||||
Now, widgets cannot send `execute_request` messages. They can only send `comm_data` messages, which
|
||||
means that it's not possible to fetch input through widget events.
|
||||
means that it's not possible to fetch input inside widget event handlers.
|
||||
|
||||
---
|
||||
|
||||
|
@ -10,7 +10,7 @@ name: ihaskell-widgets
|
||||
-- PVP summary: +-+------- breaking API changes
|
||||
-- | | +----- non-breaking API additions
|
||||
-- | | | +--- code changes with no API change
|
||||
version: 0.1.0.0
|
||||
version: 0.2.2.1
|
||||
|
||||
-- A short (one-line) description of the package.
|
||||
synopsis: IPython standard widgets for IHaskell.
|
||||
@ -57,11 +57,14 @@ library
|
||||
-- Modules included in this library but not exported.
|
||||
other-modules: IHaskell.Display.Widgets.Button
|
||||
IHaskell.Display.Widgets.Box.Box
|
||||
IHaskell.Display.Widgets.Box.Proxy
|
||||
IHaskell.Display.Widgets.Box.PlaceProxy
|
||||
IHaskell.Display.Widgets.Box.FlexBox
|
||||
IHaskell.Display.Widgets.Box.SelectionContainer.Accordion
|
||||
IHaskell.Display.Widgets.Box.SelectionContainer.Tab
|
||||
IHaskell.Display.Widgets.Bool.CheckBox
|
||||
IHaskell.Display.Widgets.Bool.ToggleButton
|
||||
IHaskell.Display.Widgets.Bool.Valid
|
||||
IHaskell.Display.Widgets.Int.IntText
|
||||
IHaskell.Display.Widgets.Int.BoundedInt.BoundedIntText
|
||||
IHaskell.Display.Widgets.Int.BoundedInt.IntProgress
|
||||
@ -92,20 +95,35 @@ library
|
||||
-- other-extensions:
|
||||
|
||||
-- Other library packages from which modules are imported.
|
||||
build-depends: aeson >=0.7 && < 0.10
|
||||
, base >=4.7 && <4.9
|
||||
, containers >= 0.5
|
||||
, ipython-kernel >= 0.6.1.2
|
||||
, text >= 0.11
|
||||
, unordered-containers -any
|
||||
, nats -any
|
||||
, vinyl >= 0.5
|
||||
, vector -any
|
||||
, singletons >= 0.9.0
|
||||
, scientific -any
|
||||
, unix -any
|
||||
|
||||
, ihaskell >= 0.6.4.1
|
||||
-- singletons 2.* require ghc 7.10.2
|
||||
if impl(ghc >= 7.10.2)
|
||||
build-depends: aeson >=0.7 && < 0.11
|
||||
, base >=4.7 && <4.9
|
||||
, containers >= 0.5
|
||||
, ipython-kernel >= 0.6.1.2
|
||||
, text >= 0.11
|
||||
, unordered-containers -any
|
||||
, nats -any
|
||||
, vinyl >= 0.5
|
||||
, vector -any
|
||||
, singletons >= 0.9.0
|
||||
, scientific -any
|
||||
, unix -any
|
||||
, ihaskell >= 0.6.4.1
|
||||
else
|
||||
build-depends: aeson >=0.7 && < 0.11
|
||||
, base >=4.7 && <4.9
|
||||
, containers >= 0.5
|
||||
, ipython-kernel >= 0.6.1.2
|
||||
, text >= 0.11
|
||||
, unordered-containers -any
|
||||
, nats -any
|
||||
, vinyl >= 0.5
|
||||
, vector -any
|
||||
, singletons >= 0.9.0 && <2.0
|
||||
, scientific -any
|
||||
, unix -any
|
||||
, ihaskell >= 0.6.4.1
|
||||
|
||||
-- Directories containing source files.
|
||||
hs-source-dirs: src
|
||||
@ -120,3 +138,8 @@ library
|
||||
-- ghc-7.10.* = 100
|
||||
if impl(ghc == 7.8.*)
|
||||
ghc-options: -fcontext-stack=100
|
||||
|
||||
-- compile without optimizations not to run out of memory on travis
|
||||
if impl(ghc == 7.10.*)
|
||||
ghc-options: -O0
|
||||
|
||||
|
@ -3,12 +3,15 @@ module IHaskell.Display.Widgets (module X) where
|
||||
import IHaskell.Display.Widgets.Button as X
|
||||
|
||||
import IHaskell.Display.Widgets.Box.Box as X
|
||||
import IHaskell.Display.Widgets.Box.Proxy as X
|
||||
import IHaskell.Display.Widgets.Box.PlaceProxy as X
|
||||
import IHaskell.Display.Widgets.Box.FlexBox as X
|
||||
import IHaskell.Display.Widgets.Box.SelectionContainer.Accordion as X
|
||||
import IHaskell.Display.Widgets.Box.SelectionContainer.Tab as X
|
||||
|
||||
import IHaskell.Display.Widgets.Bool.CheckBox as X
|
||||
import IHaskell.Display.Widgets.Bool.ToggleButton as X
|
||||
import IHaskell.Display.Widgets.Bool.Valid as X
|
||||
|
||||
import IHaskell.Display.Widgets.Int.IntText as X
|
||||
import IHaskell.Display.Widgets.Int.BoundedInt.BoundedIntText as X
|
||||
@ -38,8 +41,6 @@ import IHaskell.Display.Widgets.String.Text as X
|
||||
import IHaskell.Display.Widgets.String.TextArea as X
|
||||
|
||||
import IHaskell.Display.Widgets.Common as X
|
||||
import IHaskell.Display.Widgets.Types as X (setField, getField, properties)
|
||||
|
||||
import IHaskell.Display.Widgets.Types as X (triggerDisplay, triggerChange, triggerClick,
|
||||
triggerSelection, triggerSubmit,
|
||||
ChildWidget(..))
|
||||
import IHaskell.Display.Widgets.Types as X (setField, getField, properties, triggerDisplay,
|
||||
triggerChange, triggerClick, triggerSelection,
|
||||
triggerSubmit, ChildWidget(..))
|
||||
|
@ -12,12 +12,10 @@ CheckBox,
|
||||
-- To keep `cabal repl` happy when running from the ihaskell repo
|
||||
import Prelude
|
||||
|
||||
import Control.Monad (when, join, void)
|
||||
import Data.Aeson
|
||||
import Data.HashMap.Strict as HM
|
||||
import Data.IORef (newIORef)
|
||||
import Data.Text (Text)
|
||||
import Data.Vinyl (Rec(..), (<+>))
|
||||
|
||||
import IHaskell.Display
|
||||
import IHaskell.Eval.Widgets
|
||||
@ -40,11 +38,9 @@ mkCheckBox = do
|
||||
stateIO <- newIORef widgetState
|
||||
|
||||
let widget = IPythonWidget uuid stateIO
|
||||
initData = object
|
||||
["model_name" .= str "WidgetModel", "widget_class" .= str "IPython.Checkbox"]
|
||||
|
||||
-- Open a comm for this widget, and store it in the kernel state
|
||||
widgetSendOpen widget initData $ toJSON widgetState
|
||||
widgetSendOpen widget $ toJSON widgetState
|
||||
|
||||
-- Return the image widget
|
||||
return widget
|
||||
|
@ -12,7 +12,6 @@ ToggleButton,
|
||||
-- To keep `cabal repl` happy when running from the ihaskell repo
|
||||
import Prelude
|
||||
|
||||
import Control.Monad (when, join, void)
|
||||
import Data.Aeson
|
||||
import Data.HashMap.Strict as HM
|
||||
import Data.IORef (newIORef)
|
||||
@ -45,11 +44,9 @@ mkToggleButton = do
|
||||
stateIO <- newIORef widgetState
|
||||
|
||||
let widget = IPythonWidget uuid stateIO
|
||||
initData = object
|
||||
["model_name" .= str "WidgetModel", "widget_class" .= str "IPython.ToggleButton"]
|
||||
|
||||
-- Open a comm for this widget, and store it in the kernel state
|
||||
widgetSendOpen widget initData $ toJSON widgetState
|
||||
widgetSendOpen widget $ toJSON widgetState
|
||||
|
||||
-- Return the image widget
|
||||
return widget
|
||||
|
@ -0,0 +1,55 @@
|
||||
{-# LANGUAGE FlexibleInstances #-}
|
||||
{-# LANGUAGE OverloadedStrings #-}
|
||||
{-# LANGUAGE DataKinds #-}
|
||||
{-# LANGUAGE TypeSynonymInstances #-}
|
||||
|
||||
module IHaskell.Display.Widgets.Bool.Valid (
|
||||
-- * The Valid Widget
|
||||
ValidWidget,
|
||||
-- * Constructor
|
||||
mkValidWidget) where
|
||||
|
||||
-- To keep `cabal repl` happy when running from the ihaskell repo
|
||||
import Prelude
|
||||
|
||||
import Data.Aeson
|
||||
import Data.IORef (newIORef)
|
||||
import Data.Vinyl (Rec(..), (<+>))
|
||||
|
||||
import IHaskell.Display
|
||||
import IHaskell.Eval.Widgets
|
||||
import IHaskell.IPython.Message.UUID as U
|
||||
|
||||
import IHaskell.Display.Widgets.Types
|
||||
import IHaskell.Display.Widgets.Common
|
||||
|
||||
-- | A 'ValidWidget' represents a Valid widget from IPython.html.widgets.
|
||||
type ValidWidget = IPythonWidget ValidType
|
||||
|
||||
-- | Create a new output widget
|
||||
mkValidWidget :: IO ValidWidget
|
||||
mkValidWidget = do
|
||||
-- Default properties, with a random uuid
|
||||
uuid <- U.random
|
||||
|
||||
let boolState = defaultBoolWidget "ValidView"
|
||||
validState = (ReadOutMsg =:: "") :& RNil
|
||||
widgetState = WidgetState $ boolState <+> validState
|
||||
|
||||
stateIO <- newIORef widgetState
|
||||
|
||||
let widget = IPythonWidget uuid stateIO
|
||||
|
||||
-- Open a comm for this widget, and store it in the kernel state
|
||||
widgetSendOpen widget $ toJSON widgetState
|
||||
|
||||
-- Return the image widget
|
||||
return widget
|
||||
|
||||
instance IHaskellDisplay ValidWidget where
|
||||
display b = do
|
||||
widgetSendView b
|
||||
return $ Display []
|
||||
|
||||
instance IHaskellWidget ValidWidget where
|
||||
getCommUUID = uuid
|
@ -12,19 +12,14 @@ Box,
|
||||
-- To keep `cabal repl` happy when running from the ihaskell repo
|
||||
import Prelude
|
||||
|
||||
import Control.Monad (when, join)
|
||||
import Data.Aeson
|
||||
import Data.HashMap.Strict as HM
|
||||
import Data.IORef (newIORef)
|
||||
import Data.Text (Text)
|
||||
import Data.Vinyl (Rec(..), (<+>))
|
||||
|
||||
import IHaskell.Display
|
||||
import IHaskell.Eval.Widgets
|
||||
import IHaskell.IPython.Message.UUID as U
|
||||
|
||||
import IHaskell.Display.Widgets.Types
|
||||
import IHaskell.Display.Widgets.Common
|
||||
|
||||
-- | A 'Box' represents a Box widget from IPython.html.widgets.
|
||||
type Box = IPythonWidget BoxType
|
||||
@ -40,10 +35,9 @@ mkBox = do
|
||||
stateIO <- newIORef widgetState
|
||||
|
||||
let box = IPythonWidget uuid stateIO
|
||||
initData = object ["model_name" .= str "WidgetModel", "widget_class" .= str "IPython.Box"]
|
||||
|
||||
-- Open a comm for this widget, and store it in the kernel state
|
||||
widgetSendOpen box initData $ toJSON widgetState
|
||||
widgetSendOpen box $ toJSON widgetState
|
||||
|
||||
-- Return the widget
|
||||
return box
|
||||
|
@ -12,11 +12,8 @@ FlexBox,
|
||||
-- To keep `cabal repl` happy when running from the ihaskell repo
|
||||
import Prelude
|
||||
|
||||
import Control.Monad (when, join)
|
||||
import Data.Aeson
|
||||
import Data.HashMap.Strict as HM
|
||||
import Data.IORef (newIORef)
|
||||
import Data.Text (Text)
|
||||
import Data.Vinyl (Rec(..), (<+>))
|
||||
|
||||
import IHaskell.Display
|
||||
@ -46,10 +43,9 @@ mkFlexBox = do
|
||||
stateIO <- newIORef widgetState
|
||||
|
||||
let box = IPythonWidget uuid stateIO
|
||||
initData = object ["model_name" .= str "WidgetModel", "widget_class" .= str "IPython.FlexBox"]
|
||||
|
||||
-- Open a comm for this widget, and store it in the kernel state
|
||||
widgetSendOpen box initData $ toJSON widgetState
|
||||
widgetSendOpen box $ toJSON widgetState
|
||||
|
||||
-- Return the widget
|
||||
return box
|
||||
|
@ -0,0 +1,57 @@
|
||||
{-# LANGUAGE FlexibleInstances #-}
|
||||
{-# LANGUAGE OverloadedStrings #-}
|
||||
{-# LANGUAGE DataKinds #-}
|
||||
{-# LANGUAGE TypeSynonymInstances #-}
|
||||
|
||||
module IHaskell.Display.Widgets.Box.PlaceProxy (
|
||||
-- * The PlaceProxy widget
|
||||
PlaceProxy,
|
||||
-- * Constructor
|
||||
mkPlaceProxy) where
|
||||
|
||||
-- To keep `cabal repl` happy when running from the ihaskell repo
|
||||
import Prelude
|
||||
|
||||
import Data.Aeson
|
||||
import Data.IORef (newIORef)
|
||||
import Data.Vinyl (Rec(..), (<+>))
|
||||
import Data.Vinyl.Lens (rput)
|
||||
|
||||
import IHaskell.Display
|
||||
import IHaskell.Eval.Widgets
|
||||
import IHaskell.IPython.Message.UUID as U
|
||||
|
||||
import IHaskell.Display.Widgets.Types
|
||||
import IHaskell.Display.Widgets.Common
|
||||
|
||||
-- | A 'Box' represents a Box widget from IPython.html.widgets.
|
||||
type PlaceProxy = IPythonWidget PlaceProxyType
|
||||
|
||||
-- | Create a new box
|
||||
mkPlaceProxy :: IO PlaceProxy
|
||||
mkPlaceProxy = do
|
||||
-- Default properties, with a random uuid
|
||||
uuid <- U.random
|
||||
|
||||
let widgetClassState = defaultWidget "PlaceProxyView"
|
||||
baseState = rput (ModelName =:: "ProxyModel") widgetClassState
|
||||
proxyState = (Child =:: Nothing) :& (Selector =:: "") :& RNil
|
||||
widgetState = WidgetState $ baseState <+> proxyState
|
||||
|
||||
stateIO <- newIORef widgetState
|
||||
|
||||
let widget = IPythonWidget uuid stateIO
|
||||
|
||||
-- Open a comm for this widget, and store it in the kernel state
|
||||
widgetSendOpen widget $ toJSON widgetState
|
||||
|
||||
-- Return the widget
|
||||
return widget
|
||||
|
||||
instance IHaskellDisplay PlaceProxy where
|
||||
display b = do
|
||||
widgetSendView b
|
||||
return $ Display []
|
||||
|
||||
instance IHaskellWidget PlaceProxy where
|
||||
getCommUUID = uuid
|
@ -0,0 +1,57 @@
|
||||
{-# LANGUAGE FlexibleInstances #-}
|
||||
{-# LANGUAGE OverloadedStrings #-}
|
||||
{-# LANGUAGE DataKinds #-}
|
||||
{-# LANGUAGE TypeSynonymInstances #-}
|
||||
|
||||
module IHaskell.Display.Widgets.Box.Proxy (
|
||||
-- * The Proxy widget
|
||||
ProxyWidget,
|
||||
-- * Constructor
|
||||
mkProxyWidget) where
|
||||
|
||||
-- To keep `cabal repl` happy when running from the ihaskell repo
|
||||
import Prelude
|
||||
|
||||
import Data.Aeson
|
||||
import Data.IORef (newIORef)
|
||||
import Data.Vinyl (Rec(..), (<+>))
|
||||
import Data.Vinyl.Lens (rput)
|
||||
|
||||
import IHaskell.Display
|
||||
import IHaskell.Eval.Widgets
|
||||
import IHaskell.IPython.Message.UUID as U
|
||||
|
||||
import IHaskell.Display.Widgets.Types
|
||||
import IHaskell.Display.Widgets.Common
|
||||
|
||||
-- | A 'Box' represents a Box widget from IPython.html.widgets.
|
||||
type ProxyWidget = IPythonWidget ProxyType
|
||||
|
||||
-- | Create a new box
|
||||
mkProxyWidget :: IO ProxyWidget
|
||||
mkProxyWidget = do
|
||||
-- Default properties, with a random uuid
|
||||
uuid <- U.random
|
||||
|
||||
let widgetClassState = defaultWidget "ProxyView"
|
||||
baseState = rput (ModelName =:: "ProxyModel") widgetClassState
|
||||
proxyState = (Child =:: Nothing) :& RNil
|
||||
widgetState = WidgetState $ baseState <+> proxyState
|
||||
|
||||
stateIO <- newIORef widgetState
|
||||
|
||||
let proxy = IPythonWidget uuid stateIO
|
||||
|
||||
-- Open a comm for this widget, and store it in the kernel state
|
||||
widgetSendOpen proxy $ toJSON widgetState
|
||||
|
||||
-- Return the widget
|
||||
return proxy
|
||||
|
||||
instance IHaskellDisplay ProxyWidget where
|
||||
display b = do
|
||||
widgetSendView b
|
||||
return $ Display []
|
||||
|
||||
instance IHaskellWidget ProxyWidget where
|
||||
getCommUUID = uuid
|
@ -12,13 +12,11 @@ Accordion,
|
||||
-- To keep `cabal repl` happy when running from the ihaskell repo
|
||||
import Prelude
|
||||
|
||||
import Control.Monad (when, join)
|
||||
import Data.Aeson
|
||||
import Data.HashMap.Strict as HM
|
||||
import Data.IORef (newIORef)
|
||||
import qualified Data.Scientific as Sci
|
||||
import Data.Text (Text)
|
||||
import Data.Vinyl (Rec(..), (<+>))
|
||||
|
||||
import IHaskell.Display
|
||||
import IHaskell.Eval.Widgets
|
||||
@ -41,11 +39,9 @@ mkAccordion = do
|
||||
stateIO <- newIORef widgetState
|
||||
|
||||
let box = IPythonWidget uuid stateIO
|
||||
initData = object
|
||||
["model_name" .= str "WidgetModel", "widget_class" .= str "IPython.Accordion"]
|
||||
|
||||
-- Open a comm for this widget, and store it in the kernel state
|
||||
widgetSendOpen box initData $ toJSON widgetState
|
||||
widgetSendOpen box $ toJSON widgetState
|
||||
|
||||
-- Return the widget
|
||||
return box
|
||||
|
@ -12,13 +12,11 @@ TabWidget,
|
||||
-- To keep `cabal repl` happy when running from the ihaskell repo
|
||||
import Prelude
|
||||
|
||||
import Control.Monad (when, join)
|
||||
import Data.Aeson
|
||||
import Data.HashMap.Strict as HM
|
||||
import Data.IORef (newIORef)
|
||||
import qualified Data.Scientific as Sci
|
||||
import Data.Text (Text)
|
||||
import Data.Vinyl (Rec(..), (<+>))
|
||||
|
||||
import IHaskell.Display
|
||||
import IHaskell.Eval.Widgets
|
||||
@ -41,10 +39,9 @@ mkTabWidget = do
|
||||
stateIO <- newIORef widgetState
|
||||
|
||||
let box = IPythonWidget uuid stateIO
|
||||
initData = object ["model_name" .= str "WidgetModel", "widget_class" .= str "IPython.Tab"]
|
||||
|
||||
-- Open a comm for this widget, and store it in the kernel state
|
||||
widgetSendOpen box initData $ toJSON widgetState
|
||||
widgetSendOpen box $ toJSON widgetState
|
||||
|
||||
-- Return the widget
|
||||
return box
|
||||
|
@ -12,7 +12,7 @@ Button,
|
||||
-- To keep `cabal repl` happy when running from the ihaskell repo
|
||||
import Prelude
|
||||
|
||||
import Control.Monad (when, join)
|
||||
import Control.Monad (when)
|
||||
import Data.Aeson
|
||||
import Data.HashMap.Strict as HM
|
||||
import Data.IORef (newIORef)
|
||||
@ -49,10 +49,8 @@ mkButton = do
|
||||
|
||||
let button = IPythonWidget uuid stateIO
|
||||
|
||||
let initData = object ["model_name" .= str "WidgetModel", "widget_class" .= str "IPython.Button"]
|
||||
|
||||
-- Open a comm for this widget, and store it in the kernel state
|
||||
widgetSendOpen button initData $ toJSON buttonState
|
||||
widgetSendOpen button $ toJSON buttonState
|
||||
|
||||
-- Return the button widget
|
||||
return button
|
||||
|
@ -4,12 +4,15 @@
|
||||
{-# LANGUAGE ScopedTypeVariables #-}
|
||||
{-# LANGUAGE DataKinds #-}
|
||||
{-# LANGUAGE GADTs #-}
|
||||
{-# LANGUAGE AutoDeriveTypeable #-}
|
||||
{-# LANGUAGE DeriveDataTypeable #-}
|
||||
|
||||
module IHaskell.Display.Widgets.Common where
|
||||
|
||||
import Data.Aeson
|
||||
import Data.Aeson.Types (emptyObject)
|
||||
import Data.Text (pack, Text)
|
||||
import Data.Typeable (Typeable)
|
||||
|
||||
import IHaskell.Display (IHaskellWidget)
|
||||
import IHaskell.Eval.Widgets (widgetSendClose)
|
||||
@ -18,6 +21,8 @@ import qualified IHaskell.Display.Widgets.Singletons as S
|
||||
|
||||
pattern ViewModule = S.SViewModule
|
||||
pattern ViewName = S.SViewName
|
||||
pattern ModelModule = S.SModelModule
|
||||
pattern ModelName = S.SModelName
|
||||
pattern MsgThrottle = S.SMsgThrottle
|
||||
pattern Version = S.SVersion
|
||||
pattern DisplayHandler = S.SDisplayHandler
|
||||
@ -87,16 +92,19 @@ pattern Pack = S.SPack
|
||||
pattern Align = S.SAlign
|
||||
pattern Titles = S.STitles
|
||||
pattern SelectedIndex = S.SSelectedIndex
|
||||
pattern ReadOutMsg = S.SReadOutMsg
|
||||
pattern Child = S.SChild
|
||||
pattern Selector = S.SSelector
|
||||
|
||||
-- | Close a widget's comm
|
||||
closeWidget :: IHaskellWidget w => w -> IO ()
|
||||
closeWidget w = widgetSendClose w emptyObject
|
||||
|
||||
newtype StrInt = StrInt Integer
|
||||
deriving (Num, Ord, Eq, Enum)
|
||||
newtype PixCount = PixCount Integer
|
||||
deriving (Num, Ord, Eq, Enum, Typeable)
|
||||
|
||||
instance ToJSON StrInt where
|
||||
toJSON (StrInt x) = toJSON . pack $ show x
|
||||
instance ToJSON PixCount where
|
||||
toJSON (PixCount x) = toJSON . pack $ show x ++ "px"
|
||||
|
||||
-- | Pre-defined border styles
|
||||
data BorderStyleValue = NoBorder
|
||||
@ -196,7 +204,7 @@ instance ToJSON BarStyleValue where
|
||||
data ImageFormatValue = PNG
|
||||
| SVG
|
||||
| JPG
|
||||
deriving Eq
|
||||
deriving (Eq, Typeable)
|
||||
|
||||
instance Show ImageFormatValue where
|
||||
show PNG = "png"
|
||||
|
@ -13,13 +13,11 @@ BoundedFloatText,
|
||||
-- To keep `cabal repl` happy when running from the ihaskell repo
|
||||
import Prelude
|
||||
|
||||
import Control.Monad (when, join, void)
|
||||
import Data.Aeson
|
||||
import qualified Data.HashMap.Strict as HM
|
||||
import Data.IORef (newIORef)
|
||||
import qualified Data.Scientific as Sci
|
||||
import Data.Text (Text)
|
||||
import Data.Vinyl (Rec(..), (<+>))
|
||||
|
||||
import IHaskell.Display
|
||||
import IHaskell.Eval.Widgets
|
||||
@ -42,13 +40,9 @@ mkBoundedFloatText = do
|
||||
stateIO <- newIORef widgetState
|
||||
|
||||
let widget = IPythonWidget uuid stateIO
|
||||
initData = object
|
||||
[ "model_name" .= str "WidgetModel"
|
||||
, "widget_class" .= str "IPython.BoundedFloatText"
|
||||
]
|
||||
|
||||
-- Open a comm for this widget, and store it in the kernel state
|
||||
widgetSendOpen widget initData $ toJSON widgetState
|
||||
widgetSendOpen widget $ toJSON widgetState
|
||||
|
||||
-- Return the widget
|
||||
return widget
|
||||
|
@ -12,13 +12,8 @@ FloatProgress,
|
||||
-- To keep `cabal repl` happy when running from the ihaskell repo
|
||||
import Prelude
|
||||
|
||||
import Control.Exception (throw, ArithException(LossOfPrecision))
|
||||
import Control.Monad (when, join)
|
||||
import Data.Aeson
|
||||
import qualified Data.HashMap.Strict as HM
|
||||
import Data.IORef (newIORef)
|
||||
import qualified Data.Scientific as Sci
|
||||
import Data.Text (Text)
|
||||
import Data.Vinyl (Rec(..), (<+>))
|
||||
|
||||
import IHaskell.Display
|
||||
@ -38,19 +33,17 @@ mkFloatProgress = do
|
||||
uuid <- U.random
|
||||
|
||||
let boundedFloatAttrs = defaultBoundedFloatWidget "ProgressView"
|
||||
progressAttrs = (BarStyle =:: DefaultBar) :& RNil
|
||||
progressAttrs = (Orientation =:: HorizontalOrientation)
|
||||
:& (BarStyle =:: DefaultBar)
|
||||
:& RNil
|
||||
widgetState = WidgetState $ boundedFloatAttrs <+> progressAttrs
|
||||
|
||||
stateIO <- newIORef widgetState
|
||||
|
||||
let widget = IPythonWidget uuid stateIO
|
||||
initData = object
|
||||
[ "model_name" .= str "WidgetModel"
|
||||
, "widget_class" .= str "IPython.FloatProgress"
|
||||
]
|
||||
|
||||
-- Open a comm for this widget, and store it in the kernel state
|
||||
widgetSendOpen widget initData $ toJSON widgetState
|
||||
widgetSendOpen widget $ toJSON widgetState
|
||||
|
||||
-- Return the widget
|
||||
return widget
|
||||
|
@ -12,7 +12,6 @@ FloatSlider,
|
||||
-- To keep `cabal repl` happy when running from the ihaskell repo
|
||||
import Prelude
|
||||
|
||||
import Control.Monad (when, join, void)
|
||||
import Data.Aeson
|
||||
import qualified Data.HashMap.Strict as HM
|
||||
import Data.IORef (newIORef)
|
||||
@ -47,11 +46,9 @@ mkFloatSlider = do
|
||||
stateIO <- newIORef widgetState
|
||||
|
||||
let widget = IPythonWidget uuid stateIO
|
||||
initData = object
|
||||
["model_name" .= str "WidgetModel", "widget_class" .= str "IPython.FloatSlider"]
|
||||
|
||||
-- Open a comm for this widget, and store it in the kernel state
|
||||
widgetSendOpen widget initData $ toJSON widgetState
|
||||
widgetSendOpen widget $ toJSON widgetState
|
||||
|
||||
-- Return the widget
|
||||
return widget
|
||||
|
@ -13,8 +13,6 @@ FloatRangeSlider,
|
||||
-- To keep `cabal repl` happy when running from the ihaskell repo
|
||||
import Prelude
|
||||
|
||||
import Control.Exception (throw, ArithException(LossOfPrecision))
|
||||
import Control.Monad (when, join, void)
|
||||
import Data.Aeson
|
||||
import qualified Data.HashMap.Strict as HM
|
||||
import Data.IORef (newIORef)
|
||||
@ -50,13 +48,9 @@ mkFloatRangeSlider = do
|
||||
stateIO <- newIORef widgetState
|
||||
|
||||
let widget = IPythonWidget uuid stateIO
|
||||
initData = object
|
||||
[ "model_name" .= str "WidgetModel"
|
||||
, "widget_class" .= str "IPython.FloatRangeSlider"
|
||||
]
|
||||
|
||||
-- Open a comm for this widget, and store it in the kernel state
|
||||
widgetSendOpen widget initData $ toJSON widgetState
|
||||
widgetSendOpen widget $ toJSON widgetState
|
||||
|
||||
-- Return the widget
|
||||
return widget
|
||||
|
@ -12,13 +12,11 @@ FloatText,
|
||||
-- To keep `cabal repl` happy when running from the ihaskell repo
|
||||
import Prelude
|
||||
|
||||
import Control.Monad (when, join, void)
|
||||
import Data.Aeson
|
||||
import qualified Data.HashMap.Strict as HM
|
||||
import Data.IORef (newIORef)
|
||||
import qualified Data.Scientific as Sci
|
||||
import Data.Text (Text)
|
||||
import Data.Vinyl (Rec(..), (<+>))
|
||||
|
||||
import IHaskell.Display
|
||||
import IHaskell.Eval.Widgets
|
||||
@ -41,11 +39,9 @@ mkFloatText = do
|
||||
stateIO <- newIORef widgetState
|
||||
|
||||
let widget = IPythonWidget uuid stateIO
|
||||
initData = object
|
||||
["model_name" .= str "WidgetModel", "widget_class" .= str "IPython.FloatText"]
|
||||
|
||||
-- Open a comm for this widget, and store it in the kernel state
|
||||
widgetSendOpen widget initData $ toJSON widgetState
|
||||
widgetSendOpen widget $ toJSON widgetState
|
||||
|
||||
-- Return the widget
|
||||
return widget
|
||||
|
@ -12,12 +12,9 @@ ImageWidget,
|
||||
-- To keep `cabal repl` happy when running from the ihaskell repo
|
||||
import Prelude
|
||||
|
||||
import Control.Monad (when, join)
|
||||
import Data.Aeson
|
||||
import Data.HashMap.Strict as HM
|
||||
import Data.IORef (newIORef)
|
||||
import Data.Monoid (mempty)
|
||||
import Data.Text (Text)
|
||||
import Data.Vinyl (Rec(..), (<+>))
|
||||
|
||||
import IHaskell.Display
|
||||
@ -38,6 +35,8 @@ mkImageWidget = do
|
||||
|
||||
let dom = defaultDOMWidget "ImageView"
|
||||
img = (ImageFormat =:: PNG)
|
||||
:& (Width =:+ 0)
|
||||
:& (Height =:+ 0)
|
||||
:& (B64Value =:: mempty)
|
||||
:& RNil
|
||||
widgetState = WidgetState (dom <+> img)
|
||||
@ -46,10 +45,8 @@ mkImageWidget = do
|
||||
|
||||
let widget = IPythonWidget uuid stateIO
|
||||
|
||||
let initData = object ["model_name" .= str "WidgetModel", "widget_class" .= str "IPython.Image"]
|
||||
|
||||
-- Open a comm for this widget, and store it in the kernel state
|
||||
widgetSendOpen widget initData $ toJSON widgetState
|
||||
widgetSendOpen widget $ toJSON widgetState
|
||||
|
||||
-- Return the image widget
|
||||
return widget
|
||||
|
@ -12,13 +12,11 @@ BoundedIntText,
|
||||
-- To keep `cabal repl` happy when running from the ihaskell repo
|
||||
import Prelude
|
||||
|
||||
import Control.Monad (when, join, void)
|
||||
import Data.Aeson
|
||||
import qualified Data.HashMap.Strict as HM
|
||||
import Data.IORef (newIORef)
|
||||
import qualified Data.Scientific as Sci
|
||||
import Data.Text (Text)
|
||||
import Data.Vinyl (Rec(..), (<+>))
|
||||
|
||||
import IHaskell.Display
|
||||
import IHaskell.Eval.Widgets
|
||||
@ -41,13 +39,9 @@ mkBoundedIntText = do
|
||||
stateIO <- newIORef widgetState
|
||||
|
||||
let widget = IPythonWidget uuid stateIO
|
||||
initData = object
|
||||
[ "model_name" .= str "WidgetModel"
|
||||
, "widget_class" .= str "IPython.BoundedIntText"
|
||||
]
|
||||
|
||||
-- Open a comm for this widget, and store it in the kernel state
|
||||
widgetSendOpen widget initData $ toJSON widgetState
|
||||
widgetSendOpen widget $ toJSON widgetState
|
||||
|
||||
-- Return the widget
|
||||
return widget
|
||||
|
@ -12,13 +12,8 @@ IntProgress,
|
||||
-- To keep `cabal repl` happy when running from the ihaskell repo
|
||||
import Prelude
|
||||
|
||||
import Control.Exception (throw, ArithException(LossOfPrecision))
|
||||
import Control.Monad (when, join)
|
||||
import Data.Aeson
|
||||
import qualified Data.HashMap.Strict as HM
|
||||
import Data.IORef (newIORef)
|
||||
import qualified Data.Scientific as Sci
|
||||
import Data.Text (Text)
|
||||
import Data.Vinyl (Rec(..), (<+>))
|
||||
|
||||
import IHaskell.Display
|
||||
@ -38,17 +33,17 @@ mkIntProgress = do
|
||||
uuid <- U.random
|
||||
|
||||
let boundedIntAttrs = defaultBoundedIntWidget "ProgressView"
|
||||
progressAttrs = (BarStyle =:: DefaultBar) :& RNil
|
||||
progressAttrs = (Orientation =:: HorizontalOrientation)
|
||||
:& (BarStyle =:: DefaultBar)
|
||||
:& RNil
|
||||
widgetState = WidgetState $ boundedIntAttrs <+> progressAttrs
|
||||
|
||||
stateIO <- newIORef widgetState
|
||||
|
||||
let widget = IPythonWidget uuid stateIO
|
||||
initData = object
|
||||
["model_name" .= str "WidgetModel", "widget_class" .= str "IPython.IntProgress"]
|
||||
|
||||
-- Open a comm for this widget, and store it in the kernel state
|
||||
widgetSendOpen widget initData $ toJSON widgetState
|
||||
widgetSendOpen widget $ toJSON widgetState
|
||||
|
||||
-- Return the widget
|
||||
return widget
|
||||
|
@ -12,7 +12,6 @@ IntSlider,
|
||||
-- To keep `cabal repl` happy when running from the ihaskell repo
|
||||
import Prelude
|
||||
|
||||
import Control.Monad (when, join, void)
|
||||
import Data.Aeson
|
||||
import qualified Data.HashMap.Strict as HM
|
||||
import Data.IORef (newIORef)
|
||||
@ -47,11 +46,9 @@ mkIntSlider = do
|
||||
stateIO <- newIORef widgetState
|
||||
|
||||
let widget = IPythonWidget uuid stateIO
|
||||
initData = object
|
||||
["model_name" .= str "WidgetModel", "widget_class" .= str "IPython.IntSlider"]
|
||||
|
||||
-- Open a comm for this widget, and store it in the kernel state
|
||||
widgetSendOpen widget initData $ toJSON widgetState
|
||||
widgetSendOpen widget $ toJSON widgetState
|
||||
|
||||
-- Return the widget
|
||||
return widget
|
||||
|
@ -12,7 +12,6 @@ IntRangeSlider,
|
||||
-- To keep `cabal repl` happy when running from the ihaskell repo
|
||||
import Prelude
|
||||
|
||||
import Control.Monad (when, join, void)
|
||||
import Data.Aeson
|
||||
import qualified Data.HashMap.Strict as HM
|
||||
import Data.IORef (newIORef)
|
||||
@ -48,13 +47,9 @@ mkIntRangeSlider = do
|
||||
stateIO <- newIORef widgetState
|
||||
|
||||
let widget = IPythonWidget uuid stateIO
|
||||
initData = object
|
||||
[ "model_name" .= str "WidgetModel"
|
||||
, "widget_class" .= str "IPython.IntRangeSlider"
|
||||
]
|
||||
|
||||
-- Open a comm for this widget, and store it in the kernel state
|
||||
widgetSendOpen widget initData $ toJSON widgetState
|
||||
widgetSendOpen widget $ toJSON widgetState
|
||||
|
||||
-- Return the widget
|
||||
return widget
|
||||
|
@ -12,13 +12,11 @@ IntText,
|
||||
-- To keep `cabal repl` happy when running from the ihaskell repo
|
||||
import Prelude
|
||||
|
||||
import Control.Monad (when, join, void)
|
||||
import Data.Aeson
|
||||
import qualified Data.HashMap.Strict as HM
|
||||
import Data.IORef (newIORef)
|
||||
import qualified Data.Scientific as Sci
|
||||
import Data.Text (Text)
|
||||
import Data.Vinyl (Rec(..), (<+>))
|
||||
|
||||
import IHaskell.Display
|
||||
import IHaskell.Eval.Widgets
|
||||
@ -41,10 +39,9 @@ mkIntText = do
|
||||
stateIO <- newIORef widgetState
|
||||
|
||||
let widget = IPythonWidget uuid stateIO
|
||||
initData = object ["model_name" .= str "WidgetModel", "widget_class" .= str "IPython.IntText"]
|
||||
|
||||
-- Open a comm for this widget, and store it in the kernel state
|
||||
widgetSendOpen widget initData $ toJSON widgetState
|
||||
widgetSendOpen widget $ toJSON widgetState
|
||||
|
||||
-- Return the widget
|
||||
return widget
|
||||
|
@ -1,14 +1,11 @@
|
||||
{-# LANGUAGE DataKinds #-}
|
||||
{-# LANGUAGE TypeFamilies #-}
|
||||
{-# LANGUAGE DataKinds #-}
|
||||
{-# LANGUAGE TypeOperators #-}
|
||||
{-# LANGUAGE GADTs #-}
|
||||
{-# LANGUAGE FlexibleContexts #-}
|
||||
{-# LANGUAGE ConstraintKinds #-}
|
||||
{-# LANGUAGE UndecidableInstances #-}
|
||||
{-# LANGUAGE GADTs #-}
|
||||
{-# LANGUAGE TypeOperators #-}
|
||||
{-# LANGUAGE FlexibleContexts #-}
|
||||
{-# LANGUAGE PolyKinds #-}
|
||||
{-# LANGUAGE KindSignatures #-}
|
||||
{-# LANGUAGE ScopedTypeVariables #-}
|
||||
{-# LANGUAGE PatternSynonyms #-}
|
||||
|
||||
module IHaskell.Display.Widgets.Interactive (interactive, uncurryHList, Rec(..), Argument(..)) where
|
||||
|
||||
@ -25,7 +22,7 @@ import IHaskell.Display
|
||||
|
||||
import IHaskell.Display.Widgets.Types
|
||||
import IHaskell.Display.Widgets.Common
|
||||
import qualified IHaskell.Display.Widgets.Singletons as S (SField(..), Field(..))
|
||||
import qualified IHaskell.Display.Widgets.Singletons as S (SField, Field(..))
|
||||
|
||||
import IHaskell.Display.Widgets.Box.FlexBox
|
||||
import IHaskell.Display.Widgets.Bool.CheckBox
|
||||
@ -44,10 +41,6 @@ data WidgetConf a where
|
||||
a
|
||||
-> WidgetConf a
|
||||
|
||||
newtype WrappedConstructor a =
|
||||
WrappedConstructor
|
||||
{ wrappedConstructor :: IO (IPythonWidget (SuitableWidget a)) }
|
||||
|
||||
|
||||
type family WithTypes (ts :: [*]) (r :: *) :: * where
|
||||
WithTypes '[] r = r
|
||||
@ -70,8 +63,6 @@ newtype EventSetter a = EventSetter (IPythonWidget (SuitableWidget a) -> IO () -
|
||||
|
||||
newtype Initializer a = Initializer (IPythonWidget (SuitableWidget a) -> Argument a -> IO ())
|
||||
|
||||
newtype Trigger a = Trigger (IPythonWidget (SuitableWidget a) -> IO ())
|
||||
|
||||
|
||||
data RequiredWidget a where
|
||||
RequiredWidget ::
|
||||
@ -107,11 +98,8 @@ extractGetter (WidgetConf wr) = Getter $ getValue wr
|
||||
extractEventSetter :: WidgetConf x -> EventSetter x
|
||||
extractEventSetter (WidgetConf wr) = EventSetter $ setEvent wr
|
||||
|
||||
extractTrigger :: WidgetConf x -> Trigger x
|
||||
extractTrigger (WidgetConf wr) = Trigger $ trigger wr
|
||||
|
||||
extractInitializer :: WidgetConf x -> Initializer x
|
||||
extractInitializer (WidgetConf wr) = Initializer initializer
|
||||
extractInitializer WidgetConf{} = Initializer initializer
|
||||
|
||||
createWidget :: Constructor a -> IO (RequiredWidget a)
|
||||
createWidget (Constructor con) = fmap RequiredWidget con
|
||||
@ -146,7 +134,6 @@ liftToWidgets func rc initvals = do
|
||||
getters = rmap extractGetter rc
|
||||
eventSetters = rmap extractEventSetter rc
|
||||
initializers = rmap extractInitializer rc
|
||||
triggers = rmap extractTrigger rc
|
||||
|
||||
bx <- mkFlexBox
|
||||
out <- mkOutputWidget
|
||||
@ -188,15 +175,9 @@ construct (WrappedWidget cons _ _) = cons
|
||||
getValue :: WrappedWidget w h f a -> IPythonWidget w -> IO a
|
||||
getValue (WrappedWidget _ _ field) widget = getField widget field
|
||||
|
||||
setValue :: WrappedWidget w h f a -> IPythonWidget w -> a -> IO ()
|
||||
setValue (WrappedWidget _ _ field) widget = setField widget field
|
||||
|
||||
setEvent :: WrappedWidget w h f a -> IPythonWidget w -> IO () -> IO ()
|
||||
setEvent (WrappedWidget _ h _) widget = setField widget h
|
||||
|
||||
trigger :: WrappedWidget w h f a -> IPythonWidget w -> IO ()
|
||||
trigger (WrappedWidget _ h _) = triggerEvent h
|
||||
|
||||
class RecAll Attr (WidgetFields (SuitableWidget a)) ToPairs => FromWidget a where
|
||||
type SuitableWidget a :: WidgetType
|
||||
type SuitableHandler a :: S.Field
|
||||
|
@ -18,12 +18,8 @@ module IHaskell.Display.Widgets.Output (
|
||||
-- To keep `cabal repl` happy when running from the ihaskell repo
|
||||
import Prelude
|
||||
|
||||
import Control.Monad (when, join)
|
||||
import Data.Aeson
|
||||
import Data.HashMap.Strict as HM
|
||||
import Data.IORef (newIORef)
|
||||
import Data.Text (Text)
|
||||
import Data.Vinyl (Rec(..), (<+>))
|
||||
|
||||
import IHaskell.Display
|
||||
import IHaskell.Eval.Widgets
|
||||
@ -45,10 +41,9 @@ mkOutputWidget = do
|
||||
stateIO <- newIORef widgetState
|
||||
|
||||
let widget = IPythonWidget uuid stateIO
|
||||
initData = object ["model_name" .= str "WidgetModel"]
|
||||
|
||||
-- Open a comm for this widget, and store it in the kernel state
|
||||
widgetSendOpen widget initData $ toJSON widgetState
|
||||
widgetSendOpen widget $ toJSON widgetState
|
||||
|
||||
-- Return the image widget
|
||||
return widget
|
||||
|
@ -12,7 +12,7 @@ Dropdown,
|
||||
-- To keep `cabal repl` happy when running from the ihaskell repo
|
||||
import Prelude
|
||||
|
||||
import Control.Monad (when, join, void)
|
||||
import Control.Monad (void)
|
||||
import Data.Aeson
|
||||
import qualified Data.HashMap.Strict as HM
|
||||
import Data.IORef (newIORef)
|
||||
@ -41,11 +41,9 @@ mkDropdown = do
|
||||
stateIO <- newIORef widgetState
|
||||
|
||||
let widget = IPythonWidget uuid stateIO
|
||||
initData = object
|
||||
["model_name" .= str "WidgetModel", "widget_class" .= str "IPython.Dropdown"]
|
||||
|
||||
-- Open a comm for this widget, and store it in the kernel state
|
||||
widgetSendOpen widget initData $ toJSON widgetState
|
||||
widgetSendOpen widget $ toJSON widgetState
|
||||
|
||||
-- Return the widget
|
||||
return widget
|
||||
|
@ -12,12 +12,11 @@ RadioButtons,
|
||||
-- To keep `cabal repl` happy when running from the ihaskell repo
|
||||
import Prelude
|
||||
|
||||
import Control.Monad (when, join, void)
|
||||
import Control.Monad (when, void)
|
||||
import Data.Aeson
|
||||
import qualified Data.HashMap.Strict as HM
|
||||
import Data.IORef (newIORef)
|
||||
import Data.Text (Text)
|
||||
import Data.Vinyl (Rec(..), (<+>))
|
||||
|
||||
import IHaskell.Display
|
||||
import IHaskell.Eval.Widgets
|
||||
@ -39,11 +38,9 @@ mkRadioButtons = do
|
||||
stateIO <- newIORef widgetState
|
||||
|
||||
let widget = IPythonWidget uuid stateIO
|
||||
initData = object
|
||||
["model_name" .= str "WidgetModel", "widget_class" .= str "IPython.RadioButtons"]
|
||||
|
||||
-- Open a comm for this widget, and store it in the kernel state
|
||||
widgetSendOpen widget initData $ toJSON widgetState
|
||||
widgetSendOpen widget $ toJSON widgetState
|
||||
|
||||
-- Return the widget
|
||||
return widget
|
||||
|
@ -39,10 +39,9 @@ mkSelect = do
|
||||
stateIO <- newIORef widgetState
|
||||
|
||||
let widget = IPythonWidget uuid stateIO
|
||||
initData = object ["model_name" .= str "WidgetModel", "widget_class" .= str "IPython.Select"]
|
||||
|
||||
-- Open a comm for this widget, and store it in the kernel state
|
||||
widgetSendOpen widget initData $ toJSON widgetState
|
||||
widgetSendOpen widget $ toJSON widgetState
|
||||
|
||||
-- Return the widget
|
||||
return widget
|
||||
|
@ -12,13 +12,12 @@ SelectMultiple,
|
||||
-- To keep `cabal repl` happy when running from the ihaskell repo
|
||||
import Prelude
|
||||
|
||||
import Control.Monad (fmap, join, sequence, void)
|
||||
import Control.Monad (void)
|
||||
import Data.Aeson
|
||||
import qualified Data.HashMap.Strict as HM
|
||||
import Data.IORef (newIORef)
|
||||
import Data.Text (Text)
|
||||
import qualified Data.Vector as V
|
||||
import Data.Vinyl (Rec(..), (<+>))
|
||||
|
||||
import IHaskell.Display
|
||||
import IHaskell.Eval.Widgets
|
||||
@ -40,13 +39,9 @@ mkSelectMultiple = do
|
||||
stateIO <- newIORef widgetState
|
||||
|
||||
let widget = IPythonWidget uuid stateIO
|
||||
initData = object
|
||||
[ "model_name" .= str "WidgetModel"
|
||||
, "widget_class" .= str "IPython.SelectMultiple"
|
||||
]
|
||||
|
||||
-- Open a comm for this widget, and store it in the kernel state
|
||||
widgetSendOpen widget initData $ toJSON widgetState
|
||||
widgetSendOpen widget $ toJSON widgetState
|
||||
|
||||
-- Return the widget
|
||||
return widget
|
||||
|
@ -12,7 +12,7 @@ ToggleButtons,
|
||||
-- To keep `cabal repl` happy when running from the ihaskell repo
|
||||
import Prelude
|
||||
|
||||
import Control.Monad (when, join, void)
|
||||
import Control.Monad (void)
|
||||
import Data.Aeson
|
||||
import qualified Data.HashMap.Strict as HM
|
||||
import Data.IORef (newIORef)
|
||||
@ -44,13 +44,9 @@ mkToggleButtons = do
|
||||
stateIO <- newIORef widgetState
|
||||
|
||||
let widget = IPythonWidget uuid stateIO
|
||||
initData = object
|
||||
[ "model_name" .= str "WidgetModel"
|
||||
, "widget_class" .= str "IPython.ToggleButtons"
|
||||
]
|
||||
|
||||
-- Open a comm for this widget, and store it in the kernel state
|
||||
widgetSendOpen widget initData $ toJSON widgetState
|
||||
widgetSendOpen widget $ toJSON widgetState
|
||||
|
||||
-- Return the widget
|
||||
return widget
|
||||
|
@ -5,10 +5,13 @@
|
||||
{-# LANGUAGE UndecidableInstances #-}
|
||||
{-# LANGUAGE TemplateHaskell #-}
|
||||
{-# LANGUAGE QuasiQuotes #-}
|
||||
{-# LANGUAGE ScopedTypeVariables #-}
|
||||
{-# LANGUAGE InstanceSigs #-}
|
||||
|
||||
module IHaskell.Display.Widgets.Singletons where
|
||||
|
||||
import Data.Singletons.TH
|
||||
import Data.Singletons.Prelude.Ord
|
||||
|
||||
-- Widget properties
|
||||
singletons
|
||||
@ -16,6 +19,8 @@ singletons
|
||||
|
||||
data Field = ViewModule
|
||||
| ViewName
|
||||
| ModelModule
|
||||
| ModelName
|
||||
| MsgThrottle
|
||||
| Version
|
||||
| DisplayHandler
|
||||
@ -85,5 +90,8 @@ singletons
|
||||
| Align
|
||||
| Titles
|
||||
| SelectedIndex
|
||||
| ReadOutMsg
|
||||
| Child
|
||||
| Selector
|
||||
deriving (Eq, Ord, Show)
|
||||
|]
|
||||
|
@ -12,11 +12,8 @@ HTMLWidget,
|
||||
-- To keep `cabal repl` happy when running from the ihaskell repo
|
||||
import Prelude
|
||||
|
||||
import Control.Monad (when, join)
|
||||
import Data.Aeson
|
||||
import Data.IORef (newIORef)
|
||||
import Data.Text (Text)
|
||||
import Data.Vinyl (Rec(..), (<+>))
|
||||
|
||||
import IHaskell.Display
|
||||
import IHaskell.Eval.Widgets
|
||||
@ -37,10 +34,9 @@ mkHTMLWidget = do
|
||||
stateIO <- newIORef widgetState
|
||||
|
||||
let widget = IPythonWidget uuid stateIO
|
||||
initData = object ["model_name" .= str "WidgetModel", "widget_class" .= str "IPython.HTML"]
|
||||
|
||||
-- Open a comm for this widget, and store it in the kernel state
|
||||
widgetSendOpen widget initData $ toJSON widgetState
|
||||
widgetSendOpen widget $ toJSON widgetState
|
||||
|
||||
-- Return the widget
|
||||
return widget
|
||||
|
@ -12,11 +12,8 @@ LatexWidget,
|
||||
-- To keep `cabal repl` happy when running from the ihaskell repo
|
||||
import Prelude
|
||||
|
||||
import Control.Monad (when, join)
|
||||
import Data.Aeson
|
||||
import Data.IORef (newIORef)
|
||||
import Data.Text (Text)
|
||||
import Data.Vinyl (Rec(..), (<+>))
|
||||
|
||||
import IHaskell.Display
|
||||
import IHaskell.Eval.Widgets
|
||||
@ -37,10 +34,9 @@ mkLatexWidget = do
|
||||
stateIO <- newIORef widgetState
|
||||
|
||||
let widget = IPythonWidget uuid stateIO
|
||||
initData = object ["model_name" .= str "WidgetModel", "widget_class" .= str "IPython.Latex"]
|
||||
|
||||
-- Open a comm for this widget, and store it in the kernel state
|
||||
widgetSendOpen widget initData $ toJSON widgetState
|
||||
widgetSendOpen widget $ toJSON widgetState
|
||||
|
||||
-- Return the widget
|
||||
return widget
|
||||
|
@ -12,11 +12,10 @@ TextWidget,
|
||||
-- To keep `cabal repl` happy when running from the ihaskell repo
|
||||
import Prelude
|
||||
|
||||
import Control.Monad (when, join)
|
||||
import Control.Monad (when)
|
||||
import Data.Aeson
|
||||
import qualified Data.HashMap.Strict as Map
|
||||
import Data.IORef (newIORef)
|
||||
import Data.Text (Text)
|
||||
import Data.Vinyl (Rec(..), (<+>))
|
||||
|
||||
import IHaskell.Display
|
||||
@ -41,10 +40,9 @@ mkTextWidget = do
|
||||
stateIO <- newIORef widgetState
|
||||
|
||||
let widget = IPythonWidget uuid stateIO
|
||||
initData = object ["model_name" .= str "WidgetModel", "widget_class" .= str "IPython.Text"]
|
||||
|
||||
-- Open a comm for this widget, and store it in the kernel state
|
||||
widgetSendOpen widget initData $ toJSON widgetState
|
||||
widgetSendOpen widget $ toJSON widgetState
|
||||
|
||||
-- Return the widget
|
||||
return widget
|
||||
|
@ -12,7 +12,6 @@ TextArea,
|
||||
-- To keep `cabal repl` happy when running from the ihaskell repo
|
||||
import Prelude
|
||||
|
||||
import Control.Monad (when, join)
|
||||
import Data.Aeson
|
||||
import qualified Data.HashMap.Strict as HM
|
||||
import Data.IORef (newIORef)
|
||||
@ -41,11 +40,9 @@ mkTextArea = do
|
||||
stateIO <- newIORef widgetState
|
||||
|
||||
let widget = IPythonWidget uuid stateIO
|
||||
initData = object
|
||||
["model_name" .= str "WidgetModel", "widget_class" .= str "IPython.Textarea"]
|
||||
|
||||
-- Open a comm for this widget, and store it in the kernel state
|
||||
widgetSendOpen widget initData $ toJSON widgetState
|
||||
widgetSendOpen widget $ toJSON widgetState
|
||||
|
||||
-- Return the widget
|
||||
return widget
|
||||
|
@ -12,6 +12,8 @@
|
||||
{-# LANGUAGE BangPatterns #-}
|
||||
{-# LANGUAGE ConstraintKinds #-}
|
||||
{-# LANGUAGE ExistentialQuantification #-}
|
||||
{-# LANGUAGE GADTs #-}
|
||||
{-# LANGUAGE AutoDeriveTypeable #-}
|
||||
|
||||
module IHaskell.Display.Widgets.Types where
|
||||
|
||||
@ -48,8 +50,8 @@ module IHaskell.Display.Widgets.Types where
|
||||
--
|
||||
-- The IPython widgets expect state updates of the form {"property": value}, where an empty string
|
||||
-- for numeric values is ignored by the frontend and the default value is used instead. Some numbers
|
||||
-- need to be sent as numbers (represented by @Integer@), whereas some need to be sent as Strings
|
||||
-- (@StrInt@).
|
||||
-- need to be sent as numbers (represented by @Integer@), whereas some (css lengths) need to be sent
|
||||
-- as Strings (@PixCount@).
|
||||
--
|
||||
-- Child widgets are expected to be sent as strings of the form "IPY_MODEL_<uuid>", where @<uuid>@
|
||||
-- represents the uuid of the widget's comm.
|
||||
@ -57,20 +59,20 @@ module IHaskell.Display.Widgets.Types where
|
||||
-- To know more about the IPython messaging specification (as implemented in this package) take a
|
||||
-- look at the supplied MsgSpec.md.
|
||||
--
|
||||
-- Widgets are not able to do console input, the reason for that can also be found in the messaging
|
||||
-- specification
|
||||
import Control.Monad (unless, join, when, void, mapM_)
|
||||
-- Widgets are not able to do console input, the reason for that can be found in the messaging
|
||||
-- specification.
|
||||
import Control.Monad (unless, join, when, void)
|
||||
import Control.Applicative ((<$>))
|
||||
import qualified Control.Exception as Ex
|
||||
|
||||
import GHC.IO.Exception
|
||||
import Data.Typeable (Typeable, TypeRep, typeOf)
|
||||
import Data.IORef (IORef, readIORef, modifyIORef)
|
||||
import Data.Text (Text, pack)
|
||||
import System.IO.Error
|
||||
import System.Posix.IO
|
||||
import Text.Printf (printf)
|
||||
|
||||
import Data.Aeson
|
||||
import Data.Aeson.Types (Pair)
|
||||
import Data.IORef (IORef, readIORef, modifyIORef)
|
||||
import Data.Text (Text, pack)
|
||||
|
||||
import Data.Vinyl (Rec(..), (<+>), recordToList, reifyConstraint, rmap, Dict(..))
|
||||
import Data.Vinyl.Functor (Compose(..), Const(..))
|
||||
@ -80,17 +82,19 @@ import Data.Vinyl.TypeLevel (RecAll)
|
||||
import Data.Singletons.Prelude ((:++))
|
||||
import Data.Singletons.TH
|
||||
|
||||
import GHC.IO.Exception
|
||||
|
||||
import IHaskell.Eval.Widgets (widgetSendUpdate)
|
||||
import IHaskell.Display (Base64, IHaskellWidget(..))
|
||||
import IHaskell.IPython.Message.UUID
|
||||
|
||||
import IHaskell.Display.Widgets.Singletons (Field, SField(..))
|
||||
import IHaskell.Display.Widgets.Singletons (Field, SField)
|
||||
import qualified IHaskell.Display.Widgets.Singletons as S
|
||||
import IHaskell.Display.Widgets.Common
|
||||
|
||||
-- Classes from IPython's widget hierarchy. Defined as such to reduce code duplication.
|
||||
type WidgetClass = '[S.ViewModule, S.ViewName, S.MsgThrottle, S.Version,
|
||||
S.DisplayHandler]
|
||||
type WidgetClass = '[S.ViewModule, S.ViewName, S.ModelModule, S.ModelName,
|
||||
S.MsgThrottle, S.Version, S.DisplayHandler]
|
||||
|
||||
type DOMWidgetClass = WidgetClass :++ '[S.Visible, S.CSS, S.DOMClasses, S.Width, S.Height, S.Padding,
|
||||
S.Margin, S.Color, S.BackgroundColor, S.BorderColor, S.BorderWidth,
|
||||
@ -104,7 +108,7 @@ type BoolClass = DOMWidgetClass :++ '[S.BoolValue, S.Disabled, S.Description, S.
|
||||
type SelectionClass = DOMWidgetClass :++ '[S.Options, S.SelectedValue, S.SelectedLabel, S.Disabled,
|
||||
S.Description, S.SelectionHandler]
|
||||
|
||||
type MultipleSelectionClass = DOMWidgetClass :++ '[S.Options, S.SelectedLabels, S.SelectedValues, S.Disabled,
|
||||
type MultipleSelectionClass = DOMWidgetClass :++ '[S.Options, S.SelectedValues, S.SelectedLabels, S.Disabled,
|
||||
S.Description, S.SelectionHandler]
|
||||
|
||||
type IntClass = DOMWidgetClass :++ '[S.IntValue, S.Disabled, S.Description, S.ChangeHandler]
|
||||
@ -128,29 +132,31 @@ type BoxClass = DOMWidgetClass :++ '[S.Children, S.OverflowX, S.OverflowY, S.Box
|
||||
type SelectionContainerClass = BoxClass :++ '[S.Titles, S.SelectedIndex, S.ChangeHandler]
|
||||
|
||||
-- Types associated with Fields.
|
||||
|
||||
|
||||
type family FieldType (f :: Field) :: * where
|
||||
FieldType S.ViewModule = Text
|
||||
FieldType S.ViewName = Text
|
||||
FieldType S.ModelModule = Text
|
||||
FieldType S.ModelName = Text
|
||||
FieldType S.MsgThrottle = Integer
|
||||
FieldType S.Version = Integer
|
||||
FieldType S.DisplayHandler = IO ()
|
||||
FieldType S.Visible = Bool
|
||||
FieldType S.CSS = [(Text, Text, Text)]
|
||||
FieldType S.DOMClasses = [Text]
|
||||
FieldType S.Width = StrInt
|
||||
FieldType S.Height = StrInt
|
||||
FieldType S.Padding = StrInt
|
||||
FieldType S.Margin = StrInt
|
||||
FieldType S.Width = PixCount
|
||||
FieldType S.Height = PixCount
|
||||
FieldType S.Padding = PixCount
|
||||
FieldType S.Margin = PixCount
|
||||
FieldType S.Color = Text
|
||||
FieldType S.BackgroundColor = Text
|
||||
FieldType S.BorderColor = Text
|
||||
FieldType S.BorderWidth = StrInt
|
||||
FieldType S.BorderRadius = StrInt
|
||||
FieldType S.BorderWidth = PixCount
|
||||
FieldType S.BorderRadius = PixCount
|
||||
FieldType S.BorderStyle = BorderStyleValue
|
||||
FieldType S.FontStyle = FontStyleValue
|
||||
FieldType S.FontWeight = FontWeightValue
|
||||
FieldType S.FontSize = StrInt
|
||||
FieldType S.FontSize = PixCount
|
||||
FieldType S.FontFamily = Text
|
||||
FieldType S.Description = Text
|
||||
FieldType S.ClickHandler = IO ()
|
||||
@ -201,6 +207,9 @@ type family FieldType (f :: Field) :: * where
|
||||
FieldType S.Align = LocationValue
|
||||
FieldType S.Titles = [Text]
|
||||
FieldType S.SelectedIndex = Integer
|
||||
FieldType S.ReadOutMsg = Text
|
||||
FieldType S.Child = Maybe ChildWidget
|
||||
FieldType S.Selector = Text
|
||||
|
||||
-- | Can be used to put different widgets in a list. Useful for dealing with children widgets.
|
||||
data ChildWidget = forall w. RecAll Attr (WidgetFields w) ToPairs => ChildWidget (IPythonWidget w)
|
||||
@ -215,7 +224,7 @@ class CustomBounded a where
|
||||
upperBound :: a
|
||||
|
||||
-- Set according to what IPython widgets use
|
||||
instance CustomBounded StrInt where
|
||||
instance CustomBounded PixCount where
|
||||
upperBound = 10 ^ 16 - 1
|
||||
lowerBound = -(10 ^ 16 - 1)
|
||||
|
||||
@ -237,6 +246,7 @@ data WidgetType = ButtonType
|
||||
| TextAreaType
|
||||
| CheckBoxType
|
||||
| ToggleButtonType
|
||||
| ValidType
|
||||
| DropdownType
|
||||
| RadioButtonsType
|
||||
| SelectType
|
||||
@ -253,19 +263,21 @@ data WidgetType = ButtonType
|
||||
| FloatProgressType
|
||||
| FloatRangeSliderType
|
||||
| BoxType
|
||||
| ProxyType
|
||||
| PlaceProxyType
|
||||
| FlexBoxType
|
||||
| AccordionType
|
||||
| TabType
|
||||
|
||||
-- Fields associated with a widget
|
||||
|
||||
|
||||
type family WidgetFields (w :: WidgetType) :: [Field] where
|
||||
WidgetFields ButtonType =
|
||||
DOMWidgetClass :++
|
||||
'[S.Description, S.Tooltip, S.Disabled, S.Icon, S.ButtonStyle,
|
||||
S.ClickHandler]
|
||||
WidgetFields ImageType =
|
||||
DOMWidgetClass :++ '[S.ImageFormat, S.B64Value]
|
||||
DOMWidgetClass :++ '[S.ImageFormat, S.Width, S.Height, S.B64Value]
|
||||
WidgetFields OutputType = DOMWidgetClass
|
||||
WidgetFields HTMLType = StringClass
|
||||
WidgetFields LatexType = StringClass
|
||||
@ -275,6 +287,7 @@ type family WidgetFields (w :: WidgetType) :: [Field] where
|
||||
WidgetFields CheckBoxType = BoolClass
|
||||
WidgetFields ToggleButtonType =
|
||||
BoolClass :++ '[S.Tooltip, S.Icon, S.ButtonStyle]
|
||||
WidgetFields ValidType = BoolClass :++ '[S.ReadOutMsg]
|
||||
WidgetFields DropdownType = SelectionClass :++ '[S.ButtonStyle]
|
||||
WidgetFields RadioButtonsType = SelectionClass
|
||||
WidgetFields SelectType = SelectionClass
|
||||
@ -286,7 +299,8 @@ type family WidgetFields (w :: WidgetType) :: [Field] where
|
||||
WidgetFields IntSliderType =
|
||||
BoundedIntClass :++
|
||||
'[S.Orientation, S.ShowRange, S.ReadOut, S.SliderColor]
|
||||
WidgetFields IntProgressType = BoundedIntClass :++ '[S.BarStyle]
|
||||
WidgetFields IntProgressType =
|
||||
BoundedIntClass :++ '[S.Orientation, S.BarStyle]
|
||||
WidgetFields IntRangeSliderType =
|
||||
BoundedIntRangeClass :++
|
||||
'[S.Orientation, S.ShowRange, S.ReadOut, S.SliderColor]
|
||||
@ -296,11 +310,14 @@ type family WidgetFields (w :: WidgetType) :: [Field] where
|
||||
BoundedFloatClass :++
|
||||
'[S.Orientation, S.ShowRange, S.ReadOut, S.SliderColor]
|
||||
WidgetFields FloatProgressType =
|
||||
BoundedFloatClass :++ '[S.BarStyle]
|
||||
BoundedFloatClass :++ '[S.Orientation, S.BarStyle]
|
||||
WidgetFields FloatRangeSliderType =
|
||||
BoundedFloatRangeClass :++
|
||||
'[S.Orientation, S.ShowRange, S.ReadOut, S.SliderColor]
|
||||
WidgetFields BoxType = BoxClass
|
||||
WidgetFields ProxyType = WidgetClass :++ '[S.Child]
|
||||
WidgetFields PlaceProxyType =
|
||||
WidgetFields ProxyType :++ '[S.Selector]
|
||||
WidgetFields FlexBoxType =
|
||||
BoxClass :++ '[S.Orientation, S.Flex, S.Pack, S.Align]
|
||||
WidgetFields AccordionType = SelectionContainerClass
|
||||
@ -315,12 +332,15 @@ unwrap (Dummy x) = x
|
||||
unwrap (Real x) = x
|
||||
|
||||
-- Wrapper around a field.
|
||||
data Attr (f :: Field) =
|
||||
Attr
|
||||
{ _value :: AttrVal (FieldType f)
|
||||
, _verify :: FieldType f -> IO (FieldType f)
|
||||
, _field :: Field
|
||||
}
|
||||
data Attr (f :: Field) where
|
||||
Attr :: Typeable (FieldType f)
|
||||
=> { _value :: AttrVal (FieldType f)
|
||||
, _verify :: FieldType f -> IO (FieldType f)
|
||||
, _field :: Field
|
||||
} -> Attr f
|
||||
|
||||
getFieldType :: Attr f -> TypeRep
|
||||
getFieldType Attr { _value = attrval } = typeOf $ unwrap attrval
|
||||
|
||||
instance ToJSON (FieldType f) => ToJSON (Attr f) where
|
||||
toJSON attr =
|
||||
@ -339,6 +359,12 @@ instance ToPairs (Attr S.ViewModule) where
|
||||
instance ToPairs (Attr S.ViewName) where
|
||||
toPairs x = ["_view_name" .= toJSON x]
|
||||
|
||||
instance ToPairs (Attr S.ModelModule) where
|
||||
toPairs x = ["_model_module" .= toJSON x]
|
||||
|
||||
instance ToPairs (Attr S.ModelName) where
|
||||
toPairs x = ["_model_name" .= toJSON x]
|
||||
|
||||
instance ToPairs (Attr S.MsgThrottle) where
|
||||
toPairs x = ["msg_throttle" .= toJSON x]
|
||||
|
||||
@ -552,9 +578,18 @@ instance ToPairs (Attr S.Titles) where
|
||||
instance ToPairs (Attr S.SelectedIndex) where
|
||||
toPairs x = ["selected_index" .= toJSON x]
|
||||
|
||||
instance ToPairs (Attr S.ReadOutMsg) where
|
||||
toPairs x = ["readout" .= toJSON x]
|
||||
|
||||
instance ToPairs (Attr S.Child) where
|
||||
toPairs x = ["child" .= toJSON x]
|
||||
|
||||
instance ToPairs (Attr S.Selector) where
|
||||
toPairs x = ["selector" .= toJSON x]
|
||||
|
||||
-- | Store the value for a field, as an object parametrized by the Field. No verification is done
|
||||
-- for these values.
|
||||
(=::) :: SingI f => Sing f -> FieldType f -> Attr f
|
||||
(=::) :: (SingI f, Typeable (FieldType f)) => Sing f -> FieldType f -> Attr f
|
||||
s =:: x = Attr { _value = Real x, _verify = return, _field = reflect s }
|
||||
|
||||
-- | If the number is in the range, return it. Otherwise raise the appropriate (over/under)flow
|
||||
@ -567,13 +602,13 @@ rangeCheck (l, u) x
|
||||
| otherwise = error "The impossible happened in IHaskell.Display.Widgets.Types.rangeCheck"
|
||||
|
||||
-- | Store a numeric value, with verification mechanism for its range.
|
||||
ranged :: (SingI f, Num (FieldType f), Ord (FieldType f))
|
||||
ranged :: (SingI f, Num (FieldType f), Ord (FieldType f), Typeable (FieldType f))
|
||||
=> Sing f -> (FieldType f, FieldType f) -> AttrVal (FieldType f) -> Attr f
|
||||
ranged s range x = Attr x (rangeCheck range) (reflect s)
|
||||
|
||||
-- | Store a numeric value, with the invariant that it stays non-negative. The value set is set as a
|
||||
-- dummy value if it's equal to zero.
|
||||
(=:+) :: (SingI f, Num (FieldType f), CustomBounded (FieldType f), Ord (FieldType f))
|
||||
(=:+) :: (SingI f, Num (FieldType f), CustomBounded (FieldType f), Ord (FieldType f), Typeable (FieldType f))
|
||||
=> Sing f -> FieldType f -> Attr f
|
||||
s =:+ val = Attr
|
||||
((if val == 0
|
||||
@ -591,6 +626,8 @@ reflect = fromSing
|
||||
defaultWidget :: FieldType S.ViewName -> Rec Attr WidgetClass
|
||||
defaultWidget viewName = (ViewModule =:: "")
|
||||
:& (ViewName =:: viewName)
|
||||
:& (ModelModule =:: "")
|
||||
:& (ModelName =:: "WidgetModel")
|
||||
:& (MsgThrottle =:+ 3)
|
||||
:& (Version =:: 0)
|
||||
:& (DisplayHandler =:: return ())
|
||||
@ -656,8 +693,8 @@ defaultMultipleSelectionWidget :: FieldType S.ViewName -> Rec Attr MultipleSelec
|
||||
defaultMultipleSelectionWidget viewName = defaultDOMWidget viewName <+> mulSelAttrs
|
||||
where
|
||||
mulSelAttrs = (Options =:: OptionLabels [])
|
||||
:& (SelectedLabels =:: [])
|
||||
:& (SelectedValues =:: [])
|
||||
:& (SelectedLabels =:: [])
|
||||
:& (Disabled =:: False)
|
||||
:& (Description =:: "")
|
||||
:& (SelectionHandler =:: return ())
|
||||
@ -739,8 +776,10 @@ defaultBoundedFloatRangeWidget viewName = defaultFloatRangeWidget viewName <+> b
|
||||
|
||||
-- | A record representing a widget of the _Box class from IPython
|
||||
defaultBoxWidget :: FieldType S.ViewName -> Rec Attr BoxClass
|
||||
defaultBoxWidget viewName = defaultDOMWidget viewName <+> boxAttrs
|
||||
defaultBoxWidget viewName = domAttrs <+> boxAttrs
|
||||
where
|
||||
defaultDOM = defaultDOMWidget viewName
|
||||
domAttrs = rput (ModelName =:: "BoxModel") defaultDOM
|
||||
boxAttrs = (Children =:: [])
|
||||
:& (OverflowX =:: DefaultOverflow)
|
||||
:& (OverflowY =:: DefaultOverflow)
|
||||
@ -806,9 +845,12 @@ str = id
|
||||
properties :: IPythonWidget w -> IO ()
|
||||
properties widget = do
|
||||
st <- readIORef $ state widget
|
||||
let convert :: Attr f -> Const Field f
|
||||
convert attr = Const { getConst = _field attr }
|
||||
mapM_ print $ recordToList . rmap convert . _getState $ st
|
||||
let convert :: Attr f -> Const (Field, TypeRep) f
|
||||
convert attr = Const (_field attr, getFieldType attr)
|
||||
|
||||
renderRow (fname, ftype) = printf "%s ::: %s" (show fname) (show ftype)
|
||||
rows = map renderRow . recordToList . rmap convert $ _getState st
|
||||
mapM_ putStrLn rows
|
||||
|
||||
-- Helper function for widget to enforce their inability to fetch console input
|
||||
noStdin :: IO a -> IO ()
|
||||
|
@ -7,7 +7,7 @@ name: ihaskell
|
||||
-- PVP summary: +-+------- breaking API changes
|
||||
-- | | +----- non-breaking API additions
|
||||
-- | | | +--- code changes with no API change
|
||||
version: 0.7.0.3
|
||||
version: 0.8.2.0
|
||||
|
||||
-- A short (one-line) description of the package.
|
||||
synopsis: A Haskell backend kernel for the IPython project.
|
||||
@ -55,7 +55,7 @@ library
|
||||
hs-source-dirs: src
|
||||
default-language: Haskell2010
|
||||
build-depends:
|
||||
aeson >=0.7 && < 0.10,
|
||||
aeson >=0.7 && < 0.11,
|
||||
base >=4.6 && < 4.9,
|
||||
base64-bytestring >=1.0,
|
||||
bytestring >=0.10,
|
||||
@ -143,7 +143,7 @@ executable ihaskell
|
||||
ghc >=7.6 || < 7.11,
|
||||
process >=1.1,
|
||||
here ==1.2.*,
|
||||
aeson >=0.7 && < 0.10,
|
||||
aeson >=0.7 && < 0.11,
|
||||
bytestring >=0.10,
|
||||
containers >=0.5,
|
||||
strict >=0.3,
|
||||
@ -167,7 +167,7 @@ Test-Suite hspec
|
||||
default-language: Haskell2010
|
||||
build-depends:
|
||||
ihaskell,
|
||||
aeson >=0.6 && < 0.10,
|
||||
aeson >=0.6 && < 0.11,
|
||||
base >=4.6 && < 4.9,
|
||||
base64-bytestring >=1.0,
|
||||
bytestring >=0.10,
|
||||
|
@ -265,4 +265,5 @@ main = do
|
||||
_ -> do
|
||||
putStrLn "Usage:"
|
||||
putStrLn "simple-calc-example install -- set up the kernelspec"
|
||||
putStrLn "simple-calc-example kernel FILE -- run a kernel with FILE for communication with the frontend"
|
||||
putStrLn
|
||||
"simple-calc-example kernel FILE -- run a kernel with FILE for communication with the frontend"
|
||||
|
@ -2,13 +2,13 @@ module Main where
|
||||
|
||||
import qualified Data.Text as T
|
||||
|
||||
import System.Environment (getArgs)
|
||||
import System.Environment (getArgs)
|
||||
|
||||
import Text.Parsec
|
||||
import Text.Parsec.String
|
||||
import Text.Parsec
|
||||
import Text.Parsec.String
|
||||
|
||||
import IHaskell.IPython.EasyKernel (easyKernel, installKernelspec, KernelConfig(..))
|
||||
import IHaskell.IPython.Types
|
||||
import IHaskell.IPython.EasyKernel (easyKernel, installKernelspec, KernelConfig(..))
|
||||
import IHaskell.IPython.Types
|
||||
|
||||
-- Define the actual language!
|
||||
data Expr = Plus Expr Expr
|
||||
@ -47,12 +47,13 @@ parseExpr str =
|
||||
char ','
|
||||
y <- expr
|
||||
char ')'
|
||||
return $ case func of
|
||||
"plus" -> Plus x y
|
||||
"minus" -> Minus x y
|
||||
"times" -> Times x y
|
||||
"div" -> Div x y
|
||||
"exp" -> Exp x y
|
||||
return $
|
||||
case func of
|
||||
"plus" -> Plus x y
|
||||
"minus" -> Minus x y
|
||||
"times" -> Times x y
|
||||
"div" -> Div x y
|
||||
"exp" -> Exp x y
|
||||
|
||||
languageConfig :: LanguageInfo
|
||||
languageConfig = LanguageInfo
|
||||
@ -73,11 +74,10 @@ displayString :: String -> [DisplayData]
|
||||
displayString str = [DisplayData PlainText (T.pack str)]
|
||||
|
||||
languageCompletion :: Monad m => T.Text -> Int -> m (T.Text, [T.Text])
|
||||
languageCompletion code pos = return $
|
||||
languageCompletion code pos = return $
|
||||
let (before, _) = T.splitAt pos code
|
||||
word = last $ T.words $ T.map replace before
|
||||
in (word, map T.pack $ matches $ T.unpack word)
|
||||
|
||||
where
|
||||
matches :: String -> [String]
|
||||
matches word =
|
||||
@ -92,7 +92,7 @@ languageCompletion code pos = return $
|
||||
replace '(' = ' '
|
||||
replace ')' = ' '
|
||||
replace ',' = ' '
|
||||
replace x = x
|
||||
replace x = x
|
||||
|
||||
languageInspect :: Monad m => T.Text -> Int -> m (Maybe [DisplayData])
|
||||
languageInspect _ _ = return $
|
||||
@ -120,7 +120,6 @@ languageRun code init intermediate = do
|
||||
Left err -> err
|
||||
Right expr -> show (eval expr), IHaskell.IPython.Types.Ok, "")
|
||||
|
||||
|
||||
simpleConfig :: KernelConfig IO String String
|
||||
simpleConfig = KernelConfig
|
||||
{ kernelLanguageInfo = languageConfig
|
||||
@ -145,4 +144,5 @@ main = do
|
||||
_ -> do
|
||||
putStrLn "Usage:"
|
||||
putStrLn "fun-calc-example install -- set up the kernelspec"
|
||||
putStrLn "fun-calc-example kernel FILE -- run a kernel with FILE for communication with the frontend"
|
||||
putStrLn
|
||||
"fun-calc-example kernel FILE -- run a kernel with FILE for communication with the frontend"
|
||||
|
@ -1,5 +1,5 @@
|
||||
name: ipython-kernel
|
||||
version: 0.8.0.0
|
||||
version: 0.8.2.0
|
||||
synopsis: A library for creating kernels for IPython frontends
|
||||
|
||||
description: ipython-kernel is a library for communicating with frontends for the interactive IPython framework. It is used extensively in IHaskell, the interactive Haskell environment.
|
||||
@ -35,7 +35,7 @@ library
|
||||
hs-source-dirs: src
|
||||
default-language: Haskell2010
|
||||
build-depends: base >=4.6 && < 4.9,
|
||||
aeson >=0.6 && < 0.10,
|
||||
aeson >=0.6 && < 0.11,
|
||||
bytestring >=0.10,
|
||||
cereal >=0.3,
|
||||
containers >=0.5,
|
||||
|
@ -11,17 +11,16 @@
|
||||
--
|
||||
-- = Kernel Specs
|
||||
--
|
||||
-- To run your kernel, you will need to install the kernelspec into the Jupyter namespace.
|
||||
-- If your kernel name is `kernel`, you will need to run the command:
|
||||
-- To run your kernel, you will need to install the kernelspec into the Jupyter namespace. If your
|
||||
-- kernel name is `kernel`, you will need to run the command:
|
||||
--
|
||||
-- > kernel install
|
||||
--
|
||||
-- This will inform Jupyter of the kernel so that it may be used.
|
||||
--
|
||||
-- == Further profile improvements
|
||||
-- Consult the IPython documentation along with the generated profile
|
||||
-- source code for further configuration of the frontend, including
|
||||
-- syntax highlighting, logos, help text, and so forth.
|
||||
-- == Further profile improvements Consult the IPython documentation along with the generated
|
||||
-- profile source code for further configuration of the frontend, including syntax highlighting,
|
||||
-- logos, help text, and so forth.
|
||||
module IHaskell.IPython.EasyKernel (easyKernel, installKernelspec, KernelConfig(..)) where
|
||||
|
||||
import Data.Aeson (decode, encode)
|
||||
@ -99,7 +98,6 @@ installKernelspec config replace installPrefixMay =
|
||||
installPrefixFlag = maybe ["--user"] (\prefix -> ["--prefix", prefix]) installPrefixMay
|
||||
cmd = concat [["kernelspec", "install"], installPrefixFlag, [kernelDir], replaceFlag]
|
||||
void $ rawSystem "ipython" cmd
|
||||
|
||||
where
|
||||
withTmpDir act = do
|
||||
tmp <- getTemporaryDirectory
|
||||
|
@ -8,13 +8,15 @@
|
||||
-- the low-level 0MQ interface.
|
||||
module IHaskell.IPython.Message.Parser (parseMessage) where
|
||||
|
||||
import Data.Aeson ((.:), (.:?), decode, Result(..), Object, Value(..))
|
||||
import Control.Applicative ((<|>), (<$>), (<*>))
|
||||
import Data.Aeson ((.:), (.:?), (.!=), decode, Result(..), Object, Value(..))
|
||||
import Data.Aeson.Types (parse, parseEither)
|
||||
import Data.ByteString hiding (unpack)
|
||||
import qualified Data.ByteString.Lazy as Lazy
|
||||
import Data.HashMap.Strict as HM
|
||||
import Data.Map (Map)
|
||||
import Data.Maybe (fromMaybe)
|
||||
import Data.Text (Text)
|
||||
import Data.Text (Text, unpack)
|
||||
import Debug.Trace
|
||||
import IHaskell.IPython.Types
|
||||
@ -254,9 +256,10 @@ inputReplyParser = requestParser $ \obj -> do
|
||||
commOpenParser :: LByteString -> Message
|
||||
commOpenParser = requestParser $ \obj -> do
|
||||
uuid <- obj .: "comm_id"
|
||||
name <- obj .: "target_name"
|
||||
targetName <- obj .: "target_name"
|
||||
targetModule <- obj .:? "target_module" .!= ""
|
||||
value <- obj .: "data"
|
||||
return $ CommOpen noHeader name uuid value
|
||||
return $ CommOpen noHeader targetName targetModule uuid value
|
||||
|
||||
commDataParser :: LByteString -> Message
|
||||
commDataParser = requestParser $ \obj -> do
|
||||
|
@ -101,7 +101,12 @@ instance ToJSON Message where
|
||||
object ["prompt" .= prompt]
|
||||
|
||||
toJSON req@CommOpen{} =
|
||||
object ["comm_id" .= commUuid req, "target_name" .= commTargetName req, "data" .= commData req]
|
||||
object
|
||||
[ "comm_id" .= commUuid req
|
||||
, "target_name" .= commTargetName req
|
||||
, "target_module" .= commTargetModule req
|
||||
, "data" .= commData req
|
||||
]
|
||||
|
||||
toJSON req@CommData{} =
|
||||
object ["comm_id" .= commUuid req, "data" .= commData req]
|
||||
|
@ -417,6 +417,7 @@ data Message =
|
||||
CommOpen
|
||||
{ header :: MessageHeader
|
||||
, commTargetName :: String
|
||||
, commTargetModule :: String
|
||||
, commUuid :: UUID
|
||||
, commData :: Value
|
||||
}
|
||||
@ -497,6 +498,7 @@ replyType CompleteRequestMessage = Just CompleteReplyMessage
|
||||
replyType InspectRequestMessage = Just InspectReplyMessage
|
||||
replyType ShutdownRequestMessage = Just ShutdownReplyMessage
|
||||
replyType HistoryRequestMessage = Just HistoryReplyMessage
|
||||
replyType CommOpenMessage = Just CommDataMessage
|
||||
replyType _ = Nothing
|
||||
|
||||
-- | Data for display: a string with associated MIME type.
|
||||
|
73
main/Main.hs
73
main/Main.hs
@ -14,6 +14,7 @@ import qualified Data.ByteString.Char8 as CBS
|
||||
-- Standard library imports.
|
||||
import Control.Concurrent (threadDelay)
|
||||
import Control.Concurrent.Chan
|
||||
import Control.Arrow (second)
|
||||
import Data.Aeson
|
||||
import System.Directory
|
||||
import System.Process (readProcess, readProcessWithExitCode)
|
||||
@ -102,6 +103,8 @@ parseKernelArgs = foldl' addFlag defaultKernelSpecOptions
|
||||
kernelSpecOpts { kernelSpecGhcLibdir = libdir }
|
||||
addFlag kernelSpecOpts (KernelspecInstallPrefix prefix) =
|
||||
kernelSpecOpts { kernelSpecInstallPrefix = Just prefix }
|
||||
addFlag kernelSpecOpts KernelspecUseStack =
|
||||
kernelSpecOpts { kernelSpecUseStack = True }
|
||||
addFlag kernelSpecOpts flag = error $ "Unknown flag" ++ show flag
|
||||
|
||||
-- | Run the IHaskell language kernel.
|
||||
@ -111,6 +114,7 @@ runKernel :: KernelSpecOptions -- ^ Various options from when the kernel was ins
|
||||
runKernel kernelOpts profileSrc = do
|
||||
let debug = kernelSpecDebug kernelOpts
|
||||
libdir = kernelSpecGhcLibdir kernelOpts
|
||||
useStack = kernelSpecUseStack kernelOpts
|
||||
|
||||
-- Parse the profile file.
|
||||
Just profile <- liftM decode $ LBS.readFile profileSrc
|
||||
@ -120,22 +124,23 @@ runKernel kernelOpts profileSrc = do
|
||||
Stdin.recordKernelProfile dir profile
|
||||
|
||||
#if MIN_VERSION_ghc(7,8,0)
|
||||
-- Detect if we have stack
|
||||
runResult <- try $ readProcessWithExitCode "stack" [] ""
|
||||
let stack =
|
||||
case runResult :: Either SomeException (ExitCode, String, String) of
|
||||
Left _ -> False
|
||||
Right (exitCode, stackStdout, _) -> exitCode == ExitSuccess && "The Haskell Tool Stack" `isInfixOf` stackStdout
|
||||
when useStack $ do
|
||||
-- Detect if we have stack
|
||||
runResult <- try $ readProcessWithExitCode "stack" [] ""
|
||||
let stack =
|
||||
case runResult :: Either SomeException (ExitCode, String, String) of
|
||||
Left _ -> False
|
||||
Right (exitCode, stackStdout, _) -> exitCode == ExitSuccess && "The Haskell Tool Stack" `isInfixOf` stackStdout
|
||||
|
||||
-- If we're in a stack directory, use `stack` to set the environment
|
||||
-- We can't do this with base <= 4.6 because setEnv doesn't exist.
|
||||
when stack $ do
|
||||
stackEnv <- lines <$> readProcess "stack" ["exec", "env"] ""
|
||||
forM_ stackEnv $ \line ->
|
||||
let (var, val) = break (== '=') line
|
||||
in case tailMay val of
|
||||
Nothing -> return ()
|
||||
Just val' -> setEnv var val'
|
||||
-- If we're in a stack directory, use `stack` to set the environment
|
||||
-- We can't do this with base <= 4.6 because setEnv doesn't exist.
|
||||
when stack $ do
|
||||
stackEnv <- lines <$> readProcess "stack" ["exec", "env"] ""
|
||||
forM_ stackEnv $ \line ->
|
||||
let (var, val) = break (== '=') line
|
||||
in case tailMay val of
|
||||
Nothing -> return ()
|
||||
Just val' -> setEnv var val'
|
||||
#endif
|
||||
|
||||
-- Serve on all sockets and ports defined in the profile.
|
||||
@ -333,6 +338,44 @@ replyTo _ HistoryRequest{} replyHeader state = do
|
||||
}
|
||||
return (state, reply)
|
||||
|
||||
-- Accomodating the workaround for retrieving list of open comms from the kernel
|
||||
--
|
||||
-- The main idea is that the frontend opens a comm at kernel startup, whose target is a widget that
|
||||
-- sends back the list of live comms and commits suicide.
|
||||
--
|
||||
-- The message needs to be written to the iopub channel, and not returned from here. If returned,
|
||||
-- the same message also gets written to the shell channel, which causes issues due to two messages
|
||||
-- having the same identifiers in their headers.
|
||||
--
|
||||
-- Sending the message only on the shell_reply channel doesn't work, so we send it as a comm message
|
||||
-- on the iopub channel and return the SendNothing message.
|
||||
replyTo interface open@CommOpen{} replyHeader state = do
|
||||
let send msg = liftIO $ writeChan (iopubChannel interface) msg
|
||||
|
||||
incomingUuid = commUuid open
|
||||
target = commTargetName open
|
||||
|
||||
targetMatches = target == "ipython.widget"
|
||||
valueMatches = commData open == object ["widget_class" .= "ipywidgets.CommInfo"]
|
||||
|
||||
commMap = openComms state
|
||||
uuidTargetPairs = map (second targetName) $ Map.toList commMap
|
||||
|
||||
pairProcessor (x, y) = T.pack (UUID.uuidToString x) .= object ["target_name" .= T.pack y]
|
||||
|
||||
currentComms = object $ map pairProcessor $ (incomingUuid, "comm") : uuidTargetPairs
|
||||
|
||||
replyValue = object [ "method" .= "custom"
|
||||
, "content" .= object ["comms" .= currentComms]
|
||||
]
|
||||
|
||||
msg = CommData replyHeader (commUuid open) replyValue
|
||||
|
||||
-- To the iopub channel you go
|
||||
when (targetMatches && valueMatches) $ send msg
|
||||
|
||||
return (state, SendNothing)
|
||||
|
||||
-- TODO: What else can be implemented?
|
||||
replyTo _ message _ state = do
|
||||
liftIO $ hPutStrLn stderr $ "Unimplemented message: " ++ show message
|
||||
|
@ -52,9 +52,8 @@ widgetSend :: IHaskellWidget a
|
||||
widgetSend msgType widget value = queue $ msgType (Widget widget) value
|
||||
|
||||
-- | Send a message to open a comm
|
||||
widgetSendOpen :: IHaskellWidget a => a -> Value -> Value -> IO ()
|
||||
widgetSendOpen widget initVal stateVal =
|
||||
queue $ Open (Widget widget) initVal stateVal
|
||||
widgetSendOpen :: IHaskellWidget a => a -> Value -> IO ()
|
||||
widgetSendOpen = widgetSend Open
|
||||
|
||||
-- | Send a state update message
|
||||
widgetSendUpdate :: IHaskellWidget a => a -> Value -> IO ()
|
||||
@ -93,8 +92,9 @@ handleMessage :: (Message -> IO ())
|
||||
-> IO KernelState
|
||||
handleMessage send replyHeader state msg = do
|
||||
case msg of
|
||||
Open widget initVal stateVal -> do
|
||||
let target = targetName widget
|
||||
Open widget value -> do
|
||||
let target_name = targetName widget
|
||||
target_module = targetModule widget
|
||||
uuid = getCommUUID widget
|
||||
present = isJust $ Map.lookup uuid oldComms
|
||||
|
||||
@ -109,12 +109,9 @@ handleMessage send replyHeader state msg = do
|
||||
if present
|
||||
then return state
|
||||
else do
|
||||
-- Send the comm open
|
||||
-- Send the comm open, with the initial state
|
||||
header <- dupHeader replyHeader CommOpenMessage
|
||||
send $ CommOpen header target uuid initVal
|
||||
|
||||
-- Initial state update
|
||||
communicate . toJSON $ UpdateState stateVal
|
||||
send $ CommOpen header target_name target_module uuid value
|
||||
|
||||
-- Send anything else the widget requires.
|
||||
open widget communicate
|
||||
@ -123,8 +120,7 @@ handleMessage send replyHeader state msg = do
|
||||
return newState
|
||||
|
||||
Close widget value -> do
|
||||
let target = targetName widget
|
||||
uuid = getCommUUID widget
|
||||
let uuid = getCommUUID widget
|
||||
present = isJust $ Map.lookup uuid oldComms
|
||||
|
||||
newComms = Map.delete uuid $ openComms state
|
||||
|
@ -38,6 +38,7 @@ data Argument = ConfFile String -- ^ A file with commands to load at startup
|
||||
| ConvertToFormat NotebookFormat
|
||||
| ConvertLhsStyle (LhsStyle String)
|
||||
| KernelspecInstallPrefix String
|
||||
| KernelspecUseStack
|
||||
deriving (Eq, Show)
|
||||
|
||||
data LhsStyle string =
|
||||
@ -100,6 +101,12 @@ kernelDebugFlag = flagNone ["debug"] addDebug "Print debugging output from the k
|
||||
where
|
||||
addDebug (Args mode prev) = Args mode (KernelDebug : prev)
|
||||
|
||||
kernelStackFlag :: Flag Args
|
||||
kernelStackFlag = flagNone ["stack"] addStack
|
||||
"Inherit environment from `stack` when it is installed"
|
||||
where
|
||||
addStack (Args mode prev) = Args mode (KernelspecUseStack : prev)
|
||||
|
||||
confFlag :: Flag Args
|
||||
confFlag = flagReq ["conf", "c"] (store ConfFile) "<rc.hs>"
|
||||
"File with commands to execute at start; replaces ~/.ihaskell/rc.hs."
|
||||
@ -118,11 +125,11 @@ store constructor str (Args mode prev) = Right $ Args mode $ constructor str : p
|
||||
installKernelSpec :: Mode Args
|
||||
installKernelSpec =
|
||||
mode "install" (Args InstallKernelSpec []) "Install the Jupyter kernelspec." noArgs
|
||||
[ghcLibFlag, kernelDebugFlag, confFlag, installPrefixFlag, helpFlag]
|
||||
[ghcLibFlag, kernelDebugFlag, confFlag, installPrefixFlag, helpFlag, kernelStackFlag]
|
||||
|
||||
kernel :: Mode Args
|
||||
kernel = mode "kernel" (Args (Kernel Nothing) []) "Invoke the IHaskell kernel." kernelArg
|
||||
[ghcLibFlag, kernelDebugFlag, confFlag]
|
||||
[ghcLibFlag, kernelDebugFlag, confFlag, kernelStackFlag]
|
||||
where
|
||||
kernelArg = flagArg update "<json-kernel-file>"
|
||||
update filename (Args _ flags) = Right $ Args (Kernel $ Just filename) flags
|
||||
|
@ -47,6 +47,7 @@ data KernelSpecOptions =
|
||||
, kernelSpecDebug :: Bool -- ^ Spew debugging output?
|
||||
, kernelSpecConfFile :: IO (Maybe String) -- ^ Filename of profile JSON file.
|
||||
, kernelSpecInstallPrefix :: Maybe String
|
||||
, kernelSpecUseStack :: Bool -- ^ Whether to use @stack@ environments.
|
||||
}
|
||||
|
||||
defaultKernelSpecOptions :: KernelSpecOptions
|
||||
@ -55,6 +56,7 @@ defaultKernelSpecOptions = KernelSpecOptions
|
||||
, kernelSpecDebug = False
|
||||
, kernelSpecConfFile = defaultConfFile
|
||||
, kernelSpecInstallPrefix = Nothing
|
||||
, kernelSpecUseStack = False
|
||||
}
|
||||
|
||||
-- | The IPython kernel name.
|
||||
@ -72,6 +74,13 @@ ipythonCommand = do
|
||||
Nothing -> "ipython"
|
||||
Just _ -> "jupyter"
|
||||
|
||||
locateIPython :: SH.Sh SH.FilePath
|
||||
locateIPython = do
|
||||
mbinary <- SH.which "ipython"
|
||||
case mbinary of
|
||||
Nothing -> SH.errorExit "The IPython binary could not be located"
|
||||
Just ipython -> return ipython
|
||||
|
||||
-- | Run the IPython command with any arguments. The kernel is set to IHaskell.
|
||||
ipython :: Bool -- ^ Whether to suppress output.
|
||||
-> [Text] -- ^ IPython command line arguments.
|
||||
@ -181,6 +190,7 @@ installKernelspec replace opts = void $ do
|
||||
Nothing -> []
|
||||
Just file -> ["--conf", file])
|
||||
++ ["--ghclib", kernelSpecGhcLibdir opts]
|
||||
++ ["--stack" | kernelSpecUseStack opts]
|
||||
|
||||
let kernelSpec = KernelSpec
|
||||
{ kernelDisplayName = "Haskell"
|
||||
@ -201,15 +211,17 @@ installKernelspec replace opts = void $ do
|
||||
src <- liftIO $ Paths.getDataFileName $ "html/" ++ file
|
||||
SH.cp (SH.fromText $ T.pack src) (tmp SH.</> kernelName SH.</> file)
|
||||
|
||||
Just ipython <- SH.which "ipython"
|
||||
ipython <- locateIPython
|
||||
|
||||
let replaceFlag = ["--replace" | replace]
|
||||
installPrefixFlag = maybe ["--user"] (\prefix -> ["--prefix", T.pack prefix]) (kernelSpecInstallPrefix opts)
|
||||
cmd = concat [["kernelspec", "install"], installPrefixFlag, [SH.toTextIgnore kernelDir], replaceFlag]
|
||||
|
||||
SH.silently $ SH.run ipython cmd
|
||||
|
||||
kernelSpecCreated :: SH.Sh Bool
|
||||
kernelSpecCreated = do
|
||||
Just ipython <- SH.which "ipython"
|
||||
ipython <- locateIPython
|
||||
out <- SH.silently $ SH.run ipython ["kernelspec", "list"]
|
||||
let kernelspecs = map T.strip $ T.lines out
|
||||
return $ T.pack kernelName `elem` kernelspecs
|
||||
|
@ -65,11 +65,15 @@ class IHaskellDisplay a where
|
||||
|
||||
-- | Display as an interactive widget.
|
||||
class IHaskellDisplay a => IHaskellWidget a where
|
||||
-- | Output target name for this widget. The actual input parameter should be ignored. By default
|
||||
-- evaluate to "ipython.widget", which is used by IPython for its backbone widgets.
|
||||
-- | Target name for this widget. The actual input parameter should be ignored. By default evaluate
|
||||
-- to "ipython.widget", which is used by IPython for its backbone widgets.
|
||||
targetName :: a -> String
|
||||
targetName _ = "ipython.widget"
|
||||
|
||||
-- | Target module for this widget. Evaluates to an empty string by default.
|
||||
targetModule :: a -> String
|
||||
targetModule _ = ""
|
||||
|
||||
-- | Get the uuid for comm associated with this widget. The widget is responsible for storing the
|
||||
-- UUID during initialization.
|
||||
getCommUUID :: a -> UUID
|
||||
@ -102,6 +106,7 @@ instance IHaskellDisplay Widget where
|
||||
|
||||
instance IHaskellWidget Widget where
|
||||
targetName (Widget widget) = targetName widget
|
||||
targetModule (Widget widget) = targetModule widget
|
||||
getCommUUID (Widget widget) = getCommUUID widget
|
||||
open (Widget widget) = open widget
|
||||
comm (Widget widget) = comm widget
|
||||
@ -185,11 +190,10 @@ data LintStatus = LintOn
|
||||
deriving (Eq, Show)
|
||||
|
||||
-- | Send JSON objects with specific formats
|
||||
data WidgetMsg = Open Widget Value Value
|
||||
data WidgetMsg = Open Widget Value
|
||||
|
|
||||
-- ^ Cause the interpreter to open a new comm, and register the associated widget in
|
||||
-- the kernelState. Also sends a Value with comm_open, and then sends an initial
|
||||
-- state update Value.
|
||||
-- the kernelState. Also sends an initial state Value with comm_open.
|
||||
Update Widget Value
|
||||
|
|
||||
-- ^ Cause the interpreter to send a comm_msg containing a state update for the
|
||||
|
@ -8,7 +8,6 @@ packages:
|
||||
- ihaskell-display/ihaskell-juicypixels/
|
||||
- ihaskell-display/ihaskell-magic/
|
||||
- ihaskell-display/ihaskell-rlangqq/
|
||||
- ihaskell-display/ihaskell-parsec/
|
||||
- ihaskell-display/ihaskell-plot/
|
||||
- ihaskell-display/ihaskell-blaze/
|
||||
- ihaskell-display/ihaskell-widgets/
|
||||
|
@ -11,6 +11,7 @@ cabal update
|
||||
cabal install happy alex
|
||||
cabal install cpphs
|
||||
cabal install gtk2hs-buildtools
|
||||
cabal install HTTP
|
||||
|
||||
# Build ihaskell, and all the display packages
|
||||
./build.sh all
|
||||
|
@ -52,7 +52,10 @@ for source_dir in ["src", "ipython-kernel", "ihaskell-display"]:
|
||||
continue
|
||||
|
||||
# Ignore IHaskellPrelude.hs, it uses CPP in weird places
|
||||
ignored_files = ["IHaskellPrelude.hs"]
|
||||
if widget_dir in root:
|
||||
ignored_files = ["Types.hs"]
|
||||
else:
|
||||
ignored_files = ["IHaskellPrelude.hs"]
|
||||
for filename in filenames:
|
||||
if filename.endswith(".hs") and filename not in ignored_files:
|
||||
sources.append(os.path.join(root, filename))
|
||||
|
Loading…
x
Reference in New Issue
Block a user