Building lists of strict text in HtmlObject
This commit is contained in:
parent
12a43ef90b
commit
1f9d11eb29
@ -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
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user