\begin{code}
module Text.XML.MusicXML.Identity where
import Text.XML.MusicXML.Common
import Text.XML.HaXml.Types (Content)
import Control.Monad (MonadPlus(..))
import Prelude (Maybe, Monad(..), Functor(..), Show, Eq, (.), (++))
\end{code}
\begin{musicxml}
The identify DTD module contains the identification
element and its children, containing metadata about a
score.
Identification contains basic metadata about the score.
It includes the information in MuseData headers that
may apply at a score-wide, movement-wide, or part-wide
level. The creator, rights, source, and relation elements
are based on Dublin Core.
\end{musicxml}
\begin{code}
type Identification = ([Creator], [Rights], Maybe Encoding,
Maybe Source, [Relation], Maybe Miscellaneous)
read_Identification :: Eq i => StateT Result [Content i] Identification
read_Identification = do
y <- read_ELEMENT "identification"
read_6 (read_LIST read_Creator) (read_LIST read_Rights)
(read_MAYBE read_Encoding) (read_MAYBE read_Source)
(read_LIST read_Relation) (read_MAYBE read_Miscellaneous)
(childs y)
show_Identification :: Identification -> [Content ()]
show_Identification (a,b,c,d,e,f) =
show_ELEMENT "identification" []
(show_LIST show_Creator a ++ show_LIST show_Rights b ++
show_MAYBE show_Encoding c ++ show_MAYBE show_Source d ++
show_LIST show_Relation e ++ show_MAYBE show_Miscellaneous f)
update_Identification :: ([Software], Encoding_Date) -> Identification -> Identification
update_Identification x (a,b,c,d,e,f) = (a, b, fmap (update_Encoding x) c, d, e, f)
\end{code}
\begin{musicxml}
The creator element is borrowed from Dublin Core. It is
used for the creators of the score. The type attribute is
used to distinguish different creative contributions. Thus,
there can be multiple creators within an identification.
Standard type values are composer, lyricist, and arranger.
Other type values may be used for different types of
creative roles. The type attribute should usually be used
even if there is just a single creator element. The MusicXML
format does not use the creator / contributor distinction
from Dublin Core.
\end{musicxml}
\begin{code}
type Creator = (Maybe CDATA, PCDATA)
read_Creator :: Eq i => StateT Result [Content i] Creator
read_Creator = do
y <- read_ELEMENT "creator"
y1 <- read_1 (read_IMPLIED "type" read_CDATA) (attributes y)
y2 <- read_1 read_PCDATA (childs y)
return (y1,y2)
show_Creator :: Creator -> [Content ()]
show_Creator (a,b) =
show_ELEMENT "creator" (show_IMPLIED "type" show_CDATA a)
(show_PCDATA b)
\end{code}
\begin{musicxml}
Rights is borrowed from Dublin Core. It contains
copyright and other intellectual property notices.
Words, music, and derivatives can have different types,
so multiple rights tags with different type attributes
are supported. Standard type values are music, words,
and arrangement, but other types may be used. The
type attribute is only needed when there are multiple
rights elements.
\end{musicxml}
\begin{code}
type Rights = (Maybe CDATA, CDATA)
read_Rights :: Eq i => StateT Result [Content i] Rights
read_Rights = do
y <- read_ELEMENT "rights"
y1 <- read_1 (read_IMPLIED "type" read_CDATA) (attributes y)
y2 <- read_1 read_PCDATA (childs y)
return (y1,y2)
show_Rights :: Rights -> [Content ()]
show_Rights (a,b) =
show_ELEMENT "rights" (show_IMPLIED "type" show_CDATA a)
(show_PCDATA b)
\end{code}
\begin{musicxml}
Encoding contains information about who did the digital
encoding, when, with what software, and in what aspects.
Standard type values for the encoder element are music,
words, and arrangement, but other types may be used. The
type attribute is only needed when there are multiple
encoder elements.
The supports element indicates if the encoding supports
a particular MusicXML element. This is recommended for
elements like beam, stem, and accidental, where the
absence of an element is ambiguous if you do not know
if the encoding supports that element. For Version 2.0,
the supports element is expanded to allow programs to
indicate support for particular attributes or particular
values. This lets applications communicate, for example,
that all system and/or page breaks are contained in the
MusicXML file.
\end{musicxml}
\begin{code}
type Encoding = [Encoding_]
read_Encoding :: Eq i => StateT Result [Content i] Encoding
read_Encoding = do
y <- read_ELEMENT "encoding"
read_1 (read_LIST read_Encoding_) (childs y)
show_Encoding :: Encoding -> [Content ()]
show_Encoding a = show_ELEMENT "encoding" [] (show_LIST show_Encoding_ a)
update_Encoding :: ([Software], Encoding_Date) -> Encoding -> Encoding
update_Encoding (s,d) _ = (Encoding_1 d) : (fmap Encoding_3 s)
data Encoding_ = Encoding_1 Encoding_Date
| Encoding_2 Encoder
| Encoding_3 Software
| Encoding_4 Encoding_Description
| Encoding_5 Supports
deriving (Eq, Show)
read_Encoding_ :: Eq i => StateT Result [Content i] Encoding_
read_Encoding_ =
(read_Encoding_Date >>= return . Encoding_1) `mplus`
(read_Encoder >>= return . Encoding_2) `mplus`
(read_Software >>= return . Encoding_3) `mplus`
(read_Encoding_Description >>= return . Encoding_4) `mplus`
(read_Supports >>= return . Encoding_5)
show_Encoding_ :: Encoding_ -> [Content ()]
show_Encoding_ (Encoding_1 a) = show_Encoding_Date a
show_Encoding_ (Encoding_2 a) = show_Encoder a
show_Encoding_ (Encoding_3 a) = show_Software a
show_Encoding_ (Encoding_4 a) = show_Encoding_Description a
show_Encoding_ (Encoding_5 a) = show_Supports a
type Encoding_Date = YYYY_MM_DD
read_Encoding_Date :: Eq i => StateT Result [Content i] Encoding_Date
read_Encoding_Date = do
y <- read_ELEMENT "encoding-date"
read_1 (read_YYYY_MM_DD) (childs y)
show_Encoding_Date :: Encoding_Date -> [Content ()]
show_Encoding_Date a =
show_ELEMENT "encoding-date" [] (show_YYYY_MM_DD a)
type Encoder = (Maybe CDATA, PCDATA)
read_Encoder :: Eq i => StateT Result [Content i] Encoder
read_Encoder = do
y <- read_ELEMENT "encoder"
y1 <- read_1 (read_IMPLIED "type" read_CDATA) (attributes y)
y2 <- read_1 read_PCDATA (childs y)
return (y1,y2)
show_Encoder :: Encoder -> [Content ()]
show_Encoder (a,b) =
show_ELEMENT "encoder" (show_IMPLIED "type" show_CDATA a)
(show_PCDATA b)
type Software = PCDATA
read_Software :: Eq i => StateT Result [Content i] Software
read_Software = do
y <- read_ELEMENT "software"
read_1 read_PCDATA (childs y)
show_Software :: Software -> [Content ()]
show_Software a = show_ELEMENT "software" [] (show_PCDATA a)
type Encoding_Description = PCDATA
read_Encoding_Description :: StateT Result [Content i] Encoding_Description
read_Encoding_Description = do
y <- read_ELEMENT "encoding-description"
read_1 read_PCDATA (childs y)
show_Encoding_Description :: Encoding_Description -> [Content ()]
show_Encoding_Description a =
show_ELEMENT "encoding-description" [] (show_PCDATA a)
type Supports = ((Yes_No, CDATA, Maybe CDATA, Maybe CDATA), ())
read_Supports :: Eq i => StateT Result [Content i] Supports
read_Supports = do
y <- read_ELEMENT "supports"
y1 <- read_4 (read_REQUIRED "type" read_Yes_No)
(read_REQUIRED "element" read_CDATA)
(read_IMPLIED "attribute" read_CDATA)
(read_IMPLIED "value" read_CDATA) (attributes y)
return (y1,())
show_Supports :: Supports -> [Content ()]
show_Supports ((a,b,c,d),_) =
show_ELEMENT "supports" (show_REQUIRED "type" show_Yes_No a ++
show_REQUIRED "element" show_CDATA b ++
show_IMPLIED "attribute" show_CDATA c ++
show_IMPLIED "value" show_CDATA d) []
\end{code}
\begin{musicxml}
The source for the music that is encoded. This is similar
to the Dublin Core source element.
\end{musicxml}
\begin{code}
type Source = PCDATA
read_Source :: StateT Result [Content i] Source
read_Source = do
y <- read_ELEMENT "source"
read_1 read_PCDATA (childs y)
show_Source :: Source -> [Content ()]
show_Source a = show_ELEMENT "source" [] (show_PCDATA a)
\end{code}
\begin{musicxml}
A related resource for the music that is encoded. This is
similar to the Dublin Core relation element. Standard type
values are music, words, and arrangement, but other
types may be used.
\end{musicxml}
\begin{code}
type Relation = (Maybe CDATA, CDATA)
read_Relation :: StateT Result [Content i] Relation
read_Relation = do
y <- read_ELEMENT "relation"
y1 <- read_1 (read_IMPLIED "type" read_CDATA) (attributes y)
y2 <- read_1 read_PCDATA (childs y)
return (y1,y2)
show_Relation :: Relation -> [Content ()]
show_Relation (a,b) =
show_ELEMENT "relation" (show_IMPLIED "type" show_CDATA a)
(show_PCDATA b)
\end{code}
\begin{musicxml}
If a program has other metadata not yet supported in the
MusicXML format, it can go in the miscellaneous area.
\end{musicxml}
\begin{code}
type Miscellaneous = [Miscellaneous_Field]
read_Miscellaneous :: Eq i => StateT Result [Content i] Miscellaneous
read_Miscellaneous = do
y <- read_ELEMENT "miscellaneous"
read_1 (read_LIST read_Miscellaneous_Field) (childs y)
show_Miscellaneous :: Miscellaneous -> [Content ()]
show_Miscellaneous a =
show_ELEMENT "miscellaneous" []
(show_LIST show_Miscellaneous_Field a)
type Miscellaneous_Field = (CDATA, PCDATA)
read_Miscellaneous_Field :: StateT Result [Content i] Miscellaneous_Field
read_Miscellaneous_Field = do
y <- read_ELEMENT "miscellaneous-field"
y1 <- read_1 (read_REQUIRED "name" read_CDATA) (attributes y)
y2 <- read_1 read_PCDATA (childs y)
return (y1,y2)
show_Miscellaneous_Field :: Miscellaneous_Field -> [Content ()]
show_Miscellaneous_Field (a,b) =
show_ELEMENT "miscellaneous-field"
(show_REQUIRED "name" show_CDATA a)
(show_PCDATA b)
\end{code}