1 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
2 {-# LANGUAGE OverloadedStrings #-}
3 {-# OPTIONS_GHC -fno-warn-orphans #-}
6 import Control.Applicative (Applicative(..))
8 import Data.Default.Class (Default(..))
9 import Data.Eq (Eq(..))
10 import Data.Function (($), (.), on)
12 import Data.Hashable (Hashable(..))
13 import Data.Map.Strict (Map)
14 import Data.Maybe (Maybe(..))
15 import Data.Monoid (Monoid(..))
16 import Data.Ord (Ord(..))
17 import Data.Semigroup (Semigroup(..))
18 import Data.Sequence (Seq)
19 import Data.String (IsString(..))
20 import Data.Text (Text)
21 import Data.TreeSeq.Strict (Tree)
22 import Prelude (error, pred, succ)
23 import Text.Show (Show(..), showsPrec, showChar, showString)
24 import qualified Data.List as List
25 import qualified Data.Sequence as Seq
26 import qualified Data.Text.Lazy as TL
33 type XML = Tree (Cell XmlNode)
39 { xmlNamePrefix :: TL.Text
40 , xmlNameSpace :: TL.Text
41 , xmlNameLocal :: TL.Text
43 instance Show XmlName where
44 showsPrec _p XmlName{xmlNameSpace="", ..} =
45 showString (TL.unpack xmlNameLocal)
46 showsPrec _p XmlName{..} =
47 if TL.null xmlNameSpace
48 then showString (TL.unpack xmlNameLocal)
51 showString (TL.unpack xmlNameSpace) .
53 showString (TL.unpack xmlNameLocal)
54 instance Eq XmlName where
55 XmlName _ sx lx == XmlName _ sy ly = sx == sy && lx == ly
56 instance Ord XmlName where
57 XmlName _ sx lx `compare` XmlName _ sy ly = compare sx sy <> compare lx ly
58 instance IsString XmlName where
59 fromString "" = XmlName "" "" ""
60 fromString full@('{':rest) =
61 case List.break (== '}') rest of
62 (_, "") -> error ("Invalid Clark notation: " <> show full)
63 (ns, local) -> XmlName "" (TL.pack ns) (TL.pack $ List.drop 1 local)
64 fromString local = XmlName "" "" (TL.pack local)
65 instance Pretty XmlName
66 instance Hashable XmlName where
67 hashWithSalt s XmlName{..} =
68 s`hashWithSalt`xmlNamePrefix
69 `hashWithSalt`xmlNameSpace
70 `hashWithSalt`xmlNameLocal
72 xmlLocalName :: TL.Text -> XmlName
73 xmlLocalName = XmlName "" ""
78 | XmlAttr XmlName TL.Text
81 deriving (Eq,Ord,Show)
82 instance Pretty XmlNode
85 type XmlAttrs = Map XmlName (Cell TL.Text) -- TODO: HashMap
93 { xmlPos_Ancestors :: XmlPosPath
94 , xmlPos_AncestorsWithFigureNames :: XmlPosPath
95 , xmlPos_PrecedingSiblings :: Map XmlName Rank -- TODO: HashMap
97 instance Ord XmlPos where
98 compare = compare`on`xmlPos_Ancestors
99 -- | Return only the hash on 'xmlPos_Ancestors',
100 -- which is unique because 'XmlPosPath'
101 -- includes the 'Rank' of each 'XmlNode'.
102 instance Hashable XmlPos where
103 hashWithSalt s XmlPos{..} =
104 s`hashWithSalt`xmlPos_Ancestors
105 instance Default XmlPos where
106 def = XmlPos mempty mempty mempty
108 -- ** Type 'XmlPosPath'
109 type XmlPosPath = Seq (XmlName,Rank)
112 dropSelfPosPath :: XmlPosPath -> Maybe XmlPosPath
115 Seq.EmptyR -> Nothing
116 ls Seq.:> _ -> Just ls
119 newtype Nat = Nat { unNat :: Int }
120 deriving (Eq,Ord,Hashable)
121 instance Show Nat where
122 showsPrec p = showsPrec p . unNat
123 instance Default Nat where
126 succNat :: Nat -> Nat
127 succNat (Nat n) = Nat $ succ n
129 predNat :: Nat -> Maybe Nat
130 predNat (Nat n) | n <= 0 = Nothing
131 | otherwise = Just $ Nat $ pred n
134 newtype Nat1 = Nat1 { unNat1 :: Int }
135 deriving (Eq,Ord,Hashable)
136 instance Show Nat1 where
137 showsPrec p = showsPrec p . unNat1
138 instance Default Nat1 where
141 succNat1 :: Nat1 -> Nat1
142 succNat1 (Nat1 n) = Nat1 $ succ n
143 predNat1 :: Nat1 -> Maybe Nat1
144 predNat1 (Nat1 n) | n <= 1 = Nothing
145 | otherwise = Just $ Nat1 $ pred n
148 newtype Ident = Ident { unIdent :: TL.Text }
149 deriving (Eq,Ord,Show,Default,IsString,Semigroup,Monoid,Hashable)
152 newtype URL = URL { unURL :: TL.Text }
153 deriving (Eq,Ord,Default,Hashable)
154 instance Show URL where
155 showsPrec p = showsPrec p . unURL
156 instance Semigroup URL where
160 newtype Path = Path TL.Text
161 deriving (Eq,Show,Default)
165 = MayText { unMayText :: TL.Text }
166 deriving (Eq,Ord,Default)
167 instance Show MayText where
168 showsPrec p = showsPrec p . unMayText
169 instance Semigroup MayText where
174 whenMayText :: Applicative m => MayText -> (MayText -> m ()) -> m ()
175 whenMayText (MayText "") _f = pure ()
176 whenMayText t f = f t
178 instance Default Text where
180 instance Default TL.Text where