module Music.Score.Meta.Title (
Title,
denoteTitle,
getTitle,
getTitleAt,
title,
titleDuring,
subtitle,
subtitleDuring,
subsubtitle,
subsubtitleDuring,
withTitle,
) where
import Control.Lens (view)
import Control.Monad.Plus
import Data.Foldable (Foldable)
import qualified Data.Foldable as F
import qualified Data.List as List
import Data.Map (Map)
import qualified Data.Map as Map
import Data.Maybe
import Data.Semigroup
import Data.Set (Set)
import qualified Data.Set as Set
import Data.String
import Data.Traversable (Traversable)
import qualified Data.Traversable as T
import Data.Typeable
import Music.Pitch.Literal
import Music.Score.Meta
import Music.Score.Part
import Music.Score.Pitch
import Music.Score.Internal.Util
import Music.Time
import Music.Time.Reactive
newtype Title = Title (Int -> Option (Last String))
deriving (Typeable, Monoid, Semigroup)
instance IsString Title where
fromString x = Title $ \n -> if n == 0 then Option (Just (Last x)) else Option Nothing
instance Show Title where
show = List.intercalate " " . getTitle
titleFromString :: String -> Title
titleFromString = fromString
denoteTitle :: Title -> Title
denoteTitle (Title t) = Title (t . subtract 1)
getTitle :: Title -> [String]
getTitle t = untilFail . fmap (getTitleAt t) $ [0..]
where
untilFail = fmap fromJust . takeWhile isJust
getTitleAt :: Title -> Int -> Maybe String
getTitleAt (Title t) n = fmap getLast . getOption . t $ n
title :: (HasMeta a, HasPosition a) => Title -> a -> a
title t x = titleDuring (_era x) t x
titleDuring :: HasMeta a => Span -> Title -> a -> a
titleDuring s t = addMetaNote $ view event (s, t)
subtitle :: (HasMeta a, HasPosition a) => Title -> a -> a
subtitle t x = subtitleDuring (_era x) t x
subtitleDuring :: HasMeta a => Span -> Title -> a -> a
subtitleDuring s t = addMetaNote $ view event (s, denoteTitle t)
subsubtitle :: (HasMeta a, HasPosition a) => Title -> a -> a
subsubtitle t x = subsubtitleDuring (_era x) t x
subsubtitleDuring :: HasMeta a => Span -> Title -> a -> a
subsubtitleDuring s t = addMetaNote $ view event (s, denoteTitle (denoteTitle t))
withTitle :: (Title -> Score a -> Score a) -> Score a -> Score a
withTitle = withMetaAtStart