diff options
author | joe <joe@jerkface.net> | 2013-07-26 22:22:00 -0400 |
---|---|---|
committer | joe <joe@jerkface.net> | 2013-07-26 22:22:00 -0400 |
commit | 53d0825391f9642a99f91aa80fc0dbd6b5897e86 (patch) | |
tree | 721b8b7f0b80b473b6b29aec719ca827ea4c5221 | |
parent | f2a0bc19921db76d528d24347fc34c7fd0d78b38 (diff) |
Added tracking of xml:lang attribute.
-rw-r--r-- | Presence/NestingXML.hs | 49 |
1 files changed, 40 insertions, 9 deletions
diff --git a/Presence/NestingXML.hs b/Presence/NestingXML.hs index 5956b34d..bf12c9ae 100644 --- a/Presence/NestingXML.hs +++ b/Presence/NestingXML.hs | |||
@@ -1,29 +1,60 @@ | |||
1 | {-# LANGUAGE OverloadedStrings #-} | ||
1 | module NestingXML where | 2 | module NestingXML where |
2 | 3 | ||
3 | import Data.Conduit | 4 | import Data.Conduit |
4 | import Data.XML.Types | 5 | import Data.XML.Types |
5 | import Control.Monad.State | 6 | import Control.Monad.State |
7 | import qualified Data.Text as S | ||
8 | import Data.List (find) | ||
6 | -- import qualified Text.XML.Stream.Parse as Parse (content) | 9 | -- import qualified Text.XML.Stream.Parse as Parse (content) |
7 | 10 | ||
8 | type NestingXML o m a = StateT Int (ConduitM Event o m) a | 11 | type Lang = S.Text |
9 | 12 | ||
10 | runNestingXML :: NestingXML o m a -> Int -> ConduitM Event o m (a,Int) | 13 | data StrictList a = a :! !(StrictList a) | StrictNil |
11 | runNestingXML = runStateT | 14 | |
15 | top ( a :! as ) = Just a | ||
16 | top _ = Nothing | ||
17 | |||
18 | data XMLState = XMLState { | ||
19 | nestingLevel :: Int, | ||
20 | langStack :: StrictList (Int,Lang) | ||
21 | } | ||
22 | |||
23 | type NestingXML o m a = StateT XMLState (ConduitM Event o m) a | ||
24 | |||
25 | |||
26 | runNestingXML :: NestingXML o m a -> Int -> ConduitM Event o m (a,XMLState) | ||
27 | runNestingXML m lvl = runStateT m (XMLState lvl StrictNil) | ||
12 | 28 | ||
13 | doNestingXML :: Monad m => NestingXML o m a -> ConduitM Event o m a | 29 | doNestingXML :: Monad m => NestingXML o m a -> ConduitM Event o m a |
14 | doNestingXML = fmap fst . flip runNestingXML 0 | 30 | doNestingXML = fmap fst . flip runNestingXML 0 |
15 | 31 | ||
16 | nesting :: Monad m => NestingXML o m Int | 32 | nesting :: Monad m => NestingXML o m Int |
17 | nesting = get | 33 | nesting = fmap nestingLevel get |
34 | |||
35 | xmlLang :: Monad m => NestingXML o m (Maybe Lang) | ||
36 | xmlLang = fmap (fmap snd . top . langStack) get | ||
37 | |||
38 | lookupLang attrs = | ||
39 | case find ( (=="xml:lang") . fst) attrs of | ||
40 | Just (_,[ContentText x]) -> Just x | ||
41 | Just (_,[ContentEntity x]) -> Just x | ||
42 | _ -> Nothing | ||
18 | 43 | ||
19 | awaitXML :: Monad m => NestingXML o m (Maybe Event) | 44 | awaitXML :: Monad m => NestingXML o m (Maybe Event) |
20 | awaitXML = do | 45 | awaitXML = do |
21 | lvl <- get | 46 | XMLState lvl langs <- get |
22 | xml <- lift await | 47 | xml <- lift await |
23 | put $case xml of | 48 | put $ case xml of |
24 | Just (EventBeginElement _ _) -> lvl+1 | 49 | Just (EventBeginElement _ attrs) -> |
25 | Just (EventEndElement _) -> lvl-1 | 50 | case lookupLang attrs of |
26 | _ -> lvl | 51 | Nothing -> XMLState (lvl+1) langs |
52 | Just lang -> XMLState (lvl+1) ( (lvl+1,lang) :! langs) | ||
53 | Just (EventEndElement _) -> | ||
54 | case langs of | ||
55 | (llvl,_) :! ls | llvl==lvl -> XMLState (lvl-1) ls | ||
56 | _ | otherwise -> XMLState (lvl-1) langs | ||
57 | _ -> XMLState lvl langs | ||
27 | return xml | 58 | return xml |
28 | 59 | ||
29 | withXML | 60 | withXML |