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 +2/−2
- Text/ICalendar.hs +9/−0
- Text/ICalendar/Parser.hs +46/−359
- Text/ICalendar/Parser/Common.hs +403/−0
- Text/ICalendar/Parser/Components.hs +261/−0
- Text/ICalendar/Parser/Content.hs +113/−0
- Text/ICalendar/Parser/Parameters.hs +208/−0
- Text/ICalendar/Parser/Properties.hs +383/−0
- Text/ICalendar/Printer.hs +958/−0
- Text/ICalendar/Types.hs +806/−0
- iCalendar.cabal +36/−40
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