ihaskell 0.3.0.0 → 0.3.0.1
raw patch · 10 files changed
+230/−195 lines, 10 filesdep +setenvdep ~aeson
Dependencies added: setenv
Dependency ranges changed: aeson
Files
- ihaskell.cabal +10/−4
- installation/ipython.sh +31/−0
- installation/run.sh +12/−0
- installation/update.sh +20/−0
- installation/virtualenv.sh +18/−0
- src/Hspec.hs +1/−1
- src/IHaskell/Eval/Evaluate.hs +3/−0
- src/IHaskell/Flags.hs +14/−10
- src/IHaskell/IPython.hs +107/−166
- src/Main.hs +14/−14
ihaskell.cabal view
@@ -7,7 +7,7 @@ -- PVP summary: +-+------- breaking API changes -- | | +----- non-breaking API additions -- | | | +--- code changes with no API change-version: 0.3.0.0+version: 0.3.0.1 -- A short (one-line) description of the package. synopsis: A Haskell backend kernel for the IPython project.@@ -43,14 +43,18 @@ cabal-version: >=1.16 data-files: - profile/profile.tar+ installation/ipython.sh+ installation/update.sh+ installation/virtualenv.sh+ installation/run.sh+ profile/profile.tar library hs-source-dirs: src default-language: Haskell2010 build-depends: base ==4.6.*,- aeson >=0.6,+ aeson >=0.6.1, base64-bytestring >=1.0, bytestring >=0.10, cereal ==0.3.*,@@ -192,6 +196,7 @@ parsec -any, process >=1.1, random >=1.0,+ setenv -any, shelly >=1.3, split >= 0.2, strict >=0.3,@@ -202,7 +207,8 @@ unix >= 2.6, utf8-string -any - extensions: DoAndIfThenElse+ default-extensions:+ DoAndIfThenElse OverloadedStrings ExtendedDefaultRules
+ installation/ipython.sh view
@@ -0,0 +1,31 @@+#!/bin/bash+set -e++# Which virtualenv to use.+VIRTUALENV=$1++# Commit hash to install.+COMMIT=$2++# Activate the virtualenv.+source $VIRTUALENV/bin/activate++# Install all necessary dependencies with Pip.+echo "Installing dependency (pyzmq)."+pip install pyzmq==14.0.1++echo "Installing dependency (markupsafe)."+pip install markupsafe==0.18++echo "Installing dependency (jinja2)."+pip install jinja2==2.7.1++echo "Installing dependency (tornado)."+pip install tornado==3.1.1++echo "Installing dependency (pygments)."+pip install pygments==1.6++# Install IPython itself.+echo "Installing IPython (this may take a while)."+pip install -e git+https://github.com/ipython/ipython.git@$COMMIT#egg=ipython-dev
+ installation/run.sh view
@@ -0,0 +1,12 @@+#!/bin/bash+set -e++# Which virtualenv to use.+VIRTUALENV=$1+shift++# Activate the virtualenv.+source $VIRTUALENV/bin/activate++# Run IPython.+ipython $@
+ installation/update.sh view
@@ -0,0 +1,20 @@+#!/bin/bash+set -e++# Which virtualenv to use.+VIRTUALENV=$1++# Commit hash to install.+COMMIT=$2++# Find out current IPython commit hash.+cd $VIRTUALENV/src/ipython+CURRENT_COMMIT=`git rev-parse HEAD`+if [ $CURRENT_COMMIT != $COMMIT ]; then+ # Activate the virtualenv.+ source $VIRTUALENV/bin/activate++ # Update IPython.+ echo "Updating IPython (this may take a while)."+ pip install --upgrade -e git+https://github.com/ipython/ipython.git@$COMMIT#egg=ipython-dev+fi;
+ installation/virtualenv.sh view
@@ -0,0 +1,18 @@+#!/bin/bash+set -e++# Which version of virtualenv to use.+VIRTUALENV=virtualenv-1.9++# Where to install the virtualenv.+DESTINATION=$1++# Download virtualenv.+echo "Downloading virtualenv."+curl -O https://pypi.python.org/packages/source/v/virtualenv/$VIRTUALENV.tar.gz+tar xvfz $VIRTUALENV.tar.gz+cd $VIRTUALENV++# Create a virtualenv.+echo "Creating a virtualenv."+python virtualenv.py $DESTINATION
src/Hspec.hs view
@@ -413,7 +413,7 @@ it "parses :set x" $ parses ":set x" `like` [- Directive SetOpt "x"+ Directive SetDynFlag "x" ] it "parses :extension x" $
src/IHaskell/Eval/Evaluate.hs view
@@ -150,6 +150,9 @@ initializeImports = do -- Load packages that start with ihaskell-*, aren't just IHaskell, -- and depend directly on the right version of the ihaskell library+ --+ -- XXX this will try to load broken packages, provided they depend+ -- on the right ihaskell version dflags <- getSessionDynFlags displayPackages <- liftIO $ do (dflags, _) <- initPackages dflags
src/IHaskell/Flags.hs view
@@ -16,11 +16,13 @@ -- Command line arguments to IHaskell. A set of aruments is annotated with -- the mode being invoked. data Args = Args IHaskellMode [Argument]+ deriving Show data Argument = ServeFrom String -- ^ Which directory to serve notebooks from. | Extension String -- ^ An extension to load at startup. | ConfFile String -- ^ A file with commands to load at startup.+ | IPythonFrom String -- ^ Which executable to use for IPython. | Help -- ^ Display help text. deriving (Eq, Show) @@ -30,7 +32,6 @@ = ShowHelp String | Notebook | Console- | UpdateIPython | Kernel (Maybe String) | View (Maybe ViewFormat) (Maybe String) deriving (Eq, Show)@@ -48,8 +49,11 @@ chooseMode Console = console chooseMode Notebook = notebook chooseMode (Kernel _) = kernel- chooseMode UpdateIPython = update +ipythonFlag :: Flag Args+ipythonFlag = + flagReq ["ipython", "i"] (store IPythonFrom) "<path>" "Executable for IPython."+ universalFlags :: [Flag Args] universalFlags = [ flagReq ["extension","e", "X"] (store Extension) "<ghc-extension>" "Extension to enable at start.",@@ -65,21 +69,21 @@ notebook :: Mode Args notebook = mode "notebook" (Args Notebook []) "Browser-based notebook interface." noArgs $ flagReq ["serve","s"] (store ServeFrom) "<dir>" "Directory to serve notebooks from.":+ ipythonFlag: universalFlags console :: Mode Args-console = mode "console" (Args Console []) "Console-based interactive repl." noArgs universalFlags+console = mode "console" (Args Console []) "Console-based interactive repl." noArgs $ ipythonFlag:universalFlags kernel = mode "kernel" (Args (Kernel Nothing) []) "Invoke the IHaskell kernel." kernelArg [] where kernelArg = flagArg update "<json-kernel-file>" update filename (Args _ flags) = Right $ Args (Kernel $ Just filename) flags -update :: Mode Args-update = mode "update" (Args UpdateIPython []) "Update IPython frontends." noArgs []- view :: Mode Args-view = (modeEmpty $ Args (View Nothing Nothing) []) {+view =+ let empty = mode "view" (Args (View Nothing Nothing) []) "View IHaskell notebook." noArgs [ipythonFlag] in+ empty { modeNames = ["view"], modeCheck = \a@(Args (View fmt file) _) ->@@ -93,7 +97,8 @@ ["pdf", "html", "ipynb", "markdown", "latex"]), "." ],- modeArgs = ([formatArg, filenameArg], Nothing)+ modeArgs = ([formatArg, filenameArg] ++ fst (modeArgs empty),+ snd $ modeArgs empty) } where@@ -105,14 +110,13 @@ Nothing -> Left $ "Invalid format '" ++ fmtStr ++ "'." updateFile name (Args (View f _) flags) = Right $ Args (View f (Just name)) flags - ihaskellArgs :: Mode Args ihaskellArgs = let descr = "Haskell for Interactive Computing." helpStr = showText (Wrap 100) $ helpText [] HelpFormatAll ihaskellArgs onlyHelp = [flagHelpSimple (add Help)] noMode = mode "IHaskell" (Args (ShowHelp helpStr) []) descr noArgs onlyHelp in- noMode { modeGroupModes = toGroup [console, notebook, view, update, kernel] }+ noMode { modeGroupModes = toGroup [console, notebook, view, kernel] } where add flag (Args mode flags) = Args mode $ flag : flags
src/IHaskell/IPython.hs view
@@ -1,11 +1,8 @@ {-# LANGUAGE NoImplicitPrelude, OverloadedStrings #-} {-# LANGUAGE DoAndIfThenElse #-}--- | Description : Shell scripting wrapper using @Shelly@ for the @notebook@, @setup@, and+-- | Description : Shell scripting wrapper using @Shelly@ for the @notebook@, and -- @console@ commands. module IHaskell.IPython (- ipythonInstalled,- installIPython,- updateIPython, setupIPython, runConsole, runNotebook,@@ -14,18 +11,21 @@ getIHaskellDir, getSandboxPackageConf, nbconvert,+ subHome, ViewFormat(..),+ WhichIPython(..), ) where -import ClassyPrelude-import Prelude (read, reads, init)-import Shelly hiding (find, trace, path, (</>))-import System.Argv0-import System.Directory-import qualified Filesystem.Path.CurrentOS as FS-import Data.List.Utils (split)-import Data.String.Utils (rstrip, endswith)-import Text.Printf+import ClassyPrelude+import Control.Concurrent (threadDelay)+import Prelude (read, reads, init)+import Shelly hiding (find, trace, path, (</>))+import System.Argv0+import System.Directory+import qualified Filesystem.Path.CurrentOS as FS+import Data.List.Utils (split)+import Data.String.Utils (rstrip, endswith, strip, replace)+import Text.Printf import qualified System.IO.Strict as StrictIO import qualified Paths_ihaskell as Paths@@ -33,6 +33,11 @@ import IHaskell.Types +-- | Which IPython to use.+data WhichIPython+ = DefaultIPython -- ^ Use the one that IHaskell tries to install.+ | ExplicitIPython String -- ^ Use the command-line flag provided one.+ -- | Which commit of IPython we are on. ipythonCommit :: Text ipythonCommit = "9c922f54af799704f4000aeee94ec7c74cada194"@@ -42,12 +47,15 @@ ipythonProfile = "haskell" -- | Run IPython with any arguments.-ipython :: Bool -- ^ Whether to suppress output.+ipython :: WhichIPython -- ^ Which IPython to use (user-provided or IHaskell-installed).+ -> Bool -- ^ Whether to suppress output. -> [Text] -- ^ IPython command line arguments. -> Sh String -- ^ IPython output.-ipython suppress args = do- ipythonPath <- ipythonExePath- runHandles ipythonPath args handles doNothing+ipython which suppress args = do+ runCmd <- liftIO $ Paths.getDataFileName "installation/run.sh"+ venv <- fpToText <$> ipythonDir+ let cmdArgs = [pack runCmd, venv] ++ args+ runHandles "bash" cmdArgs handles doNothing where handles = [InHandle Inherit, outHandle suppress, errorHandle suppress] outHandle True = OutHandle CreatePipe outHandle False = OutHandle Inherit@@ -79,8 +87,11 @@ ipythonDir :: Sh FilePath ipythonDir = ensure $ (</> "ipython") <$> ihaskellDir -ipythonExePath :: Sh FilePath-ipythonExePath = (</> ("bin" </> "ipython")) <$> ipythonDir+ipythonExePath :: WhichIPython -> Sh FilePath+ipythonExePath which = + case which of+ DefaultIPython -> (</> ("bin" </> "ipython")) <$> ipythonDir+ ExplicitIPython path -> return $ fromString path notebookDir :: Sh FilePath notebookDir = ensure $ (</> "notebooks") <$> ihaskellDir@@ -102,8 +113,8 @@ -- | Find a notebook and then convert it into the provided format. -- Notebooks are searched in the current directory as well as the IHaskell -- notebook directory (in that order).-nbconvert :: ViewFormat -> String -> IO ()-nbconvert fmt name = void . shellyNoDir $ do+nbconvert :: WhichIPython -> ViewFormat -> String -> IO ()+nbconvert which fmt name = void . shellyNoDir $ do curdir <- pwd nbdir <- notebookDir -- Find which of the options is available. @@ -125,124 +136,32 @@ Pdf -> ["--to=latex", "--post=pdf"] Html -> ["--to=html", "--template=ihaskell"] fmt -> ["--to=" ++ show fmt] in- void $ runIHaskell ipythonProfile "nbconvert" $ viewArgs ++ [fpToString notebook]+ void $ runIHaskell which ipythonProfile "nbconvert" $ viewArgs ++ [fpToString notebook] -- | Set up IPython properly.-setupIPython :: IO ()-setupIPython = do+setupIPython :: WhichIPython -> IO ()++setupIPython (ExplicitIPython path) = do+ exists <- shellyNoDir $+ test_f $ fromString path++ unless exists $+ fail $ "Cannot find IPython at " ++ path++setupIPython DefaultIPython = do installed <- ipythonInstalled if installed then updateIPython else installIPython- - --- | Update the IPython source tree and rebuild.-updateIPython :: IO ()-updateIPython = void . shellyNoDir $ do- srcDir <- ipythonSourceDir- cd srcDir- gitPath <- path "git"- currentCommitHash <- silently $ pack <$> rstrip <$> unpack <$> run gitPath ["rev-parse", "HEAD"]- when (currentCommitHash /= ipythonCommit) $ do- putStrLn "Incorrect IPython repository commit hash."- putStrLn $ "Found hash: " ++ currentCommitHash - putStrLn $ "Wanted hash: " ++ ipythonCommit - putStrLn "Updating..."- run_ gitPath ["pull", "origin", "master"]- run_ gitPath ["checkout", ipythonCommit]- installPipDependencies- buildIPython---- | Install IPython from source.-installIPython :: IO ()-installIPython = void . shellyNoDir $ do- installPipDependencies-- -- Get the IPython source.- gitPath <- path "git"- putStrLn "Downloading IPython... (this may take a while)"- ipythonSrcDir <- ipythonSourceDir- run_ gitPath ["clone", "--recursive", "https://github.com/ipython/ipython.git", fpToText ipythonSrcDir]- cd ipythonSrcDir- run_ gitPath ["checkout", ipythonCommit]-- buildIPython---- | Install all Python dependencies.-installPipDependencies :: Sh ()-installPipDependencies = withTmpDir $ \tmpDir -> - mapM_ (installDependency tmpDir) - [- ("pyzmq", "14.0.1")- , ("tornado","3.1.1")- , ("jinja2","2.7.1")- -- The following cannot go first in the dependency list, because- -- their setup.py are broken and require the directory to exist- -- already.- , ("MarkupSafe", "0.18")- --, ("setuptools", "2.0.2")- ]- where- installDependency :: FilePath -> (Text, Text) -> Sh ()- installDependency tmpDir (dep, version) = sub $ do- let versioned = dep ++ "-" ++ version- putStrLn $ "Installing dependency: " ++ versioned-- pipPath <- path "pip"- tarPath <- path "tar"- pythonPath <- path "python"-- -- Download the package.- let downloadOpt = "--download=" ++ fpToText tmpDir- run_ pipPath ["install", downloadOpt, dep ++ "==" ++ version]-- -- Extract it.- cd tmpDir- run_ tarPath ["-xzf", versioned ++ ".tar.gz"]-- -- Install it.- cd $ fromText versioned- dir <- fpToText <$> ipythonDir- setenv "PYTHONPATH" $ dir ++ "/lib/python2.7/site-packages/"- let prefixOpt = "--prefix=" ++ dir- run_ pythonPath ["setup.py", "install", prefixOpt]+-- | Replace "~" with $HOME if $HOME is defined.+-- Otherwise, do nothing.+subHome :: String -> IO String+subHome path = shellyNoDir $ do+ home <- unpack <$> fromMaybe "~" <$> get_env "HOME"+ return $ replace "~" home path --- | Once things are checked out into the IPython source directory, build it and install it.-buildIPython :: Sh ()-buildIPython = do- -- Install IPython locally.- pythonPath <- path "python"- prefixOpt <- ("--prefix=" ++) <$> fpToText <$> ipythonDir- putStrLn "Installing IPython."- run_ pythonPath ["setup.py", "install", prefixOpt]-- -- Patch the IPython executable so that it doesn't use system IPython.- -- Using PYTHONPATH is not enough due to bugs in how `easy_install` sets- -- things up, at least on Mac OS X.- ipyDir <- ipythonDir- let patchLines =- [ "#!/usr/bin/env python"- , "import sys"- , "sys.path = [\"" ++ fpToText ipyDir ++- "/lib/python2.7/site-packages\"] + sys.path"]- ipythonPath <- ipythonExePath- contents <- readFile ipythonPath- writeFile ipythonPath $ unlines patchLines ++ "\n" ++ contents-- -- Remove the old IPython profile so that we write a new one in its- -- place. Users are not expected to fiddle with the profile, so we give- -- no warning whatsoever. This may be changed eventually.- removeIPythonProfile ipythonProfile- ---- | Check whether IPython is properly installed.-ipythonInstalled :: IO Bool-ipythonInstalled = shellyNoDir $ do- ipythonPath <- ipythonExePath- test_f ipythonPath- -- | Get the path to an executable. If it doensn't exist, fail with an -- error message complaining about it. path :: Text -> Sh FilePath@@ -254,13 +173,6 @@ fail $ "`" ++ unpack exe ++ "` not on $PATH." Just exePath -> return exePath --- | Use the `ipython --version` command to figure out the version.--- Return a tuple with (major, minor, patch).-ipythonVersion :: IO (Int, Int, Int)-ipythonVersion = shellyNoDir $ do- [major, minor, patch] <- parseVersion <$> ipython True ["--version"]- return (major, minor, patch)- -- | Parse an IPython version string into a list of integers. parseVersion :: String -> [Int] parseVersion versionStr = map read' $ split "." versionStr@@ -269,13 +181,14 @@ _ -> error $ "cannot parse version: "++ versionStr -- | Run an IHaskell application using the given profile.-runIHaskell :: String -- ^ IHaskell profile name. +runIHaskell :: WhichIPython+ -> String -- ^ IHaskell profile name. -> String -- ^ IPython app name. -> [String] -- ^ Arguments to IPython. -> Sh ()-runIHaskell profile app args = void $ do+runIHaskell which profile app args = void $ do -- Try to locate the profile. Do not die if it doesn't exist.- errExit False $ ipython True ["locate", "profile", pack profile]+ errExit False $ ipython which True ["locate", "profile", pack profile] -- If the profile doesn't exist, create it. -- We have an ugly hack that removes the profile whenever the IPython@@ -283,25 +196,25 @@ exitCode <- lastExitCode when (exitCode /= 0) $ liftIO $ do putStrLn "Creating IPython profile."- setupIPythonProfile profile+ setupIPythonProfile which profile -- Run the IHaskell command.- ipython False $ map pack $ [app, "--profile", profile] ++ args+ ipython which False $ map pack $ [app, "--profile", profile] ++ args -runConsole :: InitInfo -> IO ()-runConsole initInfo = void . shellyNoDir $ do+runConsole :: WhichIPython -> InitInfo -> IO ()+runConsole which initInfo = void . shellyNoDir $ do writeInitInfo initInfo- runIHaskell ipythonProfile "console" []+ runIHaskell which ipythonProfile "console" [] -runNotebook :: InitInfo -> Maybe String -> IO ()-runNotebook initInfo maybeServeDir = void . shellyNoDir $ do+runNotebook :: WhichIPython -> InitInfo -> Maybe String -> IO ()+runNotebook which initInfo maybeServeDir = void . shellyNoDir $ do notebookDirStr <- fpToString <$> notebookDir let args = case maybeServeDir of Nothing -> ["--notebook-dir", unpack notebookDirStr] Just dir -> ["--notebook-dir", dir] writeInitInfo initInfo- runIHaskell ipythonProfile "notebook" args+ runIHaskell which ipythonProfile "notebook" args writeInitInfo :: InitInfo -> Sh () writeInitInfo info = do@@ -314,28 +227,29 @@ read <$> liftIO (readFile filename) -- | Create the IPython profile.-setupIPythonProfile :: String -- ^ IHaskell profile name.+setupIPythonProfile :: WhichIPython+ -> String -- ^ IHaskell profile name. -> IO ()-setupIPythonProfile profile = shellyNoDir $ do+setupIPythonProfile which profile = shellyNoDir $ do -- Create the IPython profile.- void $ ipython True ["profile", "create", pack profile]+ void $ ipython which True ["profile", "create", pack profile] -- Find the IPython profile directory. Make sure to get rid of trailing -- newlines from the output of the `ipython locate` call.- ipythonDir <- pack <$> rstrip <$> ipython True ["locate"]+ ipythonDir <- pack <$> rstrip <$> ipython which True ["locate"] let profileDir = ipythonDir ++ "/profile_" ++ pack profile ++ "/" liftIO $ copyProfile profileDir insertIHaskellPath profileDir -removeIPythonProfile :: String -> Sh ()-removeIPythonProfile profile = do+removeIPythonProfile :: WhichIPython -> String -> Sh ()+removeIPythonProfile which profile = do -- Try to locate the profile. Do not die if it doesn't exist.- errExit False $ ipython True ["locate", "profile", pack profile]+ errExit False $ ipython which True ["locate", "profile", pack profile] -- If the profile exists, delete it. exitCode <- lastExitCode- dir <- pack <$> rstrip <$> ipython True ["locate"]+ dir <- pack <$> rstrip <$> ipython which True ["locate"] when (exitCode == 0 && dir /= "") $ do putStrLn "Updating IPython profile." let profileDir = dir ++ "/profile_" ++ pack profile ++ "/"@@ -345,16 +259,6 @@ copyProfile :: Text -> IO () copyProfile profileDir = do profileTar <- Paths.getDataFileName "profile/profile.tar"- {-- -- Load profile from Resources directory of Mac *.app.- ihaskellPath <- shellyNoDir getIHaskellPath- profileTar <- if "IHaskell.app/Contents/MacOS" `isInfixOf` ihaskellPath- then- let pieces = split "/" ihaskellPath- pathPieces = init pieces ++ ["..", "Resources", "profile.tar"] in- return $ intercalate "/" pathPieces- else Paths.getDataFileName "profile/profile.tar"- -} putStrLn $ pack $ "Loading profile from " ++ profileTar Tar.extract (unpack profileDir) profileTar @@ -409,3 +313,40 @@ [] -> return Nothing dir:_ -> return $ Just dir++-- | Check whether IPython is properly installed.+ipythonInstalled :: IO Bool+ipythonInstalled = shellyNoDir $ do+ ipythonPath <- ipythonExePath DefaultIPython+ test_f ipythonPath++-- | Update the IPython source tree and rebuild.+updateIPython :: IO ()+updateIPython = do+ updateScript <- Paths.getDataFileName "installation/update.sh"+ venv <- fpToText <$> shellyNoDir ipythonDir+ runTmp updateScript [venv, ipythonCommit]++ -- Remove the old IPython profile.+ -- A new one will be regenerated when it is needed.+ -- shellyNoDir $ removeIPythonProfile DefaultIPython ipythonProfile++-- | Install IPython from source.+installIPython :: IO ()+installIPython = do+ -- Print a message and wait a little.+ putStrLn "Installing IPython for IHaskell. This may take a while."+ threadDelay $ 3 * 1000 * 100++ -- Set up the virtualenv.+ virtualenvScript <- Paths.getDataFileName "installation/virtualenv.sh"+ venvDir <- fpToText <$> shellyNoDir ipythonDir+ runTmp virtualenvScript [venvDir]++ -- Set up Python depenencies.+ installScript <- Paths.getDataFileName "installation/ipython.sh"+ runTmp installScript [venvDir, ipythonCommit]++runTmp script args = shellyNoDir $ withTmpDir $ \tmp -> do+ cd tmp+ run_ "bash" $ pack script: args
src/Main.hs view
@@ -43,31 +43,31 @@ Right args -> ihaskell args +chooseIPython [] = return DefaultIPython+chooseIPython (IPythonFrom path:_) =+ ExplicitIPython <$> subHome path+chooseIPython (_:xs) = chooseIPython xs+ ihaskell :: Args -> IO () -- If no mode is specified, print help text. ihaskell (Args (ShowHelp help) _) = putStrLn $ pack help---- Update IPython: remove then reinstall.--- This is in case cabal updates IHaskell but the corresponding IPython--- isn't updated. This is hard to detect since versions of IPython might--- not change!-ihaskell (Args UpdateIPython _) = do- setupIPython- putStrLn "IPython updated." ihaskell (Args Console flags) = showingHelp Console flags $ do- setupIPython+ ipython <- chooseIPython flags+ setupIPython ipython flags <- addDefaultConfFile flags info <- initInfo IPythonConsole flags- runConsole info+ runConsole ipython info -ihaskell (Args (View (Just fmt) (Just name)) []) =- nbconvert fmt name+ihaskell (Args (View (Just fmt) (Just name)) args) = do+ ipython <- chooseIPython args+ nbconvert ipython fmt name ihaskell (Args Notebook flags) = showingHelp Notebook flags $ do- setupIPython+ ipython <- chooseIPython flags+ setupIPython ipython let server = case mapMaybe serveDir flags of [] -> Nothing@@ -79,7 +79,7 @@ curdir <- getCurrentDirectory let info = undirInfo { initDir = curdir } - runNotebook info server+ runNotebook ipython info server where serveDir (ServeFrom dir) = Just dir serveDir _ = Nothing