hamusic-0.1: src/MusicCount.lhs
\begin{code}
-- |
-- Maintainer : silva.samuel@alumni.uminho.pt
-- Stability : experimental
-- Portability: portable
-- This module implements
module Main where
import qualified Text.XML.MusicXML as MusicXML
--import Music.Analysis.MusicXML2Haskore
import Music.Analysis.MusicXML.Functions
import Control.Monad
import Data.List
import System.IO
import System.Environment
import System.Console.GetOpt
--import System.FilePath
--import Control.Exception (throw, Exception(..))
\end{code}
\begin{code}
-- |
warn :: String -> IO ()
warn msg = putStrLn msg >> hFlush stdout
-- |
version :: String
version = "0.1.1027"
\end{code}
\begin{code}
-- |
data Option = Part | Measure | Note | Sharp | Flat | GraceNote
-- | MusicXML | Abstract | ABC | Lilypond | Haskore
-- | Format
-- | MusicXML2Abstract
-- | Abstract2ABC
-- | Abstract2Lilypond
-- | MusicXML2Haskore
| Help
| Version
deriving (Eq, Show)
data Options = Options {part :: Bool, measure :: Bool, note :: Bool}
data ResultOptions = Result (Maybe Int) (Maybe Int) (Maybe Int)
deriving (Show)
-- |
options :: [OptDescr Option]
options = [
Option ['v','V'] ["version"] (NoArg Version) "show version number"
, Option ['h','H','?'] ["help"] (NoArg Help) "show help"
, Option ['p'] ["part"] (NoArg Part) "counts part"
, Option ['m'] ["measure"] (NoArg Measure) "counts measure"
, Option ['n'] ["note"] (NoArg Note) "counts note"
-- , Option ['i'] ["input"] (ReqArg Input "FILE") "input music file"
-- , Option ['o'] ["output"] (ReqArg Output "FILE") "output music file"
-- , Option ['a'] ["abstract"] (NoArg Abstract) "abstract format"
-- , Option ['M'] ["musicxml"] (NoArg MusicXML) "musicxml format"
-- , Option ['H'] ["haskore"] (NoArg Haskore) "haskore format"
-- , Option ['A'] ["abc"] (NoArg ABC) "abc format"
-- , Option ['L'] ["lilypond"] (NoArg Lilypond) "lilypond format"
-- , Option ['c'] ["convert"] opt1
-- "convert input format into output format"
-- , Option [] ["musicxml2abstract"] (NoArg MusicXML2Abstract)
-- "converts musicxml file into abstract music"
-- , Option [] ["musicxml2haskore"] (NoArg MusicXML2Haskore)
-- "converts musicxml file into haskore music"
-- , Option [] ["abstract2abc"] (NoArg Abstract2ABC)
-- "converts abstract music into abc notation"
-- , Option [] ["abstract2lilypond"] (NoArg Abstract2Lilypond)
-- "converts abstract music into lilypond notation"
]
-- |
header :: String -> String
header prog = "Usage: "++ prog ++" [OPTIONS...] FILES..."
\end{code}
\begin{code}
-- |
counts :: Options -> MusicXML.MusicXMLDoc -> ResultOptions
counts opt m = Result (if part opt then Just (count_part m) else Nothing)
(if measure opt then Just (count_measure m) else Nothing)
(if note opt then Just (count_note m) else Nothing)
--Nothing Nothing
importMusicXML :: FilePath -> IO (Maybe MusicXML.MusicXMLDoc)
importMusicXML input = do
musicxml <- MusicXML.read_FILE MusicXML.read_MusicXMLDoc input
case MusicXML.isOK musicxml of
True -> return (Just (MusicXML.fromOK musicxml))
False -> putStrLn ("Can't read "++show input) >> return Nothing
defaultOptions :: Options
defaultOptions = Options {part=False, measure=False, note=False}
convert :: [Option] -> Options -> Options
convert [] = id
convert (Part:xs) = \opts -> convert xs opts {part=True}
convert (Measure:xs) = \opts -> convert xs opts {measure=True}
convert (Note:xs) = \opts -> convert xs opts {note=True}
convert (_:xs) = convert xs
\end{code}
\begin{code}
main :: IO ()
main = do
argv <- getArgs
prog <- getProgName
case getOpt Permute options argv of
(o,n,[]) | Help`elem`o -> putStrLn (usageInfo (header prog) options)
| Version`elem`o -> putStrLn (unwords [prog, version])
| otherwise -> mapM_ (\input -> do
m <- importMusicXML input
maybe (return ()) (print . counts (convert o defaultOptions)) m) n
(_,_,errs) -> putStrLn (unlines errs ++ usageInfo (header prog) options)
\end{code}
\begin{nocode}
-- |
main :: IO ()
main = do
argv <- getArgs
prog <- getProgName
curdir <- getCurrentDirectory
case getOpt Permute options' argv of
(o,n,[]) | Help'`elem`o -> putStrLn (usageInfo (header prog) options')
| Version'`elem`o -> putStrLn (unwords [prog, version])
| Check`elem`o ->
mapM_ (maybe (return ())
(either (procScriptFile True) setCurrentDirectory) .
parseOptions) (o ++ map Input' n)
>> setCurrentDirectory curdir
| otherwise ->
mapM_ (maybe (return ())
(either (procScriptFile False) setCurrentDirectory) .
parseOptions) (o ++ map Input' n)
>> setCurrentDirectory curdir
(_,_,errs) -> putStrLn (unlines errs ++ usageInfo (header prog) options')
\end{nocode}