-- | Utility functions.
--
-- This module contains utility functions which might be useful elsewhere.
-- So far, there are only functions to determine if a @String@ may be a
-- valid XML element name.
module Text.SXML.Utils(isXMLNameStartChar, isXMLNameChar, isXMLName) where

import Data.Char

(<||>) :: (a -> Bool) -> (a -> Bool) -> (a -> Bool)
p <||> q = \x -> p x || q x

-- | This function returns @True@ is its input is a valid character at the
-- beginning of an XML element name.
isXMLNameStartChar = (== ':') <||> (== '_') <||> isAsciiUpper <||> isAsciiLower <||> (`elem` ['\xc0'..'\xd6'])
  <||> (`elem` ['\xd8'..'\xf6']) <||> (`elem` ['\xf8'..'\x2ff']) <||> (`elem` ['\x370'..'\x37d'])
  <||> (`elem` ['\x37f'..'\x1fff']) <||> (`elem` ['\x200c'..'\x200d']) <||> (`elem` ['\x2070'..'\x218f'])
  <||> (`elem` ['\x2c00'..'\x2fef']) <||> (`elem` ['\x3001'..'\xd7ff']) <||> (`elem` ['\xf900'..'\xfdcf'])
  <||> (`elem` ['\xfdf0'..'\xfffd']) <||> (`elem` ['\x10000'..'\xeffff'])

-- | This function returns @True@ is its input is a valid character
-- within an XML element name.
isXMLNameChar = (== '-') <||> (== '.') <||> (== '·') <||> isDigit <||> isXMLNameStartChar <||> (`elem` ['\x300'..'\x36f']) <||> (`elem` ['\x203f'..'\x2040'])

-- | This function returns @True@ is its input is a valid XML
-- element name.
isXMLName "" = False
isXMLName (c:cs) = isXMLNameStartChar c || all isXMLNameChar cs
