packages feed

iCalendar 0.0.1 → 0.1

raw patch · 11 files changed

+3225/−401 lines, 11 filesdep +base64-bytestringdep +bytestringdep +case-insensitivedep ~parsecnew-uploaderPVP ok

version bump matches the API change (PVP)

Dependencies added: base64-bytestring, bytestring, case-insensitive, containers, data-default, mime, mtl, network, old-locale, text, time

Dependency ranges changed: parsec

API changes (from Hackage documentation)

- Text.ICalendar.Parser: ACTION :: PropertyName
- Text.ICalendar.Parser: ALTREP :: ParamName
- Text.ICalendar.Parser: ATTACH :: PropertyName
- Text.ICalendar.Parser: ATTENDEE :: PropertyName
- Text.ICalendar.Parser: CALSCALE :: PropertyName
- Text.ICalendar.Parser: CATEGORIES :: PropertyName
- Text.ICalendar.Parser: CLASS :: PropertyName
- Text.ICalendar.Parser: CN :: ParamName
- Text.ICalendar.Parser: COMMENT :: PropertyName
- Text.ICalendar.Parser: COMPLETED :: PropertyName
- Text.ICalendar.Parser: CONTACT :: PropertyName
- Text.ICalendar.Parser: CREATED :: PropertyName
- Text.ICalendar.Parser: CUTYPE :: ParamName
- Text.ICalendar.Parser: Component :: ComponentName -> [Property] -> [Component] -> Component
- Text.ICalendar.Parser: DAYLIGHT :: ComponentName
- Text.ICalendar.Parser: DELEGATED_FROM :: ParamName
- Text.ICalendar.Parser: DELEGATED_TO :: ParamName
- Text.ICalendar.Parser: DESCRIPTION :: PropertyName
- Text.ICalendar.Parser: DIR :: ParamName
- Text.ICalendar.Parser: DTEND :: PropertyName
- Text.ICalendar.Parser: DTSTAMP :: PropertyName
- Text.ICalendar.Parser: DTSTART :: PropertyName
- Text.ICalendar.Parser: DUE :: PropertyName
- Text.ICalendar.Parser: DURATION :: PropertyName
- Text.ICalendar.Parser: ENCODING :: ParamName
- Text.ICalendar.Parser: EXDATE :: PropertyName
- Text.ICalendar.Parser: EXRULE :: PropertyName
- Text.ICalendar.Parser: FBTYPE :: ParamName
- Text.ICalendar.Parser: FMTYPE :: ParamName
- Text.ICalendar.Parser: FREEBUSY :: PropertyName
- Text.ICalendar.Parser: GEO :: PropertyName
- Text.ICalendar.Parser: ICalendar :: [Property] -> [Component] -> ICalendar
- Text.ICalendar.Parser: LANGUAGE :: ParamName
- Text.ICalendar.Parser: LAST_MODIFIED :: PropertyName
- Text.ICalendar.Parser: LOCATION :: PropertyName
- Text.ICalendar.Parser: MEMBER :: ParamName
- Text.ICalendar.Parser: METHOD :: PropertyName
- Text.ICalendar.Parser: ORGANIZER :: PropertyName
- Text.ICalendar.Parser: PARTSTAT :: ParamName
- Text.ICalendar.Parser: PERCENT_COMPLETE :: PropertyName
- Text.ICalendar.Parser: PRIORITY :: PropertyName
- Text.ICalendar.Parser: PRODID :: PropertyName
- Text.ICalendar.Parser: Param :: ParamName -> [ParamValue] -> Param
- Text.ICalendar.Parser: Paramtext :: String -> ParamValue
- Text.ICalendar.Parser: QuotedString :: String -> ParamValue
- Text.ICalendar.Parser: RANGE :: ParamName
- Text.ICalendar.Parser: RDATE :: PropertyName
- Text.ICalendar.Parser: RECURRENCE_ID :: PropertyName
- Text.ICalendar.Parser: RELATED :: ParamName
- Text.ICalendar.Parser: RELATED_TO :: PropertyName
- Text.ICalendar.Parser: RELTYPE :: ParamName
- Text.ICalendar.Parser: REPEAT :: PropertyName
- Text.ICalendar.Parser: REQUEST_STATUS :: PropertyName
- Text.ICalendar.Parser: RESOURCES :: PropertyName
- Text.ICalendar.Parser: ROLE :: ParamName
- Text.ICalendar.Parser: RRULE :: PropertyName
- Text.ICalendar.Parser: RSVP :: ParamName
- Text.ICalendar.Parser: SENT_BY :: ParamName
- Text.ICalendar.Parser: SEQUENCE :: PropertyName
- Text.ICalendar.Parser: STANDARD :: ComponentName
- Text.ICalendar.Parser: STATUS :: PropertyName
- Text.ICalendar.Parser: SUMMARY :: PropertyName
- Text.ICalendar.Parser: TRANSP :: PropertyName
- Text.ICalendar.Parser: TRIGGER :: PropertyName
- Text.ICalendar.Parser: TZID :: PropertyName
- Text.ICalendar.Parser: TZIDp :: ParamName
- Text.ICalendar.Parser: TZNAME :: PropertyName
- Text.ICalendar.Parser: TZOFFSETFROM :: PropertyName
- Text.ICalendar.Parser: TZOFFSETTO :: PropertyName
- Text.ICalendar.Parser: TZURL :: PropertyName
- Text.ICalendar.Parser: UID :: PropertyName
- Text.ICalendar.Parser: URL :: PropertyName
- Text.ICalendar.Parser: VALARM :: ComponentName
- Text.ICalendar.Parser: VALUE :: ParamName
- Text.ICalendar.Parser: VERSION :: PropertyName
- Text.ICalendar.Parser: VEVENT :: ComponentName
- Text.ICalendar.Parser: VFREEBUSY :: ComponentName
- Text.ICalendar.Parser: VJOURNAL :: ComponentName
- Text.ICalendar.Parser: VTIMEZONE :: ComponentName
- Text.ICalendar.Parser: VTODO :: ComponentName
- Text.ICalendar.Parser: X_ :: String -> PropertyName
- Text.ICalendar.Parser: X_c :: String -> ComponentName
- Text.ICalendar.Parser: X_p :: String -> ParamName
- Text.ICalendar.Parser: cName :: Component -> ComponentName
- Text.ICalendar.Parser: calendarProperties :: ICalendar -> [Property]
- Text.ICalendar.Parser: components :: ICalendar -> [Component]
- Text.ICalendar.Parser: data Component
- Text.ICalendar.Parser: data ComponentName
- Text.ICalendar.Parser: data ICalendar
- Text.ICalendar.Parser: data Param
- Text.ICalendar.Parser: data ParamName
- Text.ICalendar.Parser: data ParamValue
- Text.ICalendar.Parser: data PropertyName
- Text.ICalendar.Parser: instance Eq Component
- Text.ICalendar.Parser: instance Eq ComponentName
- Text.ICalendar.Parser: instance Eq ICalendar
- Text.ICalendar.Parser: instance Eq Param
- Text.ICalendar.Parser: instance Eq ParamName
- Text.ICalendar.Parser: instance Eq ParamValue
- Text.ICalendar.Parser: instance Eq PropertyName
- Text.ICalendar.Parser: instance Show Component
- Text.ICalendar.Parser: instance Show ComponentName
- Text.ICalendar.Parser: instance Show ICalendar
- Text.ICalendar.Parser: instance Show Param
- Text.ICalendar.Parser: instance Show ParamName
- Text.ICalendar.Parser: instance Show ParamValue
- Text.ICalendar.Parser: instance Show PropertyName
- Text.ICalendar.Parser: pName :: Param -> ParamName
- Text.ICalendar.Parser: pValues :: Param -> [ParamValue]
- Text.ICalendar.Parser: parser :: ParsecT [Char] u Identity ICalendar
- Text.ICalendar.Parser: properties :: Component -> [Property]
- Text.ICalendar.Parser: subcomponents :: Component -> [Component]
- Text.ICalendar.Parser: type Property = (PropertyName, [Param], Value)
- Text.ICalendar.Parser: type Value = String
+ Text.ICalendar.Parser: DecodingFunctions :: (ByteString -> Text) -> (ByteString -> CI Text) -> DecodingFunctions
+ Text.ICalendar.Parser: data DecodingFunctions
+ Text.ICalendar.Parser: dfBS2IText :: DecodingFunctions -> ByteString -> CI Text
+ Text.ICalendar.Parser: dfBS2Text :: DecodingFunctions -> ByteString -> Text
+ Text.ICalendar.Parser: parseICal :: DecodingFunctions -> FilePath -> ByteString -> Either String ([VCalendar], [String])
+ Text.ICalendar.Parser: parseICalFile :: DecodingFunctions -> FilePath -> IO (Either String ([VCalendar], [String]))
+ Text.ICalendar.Printer: EncodingFunctions :: (Char -> Builder) -> (Char -> Int) -> EncodingFunctions
+ Text.ICalendar.Printer: data EncodingFunctions
+ Text.ICalendar.Printer: efChar2Bu :: EncodingFunctions -> Char -> Builder
+ Text.ICalendar.Printer: efChar2Len :: EncodingFunctions -> Char -> Int
+ Text.ICalendar.Printer: instance (IsProperty a, IsProperty b) => IsProperty (Either a b)
+ Text.ICalendar.Printer: instance Default EncodingFunctions
+ Text.ICalendar.Printer: instance Eq Quoting
+ Text.ICalendar.Printer: instance IsProperty Attachment
+ Text.ICalendar.Printer: instance IsProperty Attendee
+ Text.ICalendar.Printer: instance IsProperty Categories
+ Text.ICalendar.Printer: instance IsProperty Class
+ Text.ICalendar.Printer: instance IsProperty Comment
+ Text.ICalendar.Printer: instance IsProperty Completed
+ Text.ICalendar.Printer: instance IsProperty Contact
+ Text.ICalendar.Printer: instance IsProperty Created
+ Text.ICalendar.Printer: instance IsProperty DTEnd
+ Text.ICalendar.Printer: instance IsProperty DTStamp
+ Text.ICalendar.Printer: instance IsProperty DTStart
+ Text.ICalendar.Printer: instance IsProperty Description
+ Text.ICalendar.Printer: instance IsProperty Due
+ Text.ICalendar.Printer: instance IsProperty DurationProp
+ Text.ICalendar.Printer: instance IsProperty EventStatus
+ Text.ICalendar.Printer: instance IsProperty ExDate
+ Text.ICalendar.Printer: instance IsProperty FreeBusy
+ Text.ICalendar.Printer: instance IsProperty Geo
+ Text.ICalendar.Printer: instance IsProperty JournalStatus
+ Text.ICalendar.Printer: instance IsProperty LastModified
+ Text.ICalendar.Printer: instance IsProperty Location
+ Text.ICalendar.Printer: instance IsProperty Organizer
+ Text.ICalendar.Printer: instance IsProperty OtherProperty
+ Text.ICalendar.Printer: instance IsProperty PercentComplete
+ Text.ICalendar.Printer: instance IsProperty Priority
+ Text.ICalendar.Printer: instance IsProperty RDate
+ Text.ICalendar.Printer: instance IsProperty RRule
+ Text.ICalendar.Printer: instance IsProperty RecurrenceId
+ Text.ICalendar.Printer: instance IsProperty RelatedTo
+ Text.ICalendar.Printer: instance IsProperty Repeat
+ Text.ICalendar.Printer: instance IsProperty RequestStatus
+ Text.ICalendar.Printer: instance IsProperty Resources
+ Text.ICalendar.Printer: instance IsProperty Sequence
+ Text.ICalendar.Printer: instance IsProperty Summary
+ Text.ICalendar.Printer: instance IsProperty TimeTransparency
+ Text.ICalendar.Printer: instance IsProperty TodoStatus
+ Text.ICalendar.Printer: instance IsProperty Trigger
+ Text.ICalendar.Printer: instance IsProperty UID
+ Text.ICalendar.Printer: instance IsProperty URL
+ Text.ICalendar.Printer: instance IsProperty a => IsProperty (Maybe a)
+ Text.ICalendar.Printer: instance IsProperty a => IsProperty (Set a)
+ Text.ICalendar.Printer: instance IsValue (Either Date DateTime)
+ Text.ICalendar.Printer: instance IsValue Attachment
+ Text.ICalendar.Printer: instance IsValue ClassValue
+ Text.ICalendar.Printer: instance IsValue DTEnd
+ Text.ICalendar.Printer: instance IsValue DTStamp
+ Text.ICalendar.Printer: instance IsValue DTStart
+ Text.ICalendar.Printer: instance IsValue Date
+ Text.ICalendar.Printer: instance IsValue DateTime
+ Text.ICalendar.Printer: instance IsValue Due
+ Text.ICalendar.Printer: instance IsValue Duration
+ Text.ICalendar.Printer: instance IsValue EventStatus
+ Text.ICalendar.Printer: instance IsValue ICalVersion
+ Text.ICalendar.Printer: instance IsValue JournalStatus
+ Text.ICalendar.Printer: instance IsValue Period
+ Text.ICalendar.Printer: instance IsValue RDate
+ Text.ICalendar.Printer: instance IsValue Recur
+ Text.ICalendar.Printer: instance IsValue RecurrenceId
+ Text.ICalendar.Printer: instance IsValue TimeTransparency
+ Text.ICalendar.Printer: instance IsValue TodoStatus
+ Text.ICalendar.Printer: instance IsValue URI
+ Text.ICalendar.Printer: instance IsValue UTCPeriod
+ Text.ICalendar.Printer: instance IsValue Weekday
+ Text.ICalendar.Printer: instance Ord Quoting
+ Text.ICalendar.Printer: instance Show Quoting
+ Text.ICalendar.Printer: instance ToParam (Text, [(Quoting, Text)])
+ Text.ICalendar.Printer: instance ToParam AlarmTriggerRelationship
+ Text.ICalendar.Printer: instance ToParam AltRep
+ Text.ICalendar.Printer: instance ToParam Attachment
+ Text.ICalendar.Printer: instance ToParam Attendee
+ Text.ICalendar.Printer: instance ToParam CN
+ Text.ICalendar.Printer: instance ToParam CUType
+ Text.ICalendar.Printer: instance ToParam DTEnd
+ Text.ICalendar.Printer: instance ToParam DTStamp
+ Text.ICalendar.Printer: instance ToParam DTStart
+ Text.ICalendar.Printer: instance ToParam DateTime
+ Text.ICalendar.Printer: instance ToParam DelFrom
+ Text.ICalendar.Printer: instance ToParam DelTo
+ Text.ICalendar.Printer: instance ToParam Dir
+ Text.ICalendar.Printer: instance ToParam Due
+ Text.ICalendar.Printer: instance ToParam ExDate
+ Text.ICalendar.Printer: instance ToParam FBType
+ Text.ICalendar.Printer: instance ToParam Language
+ Text.ICalendar.Printer: instance ToParam MIMEType
+ Text.ICalendar.Printer: instance ToParam Member
+ Text.ICalendar.Printer: instance ToParam OtherParams
+ Text.ICalendar.Printer: instance ToParam PartStat
+ Text.ICalendar.Printer: instance ToParam Period
+ Text.ICalendar.Printer: instance ToParam RDate
+ Text.ICalendar.Printer: instance ToParam RSVP
+ Text.ICalendar.Printer: instance ToParam RecurrenceId
+ Text.ICalendar.Printer: instance ToParam RelationshipType
+ Text.ICalendar.Printer: instance ToParam Role
+ Text.ICalendar.Printer: instance ToParam SentBy
+ Text.ICalendar.Printer: instance ToParam TZName
+ Text.ICalendar.Printer: instance ToParam Trigger
+ Text.ICalendar.Printer: instance ToParam a => ToParam (Maybe a)
+ Text.ICalendar.Printer: instance ToParam a => ToParam (Set a)
+ Text.ICalendar.Printer: instance ToParam x => ToParam [x]
+ Text.ICalendar.Printer: printICal :: EncodingFunctions -> VCalendar -> ByteString
+ Text.ICalendar.Types: Accepted :: PartStat
+ Text.ICalendar.Types: Attendee :: CalAddress -> CUType -> Set CalAddress -> Role -> PartStat -> Bool -> Set CalAddress -> Set CalAddress -> Maybe CalAddress -> Maybe Text -> Maybe URI -> Maybe Language -> OtherParams -> Attendee
+ Text.ICalendar.Types: BinaryAttachment :: Maybe MIMEType -> ByteString -> OtherParams -> Attachment
+ Text.ICalendar.Types: Busy :: FBType
+ Text.ICalendar.Types: BusyTentative :: FBType
+ Text.ICalendar.Types: BusyUnavailable :: FBType
+ Text.ICalendar.Types: CUTypeX :: (CI Text) -> CUType
+ Text.ICalendar.Types: CancelledEvent :: OtherParams -> EventStatus
+ Text.ICalendar.Types: CancelledJournal :: OtherParams -> JournalStatus
+ Text.ICalendar.Types: CancelledTodo :: OtherParams -> TodoStatus
+ Text.ICalendar.Types: Categories :: Set Text -> Maybe Language -> OtherParams -> Categories
+ Text.ICalendar.Types: Chair :: Role
+ Text.ICalendar.Types: Child :: RelationshipType
+ Text.ICalendar.Types: Class :: ClassValue -> OtherParams -> Class
+ Text.ICalendar.Types: ClassValueX :: (CI Text) -> ClassValue
+ Text.ICalendar.Types: Comment :: Text -> Maybe URI -> Maybe Language -> OtherParams -> Comment
+ Text.ICalendar.Types: Completed :: DateTime -> OtherParams -> Completed
+ Text.ICalendar.Types: CompletedTodo :: OtherParams -> TodoStatus
+ Text.ICalendar.Types: Confidential :: ClassValue
+ Text.ICalendar.Types: ConfirmedEvent :: OtherParams -> EventStatus
+ Text.ICalendar.Types: Contact :: Text -> Maybe URI -> Maybe Language -> OtherParams -> Contact
+ Text.ICalendar.Types: Created :: DateTime -> OtherParams -> Created
+ Text.ICalendar.Types: DTEndDate :: Date -> OtherParams -> DTEnd
+ Text.ICalendar.Types: DTEndDateTime :: DateTime -> OtherParams -> DTEnd
+ Text.ICalendar.Types: DTStamp :: UTCTime -> OtherParams -> DTStamp
+ Text.ICalendar.Types: DTStartDate :: Date -> OtherParams -> DTStart
+ Text.ICalendar.Types: DTStartDateTime :: DateTime -> OtherParams -> DTStart
+ Text.ICalendar.Types: Daily :: Frequency
+ Text.ICalendar.Types: Date :: Day -> Date
+ Text.ICalendar.Types: Declined :: PartStat
+ Text.ICalendar.Types: Delegated :: PartStat
+ Text.ICalendar.Types: Description :: Text -> Maybe URI -> Maybe Language -> OtherParams -> Description
+ Text.ICalendar.Types: DraftJournal :: OtherParams -> JournalStatus
+ Text.ICalendar.Types: DueDate :: Date -> OtherParams -> Due
+ Text.ICalendar.Types: DueDateTime :: DateTime -> OtherParams -> Due
+ Text.ICalendar.Types: DurationDate :: Sign -> Int -> Int -> Int -> Int -> Duration
+ Text.ICalendar.Types: DurationProp :: Duration -> OtherParams -> DurationProp
+ Text.ICalendar.Types: DurationTime :: Sign -> Int -> Int -> Int -> Duration
+ Text.ICalendar.Types: DurationWeek :: Sign -> Int -> Duration
+ Text.ICalendar.Types: End :: AlarmTriggerRelationship
+ Text.ICalendar.Types: ExDateTimes :: Set DateTime -> OtherParams -> ExDate
+ Text.ICalendar.Types: ExDates :: Set Date -> OtherParams -> ExDate
+ Text.ICalendar.Types: FBTypeX :: (CI Text) -> FBType
+ Text.ICalendar.Types: FinalJournal :: OtherParams -> JournalStatus
+ Text.ICalendar.Types: FloatingDateTime :: LocalTime -> DateTime
+ Text.ICalendar.Types: Free :: FBType
+ Text.ICalendar.Types: FreeBusy :: FBType -> Set UTCPeriod -> OtherParams -> FreeBusy
+ Text.ICalendar.Types: Friday :: Weekday
+ Text.ICalendar.Types: Geo :: Float -> Float -> OtherParams -> Geo
+ Text.ICalendar.Types: Group :: CUType
+ Text.ICalendar.Types: Hourly :: Frequency
+ Text.ICalendar.Types: InProcess :: PartStat
+ Text.ICalendar.Types: InProcessTodo :: OtherParams -> TodoStatus
+ Text.ICalendar.Types: Individual :: CUType
+ Text.ICalendar.Types: Language :: (CI Text) -> Language
+ Text.ICalendar.Types: LastModified :: UTCTime -> OtherParams -> LastModified
+ Text.ICalendar.Types: Location :: Text -> Maybe URI -> Maybe Language -> OtherParams -> Location
+ Text.ICalendar.Types: MaxICalVersion :: Version -> OtherParams -> ICalVersion
+ Text.ICalendar.Types: Method :: CI Text -> OtherParams -> Method
+ Text.ICalendar.Types: MinMaxICalVersion :: Version -> Version -> OtherParams -> ICalVersion
+ Text.ICalendar.Types: Minutely :: Frequency
+ Text.ICalendar.Types: Monday :: Weekday
+ Text.ICalendar.Types: Monthly :: Frequency
+ Text.ICalendar.Types: Negative :: Sign
+ Text.ICalendar.Types: NonParticipant :: Role
+ Text.ICalendar.Types: Opaque :: OtherParams -> TimeTransparency
+ Text.ICalendar.Types: OptParticipant :: Role
+ Text.ICalendar.Types: Organizer :: CalAddress -> Maybe Text -> Maybe URI -> Maybe CalAddress -> Maybe Language -> OtherParams -> Organizer
+ Text.ICalendar.Types: OtherParam :: (CI Text) -> [Text] -> OtherParam
+ Text.ICalendar.Types: OtherParams :: (Set OtherParam) -> OtherParams
+ Text.ICalendar.Types: OtherProperty :: CI Text -> ByteString -> OtherParams -> OtherProperty
+ Text.ICalendar.Types: Parent :: RelationshipType
+ Text.ICalendar.Types: PartStatCompleted :: PartStat
+ Text.ICalendar.Types: PartStatNeedsAction :: PartStat
+ Text.ICalendar.Types: PartStatX :: (CI Text) -> PartStat
+ Text.ICalendar.Types: PercentComplete :: Int -> OtherParams -> PercentComplete
+ Text.ICalendar.Types: PeriodDates :: DateTime -> DateTime -> Period
+ Text.ICalendar.Types: PeriodDuration :: DateTime -> Duration -> Period
+ Text.ICalendar.Types: Positive :: Sign
+ Text.ICalendar.Types: Priority :: Int -> OtherParams -> Priority
+ Text.ICalendar.Types: Private :: ClassValue
+ Text.ICalendar.Types: ProdId :: Text -> OtherParams -> ProdId
+ Text.ICalendar.Types: Public :: ClassValue
+ Text.ICalendar.Types: RDateDateTimes :: Set DateTime -> OtherParams -> RDate
+ Text.ICalendar.Types: RDateDates :: Set Date -> OtherParams -> RDate
+ Text.ICalendar.Types: RDatePeriods :: Set Period -> OtherParams -> RDate
+ Text.ICalendar.Types: RRule :: Recur -> OtherParams -> RRule
+ Text.ICalendar.Types: Recur :: Frequency -> Maybe (Either (Either Date DateTime) Int) -> Int -> [Int] -> [Int] -> [Int] -> [Either (Int, Weekday) Weekday] -> [Int] -> [Int] -> [Int] -> [Int] -> [Int] -> Weekday -> Recur
+ Text.ICalendar.Types: RecurrenceIdDate :: Date -> Range -> OtherParams -> RecurrenceId
+ Text.ICalendar.Types: RecurrenceIdDateTime :: DateTime -> Range -> OtherParams -> RecurrenceId
+ Text.ICalendar.Types: RelatedTo :: Text -> RelationshipType -> OtherParams -> RelatedTo
+ Text.ICalendar.Types: RelationshipTypeX :: (CI Text) -> RelationshipType
+ Text.ICalendar.Types: Repeat :: Integer -> OtherParams -> Repeat
+ Text.ICalendar.Types: ReqParticipant :: Role
+ Text.ICalendar.Types: RequestStatus :: [Int] -> Text -> Maybe Language -> Maybe Text -> OtherParams -> RequestStatus
+ Text.ICalendar.Types: Resource :: CUType
+ Text.ICalendar.Types: Resources :: Set Text -> Maybe URI -> Maybe Language -> OtherParams -> Resources
+ Text.ICalendar.Types: RoleX :: (CI Text) -> Role
+ Text.ICalendar.Types: Room :: CUType
+ Text.ICalendar.Types: Saturday :: Weekday
+ Text.ICalendar.Types: Scale :: CI Text -> OtherParams -> Scale
+ Text.ICalendar.Types: Secondly :: Frequency
+ Text.ICalendar.Types: Sequence :: Integer -> OtherParams -> Sequence
+ Text.ICalendar.Types: Sibling :: RelationshipType
+ Text.ICalendar.Types: Start :: AlarmTriggerRelationship
+ Text.ICalendar.Types: Summary :: Text -> Maybe URI -> Maybe Language -> OtherParams -> Summary
+ Text.ICalendar.Types: Sunday :: Weekday
+ Text.ICalendar.Types: TZID :: Text -> Bool -> OtherParams -> TZID
+ Text.ICalendar.Types: TZName :: Text -> Maybe Language -> OtherParams -> TZName
+ Text.ICalendar.Types: TZProp :: DTStart -> UTCOffset -> UTCOffset -> Set RRule -> Set Comment -> Set RDate -> Set TZName -> Set OtherProperty -> TZProp
+ Text.ICalendar.Types: TZUrl :: URI -> OtherParams -> TZUrl
+ Text.ICalendar.Types: Tentative :: PartStat
+ Text.ICalendar.Types: TentativeEvent :: OtherParams -> EventStatus
+ Text.ICalendar.Types: ThisAndFuture :: Range
+ Text.ICalendar.Types: ThisAndPrior :: Range
+ Text.ICalendar.Types: Thursday :: Weekday
+ Text.ICalendar.Types: TodoNeedsAction :: OtherParams -> TodoStatus
+ Text.ICalendar.Types: Transparent :: OtherParams -> TimeTransparency
+ Text.ICalendar.Types: TriggerDateTime :: UTCTime -> OtherParams -> Trigger
+ Text.ICalendar.Types: TriggerDuration :: Duration -> AlarmTriggerRelationship -> OtherParams -> Trigger
+ Text.ICalendar.Types: Tuesday :: Weekday
+ Text.ICalendar.Types: UID :: Text -> OtherParams -> UID
+ Text.ICalendar.Types: URL :: URI -> OtherParams -> URL
+ Text.ICalendar.Types: UTCDateTime :: UTCTime -> DateTime
+ Text.ICalendar.Types: UTCOffset :: Int -> OtherParams -> UTCOffset
+ Text.ICalendar.Types: UTCPeriodDates :: UTCTime -> UTCTime -> UTCPeriod
+ Text.ICalendar.Types: UTCPeriodDuration :: UTCTime -> Duration -> UTCPeriod
+ Text.ICalendar.Types: Unknown :: CUType
+ Text.ICalendar.Types: UriAttachment :: Maybe MIMEType -> URI -> OtherParams -> Attachment
+ Text.ICalendar.Types: VAlarmAudio :: Trigger -> Repeat -> Maybe DurationProp -> Maybe Attachment -> Set OtherProperty -> OtherParams -> VAlarm
+ Text.ICalendar.Types: VAlarmDisplay :: Description -> Trigger -> Repeat -> Maybe DurationProp -> Set OtherProperty -> OtherParams -> VAlarm
+ Text.ICalendar.Types: VAlarmEmail :: Description -> Trigger -> Summary -> Set Attendee -> Repeat -> Maybe DurationProp -> Set Attachment -> Set OtherProperty -> OtherParams -> VAlarm
+ Text.ICalendar.Types: VAlarmX :: CI Text -> Trigger -> OtherParams -> Set OtherProperty -> VAlarm
+ Text.ICalendar.Types: VCalendar :: ProdId -> ICalVersion -> Scale -> Maybe Method -> Set OtherProperty -> Set VTimeZone -> Set VEvent -> Set VTodo -> Set VJournal -> Set VFreeBusy -> Set VOther -> VCalendar
+ Text.ICalendar.Types: VEvent :: DTStamp -> UID -> Class -> Maybe DTStart -> Maybe Created -> Maybe Description -> Maybe Geo -> Maybe LastModified -> Maybe Location -> Maybe Organizer -> Priority -> Sequence -> Maybe EventStatus -> Maybe Summary -> TimeTransparency -> Maybe URL -> Maybe RecurrenceId -> Set RRule -> Maybe (Either DTEnd DurationProp) -> Set Attachment -> Set Attendee -> Set Categories -> Set Comment -> Set Contact -> Set ExDate -> Set RequestStatus -> Set RelatedTo -> Set Resources -> Set RDate -> Set VAlarm -> Set OtherProperty -> VEvent
+ Text.ICalendar.Types: VFreeBusy :: DTStamp -> UID -> Maybe Contact -> Maybe DTStart -> Maybe DTEnd -> Maybe Organizer -> Maybe URL -> Set Attendee -> Set Comment -> Set FreeBusy -> Set RequestStatus -> Set OtherProperty -> VFreeBusy
+ Text.ICalendar.Types: VJournal :: DTStamp -> UID -> Class -> Maybe Created -> Maybe DTStart -> Maybe LastModified -> Maybe Organizer -> Maybe RecurrenceId -> Sequence -> Maybe JournalStatus -> Maybe Summary -> Maybe URL -> Set RRule -> Set Attachment -> Set Attendee -> Set Categories -> Set Comment -> Set Contact -> Set Description -> Set ExDate -> Set RelatedTo -> Set RDate -> Set RequestStatus -> Set OtherProperty -> VJournal
+ Text.ICalendar.Types: VOther :: CI Text -> Set OtherProperty -> VOther
+ Text.ICalendar.Types: VTimeZone :: TZID -> Maybe LastModified -> Maybe TZUrl -> Set TZProp -> Set TZProp -> Set OtherProperty -> VTimeZone
+ Text.ICalendar.Types: VTodo :: DTStamp -> UID -> Class -> Maybe Completed -> Maybe Created -> Maybe Description -> Maybe DTStart -> Maybe Geo -> Maybe LastModified -> Maybe Location -> Maybe Organizer -> Maybe PercentComplete -> Priority -> Maybe RecurrenceId -> Sequence -> Maybe TodoStatus -> Maybe Summary -> Maybe URL -> Set RRule -> Maybe (Either Due DurationProp) -> Set Attachment -> Set Attendee -> Set Categories -> Set Comment -> Set Contact -> Set ExDate -> Set RequestStatus -> Set RelatedTo -> Set Resources -> Set RDate -> Set VAlarm -> Set OtherProperty -> VTodo
+ Text.ICalendar.Types: Wednesday :: Weekday
+ Text.ICalendar.Types: Weekly :: Frequency
+ Text.ICalendar.Types: Yearly :: Frequency
+ Text.ICalendar.Types: ZonedDateTime :: LocalTime -> Text -> DateTime
+ Text.ICalendar.Types: attachContent :: Attachment -> ByteString
+ Text.ICalendar.Types: attachFmtType :: Attachment -> Maybe MIMEType
+ Text.ICalendar.Types: attachOther :: Attachment -> OtherParams
+ Text.ICalendar.Types: attachUri :: Attachment -> URI
+ Text.ICalendar.Types: attendeeCN :: Attendee -> Maybe Text
+ Text.ICalendar.Types: attendeeCUType :: Attendee -> CUType
+ Text.ICalendar.Types: attendeeDelFrom :: Attendee -> Set CalAddress
+ Text.ICalendar.Types: attendeeDelTo :: Attendee -> Set CalAddress
+ Text.ICalendar.Types: attendeeDir :: Attendee -> Maybe URI
+ Text.ICalendar.Types: attendeeLanguage :: Attendee -> Maybe Language
+ Text.ICalendar.Types: attendeeMember :: Attendee -> Set CalAddress
+ Text.ICalendar.Types: attendeeOther :: Attendee -> OtherParams
+ Text.ICalendar.Types: attendeePartStat :: Attendee -> PartStat
+ Text.ICalendar.Types: attendeeRSVP :: Attendee -> Bool
+ Text.ICalendar.Types: attendeeRole :: Attendee -> Role
+ Text.ICalendar.Types: attendeeSentBy :: Attendee -> Maybe CalAddress
+ Text.ICalendar.Types: attendeeValue :: Attendee -> CalAddress
+ Text.ICalendar.Types: categoriesLanguage :: Categories -> Maybe Language
+ Text.ICalendar.Types: categoriesOther :: Categories -> OtherParams
+ Text.ICalendar.Types: categoriesValues :: Categories -> Set Text
+ Text.ICalendar.Types: classOther :: Class -> OtherParams
+ Text.ICalendar.Types: classValue :: Class -> ClassValue
+ Text.ICalendar.Types: commentAltRep :: Comment -> Maybe URI
+ Text.ICalendar.Types: commentLanguage :: Comment -> Maybe Language
+ Text.ICalendar.Types: commentOther :: Comment -> OtherParams
+ Text.ICalendar.Types: commentValue :: Comment -> Text
+ Text.ICalendar.Types: completedOther :: Completed -> OtherParams
+ Text.ICalendar.Types: completedValue :: Completed -> DateTime
+ Text.ICalendar.Types: contactAltRep :: Contact -> Maybe URI
+ Text.ICalendar.Types: contactLanguage :: Contact -> Maybe Language
+ Text.ICalendar.Types: contactOther :: Contact -> OtherParams
+ Text.ICalendar.Types: contactValue :: Contact -> Text
+ Text.ICalendar.Types: createdOther :: Created -> OtherParams
+ Text.ICalendar.Types: createdValue :: Created -> DateTime
+ Text.ICalendar.Types: data AlarmTriggerRelationship
+ Text.ICalendar.Types: data Attachment
+ Text.ICalendar.Types: data Attendee
+ Text.ICalendar.Types: data CUType
+ Text.ICalendar.Types: data Categories
+ Text.ICalendar.Types: data Class
+ Text.ICalendar.Types: data ClassValue
+ Text.ICalendar.Types: data Comment
+ Text.ICalendar.Types: data Completed
+ Text.ICalendar.Types: data Contact
+ Text.ICalendar.Types: data Created
+ Text.ICalendar.Types: data DTEnd
+ Text.ICalendar.Types: data DTStamp
+ Text.ICalendar.Types: data DTStart
+ Text.ICalendar.Types: data Date
+ Text.ICalendar.Types: data DateTime
+ Text.ICalendar.Types: data Description
+ Text.ICalendar.Types: data Due
+ Text.ICalendar.Types: data Duration
+ Text.ICalendar.Types: data DurationProp
+ Text.ICalendar.Types: data EventStatus
+ Text.ICalendar.Types: data ExDate
+ Text.ICalendar.Types: data FBType
+ Text.ICalendar.Types: data FreeBusy
+ Text.ICalendar.Types: data Frequency
+ Text.ICalendar.Types: data Geo
+ Text.ICalendar.Types: data ICalVersion
+ Text.ICalendar.Types: data JournalStatus
+ Text.ICalendar.Types: data LastModified
+ Text.ICalendar.Types: data Location
+ Text.ICalendar.Types: data Method
+ Text.ICalendar.Types: data Organizer
+ Text.ICalendar.Types: data OtherParam
+ Text.ICalendar.Types: data OtherParams
+ Text.ICalendar.Types: data OtherProperty
+ Text.ICalendar.Types: data PartStat
+ Text.ICalendar.Types: data PercentComplete
+ Text.ICalendar.Types: data Period
+ Text.ICalendar.Types: data Priority
+ Text.ICalendar.Types: data ProdId
+ Text.ICalendar.Types: data RDate
+ Text.ICalendar.Types: data RRule
+ Text.ICalendar.Types: data Range
+ Text.ICalendar.Types: data Recur
+ Text.ICalendar.Types: data RecurrenceId
+ Text.ICalendar.Types: data RelatedTo
+ Text.ICalendar.Types: data RelationshipType
+ Text.ICalendar.Types: data Repeat
+ Text.ICalendar.Types: data RequestStatus
+ Text.ICalendar.Types: data Resources
+ Text.ICalendar.Types: data Role
+ Text.ICalendar.Types: data Scale
+ Text.ICalendar.Types: data Sequence
+ Text.ICalendar.Types: data Sign
+ Text.ICalendar.Types: data Summary
+ Text.ICalendar.Types: data TZID
+ Text.ICalendar.Types: data TZName
+ Text.ICalendar.Types: data TZProp
+ Text.ICalendar.Types: data TZUrl
+ Text.ICalendar.Types: data TimeTransparency
+ Text.ICalendar.Types: data TodoStatus
+ Text.ICalendar.Types: data Trigger
+ Text.ICalendar.Types: data UID
+ Text.ICalendar.Types: data URL
+ Text.ICalendar.Types: data UTCOffset
+ Text.ICalendar.Types: data UTCPeriod
+ Text.ICalendar.Types: data VAlarm
+ Text.ICalendar.Types: data VCalendar
+ Text.ICalendar.Types: data VEvent
+ Text.ICalendar.Types: data VFreeBusy
+ Text.ICalendar.Types: data VJournal
+ Text.ICalendar.Types: data VOther
+ Text.ICalendar.Types: data VTimeZone
+ Text.ICalendar.Types: data VTodo
+ Text.ICalendar.Types: data Weekday
+ Text.ICalendar.Types: dateTimeFloating :: DateTime -> LocalTime
+ Text.ICalendar.Types: dateTimeUTC :: DateTime -> UTCTime
+ Text.ICalendar.Types: dateTimeZone :: DateTime -> Text
+ Text.ICalendar.Types: dateValue :: Date -> Day
+ Text.ICalendar.Types: descriptionAltRep :: Description -> Maybe URI
+ Text.ICalendar.Types: descriptionLanguage :: Description -> Maybe Language
+ Text.ICalendar.Types: descriptionOther :: Description -> OtherParams
+ Text.ICalendar.Types: descriptionValue :: Description -> Text
+ Text.ICalendar.Types: dtEndDateTimeValue :: DTEnd -> DateTime
+ Text.ICalendar.Types: dtEndDateValue :: DTEnd -> Date
+ Text.ICalendar.Types: dtEndOther :: DTEnd -> OtherParams
+ Text.ICalendar.Types: dtStampOther :: DTStamp -> OtherParams
+ Text.ICalendar.Types: dtStampValue :: DTStamp -> UTCTime
+ Text.ICalendar.Types: dtStartDateTimeValue :: DTStart -> DateTime
+ Text.ICalendar.Types: dtStartDateValue :: DTStart -> Date
+ Text.ICalendar.Types: dtStartOther :: DTStart -> OtherParams
+ Text.ICalendar.Types: dueDateTimeValue :: Due -> DateTime
+ Text.ICalendar.Types: dueDateValue :: Due -> Date
+ Text.ICalendar.Types: dueOther :: Due -> OtherParams
+ Text.ICalendar.Types: durDay :: Duration -> Int
+ Text.ICalendar.Types: durHour :: Duration -> Int
+ Text.ICalendar.Types: durMinute :: Duration -> Int
+ Text.ICalendar.Types: durSecond :: Duration -> Int
+ Text.ICalendar.Types: durSign :: Duration -> Sign
+ Text.ICalendar.Types: durWeek :: Duration -> Int
+ Text.ICalendar.Types: durationOther :: DurationProp -> OtherParams
+ Text.ICalendar.Types: durationValue :: DurationProp -> Duration
+ Text.ICalendar.Types: eventStatusOther :: EventStatus -> OtherParams
+ Text.ICalendar.Types: exDateOther :: ExDate -> OtherParams
+ Text.ICalendar.Types: exDateTimes :: ExDate -> Set DateTime
+ Text.ICalendar.Types: exDates :: ExDate -> Set Date
+ Text.ICalendar.Types: freeBusyOther :: FreeBusy -> OtherParams
+ Text.ICalendar.Types: freeBusyPeriods :: FreeBusy -> Set UTCPeriod
+ Text.ICalendar.Types: freeBusyType :: FreeBusy -> FBType
+ Text.ICalendar.Types: geoLat :: Geo -> Float
+ Text.ICalendar.Types: geoLong :: Geo -> Float
+ Text.ICalendar.Types: geoOther :: Geo -> OtherParams
+ Text.ICalendar.Types: instance Bounded Weekday
+ Text.ICalendar.Types: instance Default AlarmTriggerRelationship
+ Text.ICalendar.Types: instance Default CUType
+ Text.ICalendar.Types: instance Default Class
+ Text.ICalendar.Types: instance Default ClassValue
+ Text.ICalendar.Types: instance Default FBType
+ Text.ICalendar.Types: instance Default OtherParams
+ Text.ICalendar.Types: instance Default PartStat
+ Text.ICalendar.Types: instance Default Priority
+ Text.ICalendar.Types: instance Default Range
+ Text.ICalendar.Types: instance Default RelationshipType
+ Text.ICalendar.Types: instance Default Repeat
+ Text.ICalendar.Types: instance Default Role
+ Text.ICalendar.Types: instance Default Scale
+ Text.ICalendar.Types: instance Default Sequence
+ Text.ICalendar.Types: instance Default Sign
+ Text.ICalendar.Types: instance Default TimeTransparency
+ Text.ICalendar.Types: instance Default VCalendar
+ Text.ICalendar.Types: instance Enum Weekday
+ Text.ICalendar.Types: instance Eq AlarmTriggerRelationship
+ Text.ICalendar.Types: instance Eq Attachment
+ Text.ICalendar.Types: instance Eq Attendee
+ Text.ICalendar.Types: instance Eq CUType
+ Text.ICalendar.Types: instance Eq Categories
+ Text.ICalendar.Types: instance Eq Class
+ Text.ICalendar.Types: instance Eq ClassValue
+ Text.ICalendar.Types: instance Eq Comment
+ Text.ICalendar.Types: instance Eq Completed
+ Text.ICalendar.Types: instance Eq Contact
+ Text.ICalendar.Types: instance Eq Created
+ Text.ICalendar.Types: instance Eq DTEnd
+ Text.ICalendar.Types: instance Eq DTStamp
+ Text.ICalendar.Types: instance Eq DTStart
+ Text.ICalendar.Types: instance Eq Date
+ Text.ICalendar.Types: instance Eq DateTime
+ Text.ICalendar.Types: instance Eq Description
+ Text.ICalendar.Types: instance Eq Due
+ Text.ICalendar.Types: instance Eq Duration
+ Text.ICalendar.Types: instance Eq DurationProp
+ Text.ICalendar.Types: instance Eq EventStatus
+ Text.ICalendar.Types: instance Eq ExDate
+ Text.ICalendar.Types: instance Eq FBType
+ Text.ICalendar.Types: instance Eq FreeBusy
+ Text.ICalendar.Types: instance Eq Frequency
+ Text.ICalendar.Types: instance Eq Geo
+ Text.ICalendar.Types: instance Eq ICalVersion
+ Text.ICalendar.Types: instance Eq JournalStatus
+ Text.ICalendar.Types: instance Eq Language
+ Text.ICalendar.Types: instance Eq LastModified
+ Text.ICalendar.Types: instance Eq Location
+ Text.ICalendar.Types: instance Eq Method
+ Text.ICalendar.Types: instance Eq Organizer
+ Text.ICalendar.Types: instance Eq OtherParam
+ Text.ICalendar.Types: instance Eq OtherParams
+ Text.ICalendar.Types: instance Eq OtherProperty
+ Text.ICalendar.Types: instance Eq PartStat
+ Text.ICalendar.Types: instance Eq PercentComplete
+ Text.ICalendar.Types: instance Eq Period
+ Text.ICalendar.Types: instance Eq Priority
+ Text.ICalendar.Types: instance Eq ProdId
+ Text.ICalendar.Types: instance Eq RDate
+ Text.ICalendar.Types: instance Eq RRule
+ Text.ICalendar.Types: instance Eq Range
+ Text.ICalendar.Types: instance Eq Recur
+ Text.ICalendar.Types: instance Eq RecurrenceId
+ Text.ICalendar.Types: instance Eq RelatedTo
+ Text.ICalendar.Types: instance Eq RelationshipType
+ Text.ICalendar.Types: instance Eq Repeat
+ Text.ICalendar.Types: instance Eq RequestStatus
+ Text.ICalendar.Types: instance Eq Resources
+ Text.ICalendar.Types: instance Eq Role
+ Text.ICalendar.Types: instance Eq Scale
+ Text.ICalendar.Types: instance Eq Sequence
+ Text.ICalendar.Types: instance Eq Sign
+ Text.ICalendar.Types: instance Eq Summary
+ Text.ICalendar.Types: instance Eq TZID
+ Text.ICalendar.Types: instance Eq TZName
+ Text.ICalendar.Types: instance Eq TZProp
+ Text.ICalendar.Types: instance Eq TZUrl
+ Text.ICalendar.Types: instance Eq TimeTransparency
+ Text.ICalendar.Types: instance Eq TodoStatus
+ Text.ICalendar.Types: instance Eq Trigger
+ Text.ICalendar.Types: instance Eq UID
+ Text.ICalendar.Types: instance Eq URL
+ Text.ICalendar.Types: instance Eq UTCOffset
+ Text.ICalendar.Types: instance Eq UTCPeriod
+ Text.ICalendar.Types: instance Eq VAlarm
+ Text.ICalendar.Types: instance Eq VCalendar
+ Text.ICalendar.Types: instance Eq VEvent
+ Text.ICalendar.Types: instance Eq VFreeBusy
+ Text.ICalendar.Types: instance Eq VJournal
+ Text.ICalendar.Types: instance Eq VOther
+ Text.ICalendar.Types: instance Eq VTimeZone
+ Text.ICalendar.Types: instance Eq VTodo
+ Text.ICalendar.Types: instance Eq Weekday
+ Text.ICalendar.Types: instance Ord AlarmTriggerRelationship
+ Text.ICalendar.Types: instance Ord Attachment
+ Text.ICalendar.Types: instance Ord Attendee
+ Text.ICalendar.Types: instance Ord CUType
+ Text.ICalendar.Types: instance Ord Categories
+ Text.ICalendar.Types: instance Ord Class
+ Text.ICalendar.Types: instance Ord ClassValue
+ Text.ICalendar.Types: instance Ord Comment
+ Text.ICalendar.Types: instance Ord Completed
+ Text.ICalendar.Types: instance Ord Contact
+ Text.ICalendar.Types: instance Ord Created
+ Text.ICalendar.Types: instance Ord DTEnd
+ Text.ICalendar.Types: instance Ord DTStamp
+ Text.ICalendar.Types: instance Ord DTStart
+ Text.ICalendar.Types: instance Ord Date
+ Text.ICalendar.Types: instance Ord DateTime
+ Text.ICalendar.Types: instance Ord Description
+ Text.ICalendar.Types: instance Ord Due
+ Text.ICalendar.Types: instance Ord Duration
+ Text.ICalendar.Types: instance Ord DurationProp
+ Text.ICalendar.Types: instance Ord EventStatus
+ Text.ICalendar.Types: instance Ord ExDate
+ Text.ICalendar.Types: instance Ord FBType
+ Text.ICalendar.Types: instance Ord FreeBusy
+ Text.ICalendar.Types: instance Ord Frequency
+ Text.ICalendar.Types: instance Ord Geo
+ Text.ICalendar.Types: instance Ord ICalVersion
+ Text.ICalendar.Types: instance Ord JournalStatus
+ Text.ICalendar.Types: instance Ord Language
+ Text.ICalendar.Types: instance Ord LastModified
+ Text.ICalendar.Types: instance Ord Location
+ Text.ICalendar.Types: instance Ord Method
+ Text.ICalendar.Types: instance Ord Organizer
+ Text.ICalendar.Types: instance Ord OtherParam
+ Text.ICalendar.Types: instance Ord OtherParams
+ Text.ICalendar.Types: instance Ord OtherProperty
+ Text.ICalendar.Types: instance Ord PartStat
+ Text.ICalendar.Types: instance Ord PercentComplete
+ Text.ICalendar.Types: instance Ord Period
+ Text.ICalendar.Types: instance Ord Priority
+ Text.ICalendar.Types: instance Ord ProdId
+ Text.ICalendar.Types: instance Ord RDate
+ Text.ICalendar.Types: instance Ord RRule
+ Text.ICalendar.Types: instance Ord Range
+ Text.ICalendar.Types: instance Ord Recur
+ Text.ICalendar.Types: instance Ord RecurrenceId
+ Text.ICalendar.Types: instance Ord RelatedTo
+ Text.ICalendar.Types: instance Ord RelationshipType
+ Text.ICalendar.Types: instance Ord Repeat
+ Text.ICalendar.Types: instance Ord RequestStatus
+ Text.ICalendar.Types: instance Ord Resources
+ Text.ICalendar.Types: instance Ord Role
+ Text.ICalendar.Types: instance Ord Scale
+ Text.ICalendar.Types: instance Ord Sequence
+ Text.ICalendar.Types: instance Ord Sign
+ Text.ICalendar.Types: instance Ord Summary
+ Text.ICalendar.Types: instance Ord TZID
+ Text.ICalendar.Types: instance Ord TZName
+ Text.ICalendar.Types: instance Ord TZProp
+ Text.ICalendar.Types: instance Ord TZUrl
+ Text.ICalendar.Types: instance Ord TimeTransparency
+ Text.ICalendar.Types: instance Ord TodoStatus
+ Text.ICalendar.Types: instance Ord Trigger
+ Text.ICalendar.Types: instance Ord UID
+ Text.ICalendar.Types: instance Ord URL
+ Text.ICalendar.Types: instance Ord UTCOffset
+ Text.ICalendar.Types: instance Ord UTCPeriod
+ Text.ICalendar.Types: instance Ord VAlarm
+ Text.ICalendar.Types: instance Ord VCalendar
+ Text.ICalendar.Types: instance Ord VEvent
+ Text.ICalendar.Types: instance Ord VFreeBusy
+ Text.ICalendar.Types: instance Ord VJournal
+ Text.ICalendar.Types: instance Ord VOther
+ Text.ICalendar.Types: instance Ord VTimeZone
+ Text.ICalendar.Types: instance Ord VTodo
+ Text.ICalendar.Types: instance Ord Weekday
+ Text.ICalendar.Types: instance Show AlarmTriggerRelationship
+ Text.ICalendar.Types: instance Show Attachment
+ Text.ICalendar.Types: instance Show Attendee
+ Text.ICalendar.Types: instance Show CUType
+ Text.ICalendar.Types: instance Show Categories
+ Text.ICalendar.Types: instance Show Class
+ Text.ICalendar.Types: instance Show ClassValue
+ Text.ICalendar.Types: instance Show Comment
+ Text.ICalendar.Types: instance Show Completed
+ Text.ICalendar.Types: instance Show Contact
+ Text.ICalendar.Types: instance Show Created
+ Text.ICalendar.Types: instance Show DTEnd
+ Text.ICalendar.Types: instance Show DTStamp
+ Text.ICalendar.Types: instance Show DTStart
+ Text.ICalendar.Types: instance Show Date
+ Text.ICalendar.Types: instance Show DateTime
+ Text.ICalendar.Types: instance Show Description
+ Text.ICalendar.Types: instance Show Due
+ Text.ICalendar.Types: instance Show Duration
+ Text.ICalendar.Types: instance Show DurationProp
+ Text.ICalendar.Types: instance Show EventStatus
+ Text.ICalendar.Types: instance Show ExDate
+ Text.ICalendar.Types: instance Show FBType
+ Text.ICalendar.Types: instance Show FreeBusy
+ Text.ICalendar.Types: instance Show Frequency
+ Text.ICalendar.Types: instance Show Geo
+ Text.ICalendar.Types: instance Show ICalVersion
+ Text.ICalendar.Types: instance Show JournalStatus
+ Text.ICalendar.Types: instance Show Language
+ Text.ICalendar.Types: instance Show LastModified
+ Text.ICalendar.Types: instance Show Location
+ Text.ICalendar.Types: instance Show Method
+ Text.ICalendar.Types: instance Show Organizer
+ Text.ICalendar.Types: instance Show OtherParam
+ Text.ICalendar.Types: instance Show OtherParams
+ Text.ICalendar.Types: instance Show OtherProperty
+ Text.ICalendar.Types: instance Show PartStat
+ Text.ICalendar.Types: instance Show PercentComplete
+ Text.ICalendar.Types: instance Show Period
+ Text.ICalendar.Types: instance Show Priority
+ Text.ICalendar.Types: instance Show ProdId
+ Text.ICalendar.Types: instance Show RDate
+ Text.ICalendar.Types: instance Show RRule
+ Text.ICalendar.Types: instance Show Range
+ Text.ICalendar.Types: instance Show Recur
+ Text.ICalendar.Types: instance Show RecurrenceId
+ Text.ICalendar.Types: instance Show RelatedTo
+ Text.ICalendar.Types: instance Show RelationshipType
+ Text.ICalendar.Types: instance Show Repeat
+ Text.ICalendar.Types: instance Show RequestStatus
+ Text.ICalendar.Types: instance Show Resources
+ Text.ICalendar.Types: instance Show Role
+ Text.ICalendar.Types: instance Show Scale
+ Text.ICalendar.Types: instance Show Sequence
+ Text.ICalendar.Types: instance Show Sign
+ Text.ICalendar.Types: instance Show Summary
+ Text.ICalendar.Types: instance Show TZID
+ Text.ICalendar.Types: instance Show TZName
+ Text.ICalendar.Types: instance Show TZProp
+ Text.ICalendar.Types: instance Show TZUrl
+ Text.ICalendar.Types: instance Show TimeTransparency
+ Text.ICalendar.Types: instance Show TodoStatus
+ Text.ICalendar.Types: instance Show Trigger
+ Text.ICalendar.Types: instance Show UID
+ Text.ICalendar.Types: instance Show URL
+ Text.ICalendar.Types: instance Show UTCOffset
+ Text.ICalendar.Types: instance Show UTCPeriod
+ Text.ICalendar.Types: instance Show VAlarm
+ Text.ICalendar.Types: instance Show VCalendar
+ Text.ICalendar.Types: instance Show VEvent
+ Text.ICalendar.Types: instance Show VFreeBusy
+ Text.ICalendar.Types: instance Show VJournal
+ Text.ICalendar.Types: instance Show VOther
+ Text.ICalendar.Types: instance Show VTimeZone
+ Text.ICalendar.Types: instance Show VTodo
+ Text.ICalendar.Types: instance Show Weekday
+ Text.ICalendar.Types: instance Typeable AlarmTriggerRelationship
+ Text.ICalendar.Types: instance Typeable Attachment
+ Text.ICalendar.Types: instance Typeable Attendee
+ Text.ICalendar.Types: instance Typeable CUType
+ Text.ICalendar.Types: instance Typeable Categories
+ Text.ICalendar.Types: instance Typeable Class
+ Text.ICalendar.Types: instance Typeable ClassValue
+ Text.ICalendar.Types: instance Typeable Comment
+ Text.ICalendar.Types: instance Typeable Completed
+ Text.ICalendar.Types: instance Typeable Contact
+ Text.ICalendar.Types: instance Typeable Created
+ Text.ICalendar.Types: instance Typeable DTEnd
+ Text.ICalendar.Types: instance Typeable DTStamp
+ Text.ICalendar.Types: instance Typeable DTStart
+ Text.ICalendar.Types: instance Typeable Date
+ Text.ICalendar.Types: instance Typeable DateTime
+ Text.ICalendar.Types: instance Typeable Description
+ Text.ICalendar.Types: instance Typeable Due
+ Text.ICalendar.Types: instance Typeable Duration
+ Text.ICalendar.Types: instance Typeable DurationProp
+ Text.ICalendar.Types: instance Typeable EventStatus
+ Text.ICalendar.Types: instance Typeable ExDate
+ Text.ICalendar.Types: instance Typeable FBType
+ Text.ICalendar.Types: instance Typeable FreeBusy
+ Text.ICalendar.Types: instance Typeable Frequency
+ Text.ICalendar.Types: instance Typeable Geo
+ Text.ICalendar.Types: instance Typeable ICalVersion
+ Text.ICalendar.Types: instance Typeable JournalStatus
+ Text.ICalendar.Types: instance Typeable Language
+ Text.ICalendar.Types: instance Typeable LastModified
+ Text.ICalendar.Types: instance Typeable Location
+ Text.ICalendar.Types: instance Typeable Method
+ Text.ICalendar.Types: instance Typeable Organizer
+ Text.ICalendar.Types: instance Typeable OtherParam
+ Text.ICalendar.Types: instance Typeable OtherParams
+ Text.ICalendar.Types: instance Typeable OtherProperty
+ Text.ICalendar.Types: instance Typeable PartStat
+ Text.ICalendar.Types: instance Typeable PercentComplete
+ Text.ICalendar.Types: instance Typeable Period
+ Text.ICalendar.Types: instance Typeable Priority
+ Text.ICalendar.Types: instance Typeable ProdId
+ Text.ICalendar.Types: instance Typeable RDate
+ Text.ICalendar.Types: instance Typeable RRule
+ Text.ICalendar.Types: instance Typeable Range
+ Text.ICalendar.Types: instance Typeable Recur
+ Text.ICalendar.Types: instance Typeable RecurrenceId
+ Text.ICalendar.Types: instance Typeable RelatedTo
+ Text.ICalendar.Types: instance Typeable RelationshipType
+ Text.ICalendar.Types: instance Typeable Repeat
+ Text.ICalendar.Types: instance Typeable RequestStatus
+ Text.ICalendar.Types: instance Typeable Resources
+ Text.ICalendar.Types: instance Typeable Role
+ Text.ICalendar.Types: instance Typeable Scale
+ Text.ICalendar.Types: instance Typeable Sequence
+ Text.ICalendar.Types: instance Typeable Sign
+ Text.ICalendar.Types: instance Typeable Summary
+ Text.ICalendar.Types: instance Typeable TZID
+ Text.ICalendar.Types: instance Typeable TZName
+ Text.ICalendar.Types: instance Typeable TZProp
+ Text.ICalendar.Types: instance Typeable TZUrl
+ Text.ICalendar.Types: instance Typeable TimeTransparency
+ Text.ICalendar.Types: instance Typeable TodoStatus
+ Text.ICalendar.Types: instance Typeable Trigger
+ Text.ICalendar.Types: instance Typeable UID
+ Text.ICalendar.Types: instance Typeable URL
+ Text.ICalendar.Types: instance Typeable UTCOffset
+ Text.ICalendar.Types: instance Typeable UTCPeriod
+ Text.ICalendar.Types: instance Typeable VAlarm
+ Text.ICalendar.Types: instance Typeable VCalendar
+ Text.ICalendar.Types: instance Typeable VEvent
+ Text.ICalendar.Types: instance Typeable VFreeBusy
+ Text.ICalendar.Types: instance Typeable VJournal
+ Text.ICalendar.Types: instance Typeable VOther
+ Text.ICalendar.Types: instance Typeable VTimeZone
+ Text.ICalendar.Types: instance Typeable VTodo
+ Text.ICalendar.Types: instance Typeable Weekday
+ Text.ICalendar.Types: journalStatusOther :: JournalStatus -> OtherParams
+ Text.ICalendar.Types: lastModifiedOther :: LastModified -> OtherParams
+ Text.ICalendar.Types: lastModifiedValue :: LastModified -> UTCTime
+ Text.ICalendar.Types: locationAltRep :: Location -> Maybe URI
+ Text.ICalendar.Types: locationLanguage :: Location -> Maybe Language
+ Text.ICalendar.Types: locationOther :: Location -> OtherParams
+ Text.ICalendar.Types: locationValue :: Location -> Text
+ Text.ICalendar.Types: methodOther :: Method -> OtherParams
+ Text.ICalendar.Types: methodValue :: Method -> CI Text
+ Text.ICalendar.Types: newtype Language
+ Text.ICalendar.Types: organizerCN :: Organizer -> Maybe Text
+ Text.ICalendar.Types: organizerDir :: Organizer -> Maybe URI
+ Text.ICalendar.Types: organizerLanguage :: Organizer -> Maybe Language
+ Text.ICalendar.Types: organizerOther :: Organizer -> OtherParams
+ Text.ICalendar.Types: organizerSentBy :: Organizer -> Maybe CalAddress
+ Text.ICalendar.Types: organizerValue :: Organizer -> CalAddress
+ Text.ICalendar.Types: otherName :: OtherProperty -> CI Text
+ Text.ICalendar.Types: otherParams :: OtherProperty -> OtherParams
+ Text.ICalendar.Types: otherValue :: OtherProperty -> ByteString
+ Text.ICalendar.Types: percentCompleteOther :: PercentComplete -> OtherParams
+ Text.ICalendar.Types: percentCompleteValue :: PercentComplete -> Int
+ Text.ICalendar.Types: priorityOther :: Priority -> OtherParams
+ Text.ICalendar.Types: priorityValue :: Priority -> Int
+ Text.ICalendar.Types: prodIdOther :: ProdId -> OtherParams
+ Text.ICalendar.Types: prodIdValue :: ProdId -> Text
+ Text.ICalendar.Types: rDateDateTimes :: RDate -> Set DateTime
+ Text.ICalendar.Types: rDateDates :: RDate -> Set Date
+ Text.ICalendar.Types: rDateOther :: RDate -> OtherParams
+ Text.ICalendar.Types: rDatePeriods :: RDate -> Set Period
+ Text.ICalendar.Types: rRuleOther :: RRule -> OtherParams
+ Text.ICalendar.Types: rRuleValue :: RRule -> Recur
+ Text.ICalendar.Types: recurByDay :: Recur -> [Either (Int, Weekday) Weekday]
+ Text.ICalendar.Types: recurByHour :: Recur -> [Int]
+ Text.ICalendar.Types: recurByMinute :: Recur -> [Int]
+ Text.ICalendar.Types: recurByMonth :: Recur -> [Int]
+ Text.ICalendar.Types: recurByMonthDay :: Recur -> [Int]
+ Text.ICalendar.Types: recurBySecond :: Recur -> [Int]
+ Text.ICalendar.Types: recurBySetPos :: Recur -> [Int]
+ Text.ICalendar.Types: recurByWeekNo :: Recur -> [Int]
+ Text.ICalendar.Types: recurByYearDay :: Recur -> [Int]
+ Text.ICalendar.Types: recurFreq :: Recur -> Frequency
+ Text.ICalendar.Types: recurInterval :: Recur -> Int
+ Text.ICalendar.Types: recurUntilCount :: Recur -> Maybe (Either (Either Date DateTime) Int)
+ Text.ICalendar.Types: recurWkSt :: Recur -> Weekday
+ Text.ICalendar.Types: recurrenceIdDate :: RecurrenceId -> Date
+ Text.ICalendar.Types: recurrenceIdDateTime :: RecurrenceId -> DateTime
+ Text.ICalendar.Types: recurrenceIdOther :: RecurrenceId -> OtherParams
+ Text.ICalendar.Types: recurrenceIdRange :: RecurrenceId -> Range
+ Text.ICalendar.Types: relatedToOther :: RelatedTo -> OtherParams
+ Text.ICalendar.Types: relatedToType :: RelatedTo -> RelationshipType
+ Text.ICalendar.Types: relatedToValue :: RelatedTo -> Text
+ Text.ICalendar.Types: repeatOther :: Repeat -> OtherParams
+ Text.ICalendar.Types: repeatValue :: Repeat -> Integer
+ Text.ICalendar.Types: requestStatusCode :: RequestStatus -> [Int]
+ Text.ICalendar.Types: requestStatusDesc :: RequestStatus -> Text
+ Text.ICalendar.Types: requestStatusExt :: RequestStatus -> Maybe Text
+ Text.ICalendar.Types: requestStatusLanguage :: RequestStatus -> Maybe Language
+ Text.ICalendar.Types: requestStatusOther :: RequestStatus -> OtherParams
+ Text.ICalendar.Types: resourcesAltRep :: Resources -> Maybe URI
+ Text.ICalendar.Types: resourcesLanguage :: Resources -> Maybe Language
+ Text.ICalendar.Types: resourcesOther :: Resources -> OtherParams
+ Text.ICalendar.Types: resourcesValue :: Resources -> Set Text
+ Text.ICalendar.Types: scaleOther :: Scale -> OtherParams
+ Text.ICalendar.Types: scaleValue :: Scale -> CI Text
+ Text.ICalendar.Types: sequenceOther :: Sequence -> OtherParams
+ Text.ICalendar.Types: sequenceValue :: Sequence -> Integer
+ Text.ICalendar.Types: summaryAltRep :: Summary -> Maybe URI
+ Text.ICalendar.Types: summaryLanguage :: Summary -> Maybe Language
+ Text.ICalendar.Types: summaryOther :: Summary -> OtherParams
+ Text.ICalendar.Types: summaryValue :: Summary -> Text
+ Text.ICalendar.Types: timeTransparencyOther :: TimeTransparency -> OtherParams
+ Text.ICalendar.Types: todoStatusOther :: TodoStatus -> OtherParams
+ Text.ICalendar.Types: triggerDateTime :: Trigger -> UTCTime
+ Text.ICalendar.Types: triggerDuration :: Trigger -> Duration
+ Text.ICalendar.Types: triggerOther :: Trigger -> OtherParams
+ Text.ICalendar.Types: triggerRelated :: Trigger -> AlarmTriggerRelationship
+ Text.ICalendar.Types: type CalAddress = URI
+ Text.ICalendar.Types: tzNameLanguage :: TZName -> Maybe Language
+ Text.ICalendar.Types: tzNameOther :: TZName -> OtherParams
+ Text.ICalendar.Types: tzNameValue :: TZName -> Text
+ Text.ICalendar.Types: tzUrlOther :: TZUrl -> OtherParams
+ Text.ICalendar.Types: tzUrlValue :: TZUrl -> URI
+ Text.ICalendar.Types: tzidGlobal :: TZID -> Bool
+ Text.ICalendar.Types: tzidOther :: TZID -> OtherParams
+ Text.ICalendar.Types: tzidValue :: TZID -> Text
+ Text.ICalendar.Types: tzpComment :: TZProp -> Set Comment
+ Text.ICalendar.Types: tzpDTStart :: TZProp -> DTStart
+ Text.ICalendar.Types: tzpOther :: TZProp -> Set OtherProperty
+ Text.ICalendar.Types: tzpRDate :: TZProp -> Set RDate
+ Text.ICalendar.Types: tzpRRule :: TZProp -> Set RRule
+ Text.ICalendar.Types: tzpTZName :: TZProp -> Set TZName
+ Text.ICalendar.Types: tzpTZOffsetFrom :: TZProp -> UTCOffset
+ Text.ICalendar.Types: tzpTZOffsetTo :: TZProp -> UTCOffset
+ Text.ICalendar.Types: uidOther :: UID -> OtherParams
+ Text.ICalendar.Types: uidValue :: UID -> Text
+ Text.ICalendar.Types: urlOther :: URL -> OtherParams
+ Text.ICalendar.Types: urlValue :: URL -> URI
+ Text.ICalendar.Types: utcOffsetOther :: UTCOffset -> OtherParams
+ Text.ICalendar.Types: utcOffsetValue :: UTCOffset -> Int
+ Text.ICalendar.Types: vaAction :: VAlarm -> CI Text
+ Text.ICalendar.Types: vaActionOther :: VAlarm -> OtherParams
+ Text.ICalendar.Types: vaAttendee :: VAlarm -> Set Attendee
+ Text.ICalendar.Types: vaAudioAttach :: VAlarm -> Maybe Attachment
+ Text.ICalendar.Types: vaDescription :: VAlarm -> Description
+ Text.ICalendar.Types: vaDuration :: VAlarm -> Maybe DurationProp
+ Text.ICalendar.Types: vaMailAttach :: VAlarm -> Set Attachment
+ Text.ICalendar.Types: vaOther :: VAlarm -> Set OtherProperty
+ Text.ICalendar.Types: vaRepeat :: VAlarm -> Repeat
+ Text.ICalendar.Types: vaSummary :: VAlarm -> Summary
+ Text.ICalendar.Types: vaTrigger :: VAlarm -> Trigger
+ Text.ICalendar.Types: vcEvents :: VCalendar -> Set VEvent
+ Text.ICalendar.Types: vcFreeBusys :: VCalendar -> Set VFreeBusy
+ Text.ICalendar.Types: vcJournals :: VCalendar -> Set VJournal
+ Text.ICalendar.Types: vcMethod :: VCalendar -> Maybe Method
+ Text.ICalendar.Types: vcOther :: VCalendar -> Set OtherProperty
+ Text.ICalendar.Types: vcOtherComps :: VCalendar -> Set VOther
+ Text.ICalendar.Types: vcProdId :: VCalendar -> ProdId
+ Text.ICalendar.Types: vcScale :: VCalendar -> Scale
+ Text.ICalendar.Types: vcTimeZones :: VCalendar -> Set VTimeZone
+ Text.ICalendar.Types: vcTodos :: VCalendar -> Set VTodo
+ Text.ICalendar.Types: vcVersion :: VCalendar -> ICalVersion
+ Text.ICalendar.Types: veAlarms :: VEvent -> Set VAlarm
+ Text.ICalendar.Types: veAttach :: VEvent -> Set Attachment
+ Text.ICalendar.Types: veAttendee :: VEvent -> Set Attendee
+ Text.ICalendar.Types: veCategories :: VEvent -> Set Categories
+ Text.ICalendar.Types: veClass :: VEvent -> Class
+ Text.ICalendar.Types: veComment :: VEvent -> Set Comment
+ Text.ICalendar.Types: veContact :: VEvent -> Set Contact
+ Text.ICalendar.Types: veCreated :: VEvent -> Maybe Created
+ Text.ICalendar.Types: veDTEndDuration :: VEvent -> Maybe (Either DTEnd DurationProp)
+ Text.ICalendar.Types: veDTStamp :: VEvent -> DTStamp
+ Text.ICalendar.Types: veDTStart :: VEvent -> Maybe DTStart
+ Text.ICalendar.Types: veDescription :: VEvent -> Maybe Description
+ Text.ICalendar.Types: veExDate :: VEvent -> Set ExDate
+ Text.ICalendar.Types: veGeo :: VEvent -> Maybe Geo
+ Text.ICalendar.Types: veLastMod :: VEvent -> Maybe LastModified
+ Text.ICalendar.Types: veLocation :: VEvent -> Maybe Location
+ Text.ICalendar.Types: veOrganizer :: VEvent -> Maybe Organizer
+ Text.ICalendar.Types: veOther :: VEvent -> Set OtherProperty
+ Text.ICalendar.Types: vePriority :: VEvent -> Priority
+ Text.ICalendar.Types: veRDate :: VEvent -> Set RDate
+ Text.ICalendar.Types: veRRule :: VEvent -> Set RRule
+ Text.ICalendar.Types: veRStatus :: VEvent -> Set RequestStatus
+ Text.ICalendar.Types: veRecurId :: VEvent -> Maybe RecurrenceId
+ Text.ICalendar.Types: veRelated :: VEvent -> Set RelatedTo
+ Text.ICalendar.Types: veResources :: VEvent -> Set Resources
+ Text.ICalendar.Types: veSeq :: VEvent -> Sequence
+ Text.ICalendar.Types: veStatus :: VEvent -> Maybe EventStatus
+ Text.ICalendar.Types: veSummary :: VEvent -> Maybe Summary
+ Text.ICalendar.Types: veTransp :: VEvent -> TimeTransparency
+ Text.ICalendar.Types: veUID :: VEvent -> UID
+ Text.ICalendar.Types: veUrl :: VEvent -> Maybe URL
+ Text.ICalendar.Types: versionMax :: ICalVersion -> Version
+ Text.ICalendar.Types: versionMin :: ICalVersion -> Version
+ Text.ICalendar.Types: versionOther :: ICalVersion -> OtherParams
+ Text.ICalendar.Types: vfbAttendee :: VFreeBusy -> Set Attendee
+ Text.ICalendar.Types: vfbComment :: VFreeBusy -> Set Comment
+ Text.ICalendar.Types: vfbContact :: VFreeBusy -> Maybe Contact
+ Text.ICalendar.Types: vfbDTEnd :: VFreeBusy -> Maybe DTEnd
+ Text.ICalendar.Types: vfbDTStamp :: VFreeBusy -> DTStamp
+ Text.ICalendar.Types: vfbDTStart :: VFreeBusy -> Maybe DTStart
+ Text.ICalendar.Types: vfbFreeBusy :: VFreeBusy -> Set FreeBusy
+ Text.ICalendar.Types: vfbOrganizer :: VFreeBusy -> Maybe Organizer
+ Text.ICalendar.Types: vfbOther :: VFreeBusy -> Set OtherProperty
+ Text.ICalendar.Types: vfbRStatus :: VFreeBusy -> Set RequestStatus
+ Text.ICalendar.Types: vfbUID :: VFreeBusy -> UID
+ Text.ICalendar.Types: vfbUrl :: VFreeBusy -> Maybe URL
+ Text.ICalendar.Types: vjAttach :: VJournal -> Set Attachment
+ Text.ICalendar.Types: vjAttendee :: VJournal -> Set Attendee
+ Text.ICalendar.Types: vjCategories :: VJournal -> Set Categories
+ Text.ICalendar.Types: vjClass :: VJournal -> Class
+ Text.ICalendar.Types: vjComment :: VJournal -> Set Comment
+ Text.ICalendar.Types: vjContact :: VJournal -> Set Contact
+ Text.ICalendar.Types: vjCreated :: VJournal -> Maybe Created
+ Text.ICalendar.Types: vjDTStamp :: VJournal -> DTStamp
+ Text.ICalendar.Types: vjDTStart :: VJournal -> Maybe DTStart
+ Text.ICalendar.Types: vjDescription :: VJournal -> Set Description
+ Text.ICalendar.Types: vjExDate :: VJournal -> Set ExDate
+ Text.ICalendar.Types: vjLastMod :: VJournal -> Maybe LastModified
+ Text.ICalendar.Types: vjOrganizer :: VJournal -> Maybe Organizer
+ Text.ICalendar.Types: vjOther :: VJournal -> Set OtherProperty
+ Text.ICalendar.Types: vjRDate :: VJournal -> Set RDate
+ Text.ICalendar.Types: vjRRule :: VJournal -> Set RRule
+ Text.ICalendar.Types: vjRStatus :: VJournal -> Set RequestStatus
+ Text.ICalendar.Types: vjRecurId :: VJournal -> Maybe RecurrenceId
+ Text.ICalendar.Types: vjRelated :: VJournal -> Set RelatedTo
+ Text.ICalendar.Types: vjSeq :: VJournal -> Sequence
+ Text.ICalendar.Types: vjStatus :: VJournal -> Maybe JournalStatus
+ Text.ICalendar.Types: vjSummary :: VJournal -> Maybe Summary
+ Text.ICalendar.Types: vjUID :: VJournal -> UID
+ Text.ICalendar.Types: vjUrl :: VJournal -> Maybe URL
+ Text.ICalendar.Types: voName :: VOther -> CI Text
+ Text.ICalendar.Types: voProps :: VOther -> Set OtherProperty
+ Text.ICalendar.Types: vtAlarms :: VTodo -> Set VAlarm
+ Text.ICalendar.Types: vtAttach :: VTodo -> Set Attachment
+ Text.ICalendar.Types: vtAttendee :: VTodo -> Set Attendee
+ Text.ICalendar.Types: vtCategories :: VTodo -> Set Categories
+ Text.ICalendar.Types: vtClass :: VTodo -> Class
+ Text.ICalendar.Types: vtComment :: VTodo -> Set Comment
+ Text.ICalendar.Types: vtCompleted :: VTodo -> Maybe Completed
+ Text.ICalendar.Types: vtContact :: VTodo -> Set Contact
+ Text.ICalendar.Types: vtCreated :: VTodo -> Maybe Created
+ Text.ICalendar.Types: vtDTStamp :: VTodo -> DTStamp
+ Text.ICalendar.Types: vtDTStart :: VTodo -> Maybe DTStart
+ Text.ICalendar.Types: vtDescription :: VTodo -> Maybe Description
+ Text.ICalendar.Types: vtDueDuration :: VTodo -> Maybe (Either Due DurationProp)
+ Text.ICalendar.Types: vtExDate :: VTodo -> Set ExDate
+ Text.ICalendar.Types: vtGeo :: VTodo -> Maybe Geo
+ Text.ICalendar.Types: vtLastMod :: VTodo -> Maybe LastModified
+ Text.ICalendar.Types: vtLocation :: VTodo -> Maybe Location
+ Text.ICalendar.Types: vtOrganizer :: VTodo -> Maybe Organizer
+ Text.ICalendar.Types: vtOther :: VTodo -> Set OtherProperty
+ Text.ICalendar.Types: vtPercent :: VTodo -> Maybe PercentComplete
+ Text.ICalendar.Types: vtPriority :: VTodo -> Priority
+ Text.ICalendar.Types: vtRDate :: VTodo -> Set RDate
+ Text.ICalendar.Types: vtRRule :: VTodo -> Set RRule
+ Text.ICalendar.Types: vtRStatus :: VTodo -> Set RequestStatus
+ Text.ICalendar.Types: vtRecurId :: VTodo -> Maybe RecurrenceId
+ Text.ICalendar.Types: vtRelated :: VTodo -> Set RelatedTo
+ Text.ICalendar.Types: vtResources :: VTodo -> Set Resources
+ Text.ICalendar.Types: vtSeq :: VTodo -> Sequence
+ Text.ICalendar.Types: vtStatus :: VTodo -> Maybe TodoStatus
+ Text.ICalendar.Types: vtSummary :: VTodo -> Maybe Summary
+ Text.ICalendar.Types: vtUID :: VTodo -> UID
+ Text.ICalendar.Types: vtUrl :: VTodo -> Maybe URL
+ Text.ICalendar.Types: vtzDaylightC :: VTimeZone -> Set TZProp
+ Text.ICalendar.Types: vtzId :: VTimeZone -> TZID
+ Text.ICalendar.Types: vtzLastMod :: VTimeZone -> Maybe LastModified
+ Text.ICalendar.Types: vtzOther :: VTimeZone -> Set OtherProperty
+ Text.ICalendar.Types: vtzStandardC :: VTimeZone -> Set TZProp
+ Text.ICalendar.Types: vtzUrl :: VTimeZone -> Maybe TZUrl

