packages feed

mini 2.1.0.0 → 2.2.0.0

raw patch · 6 files changed

+707/−5 lines, 6 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- Mini.Data.Map: instance Mini.Hash.Class.Hashable a => Mini.Hash.Class.Hashable (Mini.Data.Map.Map k a)
+ Mini.Data.Map: instance (Mini.Hash.Class.Hashable k, Mini.Hash.Class.Hashable a) => Mini.Hash.Class.Hashable (Mini.Data.Map.Map k a)
+ Mini.Hash.Class: instance (Mini.Hash.Class.Hashable a, Mini.Hash.Class.Hashable b) => Mini.Hash.Class.Hashable (Data.Either.Either a b)
+ Mini.Hash.Class: instance (Mini.Hash.Class.Hashable a, Mini.Hash.Class.Hashable b) => Mini.Hash.Class.Hashable (a, b)
+ Mini.Hash.Class: instance Mini.Hash.Class.Hashable a => Mini.Hash.Class.Hashable (GHC.Base.NonEmpty a)
+ Mini.Hash.Class: instance Mini.Hash.Class.Hashable a => Mini.Hash.Class.Hashable (GHC.Maybe.Maybe a)
+ Mini.String.URI: instance Mini.Hash.Class.Hashable Mini.String.URI.Address
+ Mini.String.URI: instance Mini.Hash.Class.Hashable Mini.String.URI.Authority
+ Mini.String.URI: instance Mini.Hash.Class.Hashable Mini.String.URI.Fragment
+ Mini.String.URI: instance Mini.Hash.Class.Hashable Mini.String.URI.Host
+ Mini.String.URI: instance Mini.Hash.Class.Hashable Mini.String.URI.Path
+ Mini.String.URI: instance Mini.Hash.Class.Hashable Mini.String.URI.Port
+ Mini.String.URI: instance Mini.Hash.Class.Hashable Mini.String.URI.Query
+ Mini.String.URI: instance Mini.Hash.Class.Hashable Mini.String.URI.Scheme
+ Mini.String.URI: instance Mini.Hash.Class.Hashable Mini.String.URI.Segment
+ Mini.String.URI: instance Mini.Hash.Class.Hashable Mini.String.URI.URI
+ Mini.String.URI: instance Mini.Hash.Class.Hashable Mini.String.URI.UserInfo
+ Mini.String.URI: instance Mini.Hash.Class.Hashable Mini.String.URI.Version
+ Mini.String.XML: Attributes :: Map Key Value -> Attributes
+ Mini.String.XML: CData :: String -> CData
+ Mini.String.XML: Comment :: String -> Comment
+ Mini.String.XML: Document :: [Misc] -> Element -> [Misc] -> Document
+ Mini.String.XML: EType :: String -> EType
+ Mini.String.XML: Element :: EType -> Attributes -> [Node] -> Element
+ Mini.String.XML: Instruction :: String -> Instruction
+ Mini.String.XML: Key :: String -> Key
+ Mini.String.XML: MiscComment :: Comment -> Misc
+ Mini.String.XML: MiscPI :: PI -> Misc
+ Mini.String.XML: MiscSpace :: Space -> Misc
+ Mini.String.XML: NodeCData :: CData -> Node
+ Mini.String.XML: NodeComment :: Comment -> Node
+ Mini.String.XML: NodeElement :: Element -> Node
+ Mini.String.XML: NodePI :: PI -> Node
+ Mini.String.XML: PI :: Target -> Maybe Instruction -> PI
+ Mini.String.XML: Space :: String -> Space
+ Mini.String.XML: Target :: String -> Target
+ Mini.String.XML: Value :: String -> Value
+ Mini.String.XML: data Document
+ Mini.String.XML: data Element
+ Mini.String.XML: data Misc
+ Mini.String.XML: data Node
+ Mini.String.XML: data PI
+ Mini.String.XML: decode :: forall (m :: Type -> Type). Monad m => ParserT Char m Char
+ Mini.String.XML: document :: forall (m :: Type -> Type). Monad m => ParserT Char m Document
+ Mini.String.XML: encode :: Char -> String
+ Mini.String.XML: instance GHC.Classes.Eq Mini.String.XML.Attributes
+ Mini.String.XML: instance GHC.Classes.Eq Mini.String.XML.CData
+ Mini.String.XML: instance GHC.Classes.Eq Mini.String.XML.Comment
+ Mini.String.XML: instance GHC.Classes.Eq Mini.String.XML.Document
+ Mini.String.XML: instance GHC.Classes.Eq Mini.String.XML.EType
+ Mini.String.XML: instance GHC.Classes.Eq Mini.String.XML.Element
+ Mini.String.XML: instance GHC.Classes.Eq Mini.String.XML.Instruction
+ Mini.String.XML: instance GHC.Classes.Eq Mini.String.XML.Key
+ Mini.String.XML: instance GHC.Classes.Eq Mini.String.XML.Misc
+ Mini.String.XML: instance GHC.Classes.Eq Mini.String.XML.Node
+ Mini.String.XML: instance GHC.Classes.Eq Mini.String.XML.PI
+ Mini.String.XML: instance GHC.Classes.Eq Mini.String.XML.Space
+ Mini.String.XML: instance GHC.Classes.Eq Mini.String.XML.Target
+ Mini.String.XML: instance GHC.Classes.Eq Mini.String.XML.Value
+ Mini.String.XML: instance GHC.Classes.Ord Mini.String.XML.Attributes
+ Mini.String.XML: instance GHC.Classes.Ord Mini.String.XML.CData
+ Mini.String.XML: instance GHC.Classes.Ord Mini.String.XML.Comment
+ Mini.String.XML: instance GHC.Classes.Ord Mini.String.XML.Document
+ Mini.String.XML: instance GHC.Classes.Ord Mini.String.XML.EType
+ Mini.String.XML: instance GHC.Classes.Ord Mini.String.XML.Element
+ Mini.String.XML: instance GHC.Classes.Ord Mini.String.XML.Instruction
+ Mini.String.XML: instance GHC.Classes.Ord Mini.String.XML.Key
+ Mini.String.XML: instance GHC.Classes.Ord Mini.String.XML.Misc
+ Mini.String.XML: instance GHC.Classes.Ord Mini.String.XML.Node
+ Mini.String.XML: instance GHC.Classes.Ord Mini.String.XML.PI
+ Mini.String.XML: instance GHC.Classes.Ord Mini.String.XML.Space
+ Mini.String.XML: instance GHC.Classes.Ord Mini.String.XML.Target
+ Mini.String.XML: instance GHC.Classes.Ord Mini.String.XML.Value
+ Mini.String.XML: instance GHC.Show.Show Mini.String.XML.Attributes
+ Mini.String.XML: instance GHC.Show.Show Mini.String.XML.CData
+ Mini.String.XML: instance GHC.Show.Show Mini.String.XML.Comment
+ Mini.String.XML: instance GHC.Show.Show Mini.String.XML.Document
+ Mini.String.XML: instance GHC.Show.Show Mini.String.XML.EType
+ Mini.String.XML: instance GHC.Show.Show Mini.String.XML.Element
+ Mini.String.XML: instance GHC.Show.Show Mini.String.XML.Instruction
+ Mini.String.XML: instance GHC.Show.Show Mini.String.XML.Key
+ Mini.String.XML: instance GHC.Show.Show Mini.String.XML.Misc
+ Mini.String.XML: instance GHC.Show.Show Mini.String.XML.Node
+ Mini.String.XML: instance GHC.Show.Show Mini.String.XML.PI
+ Mini.String.XML: instance GHC.Show.Show Mini.String.XML.Space
+ Mini.String.XML: instance GHC.Show.Show Mini.String.XML.Target
+ Mini.String.XML: instance GHC.Show.Show Mini.String.XML.Value
+ Mini.String.XML: instance Mini.Hash.Class.Hashable Mini.String.XML.Attributes
+ Mini.String.XML: instance Mini.Hash.Class.Hashable Mini.String.XML.CData
+ Mini.String.XML: instance Mini.Hash.Class.Hashable Mini.String.XML.Comment
+ Mini.String.XML: instance Mini.Hash.Class.Hashable Mini.String.XML.Document
+ Mini.String.XML: instance Mini.Hash.Class.Hashable Mini.String.XML.EType
+ Mini.String.XML: instance Mini.Hash.Class.Hashable Mini.String.XML.Element
+ Mini.String.XML: instance Mini.Hash.Class.Hashable Mini.String.XML.Instruction
+ Mini.String.XML: instance Mini.Hash.Class.Hashable Mini.String.XML.Key
+ Mini.String.XML: instance Mini.Hash.Class.Hashable Mini.String.XML.Misc
+ Mini.String.XML: instance Mini.Hash.Class.Hashable Mini.String.XML.Node
+ Mini.String.XML: instance Mini.Hash.Class.Hashable Mini.String.XML.PI
+ Mini.String.XML: instance Mini.Hash.Class.Hashable Mini.String.XML.Space
+ Mini.String.XML: instance Mini.Hash.Class.Hashable Mini.String.XML.Target
+ Mini.String.XML: instance Mini.Hash.Class.Hashable Mini.String.XML.Value
+ Mini.String.XML: newtype Attributes
+ Mini.String.XML: newtype CData
+ Mini.String.XML: newtype Comment
+ Mini.String.XML: newtype EType
+ Mini.String.XML: newtype Instruction
+ Mini.String.XML: newtype Key
+ Mini.String.XML: newtype Space
+ Mini.String.XML: newtype Target
+ Mini.String.XML: newtype Value

