----------------------------------------------------------------------------- -- | -- Module : Network.XMPP.Print -- Copyright : (c) Dmitry Astapov, 2006 ; pierre, 2007 -- License : BSD-style (see the file LICENSE) -- Copyright : (c) riskbook, 2020 -- SPDX-License-Identifier: BSD3 -- -- Maintainer : Dmitry Astapov , pierre -- Stability : experimental -- Portability : portable -- -- An XMPP pretty-printing combinators -- Ported from Text.HTML to HaXML combinatiors -- ----------------------------------------------------------------------------- module Network.XMPP.Print ( -- Top-level rendering functions renderXmpp , putXmppLn , hPutXmpp , hPutNode -- XMPP primitives: tags , stream , streamEnd -- XMPP primitives: attributes , to ) where import System.IO import qualified Data.Text as T import qualified Data.Text.Lazy as TL import Text.XML (Node) import Text.XML.HaXml hiding (tag) import Text.XML.HaXml.Posn (Posn) import qualified Text.XML.HaXml.Pretty as P import Text.Blaze.Renderer.Text (renderMarkup) import Text.Blaze (toMarkup) import Network.XMPP.UTF8 import Network.XMPP.Utils import Network.XMPP.XML -- | Convert the internal representation (built using HaXml combinators) into string, -- and print it out putXmppLn :: Content Posn -> IO () putXmppLn = putStrLn . renderXmpp -- | Convert the internal representation (built using HaXml combinators) into string, -- and print it to the specified Handle, without trailing newline hPutXmpp :: Handle -> Content Posn -> IO () hPutXmpp h msg = do let str = renderXmpp msg debugIO $ "Sending: " ++ str hPutStr h $ toUTF8 str hPutNode :: Handle -> Node -> IO () hPutNode h n = do let str = T.unpack . TL.toStrict . renderMarkup . toMarkup $ n debugIO $ "Sending: " ++ str hPutStr h $ toUTF8 str -- | Render HaXML combinators into string, hacked for XMPP renderXmpp :: Content Posn -> String renderXmpp theXml = case theXml of -- stupid hack for and xml@(CElem (Elem (N "stream:stream") _ _) _) -> (:) '<' $ takeWhile (/= '<') $ tail $ render $ P.content xml xml -> render $ P.content xml --- --- XMPP construction combinators, based on the Text.Html --- stream :: Show a => a -> T.Text -> CFilter i stream typ server = mkElemAttr "stream:stream" [ strAttr "xmlns:stream" "http://etherx.jabber.org/streams" , strAttr "xml:language" "en" , strAttr "version" "1.0" , strAttr "to" $ T.unpack server , strAttr "xmlns" (show typ) ] [ mkElemAttr "" [] [] ] -- TODO: to use hamlet here, we shoud be able to render non-closing tag like `` -- but hamlet autho close tags and i see no ways to control it -- head [xml| -- -- streamEnd :: CFilter i streamEnd = mkElemAttr "/stream:stream" [] [mkElemAttr "" [] []] --- --- Predefined XMPP attributes --- to :: String -> (String, CFilter i) to = strAttr "to"