module Folgerhs.Stage where import Data.Maybe import Data.List import Data.Char (isLower) type Line = String type Character = String data StageEvent = Milestone Line | Entrance [Character] | Exit [Character] | Speech Character deriving (Eq, Show) onStage :: [Character] -> StageEvent -> [Character] onStage chs (Entrance chs') = nub (chs ++ chs') onStage chs (Exit chs') = chs \\ chs' onStage chs _ = chs speaker :: Character -> StageEvent -> Character speaker _ (Speech ch') = ch' speaker ch _ = ch maybeSpeaker :: StageEvent -> Maybe Character maybeSpeaker (Speech ch) = Just ch maybeSpeaker _ = Nothing line :: Line -> StageEvent -> Line line _ (Milestone l') = l' line l _ = l maybeLine :: StageEvent -> Maybe Line maybeLine (Milestone l) = Just l maybeLine _ = Nothing lines :: [StageEvent] -> [Line] lines = mapMaybe maybeLine isLine :: Line -> StageEvent -> Bool isLine l = maybe False ((==) l) . maybeLine accumStage :: [StageEvent] -> [Character] accumStage = foldl onStage [] lineStage :: Line -> [StageEvent] -> [Character] lineStage l = accumStage . takeWhile (not . isLine l) accumSpeaker :: [StageEvent] -> Character accumSpeaker = foldl speaker "" lineSpeaker :: Line -> [StageEvent] -> Character lineSpeaker l = accumSpeaker . takeWhile (not . isLine l) characters :: [StageEvent] -> [Character] characters [] = [] characters (se:ses) = case se of Entrance chs -> nub $ chs ++ characters ses _ -> characters ses hasName :: Character -> Bool hasName = any isLower . takeWhile (/= '.') selectCharacters :: (Character -> Bool) -> [StageEvent] -> [StageEvent] selectCharacters _ [] = [] selectCharacters f (se:ses) = let r = selectCharacters f ses in case se of Entrance chs -> Entrance (filter f chs) : r Exit chs -> Exit (filter f chs) : r Speech ch -> if f ch then se : r else r se -> se : r