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

{- |
   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]

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