Files

CHANGELOG.md view
@@ -4,6 +4,19 @@ (!) Breaking change ``` +2.2.0.0 [2026-09-30]+--------------------+```+    Create Mini.String.XML+    hash(class): Add Hashable instance for pairs+    hash(class): Add Hashable instance for Maybe+    hash(class): Add Hashable instance for Either+    hash(class): Add Hashable instance for NonEmpty+    string(uri): Format+    string(uri): Add Hashable instances+(!) data(map): Fix Hashable instance+```+ 2.1.0.0 [2026-09-07] -------------------- ```
mini.cabal view
@@ -1,6 +1,6 @@ cabal-version:      3.0 name:               mini-version:            2.1.0.0+version:            2.2.0.0 license:            MIT license-file:       LICENSE author:             Victor Wallsten <victor.wallsten@protonmail.com>@@ -49,6 +49,7 @@     Mini.Random.SplitMix     Mini.String.URI     Mini.String.UTF8+    Mini.String.XML     Mini.Transformers.Class     Mini.Transformers.Either     Mini.Transformers.Maybe
src/Mini/Data/Map.hs view
@@ -105,7 +105,6 @@   Show,   Traversable,   compare,-  concatMap,   const,   error,   flip,@@ -181,8 +180,8 @@ instance (Ord k) => Monoid (Map k a) where   mempty = E -instance (Hashable a) => Hashable (Map k a) where-  toBytes = concatMap toBytes+instance (Hashable k, Hashable a) => Hashable (Map k a) where+  toBytes = foldrWith (\k a b -> toBytes k <> toBytes a <> b) []  -- | Primitive recursion on maps (internally structured as trees) map
src/Mini/Hash/Class.hs view
@@ -24,6 +24,11 @@   Int64,   Int8,  )+import Data.List.NonEmpty (+  NonEmpty (+    (:|)+  ),+ ) import Data.Word (   Word,   Word16,@@ -40,8 +45,16 @@ import Prelude (   Bool,   Char,+  Either (+    Left,+    Right+  ),   Enum,   Integral,+  Maybe (+    Just,+    Nothing+  ),   concatMap,   div,   fmap,@@ -52,6 +65,7 @@   take,   ($),   (.),+  (<>),  )  -- Classes@@ -105,8 +119,22 @@ instance Hashable Word64 where   toBytes = finiteBitsIntegralToBytes +instance (Hashable a) => Hashable (Maybe a) where+  toBytes Nothing = []+  toBytes (Just a) = toBytes a++instance (Hashable a, Hashable b) => Hashable (Either a b) where+  toBytes (Left a) = toBytes a+  toBytes (Right b) = toBytes b++instance (Hashable a, Hashable b) => Hashable (a, b) where+  toBytes (a, b) = toBytes a <> toBytes b+ instance (Hashable a) => Hashable [a] where   toBytes = concatMap toBytes++instance (Hashable a) => Hashable (NonEmpty a) where+  toBytes (a :| as) = toBytes a <> toBytes as  instance (Hashable a) => Hashable (Array i a) where   toBytes = concatMap toBytes
src/Mini/String/URI.hs view
@@ -96,6 +96,10 @@ import Data.Word (   Word8,  )+import Mini.Hash.Class (+  Hashable,+  toBytes,+ ) import qualified Mini.String.UTF8 as UTF8 (   decode,   encode,@@ -177,6 +181,14 @@       <> maybe "" (("?" <>) . show) q       <> maybe "" (("#" <>) . show) f +instance Hashable URI where+  toBytes (URI s a p q f) =+    toBytes s+      <> toBytes a+      <> toBytes p+      <> toBytes q+      <> toBytes f+ -- | The authority component of a URI data Authority   = -- | without the leading @"\/\/"@@@ -189,6 +201,9 @@       <> show h       <> maybe "" ((":" <>) . show) p +instance Hashable Authority where+  toBytes (Authority u h p) = toBytes u <> toBytes h <> toBytes p+ -- | The host component of an authority data Host   = IPv4 Address@@ -203,6 +218,12 @@   show (IPvF v a) = "v" <> show v <> "." <> show a   show (RegName a) = show a +instance Hashable Host where+  toBytes (IPv4 a) = toBytes a+  toBytes (IPv6 a) = toBytes a+  toBytes (IPvF v a) = toBytes v <> toBytes a+  toBytes (RegName a) = toBytes a+ -- | The path component of a URI data Path   = Path@@ -219,6 +240,9 @@       <> intercalate "/" (fmap show segs)       <> bool "" "/" t +instance Hashable Path where+  toBytes (Path l segs t) = toBytes l <> toBytes segs <> toBytes t+ -- | The address of a host newtype Address = Address String   deriving (Eq, Ord)@@ -226,6 +250,9 @@ instance Show Address where   show (Address a) = a +instance Hashable Address where+  toBytes (Address a) = toBytes a+ -- | The fragment component of a URI newtype Fragment   = -- | without the leading @"#"@@@ -235,6 +262,9 @@ instance Show Fragment where   show (Fragment f) = f +instance Hashable Fragment where+  toBytes (Fragment f) = toBytes f+ -- | The port component of an authority newtype Port   = -- | without the leading @":"@@@ -244,6 +274,9 @@ instance Show Port where   show (Port p) = p +instance Hashable Port where+  toBytes (Port p) = toBytes p+ -- | The query component of a URI newtype Query   = -- | without the leading @"?"@@@ -253,6 +286,9 @@ instance Show Query where   show (Query q) = q +instance Hashable Query where+  toBytes (Query q) = toBytes q+ -- | The scheme component of a URI newtype Scheme   = -- | without the trailing @":"@@@ -262,6 +298,9 @@ instance Show Scheme where   show (Scheme s) = s +instance Hashable Scheme where+  toBytes (Scheme s) = toBytes s+ -- | A segment of a path newtype Segment   = -- | without any delimiting @"\/"@@@ -271,6 +310,9 @@ instance Show Segment where   show (Segment s) = s +instance Hashable Segment where+  toBytes (Segment s) = toBytes s+ -- | The userinfo component of an authority newtype UserInfo   = -- | without the trailing @"\@"@@@ -280,6 +322,9 @@ instance Show UserInfo where   show (UserInfo u) = u +instance Hashable UserInfo where+  toBytes (UserInfo u) = toBytes u+ -- | The version of a future IP newtype Version   = -- | without the leading @"v"@ and trailing @"."@@@ -289,6 +334,9 @@ instance Show Version where   show (Version v) = v +instance Hashable Version where+  toBytes (Version v) = toBytes v+ -- Parsers  -- | Parse an absolute URI (a generic URI without a fragment)@@ -342,7 +390,7 @@ encode :: Char -> String encode = concatMap (('%' :) . twoDigitHex) . UTF8.encode  where-  twoDigitHex w = [hex $ w `shiftR` 4, hex $ w .&. 0x0f]+  twoDigitHex w = [hex $ w `shiftR` 4, hex $ w .&. 0x0F]   hex n = toEnum . fromEnum . (+ n) . bool 0x37 0x30 $ n <= 9  -- | Parse a percent-encoded octet sequence in UTF-8 format into a character
+ src/Mini/String/XML.hs view
@@ -0,0 +1,613 @@+-- | XML 1.0 (Fifth Edition): <https://www.w3.org/TR/2008/REC-xml-20081126>+module Mini.String.XML (+  -- * Types+  Document (+    Document+  ),+  Element (+    Element+  ),+  Node (+    NodeCData,+    NodeComment,+    NodeElement,+    NodePI+  ),+  Misc (+    MiscComment,+    MiscPI,+    MiscSpace+  ),+  PI (+    PI+  ),+  Attributes (+    Attributes+  ),+  EType (+    EType+  ),+  CData (+    CData+  ),+  Key (+    Key+  ),+  Value (+    Value+  ),+  Comment (+    Comment+  ),+  Target (+    Target+  ),+  Instruction (+    Instruction+  ),+  Space (+    Space+  ),++  -- * Parsers+  document,++  -- * Encoding+  encode,+  decode,+) where++import Control.Applicative (+  empty,+  many,+  optional,+  some,+  (<|>),+ )+import Data.Bits (+  shiftL,+ )+import Data.Bool (+  bool,+ )+import Data.Char (+  digitToInt,+ )+import Mini.Data.Map (+  Map,+ )+import qualified Mini.Data.Map as Map (+  foldrWith,+  insert,+  member,+ )+import Mini.Hash.Class (+  Hashable,+  toBytes,+ )+import Mini.Transformers.Parser (+  ParserT,+  accept,+  noneOf,+  oneOf,+  reject,+  sat,+  string,+  symbol,+  till,+ )+import Prelude (+  Char,+  Eq,+  Maybe,+  Monad,+  Ord,+  Show,+  String,+  concatMap,+  dropWhile,+  foldl,+  fromEnum,+  maybe,+  mempty,+  null,+  pure,+  show,+  toEnum,+  ($),+  (&&),+  (*),+  (*>),+  (+),+  (.),+  (<$),+  (<$>),+  (<*),+  (<*>),+  (<=),+  (<>),+  (==),+  (>=),+  (>>=),+  (||),+ )++-- Types++-- | An XML document+data Document = Document [Misc] Element [Misc]+  deriving (Eq, Ord)++instance Show Document where+  show (Document ms e ms') = concatMap show ms <> show e <> concatMap show ms'++instance Hashable Document where+  toBytes = toBytes . show++-- | An element+data Element = Element EType Attributes [Node]+  deriving (Eq, Ord)++instance Show Element where+  show (Element t as ns) =+    "<"+      <> show t+      <> show as+      <> bool+        ( ">"+            <> concatMap show ns+            <> "</"+            <> show t+            <> ">"+        )+        ("/>")+        (null ns)++instance Hashable Element where+  toBytes = toBytes . show++-- | An element node+data Node+  = NodeCData CData+  | NodeComment Comment+  | NodeElement Element+  | NodePI PI+  deriving (Eq, Ord)++instance Show Node where+  show (NodeCData cd) = show cd+  show (NodeComment c) = show c+  show (NodeElement e) = show e+  show (NodePI p) = show p++instance Hashable Node where+  toBytes = toBytes . show++-- | A miscellaneous component+data Misc+  = MiscComment Comment+  | MiscPI PI+  | MiscSpace Space+  deriving (Eq, Ord)++instance Show Misc where+  show (MiscComment c) = show c+  show (MiscPI p) = show p+  show (MiscSpace s) = show s++instance Hashable Misc where+  toBytes = toBytes . show++-- | Element attributes+newtype Attributes = Attributes (Map Key Value)+  deriving (Eq, Ord)++-- | Values are shown within double quotes+instance Show Attributes where+  show (Attributes as) =+    Map.foldrWith+      (\k v b -> " " <> show k <> "=\"" <> show v <> "\"" <> b)+      []+      as++instance Hashable Attributes where+  toBytes = toBytes . show++-- | A processing instruction+data PI = PI Target (Maybe Instruction)+  deriving (Eq, Ord)++instance Show PI where+  show (PI t i) = "<?" <> show t <> maybe "" ((' ' :) . show) i <> "?>"++instance Hashable PI where+  toBytes = toBytes . show++-- | An element type+newtype EType = EType String+  deriving (Eq, Ord)++instance Show EType where+  show (EType t) = t++instance Hashable EType where+  toBytes = toBytes . show++-- | Character data+newtype CData = CData String+  deriving (Eq, Ord)++-- | Encodes @<&@ into predefined entities+instance Show CData where+  show (CData cd) = concatMap enc cd+   where+    enc '&' = "&amp;"+    enc '<' = "&lt;"+    enc c = [c]++instance Hashable CData where+  toBytes = toBytes . show++-- | An attribute key+newtype Key = Key String+  deriving (Eq, Ord)++instance Show Key where+  show (Key k) = k++instance Hashable Key where+  toBytes = toBytes . show++-- | An attribute value+newtype Value+  = -- | without the surrounding quotes+    Value String+  deriving (Eq, Ord)++-- | Encodes @<&"@ into predefined entities+instance Show Value where+  show (Value v) = concatMap enc v+   where+    enc '&' = "&amp;"+    enc '<' = "&lt;"+    enc '"' = "&quot;"+    enc c = [c]++instance Hashable Value where+  toBytes = toBytes . show++-- | A comment+newtype Comment+  = -- | without the leading @"<!--"@ and trailing @"-->"@+    Comment String+  deriving (Eq, Ord)++instance Show Comment where+  show (Comment c) = "<!--" <> c <> "-->"++instance Hashable Comment where+  toBytes = toBytes . show++-- | A PI target+newtype Target = Target String+  deriving (Eq, Ord)++instance Show Target where+  show (Target t) = t++instance Hashable Target where+  toBytes = toBytes . show++-- | A PI instruction+newtype Instruction = Instruction String+  deriving (Eq, Ord)++instance Show Instruction where+  show (Instruction i) = i++instance Hashable Instruction where+  toBytes = toBytes . show++-- | Miscellaneous whitespace+newtype Space = Space String+  deriving (Eq, Ord)++instance Show Space where+  show (Space s) = s++instance Hashable Space where+  toBytes = toBytes . show++-- Parsers++-- | Parse an XML document.+--+-- Enforces well-formedness constraints /Element Type Match/, /Unique Att Spec/,+-- and /Legal Character/.+--+-- Rejects documents containing a document type declaration or non-predefined+-- entity references.+--+-- Normalizes line breaks according to section 2.11 /End-of-Line Handling/.+--+-- Decodes predefined entity references and numeric references.+document :: (Monad m) => ParserT Char m Document+document = Document <$> prolog <*> element <*> many misc++-- Encoding++-- | Turn a character into a predefined or decimal reference+encode :: Char -> String+encode '&' = "&amp;"+encode '<' = "&lt;"+encode '>' = "&gt;"+encode '"' = "&quot;"+encode '\'' = "&apos;"+encode c = "&#" <> show (fromEnum c) <> ";"++-- | Parse a predefined or numeric reference into a legal character+decode :: (Monad m) => ParserT Char m Char+decode = symbol '&' *> (entityRef <|> charRef) <* symbol ';'+ where+  entityRef =+    ('&' <$ string "amp")+      <|> ('<' <$ string "lt")+      <|> ('>' <$ string "gt")+      <|> ('"' <$ string "quot")+      <|> ('\'' <$ string "apos")+  charRef = symbol '#' *> (dec <|> hex)+  dec =+    some (oneOf ['0' .. '9'])+      >>= ( \n ->+              bool+                empty+                (pure $ toEnum n)+                $ isLegal n+          )+        . foldl (\b a -> digitToInt a + b * 10) 0+        . dropWhile (== '0')+  hex =+    (symbol 'x' *> some (oneOf $ ['0' .. '9'] <> ['a' .. 'f'] <> ['A' .. 'F']))+      >>= ( \n ->+              bool+                empty+                (pure $ toEnum n)+                $ isLegal n+          )+        . foldl (\b a -> digitToInt a + (b `shiftL` 4)) 0+        . dropWhile (== '0')+  isLegal =+    ( \n ->+        n == 0x9+          || n == 0xA+          || n == 0xD+          || n >= 0x20 && n <= 0xD7FF+          || n >= 0xE000 && n <= 0xFFFD+          || n >= 0x10000 && n <= 0x10FFFF+    )+      . fromEnum++-- Helpers++char :: (Monad m) => ParserT Char m Char+char =+  ('\n' <$ string "\r\n")+    <|> ('\n' <$ symbol '\r')+    <|> ( sat $+            ( \n ->+                n == 0x9+                  || n == 0xA+                  || n >= 0x20 && n <= 0xD7FF+                  || n >= 0xE000 && n <= 0xFFFD+                  || n >= 0x10000 && n <= 0x10FFFF+            )+              . fromEnum+        )++space :: (Monad m) => ParserT Char m Space+space =+  Space+    <$> ( some . sat $+            (\n -> n == 0x20 || n == 0x9 || n == 0xD || n == 0xA) . fromEnum+        )++nameStartChar :: (Monad m) => ParserT Char m Char+nameStartChar =+  symbol ':'+    <|> oneOf ['A' .. 'Z']+    <|> symbol '_'+    <|> oneOf ['a' .. 'z']+    <|> sat+      ( ( \n ->+            n >= 0xC0 && n <= 0xD6+              || n >= 0xD8 && n <= 0xF6+              || n >= 0xF8 && n <= 0x2FF+              || n >= 0x370 && n <= 0x37D+              || n >= 0x37F && n <= 0x1FFF+              || n >= 0x200C && n <= 0x200D+              || n >= 0x2070 && n <= 0x218F+              || n >= 0x2C00 && n <= 0x2FEF+              || n >= 0x3001 && n <= 0xD7FF+              || n >= 0xF900 && n <= 0xFDCF+              || n >= 0xFDF0 && n <= 0xFFFD+              || n >= 0x10000 && n <= 0xEFFFF+        )+          . fromEnum+      )++nameChar :: (Monad m) => ParserT Char m Char+nameChar =+  nameStartChar+    <|> symbol '-'+    <|> symbol '.'+    <|> oneOf ['0' .. '9']+    <|> sat+      ( ( \n ->+            n == 0xB7+              || n >= 0x0300 && n <= 0x036F+              || n >= 0x203F && n <= 0x2040+        )+          . fromEnum+      )++name :: (Monad m) => ParserT Char m String+name = (:) <$> nameStartChar <*> many nameChar++value :: (Monad m) => ParserT Char m Value+value =+  Value+    <$> ( (doubleQuoted $ many (noneOf "<&\"" <|> decode))+            <|> (singleQuoted $ many (noneOf "<&'" <|> decode))+        )++cData :: (Monad m) => ParserT Char m CData+cData = CData <$> (some $ reject (string "]]>") *> exclude "<&")++comment :: (Monad m) => ParserT Char m Comment+comment =+  Comment+    <$> ( string "<!--"+            *> many (reject (string "--") *> char)+            <* string "-->"+        )++pi :: (Monad m) => ParserT Char m PI+pi =+  PI+    <$> (string "<?" *> target)+    <*> optional+      (Instruction <$> (space *> many (reject (string "?>") *> char)))+    <* string "?>"++target :: (Monad m) => ParserT Char m Target+target = Target <$> (reject (oneOf "Xx" *> oneOf "Mm" *> oneOf "Ll") *> name)++cdSect :: (Monad m) => ParserT Char m CData+cdSect = CData <$> (string "<![CDATA[" *> (char `till` string "]]>"))++-- NOTE: rejecting doctypedecl+prolog :: (Monad m) => ParserT Char m [Misc]+prolog = optional xmlDecl *> many misc++xmlDecl :: (Monad m) => ParserT Char m ()+xmlDecl =+  ()+    <$ ( string "<?xml"+           *> versionInfo+           *> optional encodingDecl+           *> optional sdDecl+           *> optional space+           *> string "?>"+       )++versionInfo :: (Monad m) => ParserT Char m ()+versionInfo =+  ()+    <$ ( space+           *> string "version"+           *> eq+           *> (doubleQuoted versionNum <|> singleQuoted versionNum)+       )++eq :: (Monad m) => ParserT Char m Char+eq = optional space *> symbol '=' <* optional space++versionNum :: (Monad m) => ParserT Char m ()+versionNum = () <$ (string "1." *> some (oneOf ['0' .. '9']))++misc :: (Monad m) => ParserT Char m Misc+misc =+  (MiscComment <$> comment)+    <|> (MiscPI <$> pi)+    <|> (MiscSpace <$> space)++sdDecl :: (Monad m) => ParserT Char m ()+sdDecl =+  ()+    <$ ( space+           *> string "standalone"+           *> eq+           *> ( doubleQuoted (string "yes" <|> string "no")+                  <|> singleQuoted (string "yes" <|> string "no")+              )+       )++element :: (Monad m) => ParserT Char m Element+element = do+  t <- symbol '<' *> (EType <$> name)+  as <- attributes+  (Element t as [] <$ string "/>")+    <|> ( do+            ns <- symbol '>' *> nodes+            t' <-+              string "</"+                *> (EType <$> name)+                <* optional space+                <* symbol '>'+            bool+              empty+              (pure $ Element t as ns)+              $ t == t'+        )++attributes :: (Monad m) => ParserT Char m Attributes+attributes = (many (space *> attribute) <* optional space) >>= go mempty+ where+  go t ((k, v) : as) = bool (go (Map.insert k v t) as) empty $ k `Map.member` t+  go t [] = pure $ Attributes t++attribute :: (Monad m) => ParserT Char m (Key, Value)+attribute = (,) <$> (Key <$> name) <* eq <*> value++nodes :: (Monad m) => ParserT Char m [Node]+nodes = go <$> many node+ where+  go (NodeCData (CData cd) : NodeCData (CData cd') : rest) =+    NodeCData (CData $ cd <> cd') : go rest+  go (n : ns) = n : go ns+  go [] = []++node :: (Monad m) => ParserT Char m Node+node =+  ( NodeCData+      <$> ( cData+              <|> (CData <$> (pure <$> decode))+              <|> cdSect+          )+  )+    <|> (NodeComment <$> comment)+    <|> (NodeElement <$> element)+    <|> (NodePI <$> pi)++encodingDecl :: (Monad m) => ParserT Char m ()+encodingDecl =+  ()+    <$ ( space+           *> string "encoding"+           *> eq+           *> (doubleQuoted encName <|> singleQuoted encName)+       )++encName :: (Monad m) => ParserT Char m ()+encName =+  ()+    <$ ( (:)+           <$> oneOf (['A' .. 'Z'] <> ['a' .. 'z'])+           <*> many+             ( oneOf+                 ( ['A' .. 'Z']+                     <> ['a' .. 'z']+                     <> ['0' .. '9']+                     <> "._-"+                 )+             )+       )++doubleQuoted :: (Monad m) => ParserT Char m a -> ParserT Char m a+doubleQuoted p = symbol '"' *> p <* symbol '"'++singleQuoted :: (Monad m) => ParserT Char m a -> ParserT Char m a+singleQuoted p = symbol '\'' *> p <* symbol '\''++exclude :: (Monad m) => String -> ParserT Char m Char+exclude str = accept (noneOf str) *> char