HAppS-Server-0.9.2: src/HAppS/Server/MinHaXML.hs
{-# LANGUAGE TemplateHaskell, FlexibleInstances,
OverlappingInstances, UndecidableInstances, TypeSynonymInstances #-}
module HAppS.Server.MinHaXML where
-- Copyright (C) 2005 HAppS.org. All Rights Reserved.
import Text.XML.HaXml.Types as Types
import Text.XML.HaXml.Escape
import Text.XML.HaXml.Pretty as Pretty
import Text.XML.HaXml.Verbatim as Verbatim
import HAppS.Util.Common
import Data.Maybe
import System.Time
import HAppS.Data.Xml as Xml
import HAppS.Data.Xml.HaXml
type StyleURL=String
data StyleSheet = NoStyle
| CSS {styleURL::StyleURL}
| XSL {styleURL::StyleURL} deriving (Read,Show)
hasStyleURL NoStyle = False
hasStyleURL _ = True
type Element = Types.Element
isCSS (CSS _)=True
isCSS _ = False
isXSL = not.isCSS
t=textElem
l=listElem
e=emptyElem
(</<)=l
(<>)=t
xmlElem f = \name attrs val -> xmlelem name attrs (f val)
where
xmlelem name attrs = Types.Elem name (map (uncurry attr) attrs)
attr name val= (name,AttValue [Left val])
textElem = xmlElem (return.CString True)
emptyElem = \n a->xmlElem id n a []
listElem = xmlElem $ map CElem
cdataElem = CString False
--simpleDoc xsl root = show $ document $
-- Document (simpleProlog xsl) [] $ xmlEscape stdXmlEscaper root
simpleDocOld xsl = show . document .
flip (Document (simpleProlog xsl) []) [] . xmlStdEscape
simpleDoc style elem = ("<?xml version='1.0' encoding='UTF-8' ?>\n"++
if hasStyleURL style then pi else "") ++
(verbatim $ xmlStdEscape elem)
where typeText=if isCSS style then "text/css" else "text/xsl"
pi= "<?xml-stylesheet type=\""++ typeText ++
"\" href=\""++styleURL style++"\" ?>\n"
simpleDoc' style elem = (if hasStyleURL style then pi else "") ++
(verbatim $ xmlStdEscape elem)
where typeText=if isCSS style then "text/css" else "text/xsl"
pi= "<?xml-stylesheet type=\""++ typeText ++
"\" href=\""++styleURL style++"\" ?>\n"
xmlEscaper=stdXmlEscaper
xmlStdEscape = xmlEscape stdXmlEscaper
verbim x =verbatim x
simpleProlog style =
Prolog
(Just (XMLDecl "1.0"
(Just $ EncodingDecl "UTF-8")
Nothing -- (Just True) -- standalone declaration
))
[] Nothing -- (Just docType)
(if url=="" then [] else [pi])
where
pi = PI ("xml-stylesheet", "type=\""++typeText++"\" href=\""++url++"\"")
typeText = if isCSS style then "text/css" else "text/xsl"
url=if hasStyleURL style then styleURL style else ""
nonEmpty name val = if val=="" then Nothing
else Just $ textElem name [] val
getRoot (Document _ _ root _) = root
--toXML .< "App" attrs ./>
--toXML .< "App" attrs .> []
data XML a = XML StyleSheet a
--class HasStyle x where getStyle::x->StyleSheet
class ToElement x where toElement::x->Types.Element
{--
instance (ToElement x) => ToElement (Maybe x) where
toElement = maybe (emptyElem "Nothing" [])
(\x->listElem "Just" [] [toElement x])
--}
instance (ToElement x) => ToElement (Maybe x) where
toElement = maybe (emptyElem "Nothing" []) toElement
instance ToElement String where toElement s = textElem "String" [] s
instance ToElement Types.Element where toElement = id
instance ToElement CalendarTime where
toElement = recToEl "CalendarTime"
[attrFS "year" ctYear
,attrFS "month" (fromEnum.ctMonth)
,attrFS "day" ctDay
,attrFS "hour" ctHour
,attrFS "min" ctMin
,attrFS "sec" ctSec
,attrFS "time" time
] []
where time ct = epochPico ct
instance ToElement Int where toElement = toElement . show
instance ToElement Integer where toElement = toElement . show
instance ToElement Float where toElement = toElement . show
instance ToElement Double where toElement = toElement . show
instance (Xml a) => ToElement a where
toElement = un . head . map toHaXml . toXml
where
un (CElem el) = el
--let TOD sec pico = toClockTime ct in sec*1000
--class (Show x)=>ToAttr x where toAttr::x->String; toAttr=show
wrapElem tag x= listElem tag [] [toElement x]
elF tag f = wrapElem tag.f
-- label !<=! field = wrapField label field
attrF name f rec = (name,quoteEsc $ f rec)
attrFS name f rec = (name,quoteEsc $ show $ f rec)
attrFMb r name f = maybe ("","") (\x->(name,quoteEsc $ r x)) . f
--attrFMb r name f list= maybe list ((attrF name (r . fromJust . f)):list)
--(\x->(name,quoteEsc $ r x)) . f
--(name,quoteEsc $ show $ f rec)
quoteEsc [] = []
quoteEsc ('"':list) = """ ++ quoteEsc list
quoteEsc (x:xs) = x:quoteEsc xs
--hexToInt
--hexToAlphaNum [] = []
--hexToAlphaNum (x:xs) =
--attrShowF name f rec = (name,show $ f rec)
--quotescape \\ and " \"
recToEl name attrs els rec = listElem name attrs' (revmap rec els)
where
attrs' = filter (\ (x,_)->not $ null x) (revmap rec attrs)
listToEl name attrs = listElem name attrs . map toElement
--listToEl list = listElem "List" [] $ map toElement list
--instance ToElement NELL where toElement s = e "x" []
--data NELL = NELL
toAttrs x = map (\ (s,f)->(s, f x))
{--
toElement rules:
1. if the attr is an instance of toElement then it is a child.
2. if it named and is type string then it is shown that way.
3. if it named and has non-string type then use show on the value.
4. if the attributes are not named then use the type as the label and
make the text child be a show of the object.
--}
newtype ElString = ElString {elString::String} deriving (Eq,Ord,Read,Show)
{--
store thing as XML or do multiple parse passes?
--}
{--
elstring
--}