module Derive.ParseSkeleton (
Track(..)
, default_parser, note_bottom_parser
) where
import qualified Data.Text as Text
import qualified Data.Tree as Tree
import qualified Util.Lists as Lists
import qualified Util.Trees as Trees
import qualified Derive.ParseTitle as ParseTitle
import qualified Ui.Skeleton as Skeleton
import Global
data Track = Track {
Track -> Int
_tracknum :: !Int
, Track -> Title
_title :: !Title
} deriving (Int -> Track -> ShowS
[Track] -> ShowS
Track -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Track] -> ShowS
$cshowList :: [Track] -> ShowS
show :: Track -> String
$cshow :: Track -> String
showsPrec :: Int -> Track -> ShowS
$cshowsPrec :: Int -> Track -> ShowS
Show)
type Title = Text
default_parser :: [Track] -> Skeleton.Skeleton
default_parser :: [Track] -> Skeleton
default_parser = Forest Track -> Skeleton
make_skeleton forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> [Track] -> Forest Track
parse_to_tree Bool
False
note_bottom_parser :: [Track] -> Skeleton.Skeleton
note_bottom_parser :: [Track] -> Skeleton
note_bottom_parser = Forest Track -> Skeleton
make_skeleton forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> [Track] -> Forest Track
parse_to_tree Bool
True
make_skeleton :: Tree.Forest Track -> Skeleton.Skeleton
make_skeleton :: Forest Track -> Skeleton
make_skeleton = [Edge] -> Skeleton
Skeleton.make forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. [Tree a] -> [(a, a)]
Trees.edges forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Track -> Int
_tracknum)
parse_to_tree :: Bool -> [Track] -> Tree.Forest Track
parse_to_tree :: Bool -> [Track] -> Forest Track
parse_to_tree Bool
reversed [Track]
tracks = forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap [Track] -> Forest Track
parse [[Track]]
groups
where
groups :: [[Track]]
groups = (Title -> Bool) -> [Track] -> [[Track]]
split_title Title -> Bool
ParseTitle.is_tempo_track [Track]
tracks
parse :: [Track] -> Forest Track
parse = if Bool
reversed then [Track] -> Forest Track
reverse_tempo_group else [Track] -> Forest Track
parse_tempo_group
parse_tempo_group :: [Track] -> Tree.Forest Track
parse_tempo_group :: [Track] -> Forest Track
parse_tempo_group = forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap [Track] -> Forest Track
parse_control_group forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Title -> Bool) -> [Track] -> [[Track]]
split_title Title -> Bool
is_cgroup
where
is_cgroup :: Title -> Bool
is_cgroup Title
t = Title -> Bool
ParseTitle.is_control_track Title
t Bool -> Bool -> Bool
&& Title
"-->" Title -> Title -> Bool
`Text.isSuffixOf` Title
t
parse_control_group :: [Track] -> Tree.Forest Track
parse_control_group :: [Track] -> Forest Track
parse_control_group [Track]
tracks = case (Title -> Bool) -> [Track] -> [[Track]]
split_title Title -> Bool
ParseTitle.is_note_track [Track]
tracks of
[] -> []
[Track]
non_note : [[Track]]
ngroups -> forall a. [a] -> Forest a -> Forest a
descend [Track]
non_note (forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap forall a. [a] -> Forest a
parse_note_group [[Track]]
ngroups)
split_title :: (Title -> Bool) -> [Track] -> [[Track]]
split_title :: (Title -> Bool) -> [Track] -> [[Track]]
split_title Title -> Bool
f = forall a. (a -> Bool) -> [a] -> [[a]]
Lists.splitBefore (Title -> Bool
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. Track -> Title
_title)
reverse_tempo_group :: [Track] -> Tree.Forest Track
reverse_tempo_group :: [Track] -> Forest Track
reverse_tempo_group [] = []
reverse_tempo_group (Track
track:[Track]
tracks) =
[forall a. a -> [Tree a] -> Tree a
Tree.Node Track
track forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap forall a. [a] -> Forest a
parse_note_group (forall {a}. [[a]] -> [[a]]
shift [[Track]]
groups)]
where
groups :: [[Track]]
groups = (Title -> Bool) -> [Track] -> [[Track]]
split_title Title -> Bool
ParseTitle.is_note_track [Track]
tracks
shift :: [[a]] -> [[a]]
shift ([a]
group : (a
note : [a]
rest) : [[a]]
gs) = ([a]
group forall a. [a] -> [a] -> [a]
++ [a
note]) forall a. a -> [a] -> [a]
: [[a]] -> [[a]]
shift ([a]
rest forall a. a -> [a] -> [a]
: [[a]]
gs)
shift [[a]]
gs = [[a]]
gs
parse_note_group :: [a] -> Tree.Forest a
parse_note_group :: forall a. [a] -> Forest a
parse_note_group [a]
tracks = forall a. [a] -> Forest a -> Forest a
descend [a]
tracks []
descend :: [a] -> Tree.Forest a -> Tree.Forest a
descend :: forall a. [a] -> Forest a -> Forest a
descend [] Forest a
bottom = Forest a
bottom
descend (a
track:[a]
tracks) Forest a
bottom = [forall a. a -> [Tree a] -> Tree a
Tree.Node a
track (forall a. [a] -> Forest a -> Forest a
descend [a]
tracks Forest a
bottom)]