    -- ------------------------------------------------------------

    {- |
       Module     : Text.XML.HXT.Parser.XmlDTDTokenParser
       Copyright  : Copyright (C) 2005 Uwe Schmidt
       License    : MIT

       Maintainer : Uwe Schmidt (uwe@fh-wedel.de)
       Stability  : experimental
       Portability: portable

       Parsec parser for tokenizing DTD declarations for ELEMENT, ATTLIST, ENTITY and NOTATION

    -}

    -- ------------------------------------------------------------

    module Text.XML.HXT.Parser.XmlDTDTokenParser where

    import           Text.ParserCombinators.Parsec

    import           Text.XML.HXT.DOM.Interface
    import           Text.XML.HXT.DOM.XmlNode               ( mkDTDElem'
                                                            , mkText'
                                                            )
    import qualified Text.XML.HXT.Parser.XmlTokenParser     as XT
    import           Text.XML.HXT.Parser.XmlCharParser      ( XParser )

    -- ------------------------------------------------------------
    --
    -- DTD declaration tokenizer

    dtdDeclTokenizer        :: XParser s XmlTree
    dtdDeclTokenizer :: forall s. XParser s XmlTree
    dtdDeclTokenizer
        = do
          (dcl, al) <- XParser s (DTDElem, Attributes)
    forall s. XParser s (DTDElem, Attributes)
    dtdDeclStart
          content <- many1 dtdToken
          dtdDeclEnd
          return $ mkDTDElem' dcl al content

    dtdDeclStart :: XParser s (DTDElem, Attributes)
    dtdDeclStart :: forall s. XParser s (DTDElem, Attributes)
    dtdDeclStart
        = (XParser s (DTDElem, Attributes)
     -> XParser s (DTDElem, Attributes)
     -> XParser s (DTDElem, Attributes))
    -> [XParser s (DTDElem, Attributes)]
    -> XParser s (DTDElem, Attributes)
    forall a. (a -> a -> a) -> [a] -> a
    forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
    foldr1 XParser s (DTDElem, Attributes)
    -> XParser s (DTDElem, Attributes)
    -> XParser s (DTDElem, Attributes)
    forall s u (m :: * -> *) a.
    ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
    (<|>) ([XParser s (DTDElem, Attributes)]
     -> XParser s (DTDElem, Attributes))
    -> [XParser s (DTDElem, Attributes)]
    -> XParser s (DTDElem, Attributes)
    forall a b. (a -> b) -> a -> b
    $
          (([Char], DTDElem) -> XParser s (DTDElem, Attributes))
    -> [([Char], DTDElem)] -> [XParser s (DTDElem, Attributes)]
    forall a b. (a -> b) -> [a] -> [b]
    map (([Char] -> DTDElem -> XParser s (DTDElem, Attributes))
    -> ([Char], DTDElem) -> XParser s (DTDElem, Attributes)
    forall a b c. (a -> b -> c) -> (a, b) -> c
    uncurry [Char] -> DTDElem -> XParser s (DTDElem, Attributes)
    forall s. [Char] -> DTDElem -> XParser s (DTDElem, Attributes)
    dtdStart) ([([Char], DTDElem)] -> [XParser s (DTDElem, Attributes)])
    -> [([Char], DTDElem)] -> [XParser s (DTDElem, Attributes)]
    forall a b. (a -> b) -> a -> b
    $
                  [ ([Char]
    "ELEMENT",  DTDElem
    ELEMENT )
                  , ([Char]
    "ATTLIST",  DTDElem
    ATTLIST )
                  , ([Char]
    "ENTITY",   DTDElem
    ENTITY  )
                  , ([Char]
    "NOTATION", DTDElem
    NOTATION)
                  ]
        where
        dtdStart    :: String -> DTDElem -> XParser s (DTDElem, Attributes)
        dtdStart :: forall s. [Char] -> DTDElem -> XParser s (DTDElem, Attributes)
    dtdStart [Char]
    dcl DTDElem
    element
            = GenParser Char (XPState s) (DTDElem, Attributes)
    -> GenParser Char (XPState s) (DTDElem, Attributes)
    forall tok st a. GenParser tok st a -> GenParser tok st a
    try ( do
                    _ <- [Char] -> ParsecT [Char] (XPState s) Identity [Char]
    forall s (m :: * -> *) u.
    Stream s m Char =>
    [Char] -> ParsecT s u m [Char]
    string [Char]
    "<!"
                    _ <- string dcl
                    pos <- getPosition
                    return (element, [ (a_source, sourceName pos)
                                     , (a_line,   show (sourceLine pos))
                                     , (a_column, show (sourceColumn pos))
                                     ]
                           )
                  )

    dtdDeclEnd      :: XParser s ()
    dtdDeclEnd :: forall s. XParser s ()
    dtdDeclEnd
        = do
          _ <- XParser s ()
    forall s. XParser s ()
    XT.gt
          return ()

    dtdToken        :: XParser s XmlTree
    dtdToken :: forall s. XParser s XmlTree
    dtdToken
        = XParser s XmlTree
    forall s. XParser s XmlTree
    dtdChars
          XParser s XmlTree -> XParser s XmlTree -> XParser s XmlTree
    forall s u (m :: * -> *) a.
    ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
    <|>
          XParser s XmlTree
    forall s. XParser s XmlTree
    entityValue
          XParser s XmlTree -> XParser s XmlTree -> XParser s XmlTree
    forall s u (m :: * -> *) a.
    ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
    <|>
          XParser s XmlTree -> XParser s XmlTree
    forall tok st a. GenParser tok st a -> GenParser tok st a
    try XParser s XmlTree
    forall s. XParser s XmlTree
    peReference           -- first try parameter entity ref %xxx;
          XParser s XmlTree -> XParser s XmlTree -> XParser s XmlTree
    forall s u (m :: * -> *) a.
    ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
    <|>
          XParser s XmlTree
    forall s. XParser s XmlTree
    percent                   -- else % may be indicator for parameter entity declaration
          XParser s XmlTree -> [Char] -> XParser s XmlTree
    forall s u (m :: * -> *) a.
    ParsecT s u m a -> [Char] -> ParsecT s u m a
    <?> [Char]
    "DTD token"

    peReference     :: XParser s XmlTree
    peReference :: forall s. XParser s XmlTree
    peReference
        = do
          r <- XParser s [Char]
    forall s. XParser s [Char]
    XT.peReference
          return $! (mkDTDElem' PEREF [(a_peref, r)] [])

    entityValue       :: XParser s XmlTree
    entityValue :: forall s. XParser s XmlTree
    entityValue
        = do
          v <- XParser s [Char]
    forall s. XParser s [Char]
    XT.entityValue
          return $ mkText' v

    dtdChars        :: XParser s XmlTree
    dtdChars :: forall s. XParser s XmlTree
    dtdChars
        = do
          v <- ParsecT [Char] (XPState s) Identity Char
    -> ParsecT [Char] (XPState s) Identity [Char]
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
    many1 ([Char] -> ParsecT [Char] (XPState s) Identity Char
    forall s. [Char] -> XParser s Char
    XT.singleChar [Char]
    "%\"'<>[]")             -- everything except string constants, < and >, [ and ] (for cond sections)
          return $ mkText' v                                -- all illegal chars will be detected later during declaration parsing

    percent         :: XParser s XmlTree
    percent :: forall s. XParser s XmlTree
    percent
        = do
          c <- Char -> ParsecT [Char] (XPState s) Identity Char
    forall s (m :: * -> *) u.
    Stream s m Char =>
    Char -> ParsecT s u m Char
    char Char
    '%'
          return $ mkText' [c]

    -- ------------------------------------------------------------