1 {-# LANGUAGE DeriveFunctor #-}
2 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
3 {-# LANGUAGE FlexibleInstances #-}
4 {-# LANGUAGE RankNTypes #-}
6 #if MIN_VERSION_blaze_markup(0,7,1)
9 module Text.BlazeT.Internal
11 -- * Entities exported only by the @blazeT@ version of this module
15 -- ** Specializations for @blaze-markup@ backwards compatibility
34 -- * Entities exported also by "Text.Blaze.Internal"
37 -- ** Important types.
38 Text.Blaze.ChoiceString (..)
39 , Text.Blaze.StaticString (..)
43 , Text.Blaze.Attribute
44 , Text.Blaze.AttributeValue
46 -- ** Creating custom tags and attributes.
49 , Text.Blaze.attribute
50 , Text.Blaze.dataAttribute
51 , Text.Blaze.customAttribute
53 -- ** Converting values to Markup.
59 , preEscapedTextBuilder
63 , unsafeLazyByteString
66 , Text.Blaze.textComment
67 , Text.Blaze.lazyTextComment
68 , Text.Blaze.stringComment
69 , Text.Blaze.unsafeByteStringComment
70 , Text.Blaze.unsafeLazyByteStringComment
72 -- ** Converting values to tags.
74 , Text.Blaze.stringTag
76 -- ** Converting values to attribute values.
77 , Text.Blaze.textValue
78 , Text.Blaze.preEscapedTextValue
79 , Text.Blaze.lazyTextValue
80 , Text.Blaze.preEscapedLazyTextValue
81 , Text.Blaze.textBuilderValue
82 , Text.Blaze.preEscapedTextBuilderValue
83 , Text.Blaze.stringValue
84 , Text.Blaze.preEscapedStringValue
85 , Text.Blaze.unsafeByteStringValue
86 , Text.Blaze.unsafeLazyByteStringValue
88 -- ** Setting attributes
89 , Text.Blaze.Attributable
93 -- ** Modifying Markup elements
97 -- ** Querying Markup elements
103 import Control.Monad.Identity
104 import Control.Monad.Trans.Class
105 import Control.Monad.Writer.Strict
106 import qualified Data.ByteString as BS
107 import qualified Data.ByteString.Lazy as BL
109 import qualified Data.Text as T
110 import qualified Data.Text.Lazy as LT
111 import qualified Data.Text.Lazy.Builder as LTB
112 import qualified Text.Blaze
113 import qualified Text.Blaze.Internal as Text.Blaze
115 {- | Everything is build around the simple @newtype@ definition of the
116 'MarkupT' transformer, which makes use the 'Monoid' instance of Blaze
117 'Text.Blaze.Markup' and is basically a 'WriterT' writing Blaze
120 newtype MarkupT m a= MarkupT { fromMarkupT :: WriterT Text.Blaze.Markup m a }
122 #if MIN_VERSION_base(4,8,0)
126 ,MonadWriter Text.Blaze.Markup
130 type MarkupI a = MarkupT Identity a
132 -- | Map both the return value and markup of a computation using the
134 mapMarkupT :: (m (a,Text.Blaze.Markup) -> n (b,Text.Blaze.Markup)) -> MarkupT m a -> MarkupT n b
135 mapMarkupT f = MarkupT . mapWriterT f . fromMarkupT
136 {-# INLINE mapMarkupT #-}
138 type MarkupM a = forall m . Monad m => MarkupT m a
139 type Markup = MarkupM ()
140 type Markup2 = forall m . Monad m => MarkupT m () -> MarkupT m ()
142 runMarkupT :: MarkupT m a -> m (a,Text.Blaze.Markup)
143 runMarkupT = runWriterT . fromMarkupT
144 {-# INLINE runMarkupT #-}
146 -- | run the MarkupT and return a pair consisting of the result of the
147 -- computation and the blaze markup rendered with a blaze renderer
148 -- like 'Text.BlazeT.Renderer.Text.renderHtml'
149 runWith :: Monad m => (Markup -> c) -> MarkupT m a -> m (a, c)
150 runWith renderer = liftM (second $ \x -> renderer $ wrapMarkup x) . runMarkupT
151 {-# INLINE runWith #-}
153 execMarkupT :: Monad m => MarkupT m a -> m Text.Blaze.Markup
154 execMarkupT = liftM snd . runMarkupT
155 {-# INLINE execMarkupT #-}
157 execWith :: Monad m => (Markup -> c) -> MarkupT m a -> m c
158 execWith renderer = liftM snd . runWith renderer
159 {-# INLINE execWith #-}
161 runMarkup :: MarkupI a -> (a, Text.Blaze.Markup)
162 runMarkup = runIdentity . runMarkupT
163 {-# INLINE runMarkup #-}
165 execMarkup :: MarkupI a -> Text.Blaze.Markup
166 execMarkup = snd . runMarkup
167 {-# INLINE execMarkup #-}
170 instance (Monad m,Monoid a) => Monoid (MarkupT m a) where
171 mempty = return mempty
172 {-# INLINE mempty #-}
173 a `mappend` b = do {a' <- a; b >>= return . (mappend a')}
174 {-# INLINE mappend #-}
177 instance Monad m => Text.Blaze.Attributable (MarkupT m a) where
178 h ! a = wrapMarkupT2 (Text.Blaze.! a) h
181 instance Monad m => Text.Blaze.Attributable (a -> MarkupT m b) where
182 h ! a = \x -> wrapMarkupT2 (Text.Blaze.! a) $ h x
185 instance Monad m => IsString (MarkupT m ()) where
186 fromString = wrapMarkup . fromString
187 {-# INLINE fromString #-}
189 -- | Wrapper for 'Text.Blaze.Markup' is simply
191 wrapMarkupT :: Monad m => Text.Blaze.Markup -> MarkupT m ()
193 {-# INLINE wrapMarkupT #-}
195 wrapMarkup :: Text.Blaze.Markup -> Markup
196 wrapMarkup = wrapMarkupT
197 {-# INLINE wrapMarkup #-}
200 -- | Wrapper for functions that modify 'Text.Blaze.Markup' is simply
202 wrapMarkupT2 :: Monad m => (Text.Blaze.Markup -> Text.Blaze.Markup)
203 -> MarkupT m a -> MarkupT m a
204 wrapMarkupT2 = censor
205 {-# INLINE wrapMarkupT2 #-}
207 wrapMarkup2 :: (Text.Blaze.Markup -> Text.Blaze.Markup) -> Markup2
208 wrapMarkup2 = wrapMarkupT2
209 {-# INLINE wrapMarkup2 #-}
211 unsafeByteString :: BS.ByteString -> Markup
212 unsafeByteString = wrapMarkup . Text.Blaze.unsafeByteString
213 {-# INLINE unsafeByteString #-}
215 -- | Insert a lazy 'BL.ByteString'. See 'unsafeByteString' for reasons why this
216 -- is an unsafe operation.
218 unsafeLazyByteString :: BL.ByteString -- ^ Value to insert
219 -> Markup -- ^ Resulting HTML fragment
220 unsafeLazyByteString = wrapMarkup . Text.Blaze.unsafeLazyByteString
221 {-# INLINE unsafeLazyByteString #-}
223 external :: Monad m => MarkupT m a -> MarkupT m a
224 external = wrapMarkupT2 Text.Blaze.external
225 {-# INLINE external #-}
227 contents :: Monad m => MarkupT m a -> MarkupT m a
228 contents = wrapMarkupT2 Text.Blaze.contents
229 {-# INLINE contents #-}
231 customParent ::Text.Blaze.Tag -> Markup2
232 customParent = wrapMarkup2 . Text.Blaze.customParent
233 {-# INLINE customParent #-}
235 customLeaf :: Text.Blaze.Tag -> Bool -> Markup
236 customLeaf = fmap wrapMarkup . Text.Blaze.customLeaf
237 {-# INLINE customLeaf #-}
239 preEscapedText :: T.Text -> Markup
240 preEscapedText = wrapMarkup . Text.Blaze.preEscapedText
241 {-# INLINE preEscapedText #-}
243 preEscapedLazyText :: LT.Text -> Markup
244 preEscapedLazyText = wrapMarkup . Text.Blaze.preEscapedLazyText
245 {-# INLINE preEscapedLazyText #-}
247 preEscapedTextBuilder :: LTB.Builder -> Markup
248 textBuilder :: LTB.Builder -> Markup
251 preEscapedTextBuilder = wrapMarkup . Text.Blaze.preEscapedTextBuilder
252 textBuilder = wrapMarkup . Text.Blaze.textBuilder
253 {-# INLINE preEscapedTextBuilder #-}
254 {-# INLINE textBuilder #-}
256 preEscapedTextBuilder = error "This function needs blaze-markup 0.7.1.0"
257 textBuilder = error "This function needs blaze-markup 0.7.1.0"
260 preEscapedString :: String -> Markup
261 preEscapedString = wrapMarkup . Text.Blaze.preEscapedString
262 {-# INLINE preEscapedString #-}
264 string :: String -> Markup
265 string = wrapMarkup . Text.Blaze.string
266 {-# INLINE string #-}
268 text :: T.Text -> Markup
269 text = wrapMarkup . Text.Blaze.text
272 lazyText :: LT.Text -> Markup
273 lazyText = wrapMarkup . Text.Blaze.lazyText
274 {-# INLINE lazyText #-}
277 -- The following is an adaptation of all "Text.Blaze.Internal" exports to
280 -- Entities that are reexported from "Text.Blaze.Internal" have the original
281 -- documentation attached to them.
283 -- Entities that had to be adapted are tagged with \"(Adapted)\". For
284 -- their documentation consult the "Text.Blaze.Internal" documentation.