audacity-0.0.1: src/Sound/Audacity/XML/Parser.hs
module Sound.Audacity.XML.Parser where
import qualified Text.HTML.Tagchup.Tag as Tag
import qualified Text.XML.Basic.Attribute as Attr
import qualified Text.XML.Basic.Name.MixedCase as Name
import Text.Printf (printf)
import qualified Control.Monad.Trans.State as MS
import qualified Control.Monad.Trans.Maybe as MM
import qualified Control.Monad.Trans.Class as MT
import qualified Control.Monad.Exception.Synchronous as ME
import Control.Monad (MonadPlus, void, when, guard, mzero)
import Control.Applicative (many)
import qualified Data.List.HT as ListHT
import Data.String.HT (trim)
import Data.Char (isSpace)
type T = MS.StateT [Tag.T Name.T String] (MM.MaybeT (ME.Exceptional Message))
type Message = String
tag :: T (Tag.T Name.T String)
tag = MS.StateT $ MM.MaybeT . return . ListHT.viewL
fromMaybeGen :: (MonadPlus m) => Maybe a -> m a
fromMaybeGen = maybe mzero return
fromMaybe :: Maybe a -> T a
fromMaybe = MT.lift . MM.MaybeT . return
tagOpen :: Tag.Name Name.T -> T [Attr.T Name.T String]
tagOpen name = do
x <- tag
(foundName, attrs) <- fromMaybe $ Tag.maybeOpen x
guard $ foundName == name
return attrs
tagClose :: Tag.Name Name.T -> T ()
tagClose name = do
x <- tag
foundName <- fromMaybe $ Tag.maybeClose x
guard $ foundName == name
lookupAttr :: String -> [Attr.T Name.T String] -> T String
lookupAttr name attrs =
MT.lift $ MT.lift $
ME.fromMaybe
(printf "did not find attribute %s in%s"
name (Attr.formatListBlankHead attrs "")) $
Attr.lookupLit name attrs
lookupAttrRead :: (Read a) => String -> [Attr.T Name.T String] -> T a
lookupAttrRead name attrs = do
str <- lookupAttr name attrs
case reads str of
[(x, "")] -> return x
_ ->
MT.lift $ MT.lift $ ME.throw $
"could not parse attribute value " ++ str
lookupAttrBool :: String -> [Attr.T Name.T String] -> T Bool
lookupAttrBool name attrs = do
str <- lookupAttr name attrs
case str of
"0" -> return False
"1" -> return True
_ -> MT.lift $ MT.lift $ ME.throw $ "not a bool value: " ++ str
skipSpace :: T ()
skipSpace = do
x <- tag
text <- fromMaybe $ Tag.maybeText x
when (not $ all isSpace text) $ MT.lift $ MT.lift $
ME.throw $ "expected spaces, but found: " ++ show (trim text)
skipSpaces :: T ()
skipSpaces = void $ many skipSpace