module Text.Formlets.Form where import Control.Applicative import Control.Applicative.State import Text.XHtml.Strict ((+++)) import Text.XHtml.Strict as X type Env = [(String, String)] type FormState = Names type Names = Integer type Name = String type Xml = X.Html queryParam :: Env -> Name -> String queryParam env name = case (name `lookup` env) of Nothing -> error $ "Couldn't find " ++ name Just x -> x newtype Form a = Form { deform :: Env -> State FormState (Collector a, X.Html) } instance Functor Form where fmap f (Form a) = Form $ \env -> (fmap . fmapFst . fmap) f (a env) where fmapFst f (a, b) = (f a, b) type Collector a = Env -> a instance Applicative Form where pure = pureF (<*>) = applyF pureF :: a -> Form a pureF v = Form $ \env -> pure (const v, X.noHtml) -- K applyF :: Form (a -> b) -> Form a -> Form b (Form f) `applyF` (Form v) = Form $ \env -> pure combine <*> f env <*> v env where combine (f, x) (v, y) = (\e -> f e (v e), x +++ y) -- TODO ORYO freshName :: State FormState String freshName = do n <- get put $ n + 1 return $ "input_" ++ show n currentName :: State FormState String currentName = gets $ (++) "input_" . show {- component: just some xml -} xml :: X.Html -> Form () xml x = Form $ \env -> pure (const (), x) {- component: just some text -} text :: String -> Form () text s = Form $ \env -> pure (const (), toHtml s) {- transform the XML component -} plug :: (Xml -> Xml) -> Form a -> Form a f `plug` (Form m) = Form $ \env -> pure plugin <*> m env where plugin :: (a, Xml) -> (a, Xml) plugin (c, x) = (c, f x)