Building lists of strict text in HtmlObject

This commit is contained in:
Michael Snoyman 2010-01-11 00:18:28 +02:00
parent 12a43ef90b
commit 1f9d11eb29

View File

@ -26,6 +26,8 @@ module Data.Object.Html
-- * Standard 'Object' functions -- * Standard 'Object' functions
, toHtmlObject , toHtmlObject
, fromHtmlObject , fromHtmlObject
-- * Re-export
, module Data.Object
#if TEST #if TEST
, testSuite , testSuite
#endif #endif
@ -35,11 +37,13 @@ import Data.Generics
import Data.Object.Text import Data.Object.Text
import Data.Object.Json import Data.Object.Json
import qualified Data.Text.Lazy as TL import qualified Data.Text.Lazy as TL
import qualified Data.Text as TS
import Data.ByteString.Lazy (ByteString) import Data.ByteString.Lazy (ByteString)
import Web.Encodings import Web.Encodings
import Text.StringTemplate.Classes import Text.StringTemplate.Classes
import Control.Arrow (second) import Control.Arrow (second)
import Data.Attempt import Data.Attempt
import Data.Object
#if TEST #if TEST
import Test.Framework (testGroup, Test) import Test.Framework (testGroup, Test)
@ -50,8 +54,8 @@ import Text.StringTemplate
-- | A single piece of HTML code. -- | A single piece of HTML code.
data Html = data Html =
Html Text -- ^ Already encoded HTML. Html TS.Text -- ^ Already encoded HTML.
| Text Text -- ^ Text which should be HTML escaped. | Text TS.Text -- ^ Text which should be HTML escaped.
| Tag String [(String, String)] Html -- ^ Tag which needs a closing tag. | Tag String [(String, String)] Html -- ^ Tag which needs a closing tag.
| EmptyTag String [(String, String)] -- ^ Tag without a closing tag. | EmptyTag String [(String, String)] -- ^ Tag without a closing tag.
| HtmlList [Html] | HtmlList [Html]
@ -70,57 +74,56 @@ fromHtmlObject = ca
instance ConvertSuccess String Html where instance ConvertSuccess String Html where
convertSuccess = Text . cs convertSuccess = Text . cs
instance ConvertSuccess Text Html where instance ConvertSuccess TS.Text Html where
convertSuccess = Text convertSuccess = Text
instance ConvertSuccess Text Html where
convertSuccess = Text . cs
$(deriveAttempts $(deriveAttempts
[ (''String, ''Html) [ (''String, ''Html)
, (''Text, ''Html) , (''Text, ''Html)
, (''TS.Text, ''Html)
]) ])
showAttribs :: [(String, String)] -> Text showAttribs :: [(String, String)] -> String -> String
showAttribs = TL.concat . map helper where showAttribs pairs rest = foldr ($) rest $ map helper pairs where
helper :: (String, String) -> Text helper :: (String, String) -> String -> String
helper (k, v) = TL.concat helper (k, v) rest' =
[ cs " " ' ' : encodeHtml k
, encodeHtml $ cs k ++ '=' : '"' : encodeHtml v
, cs "=\"" ++ '"' : rest'
, encodeHtml $ cs v
, cs "\""
]
htmlToText :: Bool -- ^ True to close empty tags like XML, False like HTML htmlToText :: Bool -- ^ True to close empty tags like XML, False like HTML
-> Html -> Html
-> Text -> ([TS.Text] -> [TS.Text])
htmlToText _ (Html t) = t htmlToText _ (Html t) = (:) t
htmlToText _ (Text t) = encodeHtml t htmlToText _ (Text t) = (:) $ encodeHtml t
htmlToText xml (Tag n as content) = TL.concat htmlToText xml (Tag n as content) = \rest ->
[ cs "<" (cs $ '<' : n)
, cs n : (cs $ showAttribs as ">")
, showAttribs as : (htmlToText xml content
, cs ">" $ (cs $ '<' : '/' : n)
, htmlToText xml content : cs ">"
, cs "</" : rest)
, cs n htmlToText xml (EmptyTag n as) = \rest ->
, cs ">" (cs $ '<' : n )
] : (cs $ showAttribs as (if xml then "/>" else ">"))
htmlToText xml (EmptyTag n as) = TL.concat : rest
[ cs "<" htmlToText xml (HtmlList l) = \rest ->
, cs n foldr ($) rest $ map (htmlToText xml) l
, showAttribs as
, cs $ if xml then "/>" else ">"
]
htmlToText xml (HtmlList l) = TL.concat $ map (htmlToText xml) l
newtype HtmlFragment = HtmlFragment { unHtmlFragment :: Text }
instance ConvertSuccess Html HtmlFragment where
convertSuccess h = HtmlFragment . TL.fromChunks . htmlToText False h $ []
-- FIXME remove the next instance
instance ConvertSuccess Html Text where instance ConvertSuccess Html Text where
convertSuccess = htmlToText False convertSuccess h = TL.fromChunks . htmlToText False h $ []
-- | Not fully typesafe. You must make sure that when converting to this, the -- | Not fully typesafe. You must make sure that when converting to this, the
-- 'Html' starts with a tag. -- 'Html' starts with a tag.
newtype XmlDoc = XmlDoc { unXmlDoc :: Text } newtype XmlDoc = XmlDoc { unXmlDoc :: Text }
instance ConvertSuccess Html XmlDoc where instance ConvertSuccess Html XmlDoc where
convertSuccess h = XmlDoc $ TL.concat convertSuccess h = XmlDoc $ TL.fromChunks $
[ cs "<?xml version='1.0' encoding='utf-8' ?>\n" cs "<?xml version='1.0' encoding='utf-8' ?>\n"
, htmlToText True h : htmlToText True h []
]
-- | Wrap an 'Html' in CDATA for XML output. -- | Wrap an 'Html' in CDATA for XML output.
cdata :: Html -> Html cdata :: Html -> Html