Files

LICENSE view
@@ -1,4 +1,4 @@-Copyright (c) 2008, Tupil+Copyright (c) 2012, Tingtun AS  All rights reserved. @@ -13,7 +13,7 @@       disclaimer in the documentation and/or other materials provided       with the distribution. -    * Neither the name of Tupil nor the names of other+    * Neither the name of Tingtun AS nor the names of other       contributors may be used to endorse or promote products derived       from this software without specific prior written permission. 
+ Text/ICalendar.hs view
@@ -0,0 +1,9 @@+module Text.ICalendar+    ( module Text.ICalendar.Types+    , module Text.ICalendar.Parser+    , module Text.ICalendar.Printer+    ) where++import Text.ICalendar.Types+import Text.ICalendar.Parser+import Text.ICalendar.Printer
Text/ICalendar/Parser.hs view
@@ -1,368 +1,55 @@-{-# LANGUAGE TypeSynonymInstances, FlexibleInstances #-}-{-|--Parser for the iCalendar format (version 2.0, RFC2445).-  -Features:--  * Unfolds folded lines (see RFC)- -  * Supports all IANA iCalendar tokens--/Warning!/  This is version 0.0, important things are missing-   -  * Property and parameter values are not parsed, but kept as in the file.--  * There are no restrictions on the properties components can have.-  -  * Line unfolding causes error messages to report the wrong line.- -This package is meant to grow to a full-fledged data definition, printer and-parser for the iCalendar format.  But that will probably take some time.  So,-if you've come here because you need this, please e-mail me (Eelco Lempsink).---}--module Text.ICalendar.Parser -    (-    -- * Tokens from RFC2445-      ComponentName(..)-    , PropertyName(..)-    , ParamName(..)-    , ParamValue(..)-    -- * Data definitions-    , Property-    , Value-    , ICalendar(..)-    , Component(..)-    , Param(..)-    -- * Parser-    , parser+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeSynonymInstances #-}+{-# LANGUAGE FlexibleInstances #-}+module Text.ICalendar.Parser+    ( parseICal+    , parseICalFile+    , DecodingFunctions(..)     ) where ---------------------------------------------------------------- Imports---------------------------------------------------------------import Data.Char+import Prelude+import Control.Applicative import Control.Monad+import Control.Monad.Error+import Control.Monad.RWS ( runRWS )+import Data.ByteString.Lazy (ByteString)+import qualified Data.ByteString.Lazy.Char8 as B+import Data.Monoid -import Control.Applicative-import Control.Monad (MonadPlus(..), ap)--- Hide Parsec's definitions of some Applicative functions.-import Text.ParserCombinators.Parsec hiding (many, optional, (<|>))+import Text.Parsec.Prim hiding (many, (<|>))+import Text.Parsec.Pos+import Text.Parsec.ByteString.Lazy ()+import Text.Parsec.Text.Lazy () ---------------------------------------------------------------- Tokens, as defined in RFC2445.-------------------------------------------------------------+import Text.ICalendar.Types+import Text.ICalendar.Parser.Common+import Text.ICalendar.Parser.Content+import Text.ICalendar.Parser.Components --- | Calendar Component names (4.6)-data ComponentName =-              VEVENT     -- ^ Event     Component (4.6.1)-            | VTODO      -- ^ To-do     Component (4.6.2)-            | VJOURNAL   -- ^ Journal   Component (4.6.3)-            | VFREEBUSY  -- ^ Free/Busy Component (4.6.4)-            | VTIMEZONE  -- ^ Time Zone Component (4.6.5)-            | X_c String -- ^ Non-standard/Experimental Component-            -- Time Zone subcomponents-            | STANDARD   -- ^ Standard Time        Sub-component (4.6.5)-            | DAYLIGHT   -- ^ Daylight Saving Time Sub-component (4.6.5)-            -- Event and To-do subcomponent-            | VALARM     -- ^ Alarm                Sub-component (4.6.6)-            deriving (Eq, Show) --- | Property names for Calendar Properties (4.7) and Component Properties (4.8)-data PropertyName = -                -- Calendar properties (4.7)-                  CALSCALE          -- ^ Calendar Scale (4.7.1)-                | METHOD            -- ^ Method (4.7.2)-                | PRODID            -- ^ Product Identifier (4.7.3)-                | VERSION           -- ^ Version (4.7.4)-                -                -- Component properties (4.8.1)-                | ATTACH            -- ^ Attachment (4.8.1.1)-                | CATEGORIES        -- ^ Categories (4.8.1.2)-                | CLASS             -- ^ Classification (4.8.1.3)-                | COMMENT           -- ^ Comment (4.8.1.4)-                | DESCRIPTION       -- ^ Description (4.8.1.5)-                | GEO               -- ^ Geographic Position (4.8.1.6)-                | LOCATION          -- ^ Location (4.8.1.7)-                | PERCENT_COMPLETE  -- ^ Percent Complete (4.8.1.8)-                | PRIORITY          -- ^ Priority (4.8.1.9)-                | RESOURCES         -- ^ Resources (4.8.1.10)-                | STATUS            -- ^ Status (4.8.1.11)-                | SUMMARY           -- ^ Summary (4.8.1.12)-               -                -- Date and Time Component properties (4.8.2)-                | COMPLETED         -- ^ Date/Time Completed (4.8.2.1) -                | DTEND             -- ^ Date/Time End (4.8.2.2)         -                | DUE               -- ^ Date/Time Due (4.8.2.3)-                | DTSTART           -- ^ Date/Time Start (4.8.2.4) -                | DURATION          -- ^ Duration (4.8.2.5)   -                | FREEBUSY          -- ^ Free/Busy Time (4.8.2.6)    -                | TRANSP            -- ^ Time Transparency (4.8.2.7)  -               -                -- Time Zone Component properties (4.8.3)-                | TZID              -- ^ Time Zone Identifier (4.8.3.1) -                | TZNAME            -- ^ Time Zone Name (4.8.3.2)      -                | TZOFFSETFROM      -- ^ Time Zone Offset From (4.8.3.3)     -                | TZOFFSETTO        -- ^ Time Zone Offset To (4.8.3.4)  -                | TZURL             -- ^ Time Zone URL (4.8.3.5)     -                -                -- Relationship Component properties (4.8.4)-                | ATTENDEE          -- ^ Attendee (4.8.4.1) -                | CONTACT           -- ^ Contact (4.8.4.2)-                | ORGANIZER         -- ^ Organizer (4.8.4.3)  -                | RECURRENCE_ID     -- ^ Recurrence ID (4.8.4.4)    -                | RELATED_TO        -- ^ Related To (4.8.4.5)   -                | URL               -- ^ Uniform Resource Locator (4.8.4.6) -                | UID               -- ^ Unique Identfier (4.8.4.7)  -                -                -- Recurrence Component properties (4.8.5)-                | EXDATE            -- ^ Exception Date/Times (4.8.5.1) -                | EXRULE            -- ^ Exception Rule (4.8.5.2)  -                | RDATE             -- ^ Recurrence Date/Times (4.8.5.3) -                | RRULE             -- ^ Recurrence Rule (4.8.5.4) -                -                -- Alarm Component properties (4.8.6)-                | ACTION            -- ^ Action (4.8.6.1)    -                | REPEAT            -- ^ Repeat Count (4.8.6.2)  -                | TRIGGER           -- ^ Trigger (4.8.6.3)    -                -                -- Change Management Component properties (4.8.7)-                | CREATED           -- ^ Date/Time Created (4.8.7.1)   -                | DTSTAMP           -- ^ Date/Time Stamp (4.8.7.2)     -                | LAST_MODIFIED     -- ^ Last Modified (4.8.7.3)      -                | SEQUENCE          -- ^ Sequence Number (4.8.7.4)   -                -                -- Miscellaneous Component properties (4.8.8)-                | X_ String         -- ^ Non-standard Properties (4.8.8.1)-                | REQUEST_STATUS    -- ^ Request Status (4.8.8.2)-                deriving (Eq, Show)---- | Parameter names (4.2)-data ParamName = ALTREP          -- ^ Alternate Text Represenation (4.2.1)           -               | CN              -- ^ Common Name (4.2.2)   -               | CUTYPE          -- ^ Calendar User Type (4.2.3)       -               | DELEGATED_FROM  -- ^ Delegators (4.2.4)               -               | DELEGATED_TO    -- ^ Delegatees (4.2.5)             -               | DIR             -- ^ Directory Entry Reference (4.2.6)    -               | ENCODING        -- ^ Inline Encoding (4.2.7)         -               | FMTYPE          -- ^ Format Type (4.2.8)       -               | FBTYPE          -- ^ Free/Busy Time Type (4.2.9)       -               | LANGUAGE        -- ^ Language (4.2.10)         -               | MEMBER          -- ^ Group or List Membership (4.2.11)       -               | PARTSTAT        -- ^ Participation Status (4.2.12)         -               | RANGE           -- ^ Recurrence Identfier Range (4.2.13)      -               | RELATED         -- ^ Alarm Trigger Relationship (4.2.14)        -               | RELTYPE         -- ^ Relationship Type (4.2.15)        -               | ROLE            -- ^ Participation Role (4.2.16)     -               | RSVP            -- ^ RSVP Expectation (4.2.17)     -               | SENT_BY         -- ^ Sent By (4.2.18)        -               | TZIDp           -- ^ Time Zone Identifier (4.2.19)      -               | VALUE           -- ^ Value Data Types (4.2.20)      -               | X_p String      -- ^ Non-standard Parameter (4.2.21)           -               deriving (Eq, Show)                 --data ParamValue = Paramtext    String-                | QuotedString String-                deriving (Eq, Show)----------------------------------------------------------------- Parsed datastructers and helper functions---------------------------------------------------------------type Value      = String-type Property   = (PropertyName, [Param], Value)---- | iCalendar data-data ICalendar  = ICalendar { calendarProperties :: [Property]-                            , components         :: [Component]-                            } deriving (Eq, Show)--mkICalendar     = ICalendar [] []                          --addCalendarProperty prop calendar = calendar { calendarProperties = prop : calendarProperties calendar }-addComponent        comp calendar = calendar { components         = comp : components calendar }---- | Component data-data Component   = Component { cName         :: ComponentName-                             , properties    :: [Property]-                             , subcomponents :: [Component]-                             } deriving (Eq, Show)--mkComponent name = Component name [] []--addProperty     prop component = component { properties    = prop : properties component }-addSubcomponent comp component = component { subcomponents = comp : subcomponents component }---- | Parameter data-data Param = Param { pName   :: ParamName-                   , pValues :: [ParamValue]-                   } deriving (Eq, Show)----------------------------------------------------------------- Parser helpers----------------------------------------------------------------- | Case insensitive string matching.  Also wrapped in a 'try' so the matching--- will fail as a whole and not mid-string.-ciString = try . sequence . (map (\c -> char (toUpper c) <|> char (toLower c)))--crlf = string "\r\n"---- | Parses any character except controls and double quotation marks-pQsafeChar = oneOf $ wsp ++ map chr (0x21 : [0x23..0x7e]) ++ nonUsAscii---- | Parses any character except controls, double quotation marks, ";", ":", ","-pSafeChar = oneOf $ wsp ++ map chr (0x21 : [0x23..0x2b] ++ [0x2d..0x39] ++ [0x3c..0x7e]) ++ nonUsAscii---- | Parses any textual character-pValueChar = oneOf $ wsp ++ map chr [0x21..0x7e] ++ nonUsAscii---- | Non US-ASCII characters-nonUsAscii = map chr [0x80..0xF8]---- | Linear white space-wsp = " \t"----------------------------------------------------------------- Scanner, creating a tokenstream----------------------------------------------------------------- TODO folding the lines should keep the original positions--- | Parses a "String" to an "ICalendar".  Will unfold folded lines, so error messages might be off.-parser = do input <- getInput-            setInput (foldLines input)-            pICalendar---- | Remove crlf's followed by space or tab, this is called "line folding".-foldLines [] = []-foldLines ('\r':'\n':' ' :lines) = foldLines lines-foldLines ('\r':'\n':'\t':lines) = foldLines lines-foldLines (l:lines)              = l : foldLines lines--pICalendar =  pBegin <* pVCalendar -           *> pCalendarPropertiesAndComponents-          <*  eof--pVCalendar = ciString "VCALENDAR" <* crlf--pCalendarPropertiesAndComponents =-         addCalendarProperty <$> pProperty  <*> pCalendarPropertiesAndComponents-     <|> addComponent        <$> pComponent <*> pCalendarPropertiesAndComponents-     <|> mkICalendar         <$  pEnd       <*  pVCalendar--pComponent = do component <- pComponentBegin-                pPropertiesAndSubcomponents component--pComponentBegin = mkComponent <$ pBegin <*> pComponentName--pPropertiesAndSubcomponents component =-       addProperty     <$> pProperty  <*> pPropertiesAndSubcomponents component-  <|>  addSubcomponent <$> pComponent <*> pPropertiesAndSubcomponents component-  <|>  component       <$  pComponentEnd component--pProperty = (,,) <$> pPropertyName <*> many pParam <*> pValue--pParam = Param <$ char ';' <*> pParamName <*> sepBy pParamValue (char ',')---- NOTE: pQuotedString has to go first, because the value may be empty-pParamValue   = pQuotedString <|> pParamtext -pParamtext    = Paramtext    <$> many pSafeChar-pQuotedString = QuotedString <$  char '"' <*> many pQsafeChar <* char '"'--pValue = char ':' *> many pValueChar <* crlf---- TODO: This will disappear once every component has its own parser-pComponentEnd c = do pEnd-                     component <- pComponentName-                     if component == cName c-                           then return component-                           else unexpected $ "END:" ++ show (cName c)--pBegin  = ciString "BEGIN:"-pEnd    = ciString "END:"+-- | Parse a ByteString containing iCalendar data.+-- Returns either an error, or a tuple of the result and a list of warnings.+parseICal :: DecodingFunctions+          -> FilePath+          -> ByteString+          -> Either String ([VCalendar], [String])+parseICal s f bs = do+    a <- either (Left . show) Right $ runParser parseToContent s f bs+    when (null a) $ throwError "Missing content."+    let xs = map (runCP s . parseVCalendar) a+    (x, w) <- ((flip.).) flip foldM ([], []) xs $ \(x, ws) (g, (pos, _), w) ->+             case g of+                  Left e -> Left $ show pos ++ ": " ++ e+                  Right y -> Right (y:x, w <> ws)+    return (x, w) -pComponentName = ( VEVENT           <$ ciString "VEVENT"-               <|> VTODO            <$ ciString "VTODO"-               <|> VJOURNAL         <$ ciString "VJOURNAL"-               <|> VFREEBUSY        <$ ciString "VFREEBUSY"-               <|> VTIMEZONE        <$ ciString "VTIMEZONE"-               <|> X_c              <$ ciString "X-" <*> many1 (alphaNum <|> char '-')-               <|> STANDARD         <$ ciString "STANDARD"-               <|> DAYLIGHT         <$ ciString "DAYLIGHT"-               <|> VALARM           <$ ciString "VALARM"-               ) <* crlf-       -pPropertyName  =   CALSCALE         <$ ciString "CALSCALE"-               <|> METHOD           <$ ciString "METHOD"-               <|> PRODID           <$ ciString "PRODID"-               <|> VERSION          <$ ciString "VERSION"-               <|> ATTACH           <$ ciString "ATTACH"-               <|> CATEGORIES       <$ ciString "CATEGORIES"-               <|> CLASS            <$ ciString "CLASS"-               <|> COMMENT          <$ ciString "COMMENT"-               <|> DESCRIPTION      <$ ciString "DESCRIPTION"-               <|> GEO              <$ ciString "GEO"-               <|> LOCATION         <$ ciString "LOCATION"-               <|> PERCENT_COMPLETE <$ ciString "PERCENT-COMPLETE"-               <|> PRIORITY         <$ ciString "PRIORITY"-               <|> RESOURCES        <$ ciString "RESOURCES"-               <|> STATUS           <$ ciString "STATUS"-               <|> SUMMARY          <$ ciString "SUMMARY"-               <|> COMPLETED        <$ ciString "COMPLETED"-               <|> DTEND            <$ ciString "DTEND"-               <|> DUE              <$ ciString "DUE"-               <|> DTSTART          <$ ciString "DTSTART"-               <|> DURATION         <$ ciString "DURATION"-               <|> FREEBUSY         <$ ciString "FREEBUSY"-               <|> TRANSP           <$ ciString "TRANSP"-               <|> TZID             <$ ciString "TZID"-               <|> TZNAME           <$ ciString "TZNAME"-               <|> TZOFFSETFROM     <$ ciString "TZOFFSETFROM"-               <|> TZOFFSETTO       <$ ciString "TZOFFSETTO"-               <|> TZURL            <$ ciString "TZURL"-               <|> ATTENDEE         <$ ciString "ATTENDEE"-               <|> CONTACT          <$ ciString "CONTACT"-               <|> ORGANIZER        <$ ciString "ORGANIZER"-               <|> RECURRENCE_ID    <$ ciString "RECURRENCE-ID"-               <|> RELATED_TO       <$ ciString "RELATED-TO"-               <|> URL              <$ ciString "URL"-               <|> UID              <$ ciString "UID"-               <|> EXDATE           <$ ciString "EXDATE"-               <|> EXRULE           <$ ciString "EXRULE"-               <|> RDATE            <$ ciString "RDATE"-               <|> RRULE            <$ ciString "RRULE"-               <|> ACTION           <$ ciString "ACTION"-               <|> REPEAT           <$ ciString "REPEAT"-               <|> TRIGGER          <$ ciString "TRIGGER"-               <|> CREATED          <$ ciString "CREATED"-               <|> DTSTAMP          <$ ciString "DTSTAMP"-               <|> LAST_MODIFIED    <$ ciString "LAST-MODIFIED"-               <|> SEQUENCE         <$ ciString "SEQUENCE"-               <|> X_               <$ ciString "X-" <*> many1 (alphaNum <|> char '-')-               <|> REQUEST_STATUS   <$ ciString "REQUEST-STATUS"+-- | Parse an iCalendar file.+parseICalFile :: DecodingFunctions+              -> FilePath+              -> IO (Either String ([VCalendar], [String]))+parseICalFile s f = parseICal s f <$> B.readFile f -pParamName     = ( ALTREP           <$ ciString "ALTREP"-               <|> CN               <$ ciString "CN"-               <|> CUTYPE           <$ ciString "CUTYPE"-               <|> DELEGATED_FROM   <$ ciString "DELEGATED-FROM"-               <|> DELEGATED_TO     <$ ciString "DELEGATED-TO"-               <|> DIR              <$ ciString "DIR"-               <|> ENCODING         <$ ciString "ENCODING"-               <|> FMTYPE           <$ ciString "FMTYPE"-               <|> FBTYPE           <$ ciString "FBTYPE"-               <|> LANGUAGE         <$ ciString "LANGUAGE"-               <|> MEMBER           <$ ciString "MEMBER"-               <|> PARTSTAT         <$ ciString "PARTSTAT"-               <|> RANGE            <$ ciString "RANGE"-               <|> RELATED          <$ ciString "RELATED"-               <|> RELTYPE          <$ ciString "RELTYPE"-               <|> ROLE             <$ ciString "ROLE"-               <|> RSVP             <$ ciString "RSVP"-               <|> SENT_BY          <$ ciString "SENT-BY"-               <|> TZIDp            <$ ciString "TZID"-               <|> VALUE            <$ ciString "VALUE"-               <|> X_p              <$ ciString "X-" <*> many1 (alphaNum <|> char '-')-               ) <* char '='+runCP :: DecodingFunctions -> ContentParser a+      -> (Either String a, (SourcePos, [Content]), [String])+runCP s = ((flip .) . flip) runRWS s (undefined, undefined) . runErrorT
+ Text/ICalendar/Parser/Common.hs view
@@ -0,0 +1,403 @@+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE ScopedTypeVariables #-}+module Text.ICalendar.Parser.Common where++import Prelude hiding (mapM)+import Control.Applicative+import Control.Arrow (second)+import Control.Monad.Error hiding (mapM)+import Control.Monad.RWS ( RWS, MonadWriter(tell) , MonadState(get, put), asks+                         , modify )+import Data.ByteString.Lazy.Char8 (ByteString)+import qualified Data.ByteString.Lazy.Char8 as B+import qualified Data.ByteString.Lazy.Builder as Bu+import Data.CaseInsensitive (CI)+import qualified Data.CaseInsensitive as CI+import Data.Char+import Data.Default+import Data.List (partition)+import Data.Maybe+import Data.Monoid+import Data.Set (Set)+import qualified Data.Set as S+import Data.Text.Lazy (Text)+import qualified Data.Text.Lazy as T+import qualified Data.Text.Lazy.Encoding as TE+import Data.Time ( UTCTime(UTCTime), LocalTime(LocalTime), Day+                 , TimeOfDay())+import qualified Data.Time as Time+import Data.Traversable (mapM)+import qualified Network.URI as URI+import qualified System.Locale as L++import qualified Text.Parsec as P+import Text.Parsec.Prim hiding ((<|>))+import Text.Parsec.Combinator hiding (optional)++import Text.ICalendar.Types++data Content = ContentLine P.SourcePos (CI Text) [(CI Text, [Text])] ByteString+             | Component P.SourcePos (CI Text) [Content]+               deriving (Show, Eq, Ord)++type TextParser = P.Parsec ByteString DecodingFunctions++type ContentParser = ErrorT String -- Fatal errors.+                            (RWS DecodingFunctions+                                 [String] -- Warnings.+                                 (P.SourcePos, [Content]))++-- | Functions for decoding 'ByteString's into 'Text'.+data DecodingFunctions = DecodingFunctions+    { dfBS2Text :: ByteString -> Text+    , dfBS2IText :: ByteString -> CI Text+    }++-- | UTF8.+instance Default DecodingFunctions where+    def = DecodingFunctions TE.decodeUtf8 (CI.mk . TE.decodeUtf8)++-- | Parse text. 3.3.11+parseText' :: ByteString -> ContentParser ([Text], ByteString)+parseText' bs = do c <- asks dfBS2Text+                   case runParser ((,) <$> texts <*> getInput) () "text" bs of+                        Left e -> throwError $ "parseText': " ++ show e+                        Right (x, r) -> return ( map (c . Bu.toLazyByteString) x+                                               , r)+  where texts = sepBy text (P.char ',')+        text = do x <- P.satisfy isTSafe'+                  case x of+                       '\\' -> do y <- P.anyChar+                                  case y of+                                       '\\' -> nxt '\\'+                                       ';' -> nxt ';'+                                       ',' -> nxt ','+                                       z | z `elem` "nN" -> nxt '\n'+                                       _ -> fail $ "unexpected " ++ show x+                       y -> nxt y+        -- isTSafe + 0x22, 0x3A+        isTSafe' c = let n = ord c+                      in n == 9 || (n >= 0x20 && n <= 0x3A)+                                || (n >= 0x3C && n /= 0x7F)+        nxt c = (Bu.char8 c <>) <$> (text <|> return mempty)++-- | Chech that there's no remainding text after the parser is done.+noRestText :: ([Text], ByteString) -> ContentParser [Text]+noRestText (x, "") = return x+noRestText (_, x) = throwError $ "noRestText: remainding text: " ++ show x++-- | Parse text, not allowing any remainding text.+parseText :: ByteString -> ContentParser [Text]+parseText = noRestText <=< parseText'++-- | Parse a DateTime value. 3.3.5+parseDateTime :: Maybe Text -- ^ Time Zone ID+              -> ByteString -> ContentParser DateTime+parseDateTime mTZ bs = do+    str <- asks $ T.unpack . ($ bs) . dfBS2Text+    let dayRes = parseDateStr str+        Just (day, rest') = dayRes+        t = take 1 rest'+        timeRes = parseTimeStr $ drop 1 rest'+        Just (time, isUTC) = timeRes+    when (isNothing (dayRes >> timeRes) || t /= "T") .+        throwError $ "parseDateTime: " ++ str+    when (isUTC && isJust mTZ) $+        tell ["parseDateTime: TZID on UTC timezone: " ++ str]+    return $ case (mTZ, isUTC) of+                  (Nothing, False) -> FloatingDateTime (LocalTime day time)+                  (Just tz, False) -> ZonedDateTime (LocalTime day time) tz+                  (_, True) -> UTCDateTime (UTCTime day+                                                  $ Time.timeOfDayToTime time)++-- | Parse a string to a Day. 3.3.4+parseDateStr :: String -> Maybe (Day, String)+parseDateStr = lastToMaybe . Time.readsTime L.defaultTimeLocale "%Y%m%d"++-- | Parse a string to a TimeOfDay, and a bool if it's in UTC.+parseTimeStr :: String -> Maybe (TimeOfDay, Bool)+parseTimeStr s = do+    (t, r) <- lastToMaybe (Time.readsTime L.defaultTimeLocale "%H%M%S" s)+    case r of+         "Z" -> return (t, True)+         "" -> return (t, False)+         _ -> fail ""++-- | Parse a Date value. 3.3.4+parseDate :: ByteString -> ContentParser Date+parseDate bs = do+    str <- asks $ T.unpack . ($ bs) . dfBS2Text+    let dayRes = parseDateStr str+        Just (day, rest) = dayRes+    when (isNothing dayRes) .+        throwError $ "parseDate: " ++ str+    unless (null rest) $+        tell ["parseDate: extra content: " ++ rest]+    return $ Date day++-- {{{ Misc parsers++parseURI :: String -> ContentParser URI.URI+parseURI s = case URI.parseURI s of+                  Just x -> return x+                  Nothing -> throwError $  "Invalid URI: " ++ show s+++-- | Convert a 'DateTime' to 'UTCTime', giving an appropriate error.+mustBeUTC :: DateTime -> ContentParser UTCTime+mustBeUTC (UTCDateTime x) = return x+mustBeUTC _ = throwError "DateTime-value must be UTC"++-- | Parse something simple with only a Text-field for the content, and+-- 'OtherParams'.+parseSimple :: (Text -> OtherParams -> b) -> Content -> ContentParser b+parseSimple k (ContentLine _ _ o bs) = do c <- valueOnlyOne =<< parseText bs+                                          return $ k c (toO o)+parseSimple _ x = throwError $ "parseSimple: " ++ show x++-- | Parse something simple with only a CI Text-field for the content, and+-- 'OtherParams'.+parseSimpleI :: (CI Text -> OtherParams -> b) -> Content -> ContentParser b+parseSimpleI k (ContentLine _ _ o bs) = do c <- asks dfBS2IText+                                           return $ k (c bs) (toO o)+parseSimpleI _ x = throwError $ "parseSimpleI: " ++ show x++-- | Parse something simple with only a Int-field for the content, and+-- 'OtherParams'.+parseSimpleRead :: forall a b. Read a+                => (a -> OtherParams -> b) -> Content -> ContentParser b+parseSimpleRead k (ContentLine _ _ o bs) = do+    let r = maybeRead $ B.unpack bs :: Maybe a+    when (isNothing r) . throwError $ "parseSimpleRead: " ++ show bs+    return $ k (fromJust r) (toO o)+parseSimpleRead _ x = throwError $ "parseSimpleRead: " ++ show x++-- | Parse something b with alternative representations, language+-- specification, and 'OtherParams'.+parseAltRepLang' :: ([Text] -> ContentParser b)+                 -> (b -> Maybe URI.URI -> Maybe Language -> OtherParams -> a)+                 -> Content -> ContentParser a+parseAltRepLang' m f (ContentLine _ _ o bs) = do+    t <- m =<< parseText bs+    uri <- mapM (parseURI <=< paramOnlyOne) $ T.unpack .: lookup "ALTREP" o+    lang <- mapM paramOnlyOne $ Language . CI.mk .: lookup "LANGUAGE" o+    let o' = filter (\(x, _) -> x `notElem` ["ALTREP", "LANGUAGE"]) o+    return $ f t uri lang (toO o')+parseAltRepLang' _ _ x = throwError $ "parseAltRepLang': " ++ show x++-- | Parse something 'Text' with alternative representations, language+-- specification, and 'OtherParams'.+parseAltRepLang :: (Text -> Maybe URI.URI -> Maybe Language -> OtherParams -> a)+                -> Content -> ContentParser a+parseAltRepLang = parseAltRepLang' valueOnlyOne++-- | Parse something '[Text]' with alternative representations, language+-- specification, and 'OtherParams'.+parseAltRepLangN :: (Set Text -> Maybe URI.URI -> Maybe Language+                              -> OtherParams -> a)+                -> Content -> ContentParser a+parseAltRepLangN = parseAltRepLang' (return . S.fromList)++-- | Parse something simple with only a URI-field for the content, and+-- 'OtherParams'.+parseSimpleURI :: (URI.URI -> OtherParams -> a) -> Content -> ContentParser a+parseSimpleURI f (ContentLine _ _ o bs) = do+    uri <- parseURI =<< asks (T.unpack . ($ bs) . dfBS2Text)+    return . f uri $ toO o+parseSimpleURI _ x = throwError $ "parseSimpleURI: " ++ show x+++-- | Parse something which has either a 'Date' or a 'DateTime' value, and+-- 'OtherParams'. Uses DateTime if there is no value parameter.+parseSimpleDateOrDateTime :: (DateTime -> OtherParams -> a)+                          -> (Date     -> OtherParams -> a)+                          -> Content+                          -> ContentParser a+parseSimpleDateOrDateTime dt d (ContentLine _ _ o bs) = do+    (typ, tzid, o') <- typTzIdO o+    case typ of+         "DATE-TIME" -> do x <- parseDateTime tzid bs+                           return . dt x $ toO o'+         "DATE" -> do x <- parseDate bs+                      return . d x $ toO o'+         _ -> throwError $ "Invalid type: " ++ show typ+parseSimpleDateOrDateTime _ _ x =+    throwError $ "parseSimpleDateOrDateTime: " ++ show x++-- | Parse something which has a set of either a 'Date' or a 'DateTime' value,+-- and 'OtherParams'. Uses DateTime if there is no value parameter.+parseSimpleDatesOrDateTimes :: (Set DateTime -> OtherParams -> a)+                            -> (Set Date     -> OtherParams -> a)+                            -> Content+                            -> ContentParser a+parseSimpleDatesOrDateTimes dt d (ContentLine _ _ o bs) = do+    (typ, tzid, o') <- typTzIdO o+    case typ of+         "DATE-TIME" -> do x <- S.fromList .: mapM (parseDateTime tzid) $+                                                B.split ',' bs+                           return . dt x $ toO o'+         "DATE" -> do x <- S.fromList .: mapM parseDate $ B.split ',' bs+                      return . d x $ toO o'+         _ -> throwError $ "Invalid type: " ++ show typ+parseSimpleDatesOrDateTimes _ _ x =+    throwError $ "parseSimpleDatesOrDateTimes: " ++ show x++typTzIdO :: [(CI Text, [Text])]+         -> ContentParser (Text, Maybe Text, [(CI Text, [Text])])+typTzIdO o = do+    typ <- paramOnlyOne . fromMaybe ["DATE-TIME"] $ lookup "VALUE" o+    tzid <- mapM paramOnlyOne $ if typ == "DATE-TIME" then lookup "TZID" o+                                                      else Nothing+    let f x = x /= "VALUE" && (typ /= "DATE-TIME" || x /= "TZID")+        o' = filter (f . fst) o+    return (typ, tzid, o')++-- | Parse something which has only a DateTime value, and 'OtherParams'.+parseSimpleDateTime :: (DateTime -> OtherParams -> a)+                    -> Content+                    -> ContentParser a+parseSimpleDateTime dt (ContentLine _ _ o bs) = do+    tzid <- mapM paramOnlyOne $ lookup "TZID" o+    let o' = filter ((/="TZID") . fst) o+    flip dt (toO o') <$> parseDateTime tzid bs+parseSimpleDateTime _ x = throwError $ "parseSimpleDateTime: " ++ show x++parseSimpleUTC :: (UTCTime -> OtherParams -> a)+               -> Content+               -> ContentParser a+parseSimpleUTC dt (ContentLine _ _ o bs) =+    flip dt (toO o) <$> (mustBeUTC =<< parseDateTime Nothing bs)+parseSimpleUTC _ x = throwError $ "parseSimpleUTC: " ++ show x++-- | Convert a property dictionary to 'OtherParams'.+toO :: [(CI Text, [Text])] -> OtherParams+toO = OtherParams . S.fromList . map (uncurry OtherParam)++-- | Get the remaining properties.+otherProperties :: ContentParser (Set OtherProperty)+otherProperties = do opts <- snd <$> get+                     modify (second $ const [])+                     S.fromList <$> mapM lineToOtherProp opts+  where lineToOtherProp (ContentLine _ n opts bs) =+            return (OtherProperty n bs $ toO opts)+        lineToOtherProp c@Component {} =+            down c . throwError $ "Unconsumed component: " ++ show c++neg :: TextParser (Int -> Int)+neg = maybe id (\x -> if x == '-' then negate else id)+            <$> optional (P.oneOf "+-")++digits :: TextParser Int+digits = foldl1 ((+).(*10)) . map digitToInt <$> many1 P.digit++digitsN :: TextParser [Int]+digitsN = sepBy1 digits (P.char ',')++-- }}}++-- | Set the parser context.+down :: Content -> ContentParser a -> ContentParser a+down (Component p _ x) = down' (p, x)+down x@(ContentLine p _ _ _) = down' (p, [x])++-- | Set the parser context.+down' :: (P.SourcePos, [Content]) -> ContentParser a -> ContentParser a+down' x m = get >>= \old -> put x >> m <* put old++-- | Many optional components named ...+optCompN :: Ord a+         => CI Text -> (Content -> ContentParser a) -> ContentParser (Set a)+optCompN s f = optN f . partition (`isComponentNamed` s) =<< snd <$> get++-- | One required line named ...+reqLine1 :: CI Text -> (Content -> ContentParser a) -> ContentParser a+reqLine1 s f = req1 s f . partition (`isLineNamed` s) =<< snd <$> get++-- | One optional line named ...+optLine1 :: Default b+         => CI Text -> (Content -> ContentParser b) -> ContentParser b+optLine1 s f = opt1 f . partition (`isLineNamed` s) =<< snd <$> get++-- | Many optional lines named ...+optLineN :: Ord b+         => CI Text -> (Content -> ContentParser b) -> ContentParser (Set b)+optLineN s f = optN f . partition (`isLineNamed` s) =<< snd <$> get++-- | Many lines named ..., at least one required.+reqLineN :: Ord b+         => CI Text -> (Content -> ContentParser b) -> ContentParser (Set b)+reqLineN s f = reqN s f . partition (`isLineNamed` s) =<< snd <$> get++-- | One required ...+req1 :: CI Text -> (Content -> ContentParser b) -> ([Content], [Content])+     -> ContentParser b+req1 _ f ([x], xs) = modify (second $ const xs) >> down x (f x)+req1 s _ ([], _) = throwError $ "Missing content: " ++ show s+req1 _ f (x:xs, xs') = do modify (second $ const xs')+                          tell (map (("Extra content: " ++) . show) xs)+                          down x $ f x++-- | One optional ...+opt1 :: Default b+     => (Content -> ContentParser b) -> ([Content], [Content])+     -> ContentParser b+opt1 f ([x], xs) = modify (second $ const xs) >> down x (f x)+opt1 _ ([], _) = return def+opt1 f (x:xs, xs') = do modify (second $ const xs')+                        tell (map (("Extra content: " ++) . show) xs)+                        down x $ f x++-- | Many optional ...+optN :: Ord b+     => (Content -> ContentParser b) -> ([Content], [Content])+     -> ContentParser (Set b)+optN f (xs, xs') = do modify (second $ const xs')+                      S.fromList <$> mapM (\x -> down x (f x)) xs++-- | Many ..., at least one required.+reqN :: Ord b+     => CI Text -- ^ What, needed for the error.+     -> (Content -> ContentParser b) -> ([Content], [Content])+     -> ContentParser (Set b)+reqN w f (xs, xs') = do modify (second $ const xs')+                        o <- S.fromList <$> mapM (\x -> down x (f x)) xs+                        when (S.size o < 1) .+                            throwError $ "At least one required: " ++ show w+                        return o++-- | Only allow one parameter value.+paramOnlyOne :: [a] -> ContentParser a+paramOnlyOne [x] = return x+paramOnlyOne _ = throwError "Only one parameter value allowed."++valueOnlyOne :: [a] -> ContentParser a+valueOnlyOne [x] = return x+valueOnlyOne [] = throwError "Must have one value, not zero."+valueOnlyOne _ = throwError "Only one value allowed."++-- | Line predicate.+isLineNamed :: Content -> CI Text -> Bool+isLineNamed (ContentLine _ n _ _) n' | n == n' = True+isLineNamed _ _ = False++-- | Component name predicate.+isComponentNamed :: Content -> CI Text -> Bool+isComponentNamed (Component _ n _) n' | n == n' = True+isComponentNamed _ _ = False++isComponent :: Content -> Bool+isComponent Component {} = True+isComponent _ = False++-- Util++maybeRead :: Read a => String -> Maybe a+maybeRead = fst .: lastToMaybe . reads++lastToMaybe :: [a] -> Maybe a+lastToMaybe x = if null x then Nothing else Just $ last x++(.:) :: (Functor f, Functor g) => (a -> b) -> f (g a) -> f (g b)+(.:) = fmap fmap fmap++infixl 4 .:
+ Text/ICalendar/Parser/Components.hs view
@@ -0,0 +1,261 @@+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RecordWildCards #-}+module Text.ICalendar.Parser.Components where++import Control.Applicative+import Control.Monad.Error hiding (mapM)+import Control.Monad.RWS ( MonadState(get), tell )+import qualified Data.CaseInsensitive as CI+import Data.List (partition)+import Data.Maybe+import Data.Set (Set)+import qualified Data.Set as S++import Text.ICalendar.Types+import Text.ICalendar.Parser.Common+import Text.ICalendar.Parser.Properties++-- | Parse a VCALENDAR component. 3.4+parseVCalendar :: Content -> ContentParser VCalendar+parseVCalendar c@(Component _ "VCALENDAR" _) = down c $ do+    vcProdId <- reqLine1 "PRODID" (parseSimple ProdId)+    vcVersion <- reqLine1 "VERSION" parseVersion+    vcScale <- optLine1 "CALSCALE" (parseSimpleI Scale)+    vcMethod <- optLine1 "METHOD" (parseSimpleI ((Just .) . Method))+    vcTimeZones <- optCompN "VTIMEZONE" parseVTimeZone+    vcEvents <- optCompN "VEVENT" (parseVEvent vcMethod)+    vcTodos <- optCompN "VTODO" parseVTodo+    vcJournals <- optCompN "VJOURNAL" parseVJournal+    vcFreeBusys <- optCompN "VFREEBUSY" parseVFreeBusy+    vcOtherComps <- otherComponents+    vcOther <- otherProperties+    return VCalendar {..}+parseVCalendar _ = throwError "parseVCalendar: Content given not a VCALENDAR\+                              \ component."++-- | Parse a VEVENT component. 3.6.1+parseVEvent :: Maybe Method -> Content -> ContentParser VEvent+parseVEvent mmethod (Component _ "VEVENT" _) = do+    veDTStamp <- reqLine1 "DTSTAMP" $ parseSimpleUTC DTStamp+    veUID <- reqLine1 "UID" $ parseSimple UID+    veDTStart <- optLine1 "DTSTART" $+                  Just .: parseSimpleDateOrDateTime DTStartDateTime DTStartDate+    when (isNothing mmethod && isNothing veDTStart) $+        throwError "A VEVENT in a VCALENDAR without a METHOD requires a \+                   \DTSTART property."+    veClass <- optLine1 "CLASS" parseClass+    veCreated <- optLine1 "CREATED" $ parseSimpleDateTime ((Just .) . Created)+    veDescription <- optLine1 "DESCRIPTION" .+                    parseAltRepLang $ (((Just .) .) .) . Description+    veGeo <- optLine1 "GEO" (Just .: parseGeo)+    veLastMod <- optLine1 "LAST-MODIFIED" (Just .: parseLastModified)+    veLocation <- optLine1 "LOCATION" .+        parseAltRepLang $ (((Just .) .) .) . Location+    veOrganizer <- optLine1 "ORGANIZER" (Just .: parseOrganizer)+    vePriority <- optLine1 "PRIORITY" (parseSimpleRead Priority)+    veSeq <- optLine1 "SEQUENCE" (parseSimpleRead Sequence)+    veStatus <- optLine1 "STATUS" (Just .: parseEventStatus)+    veSummary <- optLine1 "SUMMARY" .+                    parseAltRepLang $ (((Just .) .) .) . Summary+    veTransp <- optLine1 "TRANSP" parseTransp+    veUrl <- optLine1 "URL" (Just .: parseSimpleURI URL)+    veRecurId <- optLine1 "RECURRENCE-ID"+                    $ Just .: parseRecurId veDTStart+    veRRule <- optLineN "RRULE" $ parseRRule veDTStart+    when (S.size veRRule > 1) $ tell ["SHOULD NOT have multiple RRules."]+    veDTEndDuration <- parseXDurationOpt "DTEND" DTEndDateTime DTEndDate+                                         veDTStart+    veAttach <- optLineN "ATTACH" parseAttachment+    veAttendee <- optLineN "ATTENDEE" parseAttendee+    veCategories <- optLineN "CATEGORIES" parseCategories+    veComment <- optLineN "COMMENT" $ parseAltRepLang Comment+    veContact <- optLineN "CONTACT" $ parseAltRepLang Contact+    veExDate <- optLineN "EXDATE" parseExDate+    veRStatus <- optLineN "REQUEST-STATUS" parseRequestStatus+    veRelated <- optLineN "RELATED-TO" parseRelatedTo+    veResources <- optLineN "RESOURCES" $ parseAltRepLangN Resources+    veRDate <- optLineN "RDATE" parseRDate+    veAlarms <- optCompN "VALARM" parseVAlarm+    veOther <- otherProperties+    return VEvent {..}+parseVEvent _ x = throwError $ "parseVEvent: " ++ show x++-- | Parse a VTODO component.+parseVTodo :: Content -> ContentParser VTodo+parseVTodo (Component _ "VTODO" _) = do+    vtDTStamp <- reqLine1 "DTSTAMP" $ parseSimpleUTC DTStamp+    vtUID <- reqLine1 "UID" $ parseSimple UID+    vtClass <- optLine1 "CLASS" parseClass+    vtCompleted <- optLine1 "COMPLETED" . parseSimpleDateTime $+                (Just .) . Completed+    vtCreated <- optLine1 "CREATED" . parseSimpleDateTime $+                (Just .) . Created+    vtDTStart <- optLine1 "DTSTART" $+                Just .: parseSimpleDateOrDateTime DTStartDateTime DTStartDate+    vtDescription <- optLine1 "DESCRIPTION" .+                parseAltRepLang $ (((Just .) .) .) . Description+    vtGeo <- optLine1 "GEO" (Just .: parseGeo)+    vtLastMod <- optLine1 "LAST-MODIFIED" (Just .: parseLastModified)+    vtLocation <- optLine1 "LOCATION" .+                parseAltRepLang $ (((Just .) .) .) . Location+    vtOrganizer <- optLine1 "ORGANIZER" (Just .: parseOrganizer)+    vtPercent <- optLine1 "PERCENT-COMPLETE" $ Just .: parseSimpleRead+                                                             PercentComplete+    vtPriority <- optLine1 "PRIORITY" $ parseSimpleRead Priority+    vtRecurId <- optLine1 "RECURRENCE-ID" (Just .: parseRecurId vtDTStart)+    vtSeq <- optLine1 "SEQUENCE" $ parseSimpleRead Sequence+    vtStatus <- optLine1 "STATUS" (Just .: parseTodoStatus)+    vtSummary <- optLine1 "SUMMARY" .+                parseAltRepLang $ (((Just .) .) .) . Summary+    vtUrl <- optLine1 "URL" (Just .: parseSimpleURI URL)+    vtRRule <- optLineN "RRULE" $ parseRRule vtDTStart+    when (S.size vtRRule > 1) $ tell ["SHOULD NOT have multiple RRules."]+    vtDueDuration <- parseXDurationOpt "DUE" DueDateTime DueDate vtDTStart++    vtAttach <- optLineN "ATTACH" parseAttachment+    vtAttendee <- optLineN "ATTENDEE" parseAttendee+    vtCategories <- optLineN "CATEGORIES" parseCategories+    vtComment <- optLineN "COMMENT" $ parseAltRepLang Comment+    vtContact <- optLineN "CONTACT" $ parseAltRepLang Contact+    vtExDate <- optLineN "EXDATE" parseExDate+    vtRStatus <- optLineN "REQUEST-STATUS" parseRequestStatus+    vtRelated <- optLineN "RELATED-TO" parseRelatedTo+    vtResources <- optLineN "RESOURCES" $ parseAltRepLangN Resources+    vtRDate <- optLineN "RDATE" parseRDate+    vtAlarms <- optCompN "VALARM" parseVAlarm+    vtOther <- otherProperties+    return VTodo {..}+parseVTodo x = throwError $ "parseVTodo: " ++ show x++-- | Parse a VTIMEZONE component. 3.6.5+parseVTimeZone :: Content -> ContentParser VTimeZone+parseVTimeZone (Component _ "VTIMEZONE" _) = do+    vtzId <- reqLine1 "TZID" parseTZID+    vtzLastMod <- optLine1 "LAST-MODIFIED" (Just .: parseLastModified)+    vtzUrl <- optLine1 "TZURL" (Just .: parseSimpleURI TZUrl)+    vtzStandardC <- optCompN "STANDARD" parseTZProp+    vtzDaylightC <- optCompN "DAYLIGHT" parseTZProp+    when (S.size vtzStandardC + S.size vtzDaylightC < 1) .+        throwError $ "VTIMEZONE must include at least one of the STANDARD or \+                     \DAYLIGHT components."+    vtzOther <- otherProperties+    return VTimeZone {..}+parseVTimeZone x = throwError $ "parseVTimeZone: " ++ show x++-- | Parse a STANDARD or DAYLIGHT component, tzprop. 3.6.5+parseTZProp :: Content -> ContentParser TZProp+parseTZProp (Component _ n _) | n `elem` ["STANDARD", "DAYLIGHT"] = do+    tzpDTStart <- reqLine1 "DTSTART" $+                    parseSimpleDateOrDateTime DTStartDateTime DTStartDate+    tzpTZOffsetTo <- reqLine1 "TZOFFSETTO" parseUTCOffset+    tzpTZOffsetFrom <- reqLine1 "TZOFFSETFROM" parseUTCOffset+    tzpRRule <- optLineN "RRULE" (parseRRule $ Just tzpDTStart)+    when (S.size tzpRRule > 1) $ tell ["SHOULD NOT have multiple RRules."]+    tzpComment <- optLineN "COMMENT" (parseAltRepLang Comment)+    tzpRDate <- optLineN "RDATE" parseRDate+    tzpTZName <- optLineN "TZNAME" parseTZName+    tzpOther <- otherProperties+    return TZProp {..}+parseTZProp x = throwError $ "parseTZProp: " ++ show x++-- | Parse a VALARM component. 3.6.6+parseVAlarm :: Content -> ContentParser VAlarm+parseVAlarm (Component _ "VALARM" _) = do+    (ao, a') <- reqLine1 "ACTION" (\(ContentLine _ _ o bs) -> return (o, bs))+    a <- valueOnlyOne =<< parseText a'+    vaTrigger <- reqLine1 "TRIGGER" parseTrigger+    let vaActionOther = toO ao+    case CI.mk a of+         "AUDIO"   -> do+            (vaRepeat, vaDuration) <- repAndDur+            vaAudioAttach <- optLine1 "ATTACH" $ Just .: parseAttachment+            vaOther <- otherProperties+            return VAlarmAudio {..}+         "DISPLAY" -> do+             (vaRepeat, vaDuration) <- repAndDur+             vaDescription <- reqLine1 "DESCRIPTION" $+                 parseAltRepLang Description+             vaOther <- otherProperties+             return VAlarmDisplay {..}+         "EMAIL"   -> do+             (vaRepeat, vaDuration) <- repAndDur+             vaDescription <- reqLine1 "DESCRIPTION" $+                parseAltRepLang Description+             vaSummary <- reqLine1 "SUMMARY" $ parseAltRepLang Summary+             vaAttendee <- reqLineN "ATTENDEE" parseAttendee+             vaMailAttach <- optLineN "ATTACH" parseAttachment+             vaOther <- otherProperties+             return VAlarmEmail {..}+         vaAction  -> do vaOther <- otherProperties+                         return VAlarmX {..}+  where repAndDur = do+             rep <- optLine1 "REPEAT" $ parseSimpleRead Repeat+             dur <- optLine1 "DURATION" $ Just .: parseDurationProp Nothing+             -- Liberal interpretation:+             when (repeatValue rep > 0 && isNothing dur) .+                 throwError $ "parseVAlarm: when REPEAT > 0, DURATION must \+                              \ be specified."+             return (rep, dur)+parseVAlarm x = throwError $ "parseVAlarm: " ++ show x++parseVJournal :: Content -> ContentParser VJournal+parseVJournal (Component _ "VJOURNAL" _) = do+    vjDTStamp <- reqLine1 "DTSTAMP" $ parseSimpleUTC DTStamp+    vjUID <- reqLine1 "UID" $ parseSimple UID+    vjClass <- optLine1 "CLASS" parseClass+    vjCreated <- optLine1 "CREATED" . parseSimpleDateTime $+                (Just .) . Created+    vjDTStart <- optLine1 "DTSTART" $+                Just .: parseSimpleDateOrDateTime DTStartDateTime DTStartDate+    vjDescription <- optLineN "DESCRIPTION" $ parseAltRepLang Description+    vjLastMod <- optLine1 "LAST-MODIFIED" (Just .: parseLastModified)+    vjOrganizer <- optLine1 "ORGANIZER" (Just .: parseOrganizer)+    vjRecurId <- optLine1 "RECURRENCE-ID" (Just .: parseRecurId vjDTStart)+    vjSeq <- optLine1 "SEQUENCE" $ parseSimpleRead Sequence+    vjStatus <- optLine1 "STATUS" (Just .: parseJournalStatus)+    vjSummary <- optLine1 "SUMMARY" .+                parseAltRepLang $ (((Just .) .) .) . Summary+    vjUrl <- optLine1 "URL" (Just .: parseSimpleURI URL)+    vjRRule <- optLineN "RRULE" $ parseRRule vjDTStart+    when (S.size vjRRule > 1) $ tell ["SHOULD NOT have multiple RRules."]+    vjAttach <- optLineN "ATTACH" parseAttachment+    vjAttendee <- optLineN "ATTENDEE" parseAttendee+    vjCategories <- optLineN "CATEGORIES" parseCategories+    vjComment <- optLineN "COMMENT" $ parseAltRepLang Comment+    vjContact <- optLineN "CONTACT" $ parseAltRepLang Contact+    vjExDate <- optLineN "EXDATE" parseExDate+    vjRStatus <- optLineN "REQUEST-STATUS" parseRequestStatus+    vjRelated <- optLineN "RELATED-TO" parseRelatedTo+    vjRDate <- optLineN "RDATE" parseRDate+    vjOther <- otherProperties+    return VJournal {..}+parseVJournal x = throwError $ "parseVJournal: " ++ show x++parseVFreeBusy :: Content -> ContentParser VFreeBusy+parseVFreeBusy (Component _ "VFreeBusy" _) = do+    vfbDTStamp <- reqLine1 "DTSTAMP" $ parseSimpleUTC DTStamp+    vfbUID <- reqLine1 "UID" $ parseSimple UID+    vfbContact <- optLine1 "CONTACT" $ Just .: parseAltRepLang Contact+    vfbDTStart <- optLine1 "DTSTART" $+                  Just .: parseSimpleDateOrDateTime DTStartDateTime DTStartDate+    vfbDTEnd <- optLine1 "DTEND" $ Just .: parseSimpleDateOrDateTime+                                                DTEndDateTime DTEndDate+    vfbOrganizer <- optLine1 "ORGANIZER" $ Just .: parseOrganizer+    vfbAttendee <- optLineN "ATTENDEE" parseAttendee+    vfbComment <- optLineN "COMMENT" $ parseAltRepLang Comment+    vfbRStatus <- optLineN "REQUEST-STATUS" parseRequestStatus+    vfbUrl <- optLine1 "URL" (Just .: parseSimpleURI URL)+    vfbFreeBusy <- optLineN "FREEBUSY" parseFreeBusy+    vfbOther <- otherProperties+    return VFreeBusy {..}+parseVFreeBusy x = throwError $ "parseVFreeBusy: " ++ show x++otherComponents :: ContentParser (Set VOther)+otherComponents = optN parseVOther . partition isComponent =<< snd <$> get++parseVOther :: Content -> ContentParser VOther+parseVOther (Component _ voName _) = do+    voProps <- otherProperties+    return VOther {..}+parseVOther x = throwError $ "parseVOther: "++ show x+
+ Text/ICalendar/Parser/Content.hs view
@@ -0,0 +1,113 @@+{-# LANGUAGE OverloadedStrings #-}+module Text.ICalendar.Parser.Content where++import Control.Applicative+import Control.Monad+import Data.ByteString.Lazy (ByteString)+import qualified Data.ByteString.Lazy.Builder as Bu+import Data.CaseInsensitive (CI)+import Data.Char+import Data.Monoid+import Data.Text.Lazy (Text)++import qualified Text.Parsec as P+import Text.Parsec.Prim hiding (many, (<|>))+import Text.Parsec.Combinator hiding (optional)+import Text.Parsec.ByteString.Lazy ()+import Text.Parsec.Text.Lazy ()++import Text.ICalendar.Parser.Common++parseToContent :: TextParser [Content]+parseToContent = do content <- sepEndBy1 contentline newline+                    f <- dfBS2IText <$> getState+                    return $ componentalize f content++newline :: TextParser ()+newline = (char '\r' >> void (optional $ char '\n')) <|> void (char '\n')+++componentalize :: (ByteString -> CI Text) -> [Content] -> [Content]+componentalize f (ContentLine p "BEGIN" [] n:xs) =+    let (com, rest) = break g xs+        g (ContentLine _ "END" [] en) | f en == n' = True+        g _ = False+        n' = f n+     in Component p n' (componentalize f com)+                : componentalize f (drop 1 rest)+componentalize f (x:xs) = x:componentalize f xs+componentalize _ _ = []+++-- | Specialized scan function which unfolds lines.+scan :: s -- ^ Initial state.+     -> (s -> Maybe Char -> Maybe (Maybe s))+     -- ^ Nothing: Fail.+     -- Just Nothing: Done, don't use last char.+     -- Just (Just state): Continue, collecting char unless EOF.+     -> TextParser ByteString+scan state f = go state mempty+  where go st buf = do+            _ <- many (try unfold)+            c <- lookAhead (Just <$> P.anyChar <|> Nothing <$ P.eof)+            case (c, f st c) of+                 (_, Nothing) -> mzero+                 (Just c', Just (Just st')) ->+                    P.anyChar *> go st' (buf <> Bu.char8 c')+                 (_, _) -> return $ Bu.toLazyByteString buf++        unfold = (P.char '\r' >> optional (P.char '\n') >> P.oneOf " \t")+             <|> (P.char '\n' >> P.oneOf " \t")++takeWhile1 :: (Char -> Bool) -> TextParser ByteString+takeWhile1 p = scan False f <?> "takeWhile1 ..."+  where f g (Just x) | p x       = Just (Just True)+                     | g         = Just Nothing+                     | otherwise = Nothing+        f g _        | g         = Just Nothing+                     | otherwise = Nothing++char :: Char -> TextParser ByteString+char c = scan True f <?> show c+  where f True x = if Just c == x then Just (Just False) else Nothing+        f False _ = Just Nothing+++isControl', isSafe, isValue, isQSafe, isName :: Char -> Bool+isControl' c = c /= '\t' && isControl c+isSafe c = not (isControl' c) && c `notElem` "\";:,"+isValue c = let n = fromEnum c in n == 32 || n == 9 || (n >= 0x21 && n /= 0x7F)+isQSafe c = isValue c && c /= '"'+isName c = isAsciiUpper c || isAsciiLower c || isDigit c || c == '-'++contentline :: TextParser Content+contentline = do pos <- getPosition+                 n <- name+                 ps <- many (char ';' >> param)+                 _ <- char ':'+                 val <- value <|> return mempty+                 return $ ContentLine pos n ps val+  where value :: TextParser ByteString+        value = takeWhile1 isValue <?> "value"++        param :: TextParser (CI Text, [Text])+        param = do n <- name+                   _ <- char '='+                   vs <- sepBy1 paramValue (char ',')+                   return (n, vs)++        name :: TextParser (CI Text)+        name = dfBS2IText <$> getState <*> takeWhile1 isName <?> "name"++        paramValue :: TextParser Text+        paramValue = paramtext <|> quotedString++        paramtext :: TextParser Text+        paramtext = dfBS2Text <$> getState <*> takeWhile1 isSafe <?> "paramtext"++        quotedString :: TextParser Text+        quotedString = (do+            _ <- char '"'+            s <- takeWhile1 isQSafe <|> return mempty+            _ <- char '"'+            dfBS2Text <$> getState <*> pure s) <?> "quoted string"
+ Text/ICalendar/Parser/Parameters.hs view
@@ -0,0 +1,208 @@+{-# LANGUAGE OverloadedStrings #-}+module Text.ICalendar.Parser.Parameters where++import Control.Applicative+import Control.Monad.Error+import Control.Monad.RWS ( MonadWriter(tell) )+import Data.ByteString.Lazy.Char8 (ByteString)+import qualified Data.ByteString.Lazy.Char8 as B+import Data.CaseInsensitive (CI)+import Data.Char+import Data.Default+import Data.Maybe+import Data.Text.Lazy (Text)+import qualified Data.Text.Lazy as T++import Codec.MIME.Parse (parseMIMEType)+import Codec.MIME.Type (mimeType, MIMEType)+import qualified Text.Parsec as P+import Text.Parsec.Prim hiding ((<|>))+import Text.Parsec.Perm+import Text.Parsec.Combinator hiding (optional)++import Text.ICalendar.Types+import Text.ICalendar.Parser.Common++parseAlarmTriggerRelationship :: CI Text+                              -> ContentParser AlarmTriggerRelationship+parseAlarmTriggerRelationship "START" = return Start+parseAlarmTriggerRelationship "END" = return End+parseAlarmTriggerRelationship x =+    throwError $ "parseAlarmTriggerRelationship: " ++ show x++-- | Parse relationship type. 3.2.15+parseRelationshipType :: CI Text -> RelationshipType+parseRelationshipType "PARENT"  = Parent+parseRelationshipType "CHILD"   = Child+parseRelationshipType "SIBLING" = Sibling+parseRelationshipType x = RelationshipTypeX x++-- | Parse bool. 3.3.2+parseBool :: CI Text -> ContentParser Bool+parseBool "TRUE" = return True+parseBool "FALSE" = return False+parseBool x = throwError $ "parseBool: " ++ show x++-- | Parse recurrence identifier range. 3.2.13+parseRange :: CI Text -> ContentParser Range+parseRange "THISANDFUTURE" = return ThisAndFuture+parseRange "THISANDPRIOR"  = do tell ["THISANDPRIOIR RANGE is deprecated."]+                                return ThisAndPrior+parseRange x = throwError $ "parseRange: " ++ show x++-- | Parse free/busy time type. 3.2.9.+parseFBType :: CI Text -> FBType+parseFBType "FREE"             = Free+parseFBType "BUSY"             = Busy+parseFBType "BUSY-UNAVAILABLE" = BusyUnavailable+parseFBType "BUSY-TENTATIVE"   = BusyTentative+parseFBType x                  = FBTypeX x++-- | Parse participation status. 3.2.12+parsePartStat :: CI Text -> PartStat+parsePartStat "NEEDS-ACTION" = PartStatNeedsAction+parsePartStat "ACCEPTED" = Accepted+parsePartStat "DECLINED" = Declined+parsePartStat "TENTATIVE" = Tentative+parsePartStat "DELEGATED" = Delegated+parsePartStat "COMPLETED" = PartStatCompleted+parsePartStat "IN-PROCESS" = InProcess+parsePartStat x = PartStatX x++-- | Parse role.+parseRole :: CI Text -> Role+parseRole "CHAIR" = Chair+parseRole "REQ-PARTICIPANT" = ReqParticipant+parseRole "OPT-PARTICIPANT" = OptParticipant+parseRole "NON-PARTICIPANT" = NonParticipant+parseRole x = RoleX x+++parseCUType :: CI Text -> CUType+parseCUType "INDIVIDUAL" = Individual+parseCUType "GROUP" = Group+parseCUType "RESOURCE" = Resource+parseCUType "ROOM" = Room+parseCUType "UNKNOWN" = Unknown+parseCUType x = CUTypeX x++parseMime :: Text -> ContentParser MIMEType+parseMime t = let m = mimeType .: parseMIMEType $ T.unpack t+               in maybe (throwError $ "parseMime: " ++ show t) return m++-- | Parse Duration. 3.3.6+parseDuration :: String -- ^ Parser context.+              -> ByteString -- ^ What to parse.+              -> ContentParser Duration+parseDuration what bs =+    case runParser dur def what bs of+         Left e -> throwError $ "Invalid duration: "+                              ++ unlines [show bs, show e]+         Right x -> return x+  where dur = do si <- sign+                 _ <- P.char 'P'+                 day <- optional . try $ digits <* P.char 'D'+                 time <- optional $ do+                    _ <- P.char 'T'+                    h <- optional . try $ digits <* P.char 'H'+                    m <- optional . try $ digits <* P.char 'M'+                    s <- optional . try $ digits <* P.char 'S'+                    return (h, m, s)+                 week <- optional . try $ digits <* P.char 'W'+                 P.eof+                 case (day, time, week) of+                      (Just d, x, Nothing) ->+                           let (h, m, s) = deMHms x+                            in return $ DurationDate si d h m s+                      (Nothing, x@(Just _), Nothing) ->+                           let (h, m, s) = deMHms x+                            in return $ DurationTime si h m s+                      (Nothing, Nothing, Just w) ->+                           return $ DurationWeek si w+                      (_, _, _) -> fail "Invalid."++        sign = fromMaybe Positive <$> optional (Positive <$ P.char '+'+                                            <|> Negative <$ P.char '-')++        deMHms (Just (h, m, s)) = (fromMaybe 0 h, fromMaybe 0 m, fromMaybe 0 s)+        deMHms Nothing = (0, 0, 0)++-- | Parse Recur-value. 3.3.10.+-- Partly implemented in parsec.+parseRecur :: DTStart -> TextParser (ContentParser Recur)+parseRecur dts =+    permute (mkRecur <$$> (freq <* term)+                     <|?> (Nothing, untilCount <* term)+                     <|?> (1, istring "INTERVAL=" *> digits <* term)+                     <|?> ([], istring "BYSECOND=" *> digitsN <* term)+                     <|?> ([], istring "BYMINUTE=" *> digitsN <* term)+                     <|?> ([], istring "BYHOUR=" *> digitsN <* term)+                     <|?> ([], istring "BYDAY=" *> sepBy wday (P.char ',')+                                                     <* term)+                     <|?> ([], istring "BYMONTHDAY=" *> onum <* term)+                     <|?> ([], istring "BYYEARDAY=" *> onum <* term)+                     <|?> ([], istring "BYWEEKNO=" *> onum <* term)+                     <|?> ([], istring "BYMONTH=" *> digitsN <* term)+                     <|?> ([], istring "BYSETPOS=" *> onum <* term)+                     <|?> (Monday, istring "WKST=" *> weekday <* term))+      <* P.eof++  where freq = istring "FREQ=" *> frequency+        frequency = Secondly <$ istring "SECONDLY"+                <|> Minutely <$ istring "MINUTELY"+                <|> Hourly   <$ istring "HOURLY"+                <|> Daily    <$ istring "DAILY"+                <|> Weekly   <$ istring "WEEKLY"+                <|> Monthly  <$ istring "MONTHLY"+                <|> Yearly   <$ istring "YEARLY"+        weekday = Sunday    <$ istring "SU"+              <|> Monday    <$ istring "MO"+              <|> Tuesday   <$ istring "TU"+              <|> Wednesday <$ istring "WE"+              <|> Thursday  <$ istring "TH"+              <|> Friday    <$ istring "FR"+              <|> Saturday  <$ istring "SA"+        wday = Right <$> weekday+           <|> (Left .) . (,) <$> (neg <*> digits) <*> weekday+        onum = sepBy1 (neg <*> digits) (P.char ',')+        untilCount = istring "UNTIL=" *> until'+                 <|> istring "COUNT=" *> (Just . Right <$> digits)+        until' = do txt <- manyTill P.anyChar (void (P.char ';') <|> P.eof)+                    return . Just . Left $+                        case dts of+                             DTStartDateTime _ _ ->+                                 Right <$> parseDateTime Nothing (B.pack txt)+                             DTStartDate _ _ ->+                                 Left <$> parseDate (B.pack txt)+        term = optional (P.char ';')+        istring :: String -> TextParser ()+        istring = void . try . mapM (\c -> P.char c <|> P.char (toLower c))++        mkRecur f uc i s m h d md yd wn mo sp wkst = do+            uc' <- case uc of+                        Just (Left x) -> Just . Left <$> x+                        Just (Right y) -> return . Just $ Right y+                        Nothing -> return Nothing+            return $ Recur f uc' i s m h d md yd wn mo sp wkst++++parseUTCPeriod :: ByteString -> ContentParser UTCPeriod+parseUTCPeriod bs = do+    let (dateTime', x) = B.drop 1 <$> B.break (=='/') bs+    when (B.null x) . throwError $ "Invalid UTCperiod: " ++ show bs+    dateTime <- mustBeUTC =<< parseDateTime Nothing dateTime'+    case B.head x of+         z | z `elem` "+-P" -> UTCPeriodDuration dateTime+                                    <$> parseDuration "period" x+         _ -> UTCPeriodDates dateTime <$> (mustBeUTC =<< parseDateTime Nothing x)++parsePeriod :: Maybe Text -> ByteString -> ContentParser Period+parsePeriod tzid bs = do+    let (dateTime', x) = B.drop 1 <$> B.break (=='/') bs+    when (B.null x) . throwError $ "Invalid period: " ++ show bs+    dateTime <- parseDateTime tzid dateTime'+    case B.head x of+         z | z `elem` "+-P" -> PeriodDuration dateTime+                                    <$> parseDuration "period" x+         _ -> PeriodDates dateTime <$> parseDateTime tzid x
+ Text/ICalendar/Parser/Properties.hs view
@@ -0,0 +1,383 @@+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE TupleSections #-}+{-# LANGUAGE RecordWildCards #-}+module Text.ICalendar.Parser.Properties where++import Prelude hiding (mapM)+import Control.Applicative+import Control.Monad.Error hiding (mapM)+import Control.Monad.RWS ( asks )+import qualified Data.ByteString.Base64.Lazy as B64+import qualified Data.ByteString.Lazy.Char8 as B+import Data.CaseInsensitive (CI)+import qualified Data.CaseInsensitive as CI+import Data.Char+import Data.Default+import Data.Maybe+import qualified Data.Set as S+import Data.Text.Lazy (Text)+import qualified Data.Text.Lazy as T+import Data.Traversable (mapM)+import qualified Data.Version as Ver+import Text.ParserCombinators.ReadP (readP_to_S)++import Text.Parsec.Prim hiding ((<|>))++import Text.ICalendar.Types+import Text.ICalendar.Parser.Common+import Text.ICalendar.Parser.Parameters++parseFreeBusy :: Content -> ContentParser FreeBusy+parseFreeBusy (ContentLine _ "FREEBUSY" o bs) = do+    typ <- maybe (return def) (parseFBType . CI.mk .: paramOnlyOne) $+                     lookup "FBTYPE" o+    periods <- S.fromList .: mapM parseUTCPeriod $ B.split ',' bs+    return $ FreeBusy typ periods (toO $ filter ((/="FBTYPE").fst) o)+parseFreeBusy x = throwError $ "parseFreeBusy: " ++ show x++parseXDurationOpt :: CI Text+                  -> (DateTime -> OtherParams -> a)+                  -> (Date     -> OtherParams -> a)+                  -> Maybe DTStart+                  -> ContentParser (Maybe (Either a DurationProp))+parseXDurationOpt w a b dts = do+    dte <- optLine1 w $ Just .: parseSimpleDateOrDateTime a b+    dur <- optLine1 "DURATION" $ Just .: parseDurationProp dts+    case (dte, dur) of+         (Nothing, Nothing) -> return Nothing+         (Just x, Nothing) -> return . Just $ Left x+         (Nothing, Just x) -> return . Just $ Right x+         _ -> throwError "Either DTEND or DURATION can be specified, but not \+                         \both."++-- | Parse trigger. 3.8.6.3+parseTrigger :: Content -> ContentParser Trigger+parseTrigger (ContentLine _ "TRIGGER" o bs) = do+    value <- paramOnlyOne . fromMaybe ["DURATION"] $ lookup "VALUE" o+    case value of+         "DURATION" -> do+            rel <- maybe (return def)+                         (parseAlarmTriggerRelationship . CI.mk+                               <=< paramOnlyOne) $ lookup "RELATED" o+            let o' = filter (\(x,_) -> x /= "VALUE" && x /= "RELATED") o+            val <- parseDuration "TRIGGER" bs+            return $ TriggerDuration val rel (toO o')+         "DATE-TIME" -> do val <- mustBeUTC =<< parseDateTime Nothing bs+                           let o' = filter (\(x, _) -> x /= "VALUE") o+                           return $ TriggerDateTime val (toO o')+         x -> throwError $ "parseTrigger: invalid value: " ++ show x+parseTrigger x = throwError $ "parseTrigger: " ++ show x+++-- | Parse related to. 3.8.4.5+parseRelatedTo :: Content -> ContentParser RelatedTo+parseRelatedTo (ContentLine _ "RELATED-TO" o bs) = do+    val <- valueOnlyOne =<< parseText bs+    typ <- maybe (return def) (parseRelationshipType . CI.mk .: paramOnlyOne) $+                lookup "RELTYPE" o+    return $ RelatedTo val typ (toO $ filter (\(x,_) -> x /= "RELTYPE") o)+parseRelatedTo x = throwError $ "parseRelatedTo: " ++ show x+++-- | Parse request status. 3.8.8.3+parseRequestStatus :: Content -> ContentParser RequestStatus+parseRequestStatus (ContentLine _ "REQUEST-STATUS" o bs) = do+    let (statcode', rest) = B.break (==';') bs+        statcode :: Maybe [Int]+        statcode = mapM (maybeRead . B.unpack) $ B.split '.' statcode'+    when (isNothing statcode) .+        throwError $ "parseRequestStatus: invalid code: " ++ show bs+    when (B.null rest) .+        throwError $ "parseRequestStatus: missing statdesc: " ++ show bs+    (statdesc, rest') <- (\(a,b) -> (,b) <$> valueOnlyOne a)+                                   <=< parseText' $ B.tail rest+    statext <- if B.null rest'+                  then return Nothing+                  else do when (B.head rest' /= ';') .+                              throwError $ "parseRequestStatus: bad desc: " +++                                               show bs+                          Just <$> (valueOnlyOne =<< parseText (B.tail rest'))+    lang <- mapM paramOnlyOne $ Language . CI.mk .: lookup "LANGUAGE" o+    let o' = filter (\(x, _) -> x `notElem` ["LANGUAGE"]) o+    return $ RequestStatus (fromJust statcode) statdesc lang statext (toO o')+parseRequestStatus x = throwError $ "parseRequestStatus: " ++ show x++-- | Parse exception date-times. 3.8.5.1+parseExDate :: Content -> ContentParser ExDate+parseExDate (ContentLine _ "EXDATE" o bs) = do+    (typ, tzid, o') <- typTzIdO o+    let bs' = B.split ',' bs+    case typ of+         "DATE-TIME" -> do xs <- mapM (parseDateTime tzid) bs'+                           return . ExDateTimes (S.fromList xs) $ toO o'+         "DATE" -> do xs <- mapM parseDate bs'+                      return . ExDates (S.fromList xs) $ toO o'+         _ -> throwError $ "Invalid type: " ++ show typ+parseExDate x = throwError $ "parseExDate: " ++ show x++-- | Parse categories. 3.8.1.2+parseCategories :: Content -> ContentParser Categories+parseCategories (ContentLine _ "CATEGORIES" o bs) = do+    vals <- parseText bs+    lang <- mapM paramOnlyOne $ Language . CI.mk .: lookup "LANGUAGE" o+    let o' = filter (\(x, _) -> x `notElem` ["LANGUAGE"]) o+    return $ Categories (S.fromList vals) lang (toO o')+parseCategories x = throwError $ "parseCategories: " ++ show x++-- | Parse attendee. 3.8.4.1+parseAttendee :: Content -> ContentParser Attendee+parseAttendee (ContentLine _ "ATTENDEE" o bs) = do+    attendeeValue <- parseURI =<< asks (T.unpack . ($ bs) . dfBS2Text)+    attendeeCUType <- g (parseCUType . CI.mk .: paramOnlyOne) $+                        lookup "CUTYPE" o+    attendeeMember <- g (S.fromList .: mapM (parseURI . T.unpack)) $+                        lookup "MEMBER" o+    attendeeRole <- g (parseRole . CI.mk .: paramOnlyOne) $ lookup "ROLE" o+    attendeePartStat <- g (parsePartStat . CI.mk .: paramOnlyOne) $+                        lookup "PARTSTAT" o+    attendeeRSVP <- maybe (return False) (parseBool . CI.mk <=< paramOnlyOne) $+                        lookup "RSVP" o+    attendeeDelTo <- g (S.fromList .: mapM (parseURI . T.unpack)) $+                        lookup "DELEGATED-TO" o+    attendeeDelFrom <- g (S.fromList .: mapM (parseURI . T.unpack)) $+                        lookup "DELEGATED-FROM" o+    attendeeSentBy <- mapM (parseURI . T.unpack <=< paramOnlyOne) $+                        lookup "SENT-BY" o+    attendeeCN <- mapM paramOnlyOne $ lookup "CN" o+    attendeeDir <- mapM (parseURI . T.unpack <=< paramOnlyOne) $+                        lookup "DIR" o+    attendeeLanguage <- mapM (Language . CI.mk .: paramOnlyOne) $+                        lookup "LANGUAGE" o+    let attendeeOther = toO $ filter f o+        f (x, _) = x `notElem` [ "CUTYPE", "MEMBER", "ROLE", "PARTSTAT", "RSVP"+                               , "DELEGATED-TO", "DELEGATED-FROM", "SENT-BY"+                               , "CN", "DIR"]+    return Attendee {..}+  where g :: (Monad m, Default b) => (a -> m b) -> Maybe a -> m b+        g = maybe $ return def+parseAttendee x = throwError $ "parseAttendee: " ++ show x+++-- | Parse attachment. 3.8.1.1+parseAttachment :: Content -> ContentParser Attachment+parseAttachment (ContentLine _ "ATTACH" o bs) = do+    fmt <- mapM (parseMime <=< paramOnlyOne) $ lookup "FMTTYPE" o+    val <- mapM paramOnlyOne $ lookup "VALUE" o+    case val of+         Just "BINARY" -> do+             enc <- mapM paramOnlyOne $ lookup "ENCODING" o+             case enc of+                  Just "BASE64" ->+                      case B64.decode bs of+                           Left e -> throwError $ "parseAttachment: invalid \+                                                  \base64: " ++ e+                           Right v -> return $ BinaryAttachment fmt v+                                                  (toO $ filter binF o)+                  _ -> throwError $ "parseAttachment: invalid encoding: " +++                                        show enc+         Nothing -> do uri <- parseURI =<< asks (T.unpack . ($ bs) . dfBS2Text)+                       return $ UriAttachment fmt uri (toO $ filter f o)+         _ -> throwError $ "parseAttachment: invalid value: " ++ show val+  where binF a@(x, _) = f a && x /= "VALUE" && x /= "ENCODING"+        f (x, _) = x /= "FMTTYPE"+parseAttachment x = throwError $ "parseAttachment: " ++ show x++parseDurationProp :: Maybe DTStart -> Content -> ContentParser DurationProp+parseDurationProp dts (ContentLine _ "DURATION" o bs) = do+    val <- parseDuration "DURATION" bs+    case (dts, val) of+         (Just DTStartDate {}, DurationDate {..})+            | durHour == 0 && durMinute == 0 && durSecond == 0 -> return ()+         (Just DTStartDate {}, DurationWeek {}) -> return ()+         (Just DTStartDate {}, _) ->+             throwError "DURATION must be in weeks or days when DTSTART \+                        \has VALUE DATE and not DATE-TIME."+         _ -> return ()+    return . DurationProp val $ toO o+parseDurationProp _ x = throwError $ "parseDurationProp: " ++ show x++parseRecurId :: Maybe DTStart -> Content -> ContentParser RecurrenceId+parseRecurId dts (ContentLine p "RECURRENCE-ID" o bs) = do+    range' <- maybe (return def) (parseRange . CI.mk <=< paramOnlyOne) $+                                   lookup "RANGE" o+    recurid <- parseSimpleDateOrDateTime+            (($ range') . RecurrenceIdDateTime)+            (($ range') . RecurrenceIdDate)+            (ContentLine p "RECURRENCE-ID" (filter ((/="RANGE").fst) o) bs)+    case (dts, recurid) of+         (Nothing, _) -> return recurid+         (Just DTStartDate {}, RecurrenceIdDate {}) ->+             return recurid+         (Just DTStartDateTime {dtStartDateTimeValue = v},+          RecurrenceIdDateTime {recurrenceIdDateTime = r}) ->+               case (v, r) of -- TODO: Check this. iff confuse me.+                    (UTCDateTime {}, FloatingDateTime {}) -> err dts recurid+                    (UTCDateTime {}, ZonedDateTime {})    -> err dts recurid+                    (FloatingDateTime {}, UTCDateTime {}) -> err dts recurid+                    (ZonedDateTime {}, UTCDateTime {})    -> err dts recurid+                    _ -> return recurid+         _ -> err dts recurid+  where err d r = throwError $ "parseRecurId: DTSTART local time mismatch: " +++                                show (d, r)+parseRecurId _ x = throwError $ "parseRecurId: " ++ show x++-- | Parse time transparency. 3.8.2.7+parseTransp :: Content -> ContentParser TimeTransparency+parseTransp (ContentLine _ "TRANSP" o x)+    | CI.mk x == "OPAQUE" = return . Opaque $ toO o+    | CI.mk x == "TRANSPARENT" = return . Transparent $ toO o+parseTransp x = throwError $ "parseTransp: " ++ show x++-- | Parse event status. 3.8.1.11+parseEventStatus :: Content -> ContentParser EventStatus+parseEventStatus (ContentLine _ "STATUS" o x)+    | CI.mk x == "TENTATIVE" = return . TentativeEvent $ toO o+    | CI.mk x == "CONFIRMED" = return . ConfirmedEvent $ toO o+    | CI.mk x == "CANCELLED" = return . CancelledEvent $ toO o+parseEventStatus x = throwError $ "parseEventStatus: " ++ show x++-- | Parse todo status. 3.8.1.11+parseTodoStatus :: Content -> ContentParser TodoStatus+parseTodoStatus (ContentLine _ "STATUS" o x)+    | CI.mk x == "NEEDS-ACTION" = return . TodoNeedsAction $ toO o+    | CI.mk x == "COMPLETED"    = return . CompletedTodo   $ toO o+    | CI.mk x == "IN-PROCESS"   = return . InProcessTodo   $ toO o+    | CI.mk x == "CANCELLED"    = return . CancelledTodo   $ toO o+parseTodoStatus x = throwError $ "parseTodoStatus: " ++ show x++-- | Parse journal status. 3.8.1.11+parseJournalStatus :: Content -> ContentParser JournalStatus+parseJournalStatus (ContentLine _ "STATUS" o x)+    | CI.mk x == "DRAFT"     = return . DraftJournal     $ toO o+    | CI.mk x == "FINAL"     = return . FinalJournal     $ toO o+    | CI.mk x == "CANCELLED" = return . CancelledJournal $ toO o+parseJournalStatus x = throwError $ "parseJournalStatus: " ++ show x++-- | Parse organizer. 3.8.4.3+parseOrganizer :: Content -> ContentParser Organizer+parseOrganizer (ContentLine _ "ORGANIZER" o bs) = do+    organizerValue <- parseURI =<< asks (T.unpack . ($ bs) . dfBS2Text)+    organizerCN <- mapM paramOnlyOne $ lookup "CN" o+    organizerDir <- mapM (parseURI . T.unpack <=< paramOnlyOne) $ lookup "DIR" o+    organizerSentBy <- mapM (parseURI . T.unpack <=< paramOnlyOne) $+        lookup "SENT-BY" o+    organizerLanguage <- mapM (Language . CI.mk .: paramOnlyOne) $+        lookup "LANGUAGE" o+    let f x = x `notElem` ["CN", "DIR", "SENT-BY", "LANGUAGE"]+        o' = filter (f . fst) o+    return Organizer { organizerOther = toO o', .. }+parseOrganizer x = throwError $ "parseOrganizer: " ++ show x++-- | Parse geographic position. 3.8.1.6+parseGeo :: Content -> ContentParser Geo+parseGeo (ContentLine _ "GEO" o bs) = do+    let (lat', long') = B.break (==';') bs+        lat = maybeRead . stripPlus $ B.unpack lat' :: Maybe Float+        long = maybeRead . stripPlus . B.unpack $ B.tail long' :: Maybe Float+    when (B.null long' || isNothing (lat >> long)) .+        throwError $ "Invalid latitude/longitude: " ++ show bs+    return $ Geo (fromJust lat) (fromJust long) (toO o)+  where stripPlus ('+':xs) = xs+        stripPlus xs = xs+parseGeo x = throwError $ "parseGeo: " ++ show x++-- | Parse classification. 3.8.1.3+parseClass :: Content -> ContentParser Class+parseClass (ContentLine _ "CLASS" o bs) = do+    iconv <- asks dfBS2IText+    return . flip Class (toO o) $+        case iconv bs of+             "PUBLIC" -> Public+             "PRIVATE" -> Private+             "CONFIDENTIAL" -> Confidential+             x -> ClassValueX x+parseClass x = throwError $ "parseClass: " ++ show x++-- | Parse TZName. 3.8.3.1+parseTZName :: Content -> ContentParser TZName+parseTZName (ContentLine _ "TZNAME" o bs) = do+    txt <- valueOnlyOne =<< parseText bs+    lang <- mapM paramOnlyOne $ Language . CI.mk .: lookup "LANGUAGE" o+    return $ TZName txt lang (toO o)+parseTZName x = throwError $ "parseTZName: " ++ show x+++-- | Parse a VERSION property 3.7.4+parseVersion :: Content -> ContentParser ICalVersion+parseVersion (ContentLine _ "VERSION" o bs) = do+    c <- asks dfBS2Text+    let (maxver', minver'') = break (==';') . T.unpack $ c bs+        minver' = drop 1 minver''+        parseVer = fst .: listToMaybe . filter ((=="") . snd)+                                       . readP_to_S Ver.parseVersion+        maxver = parseVer maxver'+        minver = parseVer minver'+        [maxJ, minJ] = fromJust <$> [maxver, minver]+    when (isNothing maxver) .+        throwError $ "parseVersion: error parsing version: " ++ show maxver'+    if null minver''+       then return $ MaxICalVersion maxJ (toO o)+       else do when (isNothing minver) .+                    throwError $ "parseVersion: error parsing version: "+                                   ++ show minver'+               return $ MinMaxICalVersion maxJ minJ (toO o)+parseVersion x = throwError $ "parseVersion: " ++ show x++-- | Parse a TZID property. 3.8.3.1+parseTZID :: Content -> ContentParser TZID+parseTZID (ContentLine _ "TZID" o bs) = do+    tzidValue <- asks $ ($ bs) . dfBS2Text+    let tzidGlobal = (fst <$> T.uncons tzidValue) == Just '/'+        tzidOther = toO o+    return TZID {..}+parseTZID x = throwError $ "parseTZID: " ++ show x++-- | Parse RRule. 3.8.5.3+parseRRule :: Maybe DTStart -> Content -> ContentParser RRule+parseRRule Nothing _ = throwError "parseRRule: missing DTSTART."+parseRRule (Just dts) (ContentLine _ "RRULE" o bs) =+    case runParser (parseRecur dts) def "RRULE" bs of+         Left e -> throwError $ show e+         Right x -> do y <- x+                       return . RRule y $ toO o+parseRRule _ x = throwError $ "parseRRule: " ++ show x++-- | Parse Last Modified, 3.8.7.3+parseLastModified :: Content -> ContentParser LastModified+parseLastModified (ContentLine _ "LAST-MODIFIED" o bs) = do+    lastModifiedValue <- mustBeUTC =<< parseDateTime Nothing bs+    let lastModifiedOther = toO o+    return LastModified {..}+parseLastModified x = throwError $ "parseLastModified: " ++ show x++-- | Parse an RDate+parseRDate :: Content -> ContentParser RDate+parseRDate c@(ContentLine _ "RDATE" o bs) = do+    typ <- paramOnlyOne . fromMaybe ["DATE-TIME"] $ lookup "VALUE" o+    case typ of+         "PERIOD" -> do+             tzid <- mapM paramOnlyOne $ lookup "TZID" o+             p <- S.fromList .: mapM (parsePeriod tzid) $ B.split ',' bs+             return . RDatePeriods p . toO $+                filter ((`notElem` ["VALUE", "TZID"]) . fst) o+         _ -> parseSimpleDatesOrDateTimes RDateDateTimes RDateDates c+parseRDate x = throwError $ "parseRDate: " ++ show x++-- | Parse a UTC Offset property 3.3.14, 3.8.3.4, and 3.8.3.3+parseUTCOffset :: Content -> ContentParser UTCOffset+parseUTCOffset (ContentLine _ n o bs)+        | n `elem` ["TZOFFSETTO", "TZOFFSETFROM"] = do+    let str = B.unpack bs+        (s:rest) = str+        (t1:t2:m1:m2:sec) = map digitToInt rest+        (s1:s2:_) = sec+        sign x = if s == '-' then negate x else x+    when (length str < 5 || any (not . isDigit) rest || s `notElem` "+-"+                         || length sec `notElem` [0,2]) .+        throwError $ "parseUTCOffset: " ++ str+    return . UTCOffset (sign $ ((t1 * 10 + t2) * 60 + (m1 * 10 + m2)) * 60 ++                                if not (null sec) then s1 * 10 + s2 else 0)+                       $ toO o+parseUTCOffset x = throwError $ "parseUTCOffset: " ++ show x++-- }}}
+ Text/ICalendar/Printer.hs view
@@ -0,0 +1,958 @@+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE TupleSections #-}+{-# LANGUAGE FlexibleInstances #-}+module Text.ICalendar.Printer+    ( EncodingFunctions(..)+    , printICal+    ) where++import Prelude hiding (mapM_)+import Control.Applicative+import Control.Arrow ((&&&))+import Control.Monad hiding (mapM_, forM_)+import Control.Monad.RWS ( RWS, runRWS, MonadWriter(tell)+                         , MonadState(get, put), asks, modify)+import Data.ByteString.Lazy (ByteString)+import qualified Data.ByteString.Lazy.Char8 as BS+import Data.ByteString.Lazy.Builder (Builder)+import qualified Data.ByteString.Lazy.Builder as Bu+import qualified Data.CaseInsensitive as CI+import Data.Char (ord, toUpper)+import Data.Default+import Data.Foldable (mapM_, forM_)+import Data.Monoid+import Data.Set (Set)+import qualified Data.Set as S+import Data.Text.Lazy (Text)+import qualified Data.Text.Lazy as T+import Data.Time (FormatTime())+import qualified Data.Time as Time+import qualified Data.Version as Ver+import qualified Network.URI as URI+import qualified System.Locale as L+import Text.Printf (printf)++import Codec.MIME.Type (showMIMEType, MIMEType)+import qualified Data.ByteString.Base64.Lazy as B64++import Text.ICalendar.Types+++-- | Functions for encoding into bytestring builders.+data EncodingFunctions = EncodingFunctions+    { efChar2Bu  :: Char -> Builder+    , efChar2Len :: Char -> Int -- ^ How many octets the character is encoded.+    }++utf8Len :: Char -> Int+utf8Len c | o < 0x80  = 1+          | o < 0x800  = 2+          | o < 0x10000 = 3+          | o < 0x200000 = 4+          | o < 0x4000000 = 5+          | otherwise      = 6+  where o = ord c++newtype AltRep = AltRep URI.URI+newtype CN = CN Text+newtype Dir = Dir URI.URI+newtype Member = Member (Set URI.URI)+newtype DelTo = DelTo (Set URI.URI)+newtype DelFrom = DelFrom (Set URI.URI)+newtype RSVP = RSVP Bool+newtype SentBy = SentBy CalAddress++data Quoting = NeedQuotes | Optional | NoQuotes+               deriving (Eq, Ord, Show)++-- | UTF8.+instance Default EncodingFunctions where+    def = EncodingFunctions Bu.charUtf8+                            utf8Len++type ContentPrinter = RWS EncodingFunctions Builder Int++printICal :: EncodingFunctions -> VCalendar -> ByteString+printICal r v = (\(_, _, x) -> Bu.toLazyByteString x) $+                runRWS (printVCalendar v) r 0++-- {{{ Component printers++printVCalendar :: VCalendar -> ContentPrinter ()+printVCalendar VCalendar {..} = do+    line "BEGIN:VCALENDAR"+    ln $ do prop "VERSION" $ versionOther vcVersion -- Should be first for+            printValue vcVersion                    -- compatibility.+    ln $ do prop "PRODID" $ prodIdOther vcProdId+            text $ prodIdValue vcProdId+    ln $ do prop "CALSCALE" $ scaleOther vcScale+            text . CI.original $ scaleValue vcScale+    forM_ vcMethod $ \meth -> do+        prop "METHOD" $ methodOther meth+        ln . text . CI.original $ methodValue meth+    mapM_ printProperty vcOther+    mapM_ printVTimeZone vcTimeZones+    mapM_ printVEvent vcEvents+    mapM_ printVTodo vcTodos+    mapM_ printVJournal vcJournals+    mapM_ printVFreeBusy vcFreeBusys+    mapM_ printVOther vcOtherComps+    line "END:VCALENDAR"++printVTimeZone :: VTimeZone -> ContentPrinter ()+printVTimeZone VTimeZone {..} = do+    line "BEGIN:VTIMEZONE"+    ln $ do prop "TZID" $ tzidOther vtzId+            text $ tzidValue vtzId+    printProperty vtzLastMod+    forM_ vtzUrl $ \url -> do+        prop "TZURL" $ tzUrlOther url+        ln . printShow $ tzUrlValue url+    mapM_ (printTZProp "STANDARD") vtzStandardC+    mapM_ (printTZProp "DAYLIGHT") vtzDaylightC+    mapM_ printProperty vtzOther+    line "END:VTIMEZONE"++printTZProp :: ByteString -> TZProp -> ContentPrinter ()+printTZProp name TZProp {..} = do+    line $ "BEGIN:" <> name+    printProperty tzpDTStart+    ln $ do prop "TZOFFSETTO" $ utcOffsetOther tzpTZOffsetTo+            printUTCOffset $ utcOffsetValue tzpTZOffsetTo+    ln $ do prop "TZOFFSETFROM" $ utcOffsetOther tzpTZOffsetTo+            printUTCOffset $ utcOffsetValue tzpTZOffsetFrom+    printProperty tzpRRule+    printProperty tzpComment+    printProperty tzpRDate+    forM_ tzpTZName $ \TZName {..} -> ln $ do+        prop "TZNAME" $ toParam tzNameLanguage <> toParam tzNameOther+        text tzNameValue+    mapM_ printProperty tzpOther+    line $ "END:" <> name++printVEvent :: VEvent -> ContentPrinter ()+printVEvent VEvent {..} = do+    line "BEGIN:VEVENT"+    printProperty veDTStamp+    printProperty veUID+    printProperty veDTStart+    printProperty veClass+    printProperty veCreated+    printProperty veDescription+    printProperty veGeo+    printProperty veLastMod+    printProperty veLocation+    printProperty veOrganizer+    printProperty vePriority+    printProperty veSeq+    printProperty veStatus+    printProperty veSummary+    printProperty veTransp+    printProperty veUrl+    printProperty veRecurId+    printProperty veRRule+    printProperty veDTEndDuration+    printProperty veAttach+    printProperty veAttendee+    printProperty veCategories+    printProperty veComment+    printProperty veContact+    printProperty veExDate+    printProperty veRStatus+    printProperty veRelated+    printProperty veResources+    printProperty veRDate+    forM_ veAlarms printVAlarm+    printProperty veOther+    line "END:VEVENT"++printVTodo :: VTodo -> ContentPrinter ()+printVTodo VTodo {..} = do+    line "BEGIN:VTODO"+    printProperty vtDTStamp+    printProperty vtUID+    printProperty vtClass+    printProperty vtCompleted+    printProperty vtCreated+    printProperty vtDescription+    printProperty vtDTStart+    printProperty vtGeo+    printProperty vtLastMod+    printProperty vtLocation+    printProperty vtOrganizer+    printProperty vtPercent+    printProperty vtPriority+    printProperty vtSeq+    printProperty vtRecurId+    printProperty vtStatus+    printProperty vtSummary+    printProperty vtUrl+    printProperty vtRRule+    printProperty vtDueDuration+    printProperty vtAttach+    printProperty vtAttendee+    printProperty vtCategories+    printProperty vtComment+    printProperty vtContact+    printProperty vtExDate+    printProperty vtRStatus+    printProperty vtRelated+    printProperty vtResources+    printProperty vtRDate+    forM_ vtAlarms printVAlarm+    printProperty vtOther+    line "END:VTODO"++printVJournal :: VJournal -> ContentPrinter ()+printVJournal VJournal {..} = do+    line "BEGIN:VJOURNAL"+    printProperty vjDTStamp+    printProperty vjUID+    printProperty vjClass+    printProperty vjCreated+    printProperty vjDescription+    printProperty vjDTStart+    printProperty vjLastMod+    printProperty vjOrganizer+    printProperty vjSeq+    printProperty vjRecurId+    printProperty vjStatus+    printProperty vjSummary+    printProperty vjUrl+    printProperty vjRRule+    printProperty vjAttach+    printProperty vjAttendee+    printProperty vjCategories+    printProperty vjComment+    printProperty vjContact+    printProperty vjExDate+    printProperty vjRStatus+    printProperty vjRelated+    printProperty vjRDate+    printProperty vjOther+    line "END:VJOURNAL"++printVFreeBusy :: VFreeBusy -> ContentPrinter ()+printVFreeBusy VFreeBusy {..} = do+    line "BEGIN:VFREEBUSY"+    printProperty vfbDTStamp+    printProperty vfbUID+    printProperty vfbContact+    printProperty vfbDTStart+    printProperty vfbDTEnd+    printProperty vfbOrganizer+    printProperty vfbUrl+    printProperty vfbAttendee+    printProperty vfbComment+    printProperty vfbFreeBusy+    printProperty vfbRStatus+    printProperty vfbOther+    line "END:VFREEBUSY"++printVOther :: VOther -> ContentPrinter ()+printVOther VOther {..} = do+    ln . out $ "BEGIN:V" <> CI.original voName+    mapM_ printProperty voProps+    ln . out $ "END:V" <> CI.original voName++printVAlarm :: VAlarm -> ContentPrinter ()+printVAlarm va = do+    line "BEGIN:VALARM"+    prop "ACTION" $ vaActionOther va+    case va of+         VAlarmAudio {..} -> do+             ln $ bytestring "AUDIO"+             printProperty vaTrigger+             repAndDur+             printProperty vaAudioAttach+             printProperty vaOther+         VAlarmDisplay {..} -> do+             ln $ bytestring "DISPLAY"+             printProperty vaTrigger+             printProperty vaDescription+             repAndDur+             printProperty vaOther+         VAlarmEmail {..} -> do+             ln $ bytestring "EMAIL"+             printProperty vaTrigger+             printProperty vaDescription+             printProperty vaSummary+             printProperty vaAttendee+             repAndDur+             printProperty vaMailAttach+             printProperty vaOther+         VAlarmX {..} -> do+             ln . out $ CI.original vaAction+             printProperty vaTrigger+             printProperty vaOther+    line "END:VALARM"+  where repAndDur = unless (vaRepeat va == def) $ do+            printProperty $ vaRepeat va+            unless (repeatValue (vaRepeat va) == 0) $+                forM_ (vaDuration va) printProperty++-- }}}+-- {{{ Property printers.++class IsProperty a where+    printProperty :: a -> ContentPrinter ()++instance IsProperty a => IsProperty (Set a) where+    printProperty = mapM_ printProperty++instance IsProperty a => IsProperty (Maybe a) where+    printProperty (Just x) = printProperty x+    printProperty _ = return ()++instance (IsProperty a, IsProperty b) => IsProperty (Either a b) where+    printProperty (Left x) = printProperty x+    printProperty (Right x) = printProperty x++instance IsProperty FreeBusy where+    printProperty FreeBusy {..} = ln $ do+        prop "FREEBUSY" $ toParam freeBusyOther <> toParam freeBusyType+        printN printValue $ S.toList freeBusyPeriods++instance IsProperty PercentComplete where+    printProperty PercentComplete {..} = ln $ do+        prop "PERCENT-COMPLETE" percentCompleteOther+        printShow percentCompleteValue++instance IsProperty Completed where+    printProperty Completed {..} = ln $ do prop "COMPLETED" completedOther+                                           printValue completedValue++instance IsProperty DurationProp where+    printProperty DurationProp {..} = ln $ do prop "DURATION" durationOther+                                              printValue durationValue++instance IsProperty Repeat where+    printProperty Repeat {..} = ln $ do prop "REPEAT" repeatOther+                                        printShow repeatValue++instance IsProperty DTEnd where+    printProperty dtend = ln $ prop "DTEND" dtend >> printValue dtend++instance IsProperty Due where+    printProperty due = ln $ prop "DUE" due >> printValue due++instance IsProperty DTStamp where+    printProperty x = ln $ prop "DTSTAMP" x >> printValue x++instance IsProperty UID where+    printProperty UID {..} = ln $ prop "UID" uidOther >> text uidValue++instance IsProperty DTStart where+    printProperty x = ln $ prop "DTSTART" x >> printValue x++instance IsProperty Class where+    printProperty c@Class {..} | c == def = return ()+                               | otherwise = ln $ do prop "CLASS" classOther+                                                     printValue classValue++instance IsProperty Created where+    printProperty Created {..} = ln $ do +        prop "CREATED" $ toParam createdOther <> toParam createdValue+        printValue createdValue++instance IsProperty Description  where+    printProperty Description {..} = ln $ do+        prop "DESCRIPTION" $ toParam (AltRep <$> descriptionAltRep) <>+                             toParam descriptionLanguage <>+                             toParam descriptionOther+        text descriptionValue++instance IsProperty Geo where+    printProperty Geo {..} = ln $ do+        prop "GEO" geoOther+        out . T.pack $ printf "%.6f;%.6f" geoLat geoLong++instance IsProperty LastModified where+    printProperty LastModified {..} = ln $ do+        prop "LAST-MODIFIED" lastModifiedOther+        printUTCTime lastModifiedValue++instance IsProperty Location where+    printProperty Location {..} = ln $ do+        prop "LOCATION" $ toParam (AltRep <$> locationAltRep) <>+                          toParam locationLanguage <> toParam locationOther+        text locationValue++instance IsProperty Organizer where+    printProperty Organizer {..} = ln $ do+        prop "ORGANIZER" $ toParam (CN <$> organizerCN) <>+                           toParam (Dir <$> organizerDir) <>+                           toParam (SentBy <$> organizerSentBy) <>+                           toParam organizerLanguage <> toParam organizerOther+        printShow organizerValue++instance IsProperty Priority where+    printProperty x | x == def = return ()+                    | otherwise = ln $ do prop "PRIORITY" $ priorityOther x+                                          printShow $ priorityValue x++instance IsProperty Sequence where+    printProperty x | x == def = return ()+                    | otherwise = ln $ do prop "SEQUENCE" $ sequenceOther x+                                          printShow $ sequenceValue x+instance IsProperty EventStatus where+    printProperty s = ln $ do prop "STATUS" $ eventStatusOther s+                              printValue s++instance IsProperty TodoStatus where+    printProperty s = ln $ do prop "STATUS" $ todoStatusOther s+                              printValue s++instance IsProperty JournalStatus where+    printProperty s = ln $ do prop "STATUS" $ journalStatusOther s+                              printValue s++instance IsProperty Summary where+    printProperty Summary {..} = ln $ do+        prop "SUMMARY" $ toParam (AltRep <$> summaryAltRep) <>+                         toParam summaryLanguage <> toParam summaryOther+        text summaryValue++instance IsProperty TimeTransparency where+    printProperty x | x == def = return ()+                    | otherwise = ln $ do+                        prop "TRANSP" $ timeTransparencyOther x+                        printValue x++instance IsProperty URL where+    printProperty URL {..} = ln $ prop "URL" urlOther >> printShow urlValue++instance IsProperty RecurrenceId where+    printProperty r = ln $ prop "RECURRENCE-ID" r >> printValue r++instance IsProperty RRule where+    printProperty RRule {..} = ln $ do prop "RRULE" rRuleOther+                                       printValue rRuleValue++instance IsProperty Attachment where+    printProperty a = ln $ prop "ATTACH" a >> printValue a++instance IsProperty Attendee where+    printProperty att@Attendee {..} = ln $ do+        prop "ATTENDEE" att+        printValue attendeeValue++instance IsProperty Categories where+    printProperty Categories {..} = ln $ do+        prop "CATEGORIES" $ toParam categoriesOther <>+                            toParam categoriesLanguage+        texts $ S.toList categoriesValues++instance IsProperty Comment where+    printProperty Comment {..} = ln $ do+        prop "COMMENT" $ toParam (AltRep <$> commentAltRep) <>+                         toParam commentLanguage <>+                         toParam commentOther+        text commentValue++instance IsProperty Contact where+    printProperty Contact {..} = ln $ do+        prop "CONTACT" $ toParam (AltRep <$> contactAltRep) <>+                         toParam contactLanguage <>+                         toParam contactOther+        text contactValue++instance IsProperty ExDate where+    printProperty exd = ln $ do+        prop "EXDATE" exd+        case exd of+             ExDates {..} -> printN printValue $ S.toList exDates+             ExDateTimes {..} -> printN printValue $ S.toList exDateTimes++instance IsProperty RequestStatus where+    printProperty RequestStatus {..} = ln $ do+        prop "REQUEST-STATUS" $ toParam requestStatusLanguage <>+                                toParam requestStatusOther+        (\z -> case z of+                    (x:xs) -> do printShow x+                                 sequence_ [putc '.' >> printShow y | y <- xs]+                    [] -> return ()) requestStatusCode+        putc ';'+        text requestStatusDesc+        forM_ requestStatusExt $ \x -> putc ';' >> text x++instance IsProperty RelatedTo where+    printProperty RelatedTo {..} = ln $ do+        prop "RELATED-TO" $ toParam relatedToOther <> toParam relatedToType+        text relatedToValue++instance IsProperty Resources where+    printProperty Resources {..} = ln $ do+        prop "RESOURCES" $ toParam (AltRep <$> resourcesAltRep) <>+                           toParam resourcesLanguage <> toParam resourcesOther+        texts $ S.toList resourcesValue++instance IsProperty RDate where+    printProperty r = ln $ prop "RDATE" r >> printValue r++instance IsProperty OtherProperty where+    printProperty OtherProperty {..} = ln $ do+        out (CI.original otherName)+        mapM_ param $ toParam otherParams+        out ":"+        bytestring otherValue++instance IsProperty Trigger where+    printProperty tr@TriggerDuration {..} = ln $ do+        prop "TRIGGER" tr+        printValue triggerDuration+    printProperty tr@TriggerDateTime {..} = ln $ do+        prop "TRIGGER" tr+        printUTCTime triggerDateTime+++-- | Print a generic property.+prop :: ToParam a+     => ByteString+     -> a+     -> ContentPrinter ()+prop b x = do+    put (fromIntegral $ BS.length b) -- +    tell (Bu.lazyByteString b)+    mapM_ param $ toParam x+    out ":"++-- }}}+-- {{{ Parameter "printers".++class ToParam a where+    toParam :: a -> [(Text, [(Quoting, Text)])]++instance ToParam a => ToParam (Maybe a) where+    toParam Nothing = []+    toParam (Just x) = toParam x++instance ToParam a => ToParam (Set a) where+    toParam s = case S.maxView s of+                     Nothing -> []+                     Just (x, _) -> toParam x++instance ToParam ExDate where+    toParam ExDates {..} = [("VALUE", [(NoQuotes, "DATE")])] <>+                           toParam exDateOther+    toParam ExDateTimes {..} = toParam exDateOther <>+                               toParam (fst <$> S.maxView exDateTimes)++instance ToParam AltRep where+    toParam (AltRep x) = [("ALTREP", [(NeedQuotes, T.pack $ show x)])]++instance ToParam SentBy where+    toParam (SentBy x) = [("SENT-BY", [(NeedQuotes, T.pack $ show x)])]++instance ToParam Dir where+    toParam (Dir x) = [("DIR", [(NeedQuotes, T.pack $ show x)])]++instance ToParam DateTime where+    toParam ZonedDateTime {..} = [("TZID", [(Optional, dateTimeZone)])]+    toParam _ = []++instance ToParam DTEnd where+    toParam DTEndDateTime {..} = toParam dtEndOther <>+                                 toParam dtEndDateTimeValue+    toParam DTEndDate {..}     = [("VALUE", [(NoQuotes, "DATE")])] <>+                                 toParam dtEndOther++instance ToParam Due where+    toParam DueDateTime {..} = toParam dueOther <> toParam dueDateTimeValue+    toParam DueDate {..}     = [("VALUE", [(NoQuotes, "DATE")])] <>+                               toParam dueOther++instance ToParam CN where+    toParam (CN x) = [("CN", [(Optional, x)])]++instance ToParam DTStart where+    toParam DTStartDateTime {..} = toParam dtStartDateTimeValue <>+                                   toParam dtStartOther+    toParam DTStartDate {..} = [("VALUE", [(NoQuotes, "DATE")])] <>+                               toParam dtStartOther++instance ToParam RDate where+    toParam RDateDates {..} = [("VALUE", [(NoQuotes, "DATE")])] <>+                              toParam rDateOther+    toParam RDatePeriods {..} = [("VALUE", [(NoQuotes, "PERIOD")])] <>+                                toParam rDateOther <>+                                toParam (fst <$> S.maxView rDatePeriods)+    toParam RDateDateTimes {..} = toParam rDateDateTimes <> toParam rDateOther++instance ToParam Period where+    toParam (PeriodDates x _) = toParam x+    toParam (PeriodDuration x _) = toParam x++instance ToParam DTStamp where+    toParam DTStamp {..} = toParam dtStampOther++instance ToParam OtherParams where+    toParam (OtherParams l) = fromOP <$> S.toList l+      where fromOP (OtherParam x y) = (CI.original x, (Optional,) <$> y)++instance ToParam Language where+    toParam (Language x) = [("LANGUAGE", [(Optional, CI.original x)])]++instance ToParam TZName where+    toParam TZName {..} = toParam tzNameLanguage <> toParam tzNameOther++instance ToParam x => ToParam [x] where+    toParam = mconcat . map toParam++instance ToParam (Text, [(Quoting, Text)]) where+    toParam = (:[])++instance ToParam RecurrenceId where+    toParam RecurrenceIdDate {..} = [("VALUE", [(NoQuotes, "DATE")])] <>+                                    toParam recurrenceIdOther+    toParam RecurrenceIdDateTime {..} = toParam recurrenceIdDateTime <>+                                        toParam recurrenceIdOther++instance ToParam FBType where+    toParam x | x == def    = []+    toParam Free            = [("FBTYPE", [(NoQuotes, "FREE")])]+    toParam Busy            = [("FBTYPE", [(NoQuotes, "BUSY")])]+    toParam BusyUnavailable = [("FBTYPE", [(NoQuotes, "BUSY-UNAVAILABLE")])]+    toParam BusyTentative   = [("FBTYPE", [(NoQuotes, "BUSY-TENTATIVE")])]+    toParam (FBTypeX x)     = [("FBTYPE", [(Optional, CI.original x)])]++instance ToParam MIMEType where+    toParam m = [("FMTTYPE", [(NoQuotes, T.pack $ showMIMEType m)])]++instance ToParam Attachment where+    toParam UriAttachment {..} = toParam attachFmtType <>+                                 toParam attachOther+    toParam BinaryAttachment {..} = toParam attachFmtType <>+                                    toParam attachOther <>+                                    [ ("VALUE", [(NoQuotes, "BINARY")])+                                    , ("ENCODING", [(NoQuotes, "BASE64")])]++instance ToParam CUType where+    toParam x | x == def = []+    toParam Individual   = [("CUTYPE", [(NoQuotes, "INDIVIDUAL")])]+    toParam Group        = [("CUTYPE", [(NoQuotes, "GROUP")])]+    toParam Resource     = [("CUTYPE", [(NoQuotes, "RESOURCE")])]+    toParam Room         = [("CUTYPE", [(NoQuotes, "ROOM")])]+    toParam Unknown      = [("CUTYPE", [(NoQuotes, "UNKNOWN")])]+    toParam (CUTypeX x)  = [("CUTYPE", [(Optional, CI.original x)])]++instance ToParam Member where+    toParam (Member x) | S.null x = []+    toParam (Member x) = [( "MEMBER"+                          , (NeedQuotes,) . T.pack . show <$> S.toList x)]++instance ToParam Role where+    toParam x | x == def   = []+    toParam Chair          = [("ROLE", [(NoQuotes, "CHAIR")])]+    toParam ReqParticipant = [("ROLE", [(NoQuotes, "REQ-PARTICIPANT")])]+    toParam OptParticipant = [("ROLE", [(NoQuotes, "OPT-PARTICIPANT")])]+    toParam NonParticipant = [("ROLE", [(NoQuotes, "NON-PARTICIPANT")])]+    toParam (RoleX x)      = [("ROLE", [(Optional, CI.original x)])]++instance ToParam PartStat where+    toParam x | x == def        = []+    toParam PartStatNeedsAction = [("PARTSTAT", [(NoQuotes, "NEEDS-ACTION")])]+    toParam Accepted            = [("PARTSTAT", [(NoQuotes, "ACCEPTED")])]+    toParam Declined            = [("PARTSTAT", [(NoQuotes, "DECLINED")])]+    toParam Tentative           = [("PARTSTAT", [(NoQuotes, "TENTATIVE")])]+    toParam Delegated           = [("PARTSTAT", [(NoQuotes, "DELEGATED")])]+    toParam PartStatCompleted   = [("PARTSTAT", [(NoQuotes, "COMPLETED")])]+    toParam InProcess           = [("PARTSTAT", [(NoQuotes, "IN-PROCESS")])]+    toParam (PartStatX x)       = [("PARTSTAT", [(NoQuotes, CI.original x)])]++instance ToParam RelationshipType where+    toParam x | x == def          = []+    toParam Parent                = [("RELTYPE", [(NoQuotes, "PARENT")])]+    toParam Child                 = [("RELTYPE", [(NoQuotes, "CHILD")])]+    toParam Sibling               = [("RELTYPE", [(NoQuotes, "SIBLING")])]+    toParam (RelationshipTypeX x) = [("RELTYPE", [(Optional, CI.original x)])]++instance ToParam RSVP where+    toParam (RSVP False) = []+    toParam (RSVP True)  = [("RSVP", [(NoQuotes, "TRUE")])]++instance ToParam DelTo where+    toParam (DelTo x) | S.null x = []+                      | otherwise = [( "DELEGATED-TO"+                                     , (NeedQuotes,) . T.pack . show+                                                    <$> S.toList x)]++instance ToParam DelFrom where+    toParam (DelFrom x) | S.null x = []+                        | otherwise = [( "DELEGATED-FROM"+                                       , (NeedQuotes,) . T.pack . show+                                             <$> S.toList x)]++instance ToParam Attendee where+    toParam Attendee {..} = toParam attendeeCUType <>+                            toParam (Member attendeeMember) <>+                            toParam attendeeRole <>+                            toParam attendeePartStat <>+                            toParam (RSVP attendeeRSVP) <>+                            toParam (DelTo attendeeDelTo) <>+                            toParam (DelFrom attendeeDelFrom) <>+                            toParam (SentBy <$> attendeeSentBy) <>+                            toParam (CN <$> attendeeCN) <>+                            toParam (Dir <$> attendeeDir) <>+                            toParam attendeeLanguage <>+                            toParam attendeeOther++instance ToParam AlarmTriggerRelationship where+    toParam x | x == def = []+    toParam Start        = [("RELATED", [(NoQuotes, "START")])]+    toParam End          = [("RELATED", [(NoQuotes, "END")])]++instance ToParam Trigger where+    toParam TriggerDuration {..} = toParam triggerOther <>+                                   toParam triggerRelated+    toParam TriggerDateTime {..} = toParam triggerOther <>+                                   [("VALUE", [(NoQuotes, "DATE-TIME")])]++-- }}}+-- {{{ Value printers++printUTCOffset :: Int -> ContentPrinter ()+printUTCOffset n = do case signum n of+                           -1 -> putc '-'+                           _  -> putc '+'+                      out . T.pack $ printf "%02d" t+                      out . T.pack $ printf "%02d" m+                      when (s > 0) . out . T.pack $ printf "%02d" s+  where (m', s) = abs n `divMod` 60+        (t, m)  = m' `divMod` 60++printNWeekday :: Either (Int, Weekday) Weekday -> ContentPrinter ()+printNWeekday (Left (n, w)) = printShow n >> printValue w+printNWeekday (Right x) = printValue x++printShow :: Show a => a -> ContentPrinter ()+printShow = out . T.pack . show++printShowN :: Show a => [a] -> ContentPrinter ()+printShowN = printN printShow++printN :: (a -> ContentPrinter ()) -> [a] -> ContentPrinter ()+printN m (x:xs) = m x >> sequence_ [putc ',' >> m x' | x' <- xs]+printN _ _ = return ()++printShowUpper :: Show a => a -> ContentPrinter ()+printShowUpper = out . T.pack . map toUpper . show++printUTCTime :: Time.UTCTime -> ContentPrinter ()+printUTCTime = out . T.pack . formatTime "%C%y%m%dT%H%M%SZ"++class IsValue a where+    printValue :: a -> ContentPrinter ()++instance IsValue ICalVersion where+    printValue MaxICalVersion {..} = out . T.pack $ Ver.showVersion versionMax+    printValue MinMaxICalVersion {..} = do+        out . T.pack $ Ver.showVersion versionMin+        putc ';'+        out . T.pack $ Ver.showVersion versionMax++instance IsValue Recur where+    printValue Recur {..} = do+        out "FREQ="+        printShowUpper recurFreq+        forM_ recurUntilCount $ \x ->+            case x of+                 Left y -> out ";UNTIL=" >> printValue y+                 Right y -> out ";COUNT=" >> printShow y+        when (recurInterval /= 1) $+            out ";INTERVAL=" >> printShow recurInterval+        unless (null recurBySecond) $+            out ";BYSECOND=" >> printShowN recurBySecond+        unless (null recurByMinute) $+            out ";BYMINUTE=" >> printShowN recurByMinute+        unless (null recurByHour) $+            out ";BYHOUR=" >> printShowN recurByHour+        unless (null recurByDay) $+            out ";BYDAY=" >> printN printNWeekday recurByDay+        unless (null recurByMonthDay) $+            out ";BYMONTHDAY=" >> printShowN recurByMonthDay+        unless (null recurByYearDay) $+            out ";BYYEARDAY=" >> printShowN recurByYearDay+        unless (null recurByWeekNo) $+            out ";BYWEEKNO=" >> printShowN recurByWeekNo+        unless (null recurByMonth) $+            out ";BYMONTH=" >> printShowN recurByMonth+        unless (null recurBySetPos) $+            out ";BYSETPOS=" >> printShowN recurBySetPos+        unless (recurWkSt == Monday) $+            out ";WKST=" >> printValue recurWkSt++instance IsValue TimeTransparency where+    printValue Opaque {}      = out "OPAQUE"+    printValue Transparent {} = out "TRANSPARENT"++instance IsValue DTEnd where+    printValue DTEndDateTime {..} = printValue dtEndDateTimeValue+    printValue DTEndDate {..}     = printValue dtEndDateValue++instance IsValue Due where+    printValue DueDateTime {..} = printValue dueDateTimeValue+    printValue DueDate {..}     = printValue dueDateValue++instance IsValue EventStatus where+    printValue TentativeEvent {} = out "TENTATIVE"+    printValue ConfirmedEvent {} = out "CONFIRMED"+    printValue CancelledEvent {} = out "CANCELLED"++instance IsValue TodoStatus where+    printValue TodoNeedsAction {} = out "NEEDS-ACTION"+    printValue CompletedTodo {}   = out "COMPLETED"+    printValue InProcessTodo {}   = out "IN-PROCESS"+    printValue CancelledTodo {}   = out "CANCELLED"++instance IsValue JournalStatus where+    printValue DraftJournal {}     = out "DRAFT"+    printValue FinalJournal {}     = out "FINAL"+    printValue CancelledJournal {} = out "CANCELLED"++instance IsValue ClassValue where+    printValue (ClassValueX x) = out $ CI.original x+    printValue x = printShowUpper x++instance IsValue Weekday where+    printValue Sunday    = out "SU"+    printValue Monday    = out "MO"+    printValue Tuesday   = out "TU"+    printValue Wednesday = out "WE"+    printValue Thursday  = out "TH"+    printValue Friday    = out "FR"+    printValue Saturday  = out "SA"++instance IsValue Date where+    printValue Date {..} = out . T.pack $ formatTime "%C%y%m%d" dateValue++instance IsValue DateTime where+    printValue FloatingDateTime {..} =+        out . T.pack $ formatTime "%C%y%m%dT%H%M%S" dateTimeFloating+    printValue UTCDateTime {..} = printUTCTime dateTimeUTC+    printValue ZonedDateTime {..} =+        out . T.pack $ formatTime "%C%y%m%dT%H%M%S" dateTimeFloating++instance IsValue (Either Date DateTime) where+    printValue (Left x) = printValue x+    printValue (Right x) = printValue x++instance IsValue DTStamp where+    printValue DTStamp {..} = printUTCTime dtStampValue++instance IsValue DTStart where+    printValue DTStartDateTime {..} = printValue dtStartDateTimeValue+    printValue DTStartDate {..} = printValue dtStartDateValue++instance IsValue URI.URI where+    printValue = printShow++instance IsValue Duration where+    printValue DurationDate {..} = do+        when (durSign == Negative) $ putc '-'+        putc 'P'+        printShow durDay    >> putc 'D'+        putc 'T'+        printShow durHour   >> putc 'H'+        printShow durMinute >> putc 'M'+        printShow durSecond >> putc 'S'+    printValue DurationTime {..} = do+        when (durSign == Negative) $ putc '-'+        out "PT"+        printShow durHour   >> putc 'H'+        printShow durMinute >> putc 'M'+        printShow durSecond >> putc 'S'+    printValue DurationWeek {..} = do+        when (durSign == Negative) $ putc '-'+        out "P"+        printShow durWeek >> putc 'W'++instance IsValue RecurrenceId where+    printValue RecurrenceIdDate {..}     = printValue recurrenceIdDate+    printValue RecurrenceIdDateTime {..} = printValue recurrenceIdDateTime++instance IsValue Period where+    printValue (PeriodDates f t) = printValue f >> putc '/' >> printValue t+    printValue (PeriodDuration f d) = printValue f >> putc '/' >> printValue d++instance IsValue UTCPeriod where+    printValue (UTCPeriodDates f t) = printUTCTime f >> putc '/' >> printUTCTime t+    printValue (UTCPeriodDuration f d) = printUTCTime f >> putc '/' >> printValue d++instance IsValue RDate where+    printValue RDateDates {..}     = printN printValue $ S.toList rDateDates+    printValue RDateDateTimes {..} = printN printValue $ S.toList rDateDateTimes+    printValue RDatePeriods {..}   = printN printValue $ S.toList rDatePeriods++instance IsValue Attachment where+    printValue UriAttachment {..} = printShow attachUri+    printValue BinaryAttachment {..} = bytestring $ B64.encode attachContent++-- }}}+-- {{{ Lib++ln :: ContentPrinter () -> ContentPrinter ()+ln x = x >> newline++param :: (Text, [(Quoting, Text)]) -> ContentPrinter ()+param (n, xs) = putc ';' >> out n >> putc '=' >> paramVals xs++paramVals :: [(Quoting, Text)] -> ContentPrinter ()+paramVals (x:xs) = paramVal x >> sequence_ [putc ',' >> paramVal x' | x' <- xs]+paramVals _ = return ()++paramVal :: (Quoting, Text) -> ContentPrinter ()+paramVal (NeedQuotes, t) = putc '"' >> out t >> putc '"'+paramVal (NoQuotes, t) = out t+paramVal (_, t) = paramVal (NeedQuotes, t)++texts :: [Text] -> ContentPrinter ()+texts (x:xs) = text x >> sequence_ [putc ',' >> text x' | x' <- xs]+texts _ = return ()++text :: Text -> ContentPrinter ()+text t = case T.uncons t of+              Just (';', r)  -> out "\\;"  >> text r+              Just ('\n', r) -> out "\\n"  >> text r+              Just (',', r)  -> out "\\,"  >> text r+              Just ('\\', r) -> out "\\\\" >> text r+              Just (c, r)    -> putc c     >> text r+              Nothing        -> return ()++bytestring :: ByteString -> ContentPrinter ()+bytestring = BS.foldl' (\m c -> m >> putc8 c) (return ())++out :: Text -> ContentPrinter ()+out t = case T.uncons t of+             Just (c, r) -> putc c >> out r+             Nothing -> return ()++putc :: Char -> ContentPrinter ()+putc c = do x <- get+            (b, clen) <- asks (efChar2Bu &&& efChar2Len)+            let cl = clen c+            when (x + cl > 75) foldLine+            tell $ b c+            modify (+ cl)++putc8 :: Char -> ContentPrinter ()+putc8 c = do x <- get+             when (x >= 75) foldLine+             tell $ Bu.char8 c+             modify (+ 1)++foldLine :: ContentPrinter ()+foldLine = tell (Bu.byteString "\r\n ") >> put 1++newline :: ContentPrinter ()+newline = tell (Bu.byteString "\r\n") >> put 0++-- | Output a whole line. Must be less than 75 bytes.+line :: ByteString -> ContentPrinter ()+line b = tell (Bu.lazyByteString b) >> newline++formatTime :: FormatTime t => String -> t -> String+formatTime = Time.formatTime L.defaultTimeLocale++-- }}}
+ Text/ICalendar/Types.hs view
@@ -0,0 +1,806 @@+{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE OverloadedStrings #-}+-- | ICalendar types, based on RFC5545.+module Text.ICalendar.Types+    ( module Text.ICalendar.Types+    ) where++import Codec.MIME.Type (MIMEType)+import Data.ByteString.Lazy.Char8 (ByteString)+import Data.CaseInsensitive (CI)+import Data.Default+import Data.Set (Set)+import Data.Text.Lazy (Text)+import Data.Time+import Data.Typeable (Typeable)+import Data.Version (Version(..))+import Network.URI (URI)++-- | Language.+newtype Language = Language (CI Text) -- TODO: RFC5646 types and parser.+                   deriving (Eq, Show, Ord, Typeable)++type CalAddress = URI++-- | One other parameter, either x-param or iana-param.+data OtherParam = OtherParam (CI Text) [Text]+                  deriving (Show, Eq, Ord, Typeable)++-- | Other parameters, either x-param or other iana-param.+data OtherParams = OtherParams (Set OtherParam)+                   deriving (Show, Eq, Ord, Typeable)++instance Default OtherParams where+    def = OtherParams def++-- | VCalendar component. 3.4.+data VCalendar = VCalendar+    { vcProdId     :: ProdId+    , vcVersion    :: ICalVersion+    , vcScale      :: Scale+    , vcMethod     :: Maybe Method+    , vcOther      :: Set OtherProperty+    , vcTimeZones  :: Set VTimeZone+    , vcEvents     :: Set VEvent+    , vcTodos      :: Set VTodo+    , vcJournals   :: Set VJournal+    , vcFreeBusys  :: Set VFreeBusy+    , vcOtherComps :: Set VOther+    } deriving (Show, Eq, Ord, Typeable)++instance Default VCalendar where+    def = VCalendar (ProdId "-//haskell.org/NONSGML iCalendar-0.1//EN" def)+                    (MaxICalVersion (Version [2,0] []) def)+                    def Nothing def def def def def def def++-- | Product Identifier. 3.7.3.+data ProdId = ProdId+    { prodIdValue :: Text+    , prodIdOther :: OtherParams+    } deriving (Show, Eq, Ord, Typeable)++-- | Version. 3.7.4.+data ICalVersion+    = MaxICalVersion+    { versionMax   :: Version+    , versionOther :: OtherParams+    }+    | MinMaxICalVersion+    { versionMax   :: Version+    , versionMin   :: Version+    , versionOther :: OtherParams+    } deriving (Show, Eq, Ord, Typeable)++-- | Calendar Scale. 3.7.1.+data Scale = Scale+    { scaleValue :: CI Text+    , scaleOther :: OtherParams+    } deriving (Show, Eq, Ord, Typeable)++instance Default Scale where+    def = Scale "GREGORIAN" def++-- | Method. 3.7.2.+data Method = Method+    { methodValue :: CI Text -- TODO: iTIP, RFC5546+    , methodOther :: OtherParams+    } deriving (Show, Eq, Ord, Typeable)++-- | Event Component. 3.6.1.+data VEvent = VEvent+    { veDTStamp       :: DTStamp+    , veUID           :: UID+    , veClass         :: Class -- ^ 'def' = 'Public'+    , veDTStart       :: Maybe DTStart+    , veCreated       :: Maybe Created+    , veDescription   :: Maybe Description+    , veGeo           :: Maybe Geo+    , veLastMod       :: Maybe LastModified+    , veLocation      :: Maybe Location+    , veOrganizer     :: Maybe Organizer+    , vePriority      :: Priority -- ^ 'def' = 0+    , veSeq           :: Sequence -- ^ 'def' = 0+    , veStatus        :: Maybe EventStatus+    , veSummary       :: Maybe Summary+    , veTransp        :: TimeTransparency -- ^ 'def' = 'Opaque'+    , veUrl           :: Maybe URL+    , veRecurId       :: Maybe RecurrenceId+    , veRRule         :: Set RRule+    , veDTEndDuration :: Maybe (Either DTEnd DurationProp)+    , veAttach        :: Set Attachment+    , veAttendee      :: Set Attendee+    , veCategories    :: Set Categories+    , veComment       :: Set Comment+    , veContact       :: Set Contact+    , veExDate        :: Set ExDate+    , veRStatus       :: Set RequestStatus+    , veRelated       :: Set RelatedTo+    , veResources     :: Set Resources+    , veRDate         :: Set RDate+    , veAlarms        :: Set VAlarm+    , veOther         :: Set OtherProperty+    } deriving (Show, Eq, Ord, Typeable)++-- | To-Do Component. 3.6.2+data VTodo = VTodo+    { vtDTStamp       :: DTStamp+    , vtUID           :: UID+    , vtClass         :: Class -- ^ 'def' = 'Public'+    , vtCompleted     :: Maybe Completed+    , vtCreated       :: Maybe Created+    , vtDescription   :: Maybe Description+    , vtDTStart       :: Maybe DTStart+    , vtGeo           :: Maybe Geo+    , vtLastMod       :: Maybe LastModified+    , vtLocation      :: Maybe Location+    , vtOrganizer     :: Maybe Organizer+    , vtPercent       :: Maybe PercentComplete+    , vtPriority      :: Priority -- ^ 'def' = 0+    , vtRecurId       :: Maybe RecurrenceId+    , vtSeq           :: Sequence -- ^ 'def' = 0+    , vtStatus        :: Maybe TodoStatus+    , vtSummary       :: Maybe Summary+    , vtUrl           :: Maybe URL+    , vtRRule         :: Set RRule+    , vtDueDuration   :: Maybe (Either Due DurationProp)+    , vtAttach        :: Set Attachment+    , vtAttendee      :: Set Attendee+    , vtCategories    :: Set Categories+    , vtComment       :: Set Comment+    , vtContact       :: Set Contact+    , vtExDate        :: Set ExDate+    , vtRStatus       :: Set RequestStatus+    , vtRelated       :: Set RelatedTo+    , vtResources     :: Set Resources+    , vtRDate         :: Set RDate+    , vtAlarms        :: Set VAlarm+    , vtOther         :: Set OtherProperty+    } deriving (Show, Eq, Ord, Typeable)++-- | Journal Component. 3.6.3+data VJournal = VJournal+    { vjDTStamp       :: DTStamp+    , vjUID           :: UID+    , vjClass         :: Class -- ^ 'def' = 'Public'+    , vjCreated       :: Maybe Created+    , vjDTStart       :: Maybe DTStart+    , vjLastMod       :: Maybe LastModified+    , vjOrganizer     :: Maybe Organizer+    , vjRecurId       :: Maybe RecurrenceId+    , vjSeq           :: Sequence -- ^ 'def' = 0+    , vjStatus        :: Maybe JournalStatus+    , vjSummary       :: Maybe Summary+    , vjUrl           :: Maybe URL+    , vjRRule         :: Set RRule+    , vjAttach        :: Set Attachment+    , vjAttendee      :: Set Attendee+    , vjCategories    :: Set Categories+    , vjComment       :: Set Comment+    , vjContact       :: Set Contact+    , vjDescription   :: Set Description+    , vjExDate        :: Set ExDate+    , vjRelated       :: Set RelatedTo+    , vjRDate         :: Set RDate+    , vjRStatus       :: Set RequestStatus+    , vjOther         :: Set OtherProperty+    } deriving (Show, Eq, Ord, Typeable)++-- | Free/Busy Component. 3.6.4+data VFreeBusy = VFreeBusy+    { vfbDTStamp       :: DTStamp+    , vfbUID           :: UID+    , vfbContact       :: Maybe Contact+    , vfbDTStart       :: Maybe DTStart+    , vfbDTEnd         :: Maybe DTEnd+    , vfbOrganizer     :: Maybe Organizer+    , vfbUrl           :: Maybe URL+    , vfbAttendee      :: Set Attendee+    , vfbComment       :: Set Comment+    , vfbFreeBusy      :: Set FreeBusy+    , vfbRStatus       :: Set RequestStatus+    , vfbOther         :: Set OtherProperty+    } deriving (Show, Eq, Ord, Typeable)++-- | Time Zone Component. 3.6.5.+data VTimeZone = VTimeZone+    { vtzId            :: TZID+    , vtzLastMod       :: Maybe LastModified+    , vtzUrl           :: Maybe TZUrl+    , vtzStandardC     :: Set TZProp+    , vtzDaylightC     :: Set TZProp+    , vtzOther         :: Set OtherProperty+    } deriving (Show, Eq, Ord, Typeable)++-- | Time zone property, also 3.6.5.+data TZProp = TZProp+    { tzpDTStart      :: DTStart+    , tzpTZOffsetTo   :: UTCOffset+    , tzpTZOffsetFrom :: UTCOffset+    , tzpRRule        :: Set RRule -- SHOULD NOT have multiple RRules.+    , tzpComment      :: Set Comment+    , tzpRDate        :: Set RDate+    , tzpTZName       :: Set TZName+    , tzpOther        :: Set OtherProperty+    } deriving (Show, Eq, Ord, Typeable)++-- | VAlarm component. 3.6.6.+data VAlarm+    = VAlarmAudio+    { vaTrigger     :: Trigger+    , vaRepeat      :: Repeat -- ^ 'def' = 0+    , vaDuration    :: Maybe DurationProp+    , vaAudioAttach :: Maybe Attachment+    , vaOther       :: Set OtherProperty+    , vaActionOther :: OtherParams+    }+    | VAlarmDisplay+    { vaDescription :: Description+    , vaTrigger     :: Trigger+    , vaRepeat      :: Repeat+    , vaDuration    :: Maybe DurationProp+    , vaOther       :: Set OtherProperty+    , vaActionOther :: OtherParams+    }+    | VAlarmEmail+    { vaDescription :: Description+    , vaTrigger     :: Trigger+    , vaSummary     :: Summary+    , vaAttendee    :: Set Attendee+    , vaRepeat      :: Repeat+    , vaDuration    :: Maybe DurationProp+    , vaMailAttach  :: Set Attachment+    , vaOther       :: Set OtherProperty+    , vaActionOther :: OtherParams+    }+    | VAlarmX+    { vaAction      :: CI Text+    , vaTrigger     :: Trigger+    , vaActionOther :: OtherParams+    , vaOther       :: Set OtherProperty+    } deriving (Show, Eq, Ord, Typeable)++-- | Any other component not recognized.+data VOther = VOther+    { voName :: CI Text+    , voProps :: Set OtherProperty+    } deriving (Show, Eq, Ord, Typeable)++-- | Attachment. 3.8.1.1.+data Attachment+    = UriAttachment+    { attachFmtType :: Maybe MIMEType+    , attachUri     :: URI+    , attachOther   :: OtherParams+    }+    | BinaryAttachment+    { attachFmtType :: Maybe MIMEType+    , attachContent :: ByteString+    , attachOther   :: OtherParams+    } deriving (Show, Eq, Ord, Typeable)++-- | Categories. 3.8.1.2.+data Categories = Categories+    { categoriesValues   :: Set Text+    , categoriesLanguage :: Maybe Language+    , categoriesOther    :: OtherParams+    } deriving (Show, Eq, Ord, Typeable)++-- | Classification. 3.8.1.3.+data Class = Class+    { classValue :: ClassValue+    , classOther :: OtherParams+    } deriving (Show, Eq, Ord, Typeable)++instance Default Class where+    def = Class def def++-- | Classification value. 3.8.1.3.+-- Unrecognized ClassValueX MUST be treated as Private.+data ClassValue+    = Public+    | Private+    | Confidential+    | ClassValueX (CI Text)+      deriving (Show, Eq, Ord, Typeable)++instance Default ClassValue where+    def = Public++-- | Date-Time Completed. 3.8.2.1.+data Completed = Completed+    { completedValue :: DateTime+    , completedOther :: OtherParams+    } deriving (Show, Eq, Ord, Typeable)++-- | Comment. 3.8.1.4.+data Comment = Comment+    { commentValue    :: Text+    , commentAltRep   :: Maybe URI+    , commentLanguage :: Maybe Language+    , commentOther    :: OtherParams+    } deriving (Show, Eq, Ord, Typeable)++-- | Description. 3.8.1.5.+data Description = Description+    { descriptionValue    :: Text+    , descriptionAltRep   :: Maybe URI+    , descriptionLanguage :: Maybe Language+    , descriptionOther    :: OtherParams+    } deriving (Show, Eq, Ord, Typeable)++-- | Geographic Position. 3.8.1.6.+data Geo = Geo+    { geoLat   :: Float+    , geoLong  :: Float+    , geoOther :: OtherParams+    } deriving (Show, Eq, Ord, Typeable)++-- | Location. 3.8.1.7.+data Location = Location+    { locationValue    :: Text+    , locationAltRep   :: Maybe URI+    , locationLanguage :: Maybe Language+    , locationOther    :: OtherParams+    } deriving (Show, Eq, Ord, Typeable)++-- | Percent complete. 3.8.1.8.+data PercentComplete = PercentComplete+    { percentCompleteValue :: Int+    , percentCompleteOther :: OtherParams+    } deriving (Show, Eq, Ord, Typeable)++-- | Priority. 3.8.1.9.+data Priority = Priority+    { priorityValue :: Int+    , priorityOther :: OtherParams+    } deriving (Show, Eq, Ord, Typeable)++instance Default Priority where+    def = Priority 0 def++-- | Resources. 3.8.1.10.+data Resources = Resources+    { resourcesValue    :: Set Text+    , resourcesAltRep   :: Maybe URI+    , resourcesLanguage :: Maybe Language+    , resourcesOther    :: OtherParams+    } deriving (Show, Eq, Ord, Typeable)++-- | Status, but only for Events. 3.8.1.11.+data EventStatus+    = TentativeEvent { eventStatusOther :: OtherParams }+    | ConfirmedEvent { eventStatusOther :: OtherParams }+    | CancelledEvent { eventStatusOther :: OtherParams }+      deriving (Show, Eq, Ord, Typeable)++-- | Status, but only for TODOs. 3.8.1.11.+data TodoStatus+    = TodoNeedsAction { todoStatusOther :: OtherParams }+    | CompletedTodo   { todoStatusOther :: OtherParams }+    | InProcessTodo   { todoStatusOther :: OtherParams }+    | CancelledTodo   { todoStatusOther :: OtherParams }+      deriving (Show, Eq, Ord, Typeable)++-- | Status, but only for Journals. 3.8.1.11.+data JournalStatus+    = DraftJournal     { journalStatusOther :: OtherParams }+    | FinalJournal     { journalStatusOther :: OtherParams }+    | CancelledJournal { journalStatusOther :: OtherParams }+      deriving (Show, Eq, Ord, Typeable)++-- | Summary. 3.8.1.12.+data Summary = Summary+    { summaryValue    :: Text+    , summaryAltRep   :: Maybe URI+    , summaryLanguage :: Maybe Language+    , summaryOther    :: OtherParams+    } deriving (Show, Eq, Ord, Typeable)++-- | Date. 3.3.4+data Date = Date+    { dateValue :: Day+    } deriving (Show, Eq, Ord, Typeable)++-- | Date-Time value. 3.3.5.+data DateTime+    = FloatingDateTime+    { dateTimeFloating :: LocalTime+    }+    | UTCDateTime+    { dateTimeUTC      :: UTCTime+    }+    | ZonedDateTime+    { dateTimeFloating :: LocalTime+    , dateTimeZone     :: Text+    } deriving (Show, Eq, Ord, Typeable)++-- | Date-Time End. 3.8.2.2.+data DTEnd+    = DTEndDateTime+    { dtEndDateTimeValue :: DateTime+    , dtEndOther         :: OtherParams+    }+    | DTEndDate+    { dtEndDateValue     :: Date+    , dtEndOther         :: OtherParams+    } deriving (Show, Eq, Ord, Typeable)++-- | Date-Time Due. 3.8.2.3.+data Due+    = DueDateTime+    { dueDateTimeValue :: DateTime+    , dueOther         :: OtherParams+    }+    | DueDate+    { dueDateValue     :: Date+    , dueOther         :: OtherParams+    } deriving (Show, Eq, Ord, Typeable)++-- | Date-Time Start. 3.8.2.4.+data DTStart+    = DTStartDateTime+    { dtStartDateTimeValue :: DateTime+    , dtStartOther         :: OtherParams+    }+    | DTStartDate+    { dtStartDateValue     :: Date+    , dtStartOther         :: OtherParams+    } deriving (Show, Eq, Ord, Typeable)++-- | Duration value. 3.3.6.+data Duration -- TODO(?): Convert to DiffTime?+    = DurationDate+    { durSign   :: Sign -- ^ 'def' = 'Positive'+    , durDay    :: Int+    , durHour   :: Int+    , durMinute :: Int+    , durSecond :: Int+    }+    | DurationTime+    { durSign   :: Sign+    , durHour   :: Int+    , durMinute :: Int+    , durSecond :: Int+    }+    | DurationWeek+    { durSign   :: Sign+    , durWeek   :: Int+    } deriving (Show, Eq, Ord, Typeable)++-- | Sign.+data Sign = Positive | Negative+            deriving (Show, Eq, Ord, Typeable)++instance Default Sign where+    def = Positive++-- | Duration property. 3.8.2.5.+data DurationProp = DurationProp+    { durationValue :: Duration+    , durationOther :: OtherParams+    } deriving (Show, Eq, Ord, Typeable)++data FreeBusy = FreeBusy+    { freeBusyType    :: FBType+    , freeBusyPeriods :: Set UTCPeriod+    , freeBusyOther   :: OtherParams+    } deriving (Show, Eq, Ord, Typeable)++-- | Period of time. 3.3.9.+data Period+    = PeriodDates    DateTime DateTime+    | PeriodDuration DateTime Duration+      deriving (Show, Eq, Ord, Typeable)++-- | Period of time which must be UTC, as in FreeBusy. 3.3.9.+data UTCPeriod+    = UTCPeriodDates    UTCTime UTCTime+    | UTCPeriodDuration UTCTime Duration+      deriving (Show, Eq, Ord, Typeable)++-- | Free/Busy Time Type. 3.2.9.+-- Unrecognized FBTypeX MUST be treated as Busy.+data FBType+    = Free+    | Busy+    | BusyUnavailable+    | BusyTentative+    | FBTypeX (CI Text)+      deriving (Show, Eq, Ord, Typeable)++instance Default FBType where+    def = Busy++-- | Time Transparency. 3.8.2.7.+data TimeTransparency+    = Opaque      { timeTransparencyOther :: OtherParams }+    | Transparent { timeTransparencyOther :: OtherParams }+      deriving (Show, Eq, Ord, Typeable)++instance Default TimeTransparency where+    def = Opaque def++-- | Time Zone Identifier. 3.8.3.1.+data TZID = TZID+    { tzidValue  :: Text+    , tzidGlobal :: Bool+    , tzidOther  :: OtherParams+    } deriving (Show, Eq, Ord, Typeable)++-- | Time Zone Name. 3.8.3.2.+data TZName = TZName+    { tzNameValue    :: Text+    , tzNameLanguage :: Maybe Language+    , tzNameOther    :: OtherParams+    } deriving (Show, Eq, Ord, Typeable)++-- | UTC Offset. 3.3.14, 3.8.3.4, and 3.8.3.3. (unified-ish)+data UTCOffset = UTCOffset+    { utcOffsetValue :: Int -- ^ Number of seconds away from UTC+    , utcOffsetOther :: OtherParams+    } deriving (Show, Eq, Ord, Typeable)++-- | Time Zone URL. 3.8.3.5.+data TZUrl = TZUrl+    { tzUrlValue :: URI+    , tzUrlOther :: OtherParams+    } deriving (Show, Eq, Ord, Typeable)++-- | Attendee. 3.8.4.1.+data Attendee = Attendee+    { attendeeValue    :: CalAddress+    , attendeeCUType   :: CUType -- ^ 'def' = 'Individual'+    , attendeeMember   :: Set CalAddress+    , attendeeRole     :: Role -- ^ 'def' = 'ReqParticipant'+    , attendeePartStat :: PartStat -- ^ 'def' = 'PartStatNeedsAction'+    , attendeeRSVP     :: Bool+    , attendeeDelTo    :: Set CalAddress+    , attendeeDelFrom  :: Set CalAddress+    , attendeeSentBy   :: Maybe CalAddress+    , attendeeCN       :: Maybe Text+    , attendeeDir      :: Maybe URI+    , attendeeLanguage :: Maybe Language+    , attendeeOther    :: OtherParams+    } deriving (Show, Eq, Ord, Typeable)++-- | Calendar User Type. 3.2.3.+-- Unrecognized CUTypeX MUST be treated as Unknown.+data CUType+    = Individual+    | Group+    | Resource+    | Room+    | Unknown+    | CUTypeX (CI Text)+      deriving (Show, Eq, Ord, Typeable)++instance Default CUType where+    def = Individual++-- | Role. 3.2.16.+data Role = Chair+          | ReqParticipant+          | OptParticipant+          | NonParticipant+          | RoleX (CI Text)+            deriving (Show, Eq, Ord, Typeable)++instance Default Role where+    def = ReqParticipant++-- | Participation Status. 3.2.12.+data PartStat -- Splitting requires splitting attendee too...+    = PartStatNeedsAction+    | Accepted+    | Declined+    | Tentative+    | Delegated+    | PartStatCompleted+    | InProcess+    | PartStatX (CI Text)+      deriving (Show, Eq, Ord, Typeable)++instance Default PartStat where+    def = PartStatNeedsAction++-- | Contact. 3.8.4.2.+data Contact = Contact+    { contactValue    :: Text+    , contactAltRep   :: Maybe URI+    , contactLanguage :: Maybe Language+    , contactOther    :: OtherParams+    } deriving (Show, Eq, Ord, Typeable)++-- | Organizer. 3.8.4.3.+-- TODO: CAL-ADDRESS-related properties.+data Organizer = Organizer+    { organizerValue    :: CalAddress+    , organizerCN       :: Maybe Text+    , organizerDir      :: Maybe URI+    , organizerSentBy   :: Maybe CalAddress+    , organizerLanguage :: Maybe Language+    , organizerOther    :: OtherParams+    } deriving (Show, Eq, Ord, Typeable)++-- | Recurrence ID. 3.8.4.4.+data RecurrenceId+    = RecurrenceIdDate+    { recurrenceIdDate  :: Date+    , recurrenceIdRange :: Range -- ^ 'def' = 'ThisAndFuture'+    , recurrenceIdOther :: OtherParams+    }+    | RecurrenceIdDateTime+    { recurrenceIdDateTime :: DateTime+    , recurrenceIdRange    :: Range -- ^ 'def' = 'ThisAndFuture'+    , recurrenceIdOther    :: OtherParams+    } deriving (Show, Eq, Ord, Typeable)++-- | Recurrence Identifier Range. 3.2.13+data Range = ThisAndFuture | ThisAndPrior+             deriving (Show, Eq, Ord, Typeable)++instance Default Range where+    def = ThisAndFuture++-- | Related To. 3.8.4.5.+data RelatedTo = RelatedTo+    { relatedToValue :: Text+    , relatedToType  :: RelationshipType+    , relatedToOther :: OtherParams+    } deriving (Show, Eq, Ord, Typeable)++-- | Relationship Type. 3.2.15.+-- Unrecognized RelationshipTypeX values MUST be treated as Parent.+data RelationshipType = Parent | Child | Sibling | RelationshipTypeX (CI Text)+                        deriving (Show, Eq, Ord, Typeable)++instance Default RelationshipType where+    def = Parent++-- | Uniform Resource Locator. 3.8.4.6.+data URL = URL+    { urlValue :: URI+    , urlOther :: OtherParams+    } deriving (Show, Eq, Ord, Typeable)++-- | Unique Identifier. 3.8.4.7.+data UID = UID+    { uidValue :: Text+    , uidOther :: OtherParams+    } deriving (Show, Eq, Ord, Typeable)++-- | Exception Date-Times. 3.8.5.1.+data ExDate+    = ExDates+    { exDates     :: Set Date+    , exDateOther :: OtherParams+    }+    | ExDateTimes+    { exDateTimes :: Set DateTime+    , exDateOther :: OtherParams+    } deriving (Show, Eq, Ord, Typeable)++-- | Recurrence Date-Times. 3.8.5.2.+data RDate+    = RDateDates+    { rDateDates :: Set Date+    , rDateOther :: OtherParams+    }+    | RDateDateTimes+    { rDateDateTimes :: Set DateTime+    , rDateOther     :: OtherParams+    }+    | RDatePeriods+    { rDatePeriods :: Set Period+    , rDateOther   :: OtherParams+    } deriving (Show, Eq, Ord, Typeable)++-- | Frequency in recurrences. 3.3.10.+data Frequency+    = Secondly+    | Minutely+    | Hourly+    | Daily+    | Weekly+    | Monthly+    | Yearly+      deriving (Show, Eq, Ord, Typeable)++-- | Weekday, in recurrences. 3.3.10.+data Weekday = Sunday | Monday | Tuesday | Wednesday | Thursday+                      | Friday | Saturday+               deriving (Show, Eq, Ord, Bounded, Enum, Typeable)++-- | Recur value. 3.3.10.+data Recur = Recur+    { recurFreq       :: Frequency+    , recurUntilCount :: Maybe (Either (Either Date DateTime) Int)+    , recurInterval   :: Int+    , recurBySecond   :: [Int]+    , recurByMinute   :: [Int]+    , recurByHour     :: [Int]+    , recurByDay      :: [Either (Int, Weekday) Weekday]+    , recurByMonthDay :: [Int]+    , recurByYearDay  :: [Int]+    , recurByWeekNo   :: [Int]+    , recurByMonth    :: [Int]+    , recurBySetPos   :: [Int]+    , recurWkSt       :: Weekday+    } deriving (Show, Eq, Ord, Typeable)++-- | Recurrence Rule. 3.8.5.3.+data RRule = RRule+    { rRuleValue :: Recur+    , rRuleOther :: OtherParams+    } deriving (Show, Eq, Ord, Typeable)++-- | Repeat count. 3.8.6.2.+data Repeat = Repeat+    { repeatValue :: Integer+    , repeatOther :: OtherParams+    } deriving (Show, Eq, Ord, Typeable)++instance Default Repeat where+    def = Repeat 0 def++-- | Alarm Trigger Relationship. 3.2.14.+data AlarmTriggerRelationship = Start | End+                                deriving (Show, Eq, Ord, Typeable)++instance Default AlarmTriggerRelationship where+    def = Start++-- | Trigger. 3.8.6.3.+data Trigger+    = TriggerDuration+    { triggerDuration :: Duration+    , triggerRelated  :: AlarmTriggerRelationship -- ^ 'def' = 'Start'+    , triggerOther    :: OtherParams+    }+    | TriggerDateTime+    { triggerDateTime :: UTCTime+    , triggerOther    :: OtherParams+    } deriving (Show, Eq, Ord, Typeable)++-- | Date-Time Created. 3.8.7.1.+data Created = Created+    { createdValue :: DateTime+    , createdOther :: OtherParams+    } deriving (Show, Eq, Ord, Typeable)++-- | Date-Time Stamp. 3.8.7.2.+data DTStamp = DTStamp+    { dtStampValue :: UTCTime+    , dtStampOther :: OtherParams+    } deriving (Show, Eq, Ord, Typeable)++-- | Last Modified. 3.8.7.3.+data LastModified = LastModified+    { lastModifiedValue :: UTCTime+    , lastModifiedOther :: OtherParams+    } deriving (Show, Eq, Ord, Typeable)++-- | Sequence number. 3.8.7.4.+data Sequence = Sequence+    { sequenceValue :: Integer+    , sequenceOther :: OtherParams+    } deriving (Show, Eq, Ord, Typeable)++instance Default Sequence where+    def = Sequence 0 def++-- | Request Status. 3.8.8.3.+data RequestStatus = RequestStatus+    { requestStatusCode     :: [Int]+    , requestStatusDesc     :: Text+    , requestStatusLanguage :: Maybe Language+    , requestStatusExt      :: Maybe Text+    , requestStatusOther    :: OtherParams+    } deriving (Show, Eq, Ord, Typeable)++-- | Any other property.+data OtherProperty = OtherProperty+    { otherName   :: CI Text+    , otherValue  :: ByteString+    , otherParams :: OtherParams+    } deriving (Show, Eq, Ord, Typeable)
iCalendar.cabal view
@@ -1,42 +1,38 @@-Name:            iCalendar-Version:         0.0.1-Synopsis:        Parser for iCalendar format (RFC2445)--Description: Parser for the iCalendar format (version 2.0, RFC2445).-             .  -             Features:-             .-               * Unfolds folded lines (see RFC)-             . -               * Supports all IANA iCalendar tokens-             .-             /Warning!/  This is version 0.0, important things are missing-             .   -               * Property and parameter values are not parsed, but kept as in the file.-             . -               * There are no restrictions on the properties components can have.-             .  -               * Line unfolding causes error messages to report the wrong line.-             . -             This package is meant to grow to a full-fledged data definition, printer and-             parser for the iCalendar format.  But that will probably take some time.  So,-             if you've come here because you need this, please e-mail me (Eelco Lempsink).--Category:        Text-License:         BSD3-License-file:    LICENSE-Copyright:       (c) Tupil-Author:          Eelco Lempsink <eml+hackage@tupil.com>-Maintainer:      Clint Adams <clint@debian.org>-Build-Type:      Simple-Cabal-Version:   >=1.10--Library-  build-depends:   base >= 4 && < 5-                 , parsec >=3 && <4-  exposed-modules: Text.ICalendar.Parser-  default-language: Haskell98+name:                iCalendar+version:             0.1+synopsis:            iCalendar data types, parser, and printer.+description:         Data definitions, parsing and printing of the iCalendar+                     format (RFC5545).+homepage:            http://github.com/tingtun/iCalendar+bug-reports:         http://github.com/tingtun/iCalendar/issues+license:             BSD3+license-file:        LICENSE+author:              Christian Rødli Amble+maintainer:          cra+code@cra.no+copyright:           (c) Tingtun+stability:           experimental+category:            Text+build-type:          Simple+tested-with:         GHC==7.6.1+cabal-version:       >=1.8  source-repository head-  type:     git-  location: git://git.debian.org/users/clint/iCalendar-Haskell.git+  type:              git+  location:          git://github.com/tingtun/iCalendar.git++library+  exposed-modules:     Text.ICalendar.Types+                     , Text.ICalendar.Parser+                     , Text.ICalendar.Printer+                     , Text.ICalendar+  other-modules:       Text.ICalendar.Parser.Common+                     , Text.ICalendar.Parser.Components+                     , Text.ICalendar.Parser.Content+                     , Text.ICalendar.Parser.Parameters+                     , Text.ICalendar.Parser.Properties+  build-depends:       base ==4.*, time ==1.4.*, data-default >=0.3+                     , case-insensitive ==0.4.*, network ==2.4.*+                     , bytestring >=0.10 && < 0.11, parsec ==3.1.*+                     , text, containers >= 0.4 && < 0.6, mime ==0.3.*+                     , mtl ==2.1.*, old-locale, base64-bytestring ==1.0.*+  ghc-options:       -Wall