module Text.XML.HXT.Parser.XmlCharParser
( XParser
, SimpleXParser
, XPState(..)
, withNormNewline
, withoutNormNewline
, xmlChar
, xmlNameChar
, xmlNameStartChar
, xmlNCNameChar
, xmlNCNameStartChar
, xmlLetter
, xmlSpaceChar
, xmlCRLFChar
)
where
import Data.Char.Properties.XMLCharProps ( isXmlCharCR
, isXmlNameChar
, isXmlNameStartChar
, isXmlNCNameChar
, isXmlNCNameStartChar
, isXmlLetter
, isXmlSpaceCharCR
)
import Data.String.Unicode
import Text.ParserCombinators.Parsec
type XParser s a = GenParser Char (XPState s) a
type SimpleXParser a = XParser () a
data XPState s = XPState
{ xps_normalizeNewline :: ! Bool
, xps_userState :: s
}
withNormNewline :: a -> XPState a
withNormNewline x = XPState True x
withoutNormNewline :: a -> XPState a
withoutNormNewline x = XPState False x
xmlChar :: XParser s Unicode
xmlChar = ( satisfy isXmlCharCR
<|>
xmlCRLFChar
)
<?> "legal XML character"
xmlNameChar :: XParser s Unicode
xmlNameChar = satisfy isXmlNameChar <?> "legal XML name character"
xmlNameStartChar :: XParser s Unicode
xmlNameStartChar = satisfy isXmlNameStartChar <?> "legal XML name start character"
xmlNCNameChar :: XParser s Unicode
xmlNCNameChar = satisfy isXmlNCNameChar <?> "legal XML NCName character"
xmlNCNameStartChar :: XParser s Unicode
xmlNCNameStartChar = satisfy isXmlNCNameStartChar <?> "legal XML NCName start character"
xmlLetter :: XParser s Unicode
xmlLetter = satisfy isXmlLetter <?> "legal XML letter"
xmlSpaceChar :: XParser s Char
xmlSpaceChar = ( satisfy isXmlSpaceCharCR
<|>
xmlCRLFChar
)
<?> "white space"
xmlCRLFChar :: XParser s Char
xmlCRLFChar = ( do
_ <- char '\r'
s <- getState
if xps_normalizeNewline s
then option '\n' (char '\n')
else return '\r'
)
<?> "newline"