packages feed

music-preludes 1.6 → 1.6.1

raw patch · 14 files changed

+464/−200 lines, 14 filesdep +containersdep +filepathdep +music-preludesdep ~basenew-component:exe:music2lynew-component:exe:music2midinew-component:exe:music2musicxmlnew-component:exe:music2pdfnew-component:exe:music2pngnew-component:exe:music2svg

Dependencies added: containers, filepath, music-preludes, optparse-applicative, split, tasty, tasty-golden, temporary, unix

Dependency ranges changed: base

Files

music-preludes.cabal view
@@ -1,62 +1,107 @@ -name:               music-preludes-version:            1.6-cabal-version:      >= 1.10-author:             Hans Hoglund-maintainer:         Hans Hoglund-license:            BSD3-license-file:       COPYING-synopsis:           Some useful preludes for the Music Suite.-category:           Music-tested-with:        GHC-build-type:         Simple+name:                   music-preludes+version:                1.6.1+author:                 Hans Hoglund+maintainer:             Hans Hoglund+license:                BSD3+license-file:           COPYING+synopsis:               Some useful preludes for the Music Suite.+category:               Music+tested-with:            GHC+build-type:             Simple+cabal-version:          >= 1.10 -description: +description:     Some useful preludes for the Music Suite.-+    .     This library is part of the Music Suite, see <http://music-suite.github.io>.  source-repository head-  type:             git-  location:         git://github.com/music-suite/music-preludes.git-  -library                    -    build-depends: -        base                    >= 4 && < 5,-        lens,-        vector-space,-        vector-space-points,-        lilypond                == 1.6,-        musicxml2               == 1.6,-        process,-        semigroups,-        data-default,-        monadplus,-        reverse-apply,-        music-score             == 1.6,-        music-pitch             == 1.6,-        music-dynamics          == 1.6,-        music-parts             == 1.6,-        music-pitch-literal     == 1.6,-        music-dynamics-literal  == 1.6-    hs-source-dirs: src-    default-language: Haskell2010-    exposed-modules:-        Music.Prelude.Basic-        Music.Prelude.Standard-        Music.Prelude.Piano-        Music.Prelude.StringQuartet-        Music.Prelude.Instances+  type:                 git+  location:             git://github.com/music-suite/music-preludes.git --- test-suite properties---     type: exitcode-stdio-1.0---     main-is: properties.hs---     hs-source-dirs: tests---     default-language: Haskell2010---     ghc-options: -w -threaded -rtsopts -with-rtsopts=-N---     build-depends:---         HUnit                       >= 1.2,---         QuickCheck                  >= 1.2 && < 1.3,---         test-framework              >= 0.6,---         test-framework-th           >= 0.2,---         test-framework-quickcheck   >= 0.3+library+    build-depends:      base                    >= 4 && < 5,+                        lens,+                        split,+                        unix,+                        containers,+                        vector-space,+                        vector-space-points,+                        lilypond                == 1.6,+                        musicxml2               == 1.6,+                        process,+                        filepath                >= 1.3  && < 2,+                        temporary               >= 1.1  && < 2,+                        optparse-applicative    >= 0.8  && < 1,+                        semigroups,+                        data-default,+                        monadplus,+                        reverse-apply,+                        music-score             == 1.6,+                        music-pitch             == 1.6,+                        music-dynamics          == 1.6,+                        music-parts             == 1.6,+                        music-pitch-literal     == 1.6,+                        music-dynamics-literal  == 1.6+    exposed-modules:    Music.Prelude.Basic+                        Music.Prelude.Standard+                        Music.Prelude.Piano+                        Music.Prelude.StringQuartet+                        Music.Prelude.CmdLine+                        Music.Prelude.Instances+    hs-source-dirs:     src+    default-language:   Haskell2010++executable "music2ly"+    build-depends:      base,+                        music-preludes+    main-is:            music2ly.hs+    hs-source-dirs:     tools+    default-language:   Haskell2010++executable "music2pdf"+    build-depends:      base,+                        music-preludes+    main-is:            music2pdf.hs+    hs-source-dirs:     tools+    default-language:   Haskell2010++executable "music2png"+    build-depends:      base,+                        music-preludes+    main-is:            music2png.hs+    hs-source-dirs:     tools+    default-language:   Haskell2010++executable "music2svg"+    build-depends:      base,+                        music-preludes+    main-is:            music2svg.hs+    hs-source-dirs:     tools+    default-language:   Haskell2010++executable "music2musicxml"+    build-depends:      base,+                        music-preludes+    main-is:            music2musicxml.hs+    hs-source-dirs:     tools+    default-language:   Haskell2010++executable "music2midi"+    build-depends:      base,+                        music-preludes+    main-is:            music2midi.hs+    hs-source-dirs:     tools+    default-language:   Haskell2010++test-suite "regression"+    build-depends:      base                    >= 4   && < 5,+                        tasty                   >= 0.8 && < 1,+                        tasty-golden            >= 2.2 && < 3,+                        process+    type:               exitcode-stdio-1.0+    main-is:            tests.hs+    hs-source-dirs:     tests+    default-language:   Haskell2010+
src/Music/Prelude/Basic.hs view
@@ -47,8 +47,8 @@ import qualified Music.Pitch import           Music.Score             hiding (Pitch) +import           Control.Lens.Operators  hiding ((<.>), (<|), (|>)) import           Control.Monad.Plus-import           Control.Lens.Operators   hiding ((|>), (<|), (<.>))  import           Music.Prelude.Instances () 
+ src/Music/Prelude/CmdLine.hs view
@@ -0,0 +1,146 @@++module Music.Prelude.CmdLine (+        converterMain,+        translateFileAndRunLilypond,+        translateFile,+        versionString+) where++import           Data.Version          (showVersion)+import           Data.Monoid+import           Options.Applicative+-- import           Paths_music_preludes  (version)+import           Data.Char+import           Data.List          (intercalate)+import           Data.List.Split+import           Data.Map           (Map)+import qualified Data.Map           as Map+import           Data.Maybe+import           Prelude            hiding (readFile, writeFile)+-- import           System.Console.GetOpt+import           System.Environment+import           System.Exit+import           System.FilePath+import           System.IO+import           System.IO.Temp+import qualified System.Posix.Env   as PE+import           System.Process++-- TODO Can not link due to haskell/cabal#1759+versionString :: String+versionString = "1.6"+-- versionString = showVersion version++data Options = Options {+    prelude :: Maybe String,+    outFile :: Maybe FilePath,+    inFile  :: FilePath+  } deriving (Show)++converterOptions :: Parser Options+converterOptions = Options+  <$> (optional $ strOption $ mconcat [long "prelude", metavar "<name>"])+  <*> (optional $ strOption $ mconcat [short 'o', long "output", metavar "<file>"])+  <*> (argument str $ metavar "<input>")++runConverter :: String -> String -> Options -> IO ()+runConverter func ext (Options prelude outFile inFile) =+  translateFile func ext prelude (Just inFile) outFile++converterMain :: String -> String -> String -> IO ()+converterMain func ext pgmName = execParser opts >>= runConverter func ext+  where +      opts = info +        (helper <*> converterOptions) +        (fullDesc <> header (pgmName ++ "-" ++ versionString))+++translateFileAndRunLilypond :: String -> Maybe String -> Maybe FilePath -> IO ()+translateFileAndRunLilypond format preludeName' inFile' = do+  let inFile      = fromMaybe "test.music" inFile'+  let preludeName = fromMaybe "basic" preludeName'+  let lyFile      = takeBaseName inFile ++ ".ly"++  translateFile "writeLilypond" "ly" (Just preludeName) (Just inFile) (Just lyFile)+  rawSystem "lilypond" ["--" ++ format, "-o", takeBaseName inFile, lyFile]+  runCommand $ "rm -f " ++ takeBaseName inFile ++ "-*.tex " ++ takeBaseName inFile ++ "-*.texi " ++ takeBaseName inFile ++ "-*.count " ++ takeBaseName inFile ++ "-*.eps " ++ takeBaseName inFile ++ "-*.pdf " ++ takeBaseName inFile ++ ".eps"+  return ()++translateFile :: String -> String -> Maybe String -> Maybe FilePath -> Maybe FilePath -> IO ()+translateFile translationFunction outSuffix preludeName' inFile' outFile' = do+  let inFile      = fromMaybe "test.music" inFile'+  let preludeName = fromMaybe "basic" preludeName'+  let outFile     = fromMaybe (+                    takeDirectory inFile ++ "/" +                    ++ takeBaseName inFile +                    ++ "." ++ outSuffix) +                    outFile'++  let prelude   = "Music.Prelude." ++ toCamel preludeName+  let scoreType = "Score " ++ toCamel preludeName ++ "Note"+  let main      = translationFunction+  score       <- readFile inFile+  newScore    <- return $ expand templ (Map.fromList [+    ("prelude"   , prelude),+    ("main"      , main),+    ("scoreType" , scoreType),+    ("score"     , score),+    ("outFile"   , outFile)+    ])++  withSystemTempDirectory "music-suite." $ \tmpDir -> do+    let tmpFile = tmpDir ++ "/" ++ takeFileName inFile+    putStrLn $ "Converting music..."+    writeFile tmpFile newScore+    withMusicSuiteInScope $ do+      putStrLn $ "Writing '" ++ outFile ++ "'..."+      rawSystem "runhaskell" [tmpFile]++  return ()+  where+    templ = "module Main where { import $(prelude); main = $(main) \"$(outFile)\" ( $(score) :: $(scoreType) ) }"+++type Template = String++-- |+-- Simple templating system.+--+-- >>> expand "me : $(name)" (Map.fromList [("name","Hans")])+-- "me : Hans"+--+expand :: Template -> Map String String -> String+expand t vs = (composed $ fmap (expander vs) $ Map.keys $ vs) t+  where+    expander vs k = replace ("$(" ++ k ++ ")") (fromJust $ Map.lookup k vs)++composed :: [a -> a] -> a -> a+composed = foldr (.) id+++replace :: Eq a => [a] -> [a] -> [a] -> [a]+replace old new = intercalate new . splitOn old++toCamel [] = []+toCamel (x:xs) = toUpper x : xs++-- | Temporarily modfiy an environment variable (POSIX only).+--+-- @+-- withEnv MYVAR (\oldValue -> newValue) $ do+--    ...+-- @+--+withEnv :: String -> (Maybe String -> String) -> IO a -> IO ()+withEnv n f k = do+  x <- PE.getEnv n+  PE.setEnv n (f x) True+  k+  case x of+    Nothing -> PE.unsetEnv n+    Just x2 -> PE.setEnv n x2 True++-- TODO if no music-util, use ""+withMusicSuiteInScope k = do+  packagePath <- readProcess "music-util" ["package-path"] ""+  withEnv "GHC_PACKAGE_PATH" (const packagePath) k
src/Music/Prelude/Instances.hs view
@@ -1,13 +1,12 @@ -{-# LANGUAGE-    GeneralizedNewtypeDeriving,-    StandaloneDeriving,-    MultiParamTypeClasses,-    DeriveDataTypeable,-    TypeFamilies, -    FlexibleInstances,-    UndecidableInstances,-    ViewPatterns #-} +{-# LANGUAGE DeriveDataTypeable         #-}+{-# LANGUAGE FlexibleInstances          #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE MultiParamTypeClasses      #-}+{-# LANGUAGE StandaloneDeriving         #-}+{-# LANGUAGE TypeFamilies               #-}+{-# LANGUAGE UndecidableInstances       #-}+{-# LANGUAGE ViewPatterns               #-}  ------------------------------------------------------------------------------------ -- |@@ -25,28 +24,28 @@  module Music.Prelude.Instances () where -import Data.Default-import Data.Typeable-import Data.AffineSpace.Point+import           Data.AffineSpace.Point+import           Data.Default+import           Data.Typeable -import Music.Pitch-import Music.Dynamics-import Music.Parts-import Music.Score hiding (Pitch, Interval, Fifths, Note)+import           Music.Dynamics+import           Music.Parts+import           Music.Pitch+import           Music.Score            hiding (Fifths, Interval, Note, Pitch) -import qualified Music.Score as Score-import qualified Music.Lilypond as Lilypond-import qualified Music.MusicXml.Simple as Xml+import qualified Music.Lilypond         as Lilypond+import qualified Music.MusicXml.Simple  as Xml+import qualified Music.Score            as Score  deriving instance Typeable Music.Parts.Part  type instance Music.Score.Part BasicPart = BasicPart instance HasPart BasicPart where-        getPart = id-        modifyPart = id+    getPart = id+    modifyPart = id  -- FIXME-instance Delayable Pitch      +instance Delayable Pitch instance Stretchable Pitch type instance Score.Pitch Pitch = Pitch @@ -60,109 +59,29 @@     endTie = id  instance HasMidi Semitones where-    getMidi a = getMidi $ (60 + fromIntegral a :: Integer)+    getMidi a = getMidi $ (fromIntegral a :: Integer)  instance HasMidi Pitch where     getMidi p = getMidi $ semitones (p .-. c)  instance HasMusicXml Pitch where-    getMusicXml      (realToFrac -> d) = (`Xml.note` d) . snd3 Just . spellPitch-    getMusicXmlChord (realToFrac -> d) = (`Xml.chord` (realToFrac d)) . fmap (snd3 Just . spellPitch)+    getMusicXml      (realToFrac -> d) = (`Xml.note` d) . snd3 Just . spellPitch 4+    getMusicXmlChord (realToFrac -> d) = (`Xml.chord` (realToFrac d)) . fmap (snd3 Just . spellPitch 4)  instance HasLilypond Pitch where-    getLilypond      d = (^*realToFrac (d*4)) . Lilypond.note . pitchLilypond . Lilypond.Pitch . spellPitch . (.+^ perfect octave)-    getLilypondChord d = (^*realToFrac (d*4)) . Lilypond.chord . fmap (pitchLilypond . Lilypond.Pitch . spellPitch . (.+^ perfect octave))+    getLilypond      d = (^*realToFrac (d*4)) . Lilypond.note . pitchLilypond . Lilypond.Pitch . spellPitch 5+    getLilypondChord d = (^*realToFrac (d*4)) . Lilypond.chord . fmap (pitchLilypond . Lilypond.Pitch . spellPitch 5)  -- TODO move snd3 f (a, b, c) = (a, f b, c) pitchLilypond a = Lilypond.NotePitch a Nothing -spellPitch :: (Enum p, Num a, Num o) => Pitch -> (p, a, o)-spellPitch p = (pitchName, pitchAccidental, octave)+spellPitch :: (Enum p, Num a, Num o) => Octaves -> Pitch -> (p, a, o)+spellPitch referenceOctave p = (pitchName, pitchAccidental, octave)     where         pitchName       = toEnum $ fromEnum $ name p         pitchAccidental = fromIntegral $ accidental p-        octave          = fromIntegral $ (+ 4) $ octaves (p .-. c)--instance Alterable a => Alterable (Score a) where-    sharpen = fmap sharpen-    flatten = fmap flatten--instance Alterable a => Alterable (ChordT a) where-    sharpen = fmap sharpen-    flatten = fmap flatten--instance Alterable a => Alterable (DynamicT a) where-    sharpen = fmap sharpen-    flatten = fmap flatten--instance Alterable a => Alterable (SlideT a) where-    sharpen = fmap sharpen-    flatten = fmap flatten--instance Alterable a => Alterable (TieT a) where-    sharpen = fmap sharpen-    flatten = fmap flatten--instance Alterable a => Alterable (HarmonicT a) where-    sharpen = fmap sharpen-    flatten = fmap flatten--instance Alterable a => Alterable (ArticulationT a) where-    sharpen = fmap sharpen-    flatten = fmap flatten--instance Alterable a => Alterable (TextT a) where-    sharpen = fmap sharpen-    flatten = fmap flatten--instance Alterable a => Alterable (TremoloT a) where-    sharpen = fmap sharpen-    flatten = fmap flatten--instance Alterable a => Alterable (PartT n a) where-    sharpen = fmap sharpen-    flatten = fmap flatten--instance Augmentable a => Augmentable (Score a) where-    augment = fmap augment-    diminish = fmap diminish--instance Augmentable a => Augmentable (ChordT a) where-    augment = fmap augment-    diminish = fmap diminish--instance Augmentable a => Augmentable (DynamicT a) where-    augment = fmap augment-    diminish = fmap diminish--instance Augmentable a => Augmentable (SlideT a) where-    augment = fmap augment-    diminish = fmap diminish--instance Augmentable a => Augmentable (TieT a) where-    augment = fmap augment-    diminish = fmap diminish--instance Augmentable a => Augmentable (HarmonicT a) where-    augment = fmap augment-    diminish = fmap diminish--instance Augmentable a => Augmentable (ArticulationT a) where-    augment = fmap augment-    diminish = fmap diminish--instance Augmentable a => Augmentable (TextT a) where-    augment = fmap augment-    diminish = fmap diminish--instance Augmentable a => Augmentable (TremoloT a) where-    augment = fmap augment-    diminish = fmap diminish--instance Augmentable a => Augmentable (PartT n a) where-    augment = fmap augment-    diminish = fmap diminish+        octave          = fromIntegral $ (+ referenceOctave) $ octaves (p .-. c)  instance HasMidiProgram BasicPart where     getMidiChannel _ = 0
src/Music/Prelude/Piano.hs view
@@ -1,7 +1,6 @@ -{-# LANGUAGE-    GeneralizedNewtypeDeriving,-    DeriveDataTypeable #-} +{-# LANGUAGE DeriveDataTypeable         #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}  ------------------------------------------------------------------------------------ -- |@@ -24,14 +23,14 @@         asScore   ) where -import Music.Pitch-import Music.Score hiding (Pitch, Interval, Note)-import Music.Dynamics.Literal --TODO-import Data.Typeable-import Data.AffineSpace.Point-import qualified Music.Score as Score-import qualified Music.Lilypond as Lilypond-import qualified Music.MusicXml.Simple as Xml+import           Data.AffineSpace.Point+import           Data.Typeable+import           Music.Dynamics.Literal+import qualified Music.Lilypond         as Lilypond+import qualified Music.MusicXml.Simple  as Xml+import           Music.Pitch+import           Music.Score            hiding (Interval, Note, Pitch)+import qualified Music.Score            as Score  asScore :: Score Note -> Score Note asScore = id
src/Music/Prelude/Standard.hs view
@@ -1,8 +1,7 @@ -{-# LANGUAGE-    GeneralizedNewtypeDeriving,-    DeriveDataTypeable,-    TypeFamilies #-}+{-# LANGUAGE DeriveDataTypeable         #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE TypeFamilies               #-}  ------------------------------------------------------------------------------------ -- |@@ -33,15 +32,16 @@         openAndPlay   ) where -import Data.Default-import Data.Typeable+import           Data.Default+import           Data.Typeable -import Music.Pitch-import Music.Dynamics-import Music.Parts-import Music.Score hiding (Pitch, Interval, Fifths, Note, Part, pitch)+import           Music.Dynamics+import           Music.Parts+import           Music.Pitch+import           Music.Score             hiding (Fifths, Interval, Note, Part,+                                          Pitch, pitch) -import Music.Prelude.Instances ()+import           Music.Prelude.Instances ()  asNote :: Note -> Note asNote = id@@ -57,7 +57,7 @@  -- newtype BasicPart = BasicPart { getBasicPart :: Integer } --     deriving (Eq, Ord, Num, Integral, Real, Enum, Typeable)--- +-- -- instance Default BasicPart where def = BasicPart 0 -- instance Show BasicPart where --     show _ = ""
src/Music/Prelude/StringQuartet.hs view
@@ -1,7 +1,6 @@ -{-# LANGUAGE-    GeneralizedNewtypeDeriving,-    DeriveDataTypeable #-} +{-# LANGUAGE DeriveDataTypeable         #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}  ------------------------------------------------------------------------------------ -- |@@ -23,14 +22,14 @@         asScore   ) where -import Music.Pitch-import Music.Score hiding (Pitch, Interval, Note)-import Music.Dynamics.Literal --TODO-import Data.Typeable-import Data.AffineSpace.Point-import qualified Music.Score as Score-import qualified Music.Lilypond as Lilypond-import qualified Music.MusicXml.Simple as Xml+import           Data.AffineSpace.Point+import           Data.Typeable+import           Music.Dynamics.Literal+import qualified Music.Lilypond         as Lilypond+import qualified Music.MusicXml.Simple  as Xml+import           Music.Pitch+import           Music.Score            hiding (Interval, Note, Pitch)+import qualified Music.Score            as Score  asScore :: Score Note -> Score Note asScore = id
+ tests/tests.hs view
@@ -0,0 +1,90 @@++module Main where++import Test.Tasty+import Test.Tasty.Golden+import System.Process++main = defaultMain $ testGroup "All tests" [sanity, golden]++testMusicFile name = testGroup name [+  testMusicFileAs "mid" name,+  testMusicFileAs "xml" name,+  testMusicFileAs "ly"  name+  ]++converter ext = case ext of+  "mid" -> "music2midi"+  "xml" -> "music2musicxml"+  "ly"  -> "music2ly"++testMusicFileAs ext name =+  goldenVsFile +    (name ++ "." ++ ext)+    ("tests/golden/" ++ name ++ "." ++ ext)+    ("tests/current/" ++ name ++ "." ++ ext)+    ((system $ converter ext ++" -o tests/current/"++name++"."++ext++" tests/"++name++".music") +      >> return ())++{-+  This test will always fail if the test files have been edited.++  If you have edited one or more test files and DEFINITELY intend to make +  your changes permanent, please assure that you are in a clean working+  directory (except for your edits), and then run:++      $ make generate+  +  You should commit all the resulting files along with your edits.+-}+sanity = testGroup "Sanity checks" [+  testMusicFilesCheckSum,+  testGenratedFilesChecksum+  ]++testMusicFilesCheckSum =+  goldenVsFile+      "Original file checksums"+      "tests/originals_ref.sha"+      "tests/originals_check.sha"+      (system "shasum tests/*.music | shasum > tests/originals_check.sha" >> return ())++testGenratedFilesChecksum =+  goldenVsFile+      "Generated file checksums"+      "tests/generated_ref.sha"+      "tests/generated_check.sha"+      (system "shasum tests/golden/* | shasum > tests/generated_check.sha" >> return ())++golden = testGroup "Regression tests" [+  testMusicFile "articulation_all_accents",+  testMusicFile "articulation_all_separations",+  testMusicFile "articulation_legato",+  testMusicFile "articulation_portato",+  testMusicFile "articulation_staccato",+  testMusicFile "dynamics_constant",+  testMusicFile "melody_chords",+  testMusicFile "meta_annotations",+  testMusicFile "meta_clef1",+  testMusicFile "meta_composer",+  testMusicFile "meta_time_signature",+  testMusicFile "misc_counterpoint",+  testMusicFile "octaves",+  testMusicFile "overlay_chords",+  testMusicFile "overlay_voices",+  testMusicFile "pitch_inv",+  testMusicFile "sharpen",+  testMusicFile "simple_figure",+  testMusicFile "simple_start_later",+  testMusicFile "single_note",+  testMusicFile "special_gliss",+  testMusicFile "special_harmonics",+  testMusicFile "special_text",+  testMusicFile "special_tremolo",+  testMusicFile "stretch_single_note1",+  testMusicFile "stretch_single_note2",+  testMusicFile "stretch_single_note3",+  testMusicFile "times",+  testMusicFile "track_single",+  testMusicFile "voice_single"+  ]
+ tools/music2ly.hs view
@@ -0,0 +1,8 @@++module Main where++import           Music.Prelude.CmdLine+import           System.Environment++main :: IO ()+main = getProgName >>= converterMain "writeLilypond" "ly"
+ tools/music2midi.hs view
@@ -0,0 +1,8 @@++module Main where++import           Music.Prelude.CmdLine+import           System.Environment++main :: IO ()+main = getProgName >>= converterMain "writeMidi" "mid"
+ tools/music2musicxml.hs view
@@ -0,0 +1,8 @@++module Main where++import           Music.Prelude.CmdLine+import           System.Environment++main :: IO ()+main = getProgName >>= converterMain "writeMusicXml" "xml"
+ tools/music2pdf.hs view
@@ -0,0 +1,14 @@++module Main where++import           Music.Prelude.CmdLine+import           System.Environment++-- TODO+main = do+  args <- getArgs+  main2 args++main2 args = do+  [inFile] <- return args+  translateFileAndRunLilypond "pdf" (Just "basic") (Just inFile)
+ tools/music2png.hs view
@@ -0,0 +1,14 @@++module Main where++import           Music.Prelude.CmdLine+import           System.Environment++-- TODO+main = do+  args <- getArgs+  main2 args++main2 args = do+  [inFile] <- return args+  translateFileAndRunLilypond "png" (Just "basic") (Just inFile)
+ tools/music2svg.hs view
@@ -0,0 +1,14 @@++module Main where++import           Music.Prelude.CmdLine+import           System.Environment++-- TODO+main = do+  args <- getArgs+  main2 args++main2 args = do+  [inFile] <- return args+  translateFileAndRunLilypond "svg" (Just "basic") (Just inFile)