summaryrefslogtreecommitdiff
path: root/public/vendor/codemirror/mode/haskell-literate/index.html
diff options
context:
space:
mode:
authorWu Cheng-Han2016-01-17 14:28:04 -0600
committerWu Cheng-Han2016-01-17 14:28:04 -0600
commiteaa8ccaccb1091820d0a8d1223996a6dd057347d (patch)
tree6b4aaa3b3d1a2fed68147510142663222533775a /public/vendor/codemirror/mode/haskell-literate/index.html
parentce65e58096d57ace02723d11a125673f9d48c293 (diff)
Upgrade CodeMirror to 5.10.1 and now support fullscreen, jump-to-line in editor
Diffstat (limited to 'public/vendor/codemirror/mode/haskell-literate/index.html')
-rw-r--r--public/vendor/codemirror/mode/haskell-literate/index.html282
1 files changed, 282 insertions, 0 deletions
diff --git a/public/vendor/codemirror/mode/haskell-literate/index.html b/public/vendor/codemirror/mode/haskell-literate/index.html
new file mode 100644
index 00000000..8c9bc60d
--- /dev/null
+++ b/public/vendor/codemirror/mode/haskell-literate/index.html
@@ -0,0 +1,282 @@
+<!doctype html>
+
+<title>CodeMirror: Haskell-literate mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="haskell-literate.js"></script>
+<script src="../haskell/haskell.js"></script>
+<style>.CodeMirror {
+ border-top : 1px solid #DDDDDD;
+ border-bottom : 1px solid #DDDDDD;
+}</style>
+<div id=nav>
+ <a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo
+ src="../../doc/logo.png"></a>
+
+ <ul>
+ <li><a href="../../index.html">Home</a>
+ <li><a href="../../doc/manual.html">Manual</a>
+ <li><a href="https://github.com/codemirror/codemirror">Code</a>
+ </ul>
+ <ul>
+ <li><a href="../index.html">Language modes</a>
+ <li><a class=active href="#">Haskell-literate</a>
+ </ul>
+</div>
+
+<article>
+ <h2>Haskell literate mode</h2>
+ <form>
+ <textarea id="code" name="code">
+> {-# LANGUAGE OverloadedStrings #-}
+> {-# OPTIONS_GHC -fno-warn-unused-do-bind #-}
+> import Control.Applicative ((<$>), (<*>))
+> import Data.Maybe (isJust)
+
+> import Data.Text (Text)
+> import Text.Blaze ((!))
+> import qualified Data.Text as T
+> import qualified Happstack.Server as Happstack
+> import qualified Text.Blaze.Html5 as H
+> import qualified Text.Blaze.Html5.Attributes as A
+
+> import Text.Digestive
+> import Text.Digestive.Blaze.Html5
+> import Text.Digestive.Happstack
+> import Text.Digestive.Util
+
+Simple forms and validation
+---------------------------
+
+Let's start by creating a very simple datatype to represent a user:
+
+> data User = User
+> { userName :: Text
+> , userMail :: Text
+> } deriving (Show)
+
+And dive in immediately to create a `Form` for a user. The `Form v m a` type
+has three parameters:
+
+- `v`: the type for messages and errors (usually a `String`-like type, `Text` in
+ this case);
+- `m`: the monad we are operating in, not specified here;
+- `a`: the return type of the `Form`, in this case, this is obviously `User`.
+
+> userForm :: Monad m => Form Text m User
+
+We create forms by using the `Applicative` interface. A few form types are
+provided in the `Text.Digestive.Form` module, such as `text`, `string`,
+`bool`...
+
+In the `digestive-functors` library, the developer is required to label each
+field using the `.:` operator. This might look like a bit of a burden, but it
+allows you to do some really useful stuff, like separating the `Form` from the
+actual HTML layout.
+
+> userForm = User
+> <$> "name" .: text Nothing
+> <*> "mail" .: check "Not a valid email address" checkEmail (text Nothing)
+
+The `check` function enables you to validate the result of a form. For example,
+we can validate the email address with a really naive `checkEmail` function.
+
+> checkEmail :: Text -> Bool
+> checkEmail = isJust . T.find (== '@')
+
+More validation
+---------------
+
+For our example, we also want descriptions of Haskell libraries, and in order to
+do that, we need package versions...
+
+> type Version = [Int]
+
+We want to let the user input a version number such as `0.1.0.0`. This means we
+need to validate if the input `Text` is of this form, and then we need to parse
+it to a `Version` type. Fortunately, we can do this in a single function:
+`validate` allows conversion between values, which can optionally fail.
+
+`readMaybe :: Read a => String -> Maybe a` is a utility function imported from
+`Text.Digestive.Util`.
+
+> validateVersion :: Text -> Result Text Version
+> validateVersion = maybe (Error "Cannot parse version") Success .
+> mapM (readMaybe . T.unpack) . T.split (== '.')
+
+A quick test in GHCi:
+
+ ghci> validateVersion (T.pack "0.3.2.1")
+ Success [0,3,2,1]
+ ghci> validateVersion (T.pack "0.oops")
+ Error "Cannot parse version"
+
+It works! This means we can now easily add a `Package` type and a `Form` for it:
+
+> data Category = Web | Text | Math
+> deriving (Bounded, Enum, Eq, Show)
+
+> data Package = Package Text Version Category
+> deriving (Show)
+
+> packageForm :: Monad m => Form Text m Package
+> packageForm = Package
+> <$> "name" .: text Nothing
+> <*> "version" .: validate validateVersion (text (Just "0.0.0.1"))
+> <*> "category" .: choice categories Nothing
+> where
+> categories = [(x, T.pack (show x)) | x <- [minBound .. maxBound]]
+
+Composing forms
+---------------
+
+A release has an author and a package. Let's use this to illustrate the
+composability of the digestive-functors library: we can reuse the forms we have
+written earlier on.
+
+> data Release = Release User Package
+> deriving (Show)
+
+> releaseForm :: Monad m => Form Text m Release
+> releaseForm = Release
+> <$> "author" .: userForm
+> <*> "package" .: packageForm
+
+Views
+-----
+
+As mentioned before, one of the advantages of using digestive-functors is
+separation of forms and their actual HTML layout. In order to do this, we have
+another type, `View`.
+
+We can get a `View` from a `Form` by supplying input. A `View` contains more
+information than a `Form`, it has:
+
+- the original form;
+- the input given by the user;
+- any errors that have occurred.
+
+It is this view that we convert to HTML. For this tutorial, we use the
+[blaze-html] library, and some helpers from the `digestive-functors-blaze`
+library.
+
+[blaze-html]: http://jaspervdj.be/blaze/
+
+Let's write a view for the `User` form. As you can see, we here refer to the
+different fields in the `userForm`. The `errorList` will generate a list of
+errors for the `"mail"` field.
+
+> userView :: View H.Html -> H.Html
+> userView view = do
+> label "name" view "Name: "
+> inputText "name" view
+> H.br
+>
+> errorList "mail" view
+> label "mail" view "Email address: "
+> inputText "mail" view
+> H.br
+
+Like forms, views are also composable: let's illustrate that by adding a view
+for the `releaseForm`, in which we reuse `userView`. In order to do this, we
+take only the parts relevant to the author from the view by using `subView`. We
+can then pass the resulting view to our own `userView`.
+We have no special view code for `Package`, so we can just add that to
+`releaseView` as well. `childErrorList` will generate a list of errors for each
+child of the specified form. In this case, this means a list of errors from
+`"package.name"` and `"package.version"`. Note how we use `foo.bar` to refer to
+nested forms.
+
+> releaseView :: View H.Html -> H.Html
+> releaseView view = do
+> H.h2 "Author"
+> userView $ subView "author" view
+>
+> H.h2 "Package"
+> childErrorList "package" view
+>
+> label "package.name" view "Name: "
+> inputText "package.name" view
+> H.br
+>
+> label "package.version" view "Version: "
+> inputText "package.version" view
+> H.br
+>
+> label "package.category" view "Category: "
+> inputSelect "package.category" view
+> H.br
+
+The attentive reader might have wondered what the type parameter for `View` is:
+it is the `String`-like type used for e.g. error messages.
+But wait! We have
+ releaseForm :: Monad m => Form Text m Release
+ releaseView :: View H.Html -> H.Html
+... doesn't this mean that we need a `View Text` rather than a `View Html`? The
+answer is yes -- but having `View Html` allows us to write these views more
+easily with the `digestive-functors-blaze` library. Fortunately, we will be able
+to fix this using the `Functor` instance of `View`.
+ fmap :: Monad m => (v -> w) -> View v -> View w
+A backend
+---------
+To finish this tutorial, we need to be able to actually run this code. We need
+an HTTP server for that, and we use [Happstack] for this tutorial. The
+`digestive-functors-happstack` library gives about everything we need for this.
+[Happstack]: http://happstack.com/
+
+> site :: Happstack.ServerPart Happstack.Response
+> site = do
+> Happstack.decodeBody $ Happstack.defaultBodyPolicy "/tmp" 4096 4096 4096
+> r <- runForm "test" releaseForm
+> case r of
+> (view, Nothing) -> do
+> let view' = fmap H.toHtml view
+> Happstack.ok $ Happstack.toResponse $
+> template $
+> form view' "/" $ do
+> releaseView view'
+> H.br
+> inputSubmit "Submit"
+> (_, Just release) -> Happstack.ok $ Happstack.toResponse $
+> template $ do
+> css
+> H.h1 "Release received"
+> H.p $ H.toHtml $ show release
+>
+> main :: IO ()
+> main = Happstack.simpleHTTP Happstack.nullConf site
+
+Utilities
+---------
+
+> template :: H.Html -> H.Html
+> template body = H.docTypeHtml $ do
+> H.head $ do
+> H.title "digestive-functors tutorial"
+> css
+> H.body body
+> css :: H.Html
+> css = H.style ! A.type_ "text/css" $ do
+> "label {width: 130px; float: left; clear: both}"
+> "ul.digestive-functors-error-list {"
+> " color: red;"
+> " list-style-type: none;"
+> " padding-left: 0px;"
+> "}"
+ </textarea>
+ </form>
+
+ <p><strong>MIME types
+ defined:</strong> <code>text/x-literate-haskell</code>.</p>
+
+ <p>Parser configuration parameters recognized: <code>base</code> to
+ set the base mode (defaults to <code>"haskell"</code>).</p>
+
+ <script>
+ var editor = CodeMirror.fromTextArea(document.getElementById("code"), {mode: "haskell-literate"});
+ </script>
+
+</article>