orgmode-parse 0.1.1.3 → 0.2.0
raw patch · 27 files changed
+1578/−761 lines, 27 filesdep +neat-interpolationdep +orgmode-parsedep ~HUnitdep ~aesondep ~attoparsecPVP ok
version bump matches the API change (PVP)
Dependencies added: neat-interpolation, orgmode-parse
Dependency ranges changed: HUnit, aeson, attoparsec, base, bytestring, containers, tasty, tasty-hunit, text, unordered-containers
API changes (from Hackage documentation)
- Data.OrgMode.Parse.Attoparsec.Headings: headingBelowLevel :: [Text] -> LevelDepth -> Parser Text Heading
- Data.OrgMode.Parse.Attoparsec.Headings: headingLevel :: LevelDepth -> Parser Text Level
- Data.OrgMode.Parse.Attoparsec.Headings: headingPriority :: Parser Text Priority
- Data.OrgMode.Parse.Attoparsec.Headings: parseStats :: Parser Text Stats
- Data.OrgMode.Parse.Attoparsec.Headings: parseTags :: Parser Text [Tag]
- Data.OrgMode.Parse.Attoparsec.PropertyDrawer: parseDrawer :: Parser Text Properties
- Data.OrgMode.Parse.Attoparsec.PropertyDrawer: property :: Parser Text (PropertyKey, PropertyVal)
- Data.OrgMode.Parse.Attoparsec.Section: nonHeaderLine :: Parser Text Text
- Data.OrgMode.Parse.Attoparsec.Time: BracketedDateTime :: YearMonthDay -> Maybe Weekday -> Maybe TimePart -> Maybe Repeater -> Maybe Delay -> Bool -> BracketedDateTime
- Data.OrgMode.Parse.Attoparsec.Time: TimePart :: (Either AbsoluteTime TimestampRange) -> TimePart
- Data.OrgMode.Parse.Attoparsec.Time: [datePart] :: BracketedDateTime -> YearMonthDay
- Data.OrgMode.Parse.Attoparsec.Time: [dayNamePart] :: BracketedDateTime -> Maybe Weekday
- Data.OrgMode.Parse.Attoparsec.Time: [delayPart] :: BracketedDateTime -> Maybe Delay
- Data.OrgMode.Parse.Attoparsec.Time: [isActive] :: BracketedDateTime -> Bool
- Data.OrgMode.Parse.Attoparsec.Time: [repeat] :: BracketedDateTime -> Maybe Repeater
- Data.OrgMode.Parse.Attoparsec.Time: [timePart] :: BracketedDateTime -> Maybe TimePart
- Data.OrgMode.Parse.Attoparsec.Time: data BracketedDateTime
- Data.OrgMode.Parse.Attoparsec.Time: instance GHC.Classes.Eq Data.OrgMode.Parse.Attoparsec.Time.BracketedDateTime
- Data.OrgMode.Parse.Attoparsec.Time: instance GHC.Classes.Eq Data.OrgMode.Parse.Attoparsec.Time.TimePart
- Data.OrgMode.Parse.Attoparsec.Time: instance GHC.Classes.Ord Data.OrgMode.Parse.Attoparsec.Time.TimePart
- Data.OrgMode.Parse.Attoparsec.Time: instance GHC.Show.Show Data.OrgMode.Parse.Attoparsec.Time.BracketedDateTime
- Data.OrgMode.Parse.Attoparsec.Time: instance GHC.Show.Show Data.OrgMode.Parse.Attoparsec.Time.TimePart
- Data.OrgMode.Parse.Attoparsec.Time: newtype TimePart
- Data.OrgMode.Parse.Attoparsec.Time: parseBracketedDateTime :: Parser Text BracketedDateTime
- Data.OrgMode.Parse.Attoparsec.Time: parseDate :: Parser Text YearMonthDay
- Data.OrgMode.Parse.Attoparsec.Time: parseDay :: Parser Text Text
- Data.OrgMode.Parse.Attoparsec.Time: parseDelay :: Parser Text Delay
- Data.OrgMode.Parse.Attoparsec.Time: parseHM :: Parser Text (Hours, Minutes)
- Data.OrgMode.Parse.Attoparsec.Time: parseRepeater :: Parser Text Repeater
- Data.OrgMode.Parse.Attoparsec.Time: parseTime' :: Parser Text TimePart
- Data.OrgMode.Parse.Attoparsec.Time: parseTimeUnit :: Parser Text TimeUnit
- Data.OrgMode.Parse.Attoparsec.Time: transformBracketedDateTime :: BracketedDateTime -> (DateTime, Maybe (Hours, Minutes), Bool)
- Data.OrgMode.Parse.Attoparsec.Time: type AbsoluteTime = (Hours, Minutes)
- Data.OrgMode.Parse.Attoparsec.Time: type TimestampRange = (AbsoluteTime, AbsoluteTime)
- Data.OrgMode.Parse.Attoparsec.Time: type Weekday = Text
- Data.OrgMode.Parse.Types: A :: Priority
- Data.OrgMode.Parse.Types: B :: Priority
- Data.OrgMode.Parse.Types: C :: Priority
- Data.OrgMode.Parse.Types: CLOSED :: PlanningKeyword
- Data.OrgMode.Parse.Types: DEADLINE :: PlanningKeyword
- Data.OrgMode.Parse.Types: DateTime :: YearMonthDay' -> Maybe Text -> Maybe (Hour, Minute) -> Maybe Repeater -> Maybe Delay -> DateTime
- Data.OrgMode.Parse.Types: Delay :: DelayType -> Int -> TimeUnit -> Delay
- Data.OrgMode.Parse.Types: DelayAll :: DelayType
- Data.OrgMode.Parse.Types: DelayFirst :: DelayType
- Data.OrgMode.Parse.Types: Document :: Text -> [Heading] -> Document
- Data.OrgMode.Parse.Types: Heading :: Level -> Maybe StateKeyword -> Maybe Priority -> Text -> Maybe Stats -> [Tag] -> Section -> [Heading] -> Heading
- Data.OrgMode.Parse.Types: Level :: Int -> Level
- Data.OrgMode.Parse.Types: LevelDepth :: Int -> LevelDepth
- Data.OrgMode.Parse.Types: Plns :: (HashMap PlanningKeyword Timestamp) -> Plannings
- Data.OrgMode.Parse.Types: RepeatCatchUp :: RepeaterType
- Data.OrgMode.Parse.Types: RepeatCumulate :: RepeaterType
- Data.OrgMode.Parse.Types: RepeatRestart :: RepeaterType
- Data.OrgMode.Parse.Types: Repeater :: RepeaterType -> Int -> TimeUnit -> Repeater
- Data.OrgMode.Parse.Types: SCHEDULED :: PlanningKeyword
- Data.OrgMode.Parse.Types: Section :: Plannings -> [Clock] -> Properties -> Text -> Section
- Data.OrgMode.Parse.Types: StateKeyword :: Text -> StateKeyword
- Data.OrgMode.Parse.Types: StatsOf :: Int -> Int -> Stats
- Data.OrgMode.Parse.Types: StatsPct :: Int -> Stats
- Data.OrgMode.Parse.Types: Timestamp :: DateTime -> Bool -> Maybe DateTime -> Timestamp
- Data.OrgMode.Parse.Types: TitleMeta :: Text -> (Maybe Stats) -> (Maybe [Tag]) -> TitleMeta
- Data.OrgMode.Parse.Types: UnitDay :: TimeUnit
- Data.OrgMode.Parse.Types: UnitHour :: TimeUnit
- Data.OrgMode.Parse.Types: UnitMonth :: TimeUnit
- Data.OrgMode.Parse.Types: UnitWeek :: TimeUnit
- Data.OrgMode.Parse.Types: UnitYear :: TimeUnit
- Data.OrgMode.Parse.Types: YMD' :: YearMonthDay -> YearMonthDay'
- Data.OrgMode.Parse.Types: YearMonthDay :: SrictNotUnpackedYear -> SrictNotUnpackedMonth -> SrictNotUnpackedDayOfMonth -> YearMonthDay
- Data.OrgMode.Parse.Types: [dayName] :: DateTime -> Maybe Text
- Data.OrgMode.Parse.Types: [delayType] :: Delay -> DelayType
- Data.OrgMode.Parse.Types: [delayUnit] :: Delay -> TimeUnit
- Data.OrgMode.Parse.Types: [delayValue] :: Delay -> Int
- Data.OrgMode.Parse.Types: [delay] :: DateTime -> Maybe Delay
- Data.OrgMode.Parse.Types: [documentHeadings] :: Document -> [Heading]
- Data.OrgMode.Parse.Types: [documentText] :: Document -> Text
- Data.OrgMode.Parse.Types: [hourMinute] :: DateTime -> Maybe (Hour, Minute)
- Data.OrgMode.Parse.Types: [keyword] :: Heading -> Maybe StateKeyword
- Data.OrgMode.Parse.Types: [level] :: Heading -> Level
- Data.OrgMode.Parse.Types: [priority] :: Heading -> Maybe Priority
- Data.OrgMode.Parse.Types: [repeaterType] :: Repeater -> RepeaterType
- Data.OrgMode.Parse.Types: [repeaterUnit] :: Repeater -> TimeUnit
- Data.OrgMode.Parse.Types: [repeaterValue] :: Repeater -> Int
- Data.OrgMode.Parse.Types: [repeater] :: DateTime -> Maybe Repeater
- Data.OrgMode.Parse.Types: [sectionClocks] :: Section -> [Clock]
- Data.OrgMode.Parse.Types: [sectionParagraph] :: Section -> Text
- Data.OrgMode.Parse.Types: [sectionPlannings] :: Section -> Plannings
- Data.OrgMode.Parse.Types: [sectionProperties] :: Section -> Properties
- Data.OrgMode.Parse.Types: [section] :: Heading -> Section
- Data.OrgMode.Parse.Types: [stats] :: Heading -> Maybe Stats
- Data.OrgMode.Parse.Types: [subHeadings] :: Heading -> [Heading]
- Data.OrgMode.Parse.Types: [tags] :: Heading -> [Tag]
- Data.OrgMode.Parse.Types: [title] :: Heading -> Text
- Data.OrgMode.Parse.Types: [tsActive] :: Timestamp -> Bool
- Data.OrgMode.Parse.Types: [tsEndTime] :: Timestamp -> Maybe DateTime
- Data.OrgMode.Parse.Types: [tsTime] :: Timestamp -> DateTime
- Data.OrgMode.Parse.Types: [unStateKeyword] :: StateKeyword -> Text
- Data.OrgMode.Parse.Types: [yearMonthDay] :: DateTime -> YearMonthDay'
- Data.OrgMode.Parse.Types: [ymdDay] :: YearMonthDay -> SrictNotUnpackedDayOfMonth
- Data.OrgMode.Parse.Types: [ymdMonth] :: YearMonthDay -> SrictNotUnpackedMonth
- Data.OrgMode.Parse.Types: [ymdYear] :: YearMonthDay -> SrictNotUnpackedYear
- Data.OrgMode.Parse.Types: data DateTime
- Data.OrgMode.Parse.Types: data Delay
- Data.OrgMode.Parse.Types: data DelayType
- Data.OrgMode.Parse.Types: data Document
- Data.OrgMode.Parse.Types: data Heading
- Data.OrgMode.Parse.Types: data PlanningKeyword
- Data.OrgMode.Parse.Types: data Priority
- Data.OrgMode.Parse.Types: data Repeater
- Data.OrgMode.Parse.Types: data RepeaterType
- Data.OrgMode.Parse.Types: data Section
- Data.OrgMode.Parse.Types: data Stats
- Data.OrgMode.Parse.Types: data TimeUnit
- Data.OrgMode.Parse.Types: data Timestamp
- Data.OrgMode.Parse.Types: data TitleMeta
- Data.OrgMode.Parse.Types: data YearMonthDay :: *
- Data.OrgMode.Parse.Types: instance Data.Aeson.Types.Class.FromJSON Data.OrgMode.Parse.Types.DateTime
- Data.OrgMode.Parse.Types: instance Data.Aeson.Types.Class.FromJSON Data.OrgMode.Parse.Types.Delay
- Data.OrgMode.Parse.Types: instance Data.Aeson.Types.Class.FromJSON Data.OrgMode.Parse.Types.DelayType
- Data.OrgMode.Parse.Types: instance Data.Aeson.Types.Class.FromJSON Data.OrgMode.Parse.Types.Document
- Data.OrgMode.Parse.Types: instance Data.Aeson.Types.Class.FromJSON Data.OrgMode.Parse.Types.Heading
- Data.OrgMode.Parse.Types: instance Data.Aeson.Types.Class.FromJSON Data.OrgMode.Parse.Types.Level
- Data.OrgMode.Parse.Types: instance Data.Aeson.Types.Class.FromJSON Data.OrgMode.Parse.Types.PlanningKeyword
- Data.OrgMode.Parse.Types: instance Data.Aeson.Types.Class.FromJSON Data.OrgMode.Parse.Types.Plannings
- Data.OrgMode.Parse.Types: instance Data.Aeson.Types.Class.FromJSON Data.OrgMode.Parse.Types.Priority
- Data.OrgMode.Parse.Types: instance Data.Aeson.Types.Class.FromJSON Data.OrgMode.Parse.Types.Repeater
- Data.OrgMode.Parse.Types: instance Data.Aeson.Types.Class.FromJSON Data.OrgMode.Parse.Types.RepeaterType
- Data.OrgMode.Parse.Types: instance Data.Aeson.Types.Class.FromJSON Data.OrgMode.Parse.Types.Section
- Data.OrgMode.Parse.Types: instance Data.Aeson.Types.Class.FromJSON Data.OrgMode.Parse.Types.StateKeyword
- Data.OrgMode.Parse.Types: instance Data.Aeson.Types.Class.FromJSON Data.OrgMode.Parse.Types.Stats
- Data.OrgMode.Parse.Types: instance Data.Aeson.Types.Class.FromJSON Data.OrgMode.Parse.Types.TimeUnit
- Data.OrgMode.Parse.Types: instance Data.Aeson.Types.Class.FromJSON Data.OrgMode.Parse.Types.Timestamp
- Data.OrgMode.Parse.Types: instance Data.Aeson.Types.Class.FromJSON Data.OrgMode.Parse.Types.YearMonthDay'
- Data.OrgMode.Parse.Types: instance Data.Aeson.Types.Class.ToJSON Data.OrgMode.Parse.Types.DateTime
- Data.OrgMode.Parse.Types: instance Data.Aeson.Types.Class.ToJSON Data.OrgMode.Parse.Types.Delay
- Data.OrgMode.Parse.Types: instance Data.Aeson.Types.Class.ToJSON Data.OrgMode.Parse.Types.DelayType
- Data.OrgMode.Parse.Types: instance Data.Aeson.Types.Class.ToJSON Data.OrgMode.Parse.Types.Document
- Data.OrgMode.Parse.Types: instance Data.Aeson.Types.Class.ToJSON Data.OrgMode.Parse.Types.Heading
- Data.OrgMode.Parse.Types: instance Data.Aeson.Types.Class.ToJSON Data.OrgMode.Parse.Types.Level
- Data.OrgMode.Parse.Types: instance Data.Aeson.Types.Class.ToJSON Data.OrgMode.Parse.Types.PlanningKeyword
- Data.OrgMode.Parse.Types: instance Data.Aeson.Types.Class.ToJSON Data.OrgMode.Parse.Types.Plannings
- Data.OrgMode.Parse.Types: instance Data.Aeson.Types.Class.ToJSON Data.OrgMode.Parse.Types.Priority
- Data.OrgMode.Parse.Types: instance Data.Aeson.Types.Class.ToJSON Data.OrgMode.Parse.Types.Repeater
- Data.OrgMode.Parse.Types: instance Data.Aeson.Types.Class.ToJSON Data.OrgMode.Parse.Types.RepeaterType
- Data.OrgMode.Parse.Types: instance Data.Aeson.Types.Class.ToJSON Data.OrgMode.Parse.Types.Section
- Data.OrgMode.Parse.Types: instance Data.Aeson.Types.Class.ToJSON Data.OrgMode.Parse.Types.StateKeyword
- Data.OrgMode.Parse.Types: instance Data.Aeson.Types.Class.ToJSON Data.OrgMode.Parse.Types.Stats
- Data.OrgMode.Parse.Types: instance Data.Aeson.Types.Class.ToJSON Data.OrgMode.Parse.Types.TimeUnit
- Data.OrgMode.Parse.Types: instance Data.Aeson.Types.Class.ToJSON Data.OrgMode.Parse.Types.Timestamp
- Data.OrgMode.Parse.Types: instance Data.Aeson.Types.Class.ToJSON Data.OrgMode.Parse.Types.YearMonthDay'
- Data.OrgMode.Parse.Types: instance Data.Hashable.Class.Hashable Data.OrgMode.Parse.Types.PlanningKeyword
- Data.OrgMode.Parse.Types: instance GHC.Classes.Eq Data.OrgMode.Parse.Types.DateTime
- Data.OrgMode.Parse.Types: instance GHC.Classes.Eq Data.OrgMode.Parse.Types.Delay
- Data.OrgMode.Parse.Types: instance GHC.Classes.Eq Data.OrgMode.Parse.Types.DelayType
- Data.OrgMode.Parse.Types: instance GHC.Classes.Eq Data.OrgMode.Parse.Types.Document
- Data.OrgMode.Parse.Types: instance GHC.Classes.Eq Data.OrgMode.Parse.Types.Heading
- Data.OrgMode.Parse.Types: instance GHC.Classes.Eq Data.OrgMode.Parse.Types.Level
- Data.OrgMode.Parse.Types: instance GHC.Classes.Eq Data.OrgMode.Parse.Types.LevelDepth
- Data.OrgMode.Parse.Types: instance GHC.Classes.Eq Data.OrgMode.Parse.Types.PlanningKeyword
- Data.OrgMode.Parse.Types: instance GHC.Classes.Eq Data.OrgMode.Parse.Types.Plannings
- Data.OrgMode.Parse.Types: instance GHC.Classes.Eq Data.OrgMode.Parse.Types.Priority
- Data.OrgMode.Parse.Types: instance GHC.Classes.Eq Data.OrgMode.Parse.Types.Repeater
- Data.OrgMode.Parse.Types: instance GHC.Classes.Eq Data.OrgMode.Parse.Types.RepeaterType
- Data.OrgMode.Parse.Types: instance GHC.Classes.Eq Data.OrgMode.Parse.Types.Section
- Data.OrgMode.Parse.Types: instance GHC.Classes.Eq Data.OrgMode.Parse.Types.StateKeyword
- Data.OrgMode.Parse.Types: instance GHC.Classes.Eq Data.OrgMode.Parse.Types.Stats
- Data.OrgMode.Parse.Types: instance GHC.Classes.Eq Data.OrgMode.Parse.Types.TimeUnit
- Data.OrgMode.Parse.Types: instance GHC.Classes.Eq Data.OrgMode.Parse.Types.Timestamp
- Data.OrgMode.Parse.Types: instance GHC.Classes.Eq Data.OrgMode.Parse.Types.TitleMeta
- Data.OrgMode.Parse.Types: instance GHC.Classes.Eq Data.OrgMode.Parse.Types.YearMonthDay'
- Data.OrgMode.Parse.Types: instance GHC.Classes.Ord Data.OrgMode.Parse.Types.PlanningKeyword
- Data.OrgMode.Parse.Types: instance GHC.Classes.Ord Data.OrgMode.Parse.Types.Priority
- Data.OrgMode.Parse.Types: instance GHC.Enum.Enum Data.OrgMode.Parse.Types.PlanningKeyword
- Data.OrgMode.Parse.Types: instance GHC.Generics.Constructor Data.OrgMode.Parse.Types.C1_0DateTime
- Data.OrgMode.Parse.Types: instance GHC.Generics.Constructor Data.OrgMode.Parse.Types.C1_0Delay
- Data.OrgMode.Parse.Types: instance GHC.Generics.Constructor Data.OrgMode.Parse.Types.C1_0DelayType
- Data.OrgMode.Parse.Types: instance GHC.Generics.Constructor Data.OrgMode.Parse.Types.C1_0Document
- Data.OrgMode.Parse.Types: instance GHC.Generics.Constructor Data.OrgMode.Parse.Types.C1_0Heading
- Data.OrgMode.Parse.Types: instance GHC.Generics.Constructor Data.OrgMode.Parse.Types.C1_0Level
- Data.OrgMode.Parse.Types: instance GHC.Generics.Constructor Data.OrgMode.Parse.Types.C1_0PlanningKeyword
- Data.OrgMode.Parse.Types: instance GHC.Generics.Constructor Data.OrgMode.Parse.Types.C1_0Plannings
- Data.OrgMode.Parse.Types: instance GHC.Generics.Constructor Data.OrgMode.Parse.Types.C1_0Priority
- Data.OrgMode.Parse.Types: instance GHC.Generics.Constructor Data.OrgMode.Parse.Types.C1_0Repeater
- Data.OrgMode.Parse.Types: instance GHC.Generics.Constructor Data.OrgMode.Parse.Types.C1_0RepeaterType
- Data.OrgMode.Parse.Types: instance GHC.Generics.Constructor Data.OrgMode.Parse.Types.C1_0Section
- Data.OrgMode.Parse.Types: instance GHC.Generics.Constructor Data.OrgMode.Parse.Types.C1_0StateKeyword
- Data.OrgMode.Parse.Types: instance GHC.Generics.Constructor Data.OrgMode.Parse.Types.C1_0Stats
- Data.OrgMode.Parse.Types: instance GHC.Generics.Constructor Data.OrgMode.Parse.Types.C1_0TimeUnit
- Data.OrgMode.Parse.Types: instance GHC.Generics.Constructor Data.OrgMode.Parse.Types.C1_0Timestamp
- Data.OrgMode.Parse.Types: instance GHC.Generics.Constructor Data.OrgMode.Parse.Types.C1_0YearMonthDay'
- Data.OrgMode.Parse.Types: instance GHC.Generics.Constructor Data.OrgMode.Parse.Types.C1_1DelayType
- Data.OrgMode.Parse.Types: instance GHC.Generics.Constructor Data.OrgMode.Parse.Types.C1_1PlanningKeyword
- Data.OrgMode.Parse.Types: instance GHC.Generics.Constructor Data.OrgMode.Parse.Types.C1_1Priority
- Data.OrgMode.Parse.Types: instance GHC.Generics.Constructor Data.OrgMode.Parse.Types.C1_1RepeaterType
- Data.OrgMode.Parse.Types: instance GHC.Generics.Constructor Data.OrgMode.Parse.Types.C1_1Stats
- Data.OrgMode.Parse.Types: instance GHC.Generics.Constructor Data.OrgMode.Parse.Types.C1_1TimeUnit
- Data.OrgMode.Parse.Types: instance GHC.Generics.Constructor Data.OrgMode.Parse.Types.C1_2PlanningKeyword
- Data.OrgMode.Parse.Types: instance GHC.Generics.Constructor Data.OrgMode.Parse.Types.C1_2Priority
- Data.OrgMode.Parse.Types: instance GHC.Generics.Constructor Data.OrgMode.Parse.Types.C1_2RepeaterType
- Data.OrgMode.Parse.Types: instance GHC.Generics.Constructor Data.OrgMode.Parse.Types.C1_2TimeUnit
- Data.OrgMode.Parse.Types: instance GHC.Generics.Constructor Data.OrgMode.Parse.Types.C1_3TimeUnit
- Data.OrgMode.Parse.Types: instance GHC.Generics.Constructor Data.OrgMode.Parse.Types.C1_4TimeUnit
- Data.OrgMode.Parse.Types: instance GHC.Generics.Datatype Data.OrgMode.Parse.Types.D1DateTime
- Data.OrgMode.Parse.Types: instance GHC.Generics.Datatype Data.OrgMode.Parse.Types.D1Delay
- Data.OrgMode.Parse.Types: instance GHC.Generics.Datatype Data.OrgMode.Parse.Types.D1DelayType
- Data.OrgMode.Parse.Types: instance GHC.Generics.Datatype Data.OrgMode.Parse.Types.D1Document
- Data.OrgMode.Parse.Types: instance GHC.Generics.Datatype Data.OrgMode.Parse.Types.D1Heading
- Data.OrgMode.Parse.Types: instance GHC.Generics.Datatype Data.OrgMode.Parse.Types.D1Level
- Data.OrgMode.Parse.Types: instance GHC.Generics.Datatype Data.OrgMode.Parse.Types.D1PlanningKeyword
- Data.OrgMode.Parse.Types: instance GHC.Generics.Datatype Data.OrgMode.Parse.Types.D1Plannings
- Data.OrgMode.Parse.Types: instance GHC.Generics.Datatype Data.OrgMode.Parse.Types.D1Priority
- Data.OrgMode.Parse.Types: instance GHC.Generics.Datatype Data.OrgMode.Parse.Types.D1Repeater
- Data.OrgMode.Parse.Types: instance GHC.Generics.Datatype Data.OrgMode.Parse.Types.D1RepeaterType
- Data.OrgMode.Parse.Types: instance GHC.Generics.Datatype Data.OrgMode.Parse.Types.D1Section
- Data.OrgMode.Parse.Types: instance GHC.Generics.Datatype Data.OrgMode.Parse.Types.D1StateKeyword
- Data.OrgMode.Parse.Types: instance GHC.Generics.Datatype Data.OrgMode.Parse.Types.D1Stats
- Data.OrgMode.Parse.Types: instance GHC.Generics.Datatype Data.OrgMode.Parse.Types.D1TimeUnit
- Data.OrgMode.Parse.Types: instance GHC.Generics.Datatype Data.OrgMode.Parse.Types.D1Timestamp
- Data.OrgMode.Parse.Types: instance GHC.Generics.Datatype Data.OrgMode.Parse.Types.D1YearMonthDay'
- Data.OrgMode.Parse.Types: instance GHC.Generics.Generic Data.OrgMode.Parse.Types.DateTime
- Data.OrgMode.Parse.Types: instance GHC.Generics.Generic Data.OrgMode.Parse.Types.Delay
- Data.OrgMode.Parse.Types: instance GHC.Generics.Generic Data.OrgMode.Parse.Types.DelayType
- Data.OrgMode.Parse.Types: instance GHC.Generics.Generic Data.OrgMode.Parse.Types.Document
- Data.OrgMode.Parse.Types: instance GHC.Generics.Generic Data.OrgMode.Parse.Types.Heading
- Data.OrgMode.Parse.Types: instance GHC.Generics.Generic Data.OrgMode.Parse.Types.Level
- Data.OrgMode.Parse.Types: instance GHC.Generics.Generic Data.OrgMode.Parse.Types.PlanningKeyword
- Data.OrgMode.Parse.Types: instance GHC.Generics.Generic Data.OrgMode.Parse.Types.Plannings
- Data.OrgMode.Parse.Types: instance GHC.Generics.Generic Data.OrgMode.Parse.Types.Priority
- Data.OrgMode.Parse.Types: instance GHC.Generics.Generic Data.OrgMode.Parse.Types.Repeater
- Data.OrgMode.Parse.Types: instance GHC.Generics.Generic Data.OrgMode.Parse.Types.RepeaterType
- Data.OrgMode.Parse.Types: instance GHC.Generics.Generic Data.OrgMode.Parse.Types.Section
- Data.OrgMode.Parse.Types: instance GHC.Generics.Generic Data.OrgMode.Parse.Types.StateKeyword
- Data.OrgMode.Parse.Types: instance GHC.Generics.Generic Data.OrgMode.Parse.Types.Stats
- Data.OrgMode.Parse.Types: instance GHC.Generics.Generic Data.OrgMode.Parse.Types.TimeUnit
- Data.OrgMode.Parse.Types: instance GHC.Generics.Generic Data.OrgMode.Parse.Types.Timestamp
- Data.OrgMode.Parse.Types: instance GHC.Generics.Generic Data.OrgMode.Parse.Types.YearMonthDay'
- Data.OrgMode.Parse.Types: instance GHC.Generics.Selector Data.OrgMode.Parse.Types.S1_0_0DateTime
- Data.OrgMode.Parse.Types: instance GHC.Generics.Selector Data.OrgMode.Parse.Types.S1_0_0Delay
- Data.OrgMode.Parse.Types: instance GHC.Generics.Selector Data.OrgMode.Parse.Types.S1_0_0Document
- Data.OrgMode.Parse.Types: instance GHC.Generics.Selector Data.OrgMode.Parse.Types.S1_0_0Heading
- Data.OrgMode.Parse.Types: instance GHC.Generics.Selector Data.OrgMode.Parse.Types.S1_0_0Repeater
- Data.OrgMode.Parse.Types: instance GHC.Generics.Selector Data.OrgMode.Parse.Types.S1_0_0Section
- Data.OrgMode.Parse.Types: instance GHC.Generics.Selector Data.OrgMode.Parse.Types.S1_0_0StateKeyword
- Data.OrgMode.Parse.Types: instance GHC.Generics.Selector Data.OrgMode.Parse.Types.S1_0_0Timestamp
- Data.OrgMode.Parse.Types: instance GHC.Generics.Selector Data.OrgMode.Parse.Types.S1_0_1DateTime
- Data.OrgMode.Parse.Types: instance GHC.Generics.Selector Data.OrgMode.Parse.Types.S1_0_1Delay
- Data.OrgMode.Parse.Types: instance GHC.Generics.Selector Data.OrgMode.Parse.Types.S1_0_1Document
- Data.OrgMode.Parse.Types: instance GHC.Generics.Selector Data.OrgMode.Parse.Types.S1_0_1Heading
- Data.OrgMode.Parse.Types: instance GHC.Generics.Selector Data.OrgMode.Parse.Types.S1_0_1Repeater
- Data.OrgMode.Parse.Types: instance GHC.Generics.Selector Data.OrgMode.Parse.Types.S1_0_1Section
- Data.OrgMode.Parse.Types: instance GHC.Generics.Selector Data.OrgMode.Parse.Types.S1_0_1Timestamp
- Data.OrgMode.Parse.Types: instance GHC.Generics.Selector Data.OrgMode.Parse.Types.S1_0_2DateTime
- Data.OrgMode.Parse.Types: instance GHC.Generics.Selector Data.OrgMode.Parse.Types.S1_0_2Delay
- Data.OrgMode.Parse.Types: instance GHC.Generics.Selector Data.OrgMode.Parse.Types.S1_0_2Heading
- Data.OrgMode.Parse.Types: instance GHC.Generics.Selector Data.OrgMode.Parse.Types.S1_0_2Repeater
- Data.OrgMode.Parse.Types: instance GHC.Generics.Selector Data.OrgMode.Parse.Types.S1_0_2Section
- Data.OrgMode.Parse.Types: instance GHC.Generics.Selector Data.OrgMode.Parse.Types.S1_0_2Timestamp
- Data.OrgMode.Parse.Types: instance GHC.Generics.Selector Data.OrgMode.Parse.Types.S1_0_3DateTime
- Data.OrgMode.Parse.Types: instance GHC.Generics.Selector Data.OrgMode.Parse.Types.S1_0_3Heading
- Data.OrgMode.Parse.Types: instance GHC.Generics.Selector Data.OrgMode.Parse.Types.S1_0_3Section
- Data.OrgMode.Parse.Types: instance GHC.Generics.Selector Data.OrgMode.Parse.Types.S1_0_4DateTime
- Data.OrgMode.Parse.Types: instance GHC.Generics.Selector Data.OrgMode.Parse.Types.S1_0_4Heading
- Data.OrgMode.Parse.Types: instance GHC.Generics.Selector Data.OrgMode.Parse.Types.S1_0_5Heading
- Data.OrgMode.Parse.Types: instance GHC.Generics.Selector Data.OrgMode.Parse.Types.S1_0_6Heading
- Data.OrgMode.Parse.Types: instance GHC.Generics.Selector Data.OrgMode.Parse.Types.S1_0_7Heading
- Data.OrgMode.Parse.Types: instance GHC.Num.Num Data.OrgMode.Parse.Types.Level
- Data.OrgMode.Parse.Types: instance GHC.Num.Num Data.OrgMode.Parse.Types.LevelDepth
- Data.OrgMode.Parse.Types: instance GHC.Read.Read Data.OrgMode.Parse.Types.Priority
- Data.OrgMode.Parse.Types: instance GHC.Show.Show Data.OrgMode.Parse.Types.DateTime
- Data.OrgMode.Parse.Types: instance GHC.Show.Show Data.OrgMode.Parse.Types.Delay
- Data.OrgMode.Parse.Types: instance GHC.Show.Show Data.OrgMode.Parse.Types.DelayType
- Data.OrgMode.Parse.Types: instance GHC.Show.Show Data.OrgMode.Parse.Types.Document
- Data.OrgMode.Parse.Types: instance GHC.Show.Show Data.OrgMode.Parse.Types.Heading
- Data.OrgMode.Parse.Types: instance GHC.Show.Show Data.OrgMode.Parse.Types.Level
- Data.OrgMode.Parse.Types: instance GHC.Show.Show Data.OrgMode.Parse.Types.LevelDepth
- Data.OrgMode.Parse.Types: instance GHC.Show.Show Data.OrgMode.Parse.Types.PlanningKeyword
- Data.OrgMode.Parse.Types: instance GHC.Show.Show Data.OrgMode.Parse.Types.Plannings
- Data.OrgMode.Parse.Types: instance GHC.Show.Show Data.OrgMode.Parse.Types.Priority
- Data.OrgMode.Parse.Types: instance GHC.Show.Show Data.OrgMode.Parse.Types.Repeater
- Data.OrgMode.Parse.Types: instance GHC.Show.Show Data.OrgMode.Parse.Types.RepeaterType
- Data.OrgMode.Parse.Types: instance GHC.Show.Show Data.OrgMode.Parse.Types.Section
- Data.OrgMode.Parse.Types: instance GHC.Show.Show Data.OrgMode.Parse.Types.StateKeyword
- Data.OrgMode.Parse.Types: instance GHC.Show.Show Data.OrgMode.Parse.Types.Stats
- Data.OrgMode.Parse.Types: instance GHC.Show.Show Data.OrgMode.Parse.Types.TimeUnit
- Data.OrgMode.Parse.Types: instance GHC.Show.Show Data.OrgMode.Parse.Types.Timestamp
- Data.OrgMode.Parse.Types: instance GHC.Show.Show Data.OrgMode.Parse.Types.TitleMeta
- Data.OrgMode.Parse.Types: instance GHC.Show.Show Data.OrgMode.Parse.Types.YearMonthDay'
- Data.OrgMode.Parse.Types: newtype Level
- Data.OrgMode.Parse.Types: newtype LevelDepth
- Data.OrgMode.Parse.Types: newtype Plannings
- Data.OrgMode.Parse.Types: newtype StateKeyword
- Data.OrgMode.Parse.Types: newtype YearMonthDay'
- Data.OrgMode.Parse.Types: type Duration = (Hour, Minute)
- Data.OrgMode.Parse.Types: type Properties = HashMap Text Text
- Data.OrgMode.Parse.Types: type Tag = Text
+ Data.OrgMode.Parse.Attoparsec.Drawer.Generic: drawerEnd :: Parser Text Text
+ Data.OrgMode.Parse.Attoparsec.Drawer.Generic: parseDrawer :: Parser Text Drawer
+ Data.OrgMode.Parse.Attoparsec.Drawer.Generic: parseDrawerDelim :: Text -> Parser Text Text
+ Data.OrgMode.Parse.Attoparsec.Drawer.Logbook: parseLogbook :: Parser Text Logbook
+ Data.OrgMode.Parse.Attoparsec.Drawer.Property: parseProperties :: Parser Text Properties
+ Data.OrgMode.Parse.Attoparsec.Drawer.Property: property :: Parser Text (PropertyKey, PropertyVal)
+ Data.OrgMode.Parse.Attoparsec.Drawer.Property: type PropertyKey = Text
+ Data.OrgMode.Parse.Attoparsec.Drawer.Property: type PropertyVal = Text
+ Data.OrgMode.Parse.Attoparsec.Headline: data TitleMeta
+ Data.OrgMode.Parse.Attoparsec.Headline: headingPriority :: Parser Text Priority
+ Data.OrgMode.Parse.Attoparsec.Headline: headlineBelowDepth :: [Text] -> Depth -> Parser Text Headline
+ Data.OrgMode.Parse.Attoparsec.Headline: headlineDepth :: Depth -> Parser Text Depth
+ Data.OrgMode.Parse.Attoparsec.Headline: instance GHC.Classes.Eq Data.OrgMode.Parse.Attoparsec.Headline.TitleMeta
+ Data.OrgMode.Parse.Attoparsec.Headline: instance GHC.Show.Show Data.OrgMode.Parse.Attoparsec.Headline.TitleMeta
+ Data.OrgMode.Parse.Attoparsec.Headline: mkTitleMeta :: Text -> Maybe Stats -> Maybe [Tag] -> Text -> TitleMeta
+ Data.OrgMode.Parse.Attoparsec.Headline: parseStats :: Parser Text Stats
+ Data.OrgMode.Parse.Attoparsec.Headline: parseTags :: Parser Text [Tag]
+ Data.OrgMode.Parse.Attoparsec.Util: nonHeadline :: Parser Text Text
+ Data.OrgMode.Parse.Attoparsec.Util: skipOnlySpace :: Parser Text ()
+ Data.OrgMode.Types: A :: Priority
+ Data.OrgMode.Types: AbsoluteTime :: AbsTime -> TimePart
+ Data.OrgMode.Types: Active :: ActiveState
+ Data.OrgMode.Types: B :: Priority
+ Data.OrgMode.Types: BracketedDateTime :: YearMonthDay -> Maybe Weekday -> Maybe TimePart -> Maybe Repeater -> Maybe Delay -> ActiveState -> BracketedDateTime
+ Data.OrgMode.Types: C :: Priority
+ Data.OrgMode.Types: CLOSED :: PlanningKeyword
+ Data.OrgMode.Types: Clock :: (Maybe Timestamp, Maybe Duration) -> Clock
+ Data.OrgMode.Types: DEADLINE :: PlanningKeyword
+ Data.OrgMode.Types: DateTime :: YearMonthDay -> Maybe Text -> Maybe (Hour, Minute) -> Maybe Repeater -> Maybe Delay -> DateTime
+ Data.OrgMode.Types: Delay :: DelayType -> Int -> TimeUnit -> Delay
+ Data.OrgMode.Types: DelayAll :: DelayType
+ Data.OrgMode.Types: DelayFirst :: DelayType
+ Data.OrgMode.Types: Depth :: Int -> Depth
+ Data.OrgMode.Types: Document :: Text -> [Headline] -> Document
+ Data.OrgMode.Types: Drawer :: Text -> Text -> Drawer
+ Data.OrgMode.Types: Headline :: Depth -> Maybe StateKeyword -> Maybe Priority -> Text -> Maybe Timestamp -> Maybe Stats -> [Tag] -> Section -> [Headline] -> Headline
+ Data.OrgMode.Types: Inactive :: ActiveState
+ Data.OrgMode.Types: Logbook :: [Clock] -> Logbook
+ Data.OrgMode.Types: Plns :: (HashMap PlanningKeyword Timestamp) -> Plannings
+ Data.OrgMode.Types: Properties :: HashMap Text Text -> Properties
+ Data.OrgMode.Types: RepeatCatchUp :: RepeaterType
+ Data.OrgMode.Types: RepeatCumulate :: RepeaterType
+ Data.OrgMode.Types: RepeatRestart :: RepeaterType
+ Data.OrgMode.Types: Repeater :: RepeaterType -> Int -> TimeUnit -> Repeater
+ Data.OrgMode.Types: SCHEDULED :: PlanningKeyword
+ Data.OrgMode.Types: Section :: Maybe Timestamp -> Plannings -> [Clock] -> Properties -> Logbook -> [Drawer] -> Text -> Section
+ Data.OrgMode.Types: StateKeyword :: Text -> StateKeyword
+ Data.OrgMode.Types: StatsOf :: Int -> Int -> Stats
+ Data.OrgMode.Types: StatsPct :: Int -> Stats
+ Data.OrgMode.Types: TimeStampRange :: (AbsTime, AbsTime) -> TimePart
+ Data.OrgMode.Types: Timestamp :: DateTime -> ActiveState -> Maybe DateTime -> Timestamp
+ Data.OrgMode.Types: UnitDay :: TimeUnit
+ Data.OrgMode.Types: UnitHour :: TimeUnit
+ Data.OrgMode.Types: UnitMonth :: TimeUnit
+ Data.OrgMode.Types: UnitWeek :: TimeUnit
+ Data.OrgMode.Types: UnitYear :: TimeUnit
+ Data.OrgMode.Types: YearMonthDay :: {-# UNPACK #-} ~Year -> {-# UNPACK #-} ~Month -> {-# UNPACK #-} ~DayOfMonth -> YearMonthDay
+ Data.OrgMode.Types: [activeState] :: BracketedDateTime -> ActiveState
+ Data.OrgMode.Types: [contents] :: Drawer -> Text
+ Data.OrgMode.Types: [datePart] :: BracketedDateTime -> YearMonthDay
+ Data.OrgMode.Types: [dayNamePart] :: BracketedDateTime -> Maybe Weekday
+ Data.OrgMode.Types: [dayName] :: DateTime -> Maybe Text
+ Data.OrgMode.Types: [delayPart] :: BracketedDateTime -> Maybe Delay
+ Data.OrgMode.Types: [delayType] :: Delay -> DelayType
+ Data.OrgMode.Types: [delayUnit] :: Delay -> TimeUnit
+ Data.OrgMode.Types: [delayValue] :: Delay -> Int
+ Data.OrgMode.Types: [delay] :: DateTime -> Maybe Delay
+ Data.OrgMode.Types: [depth] :: Headline -> Depth
+ Data.OrgMode.Types: [documentHeadlines] :: Document -> [Headline]
+ Data.OrgMode.Types: [documentText] :: Document -> Text
+ Data.OrgMode.Types: [hourMinute] :: DateTime -> Maybe (Hour, Minute)
+ Data.OrgMode.Types: [name] :: Drawer -> Text
+ Data.OrgMode.Types: [priority] :: Headline -> Maybe Priority
+ Data.OrgMode.Types: [repeat] :: BracketedDateTime -> Maybe Repeater
+ Data.OrgMode.Types: [repeaterType] :: Repeater -> RepeaterType
+ Data.OrgMode.Types: [repeaterUnit] :: Repeater -> TimeUnit
+ Data.OrgMode.Types: [repeaterValue] :: Repeater -> Int
+ Data.OrgMode.Types: [repeater] :: DateTime -> Maybe Repeater
+ Data.OrgMode.Types: [sectionClocks] :: Section -> [Clock]
+ Data.OrgMode.Types: [sectionDrawers] :: Section -> [Drawer]
+ Data.OrgMode.Types: [sectionLogbook] :: Section -> Logbook
+ Data.OrgMode.Types: [sectionParagraph] :: Section -> Text
+ Data.OrgMode.Types: [sectionPlannings] :: Section -> Plannings
+ Data.OrgMode.Types: [sectionProperties] :: Section -> Properties
+ Data.OrgMode.Types: [sectionTimestamp] :: Section -> Maybe Timestamp
+ Data.OrgMode.Types: [section] :: Headline -> Section
+ Data.OrgMode.Types: [stateKeyword] :: Headline -> Maybe StateKeyword
+ Data.OrgMode.Types: [stats] :: Headline -> Maybe Stats
+ Data.OrgMode.Types: [subHeadlines] :: Headline -> [Headline]
+ Data.OrgMode.Types: [tags] :: Headline -> [Tag]
+ Data.OrgMode.Types: [timePart] :: BracketedDateTime -> Maybe TimePart
+ Data.OrgMode.Types: [timestamp] :: Headline -> Maybe Timestamp
+ Data.OrgMode.Types: [title] :: Headline -> Text
+ Data.OrgMode.Types: [tsActive] :: Timestamp -> ActiveState
+ Data.OrgMode.Types: [tsEndTime] :: Timestamp -> Maybe DateTime
+ Data.OrgMode.Types: [tsTime] :: Timestamp -> DateTime
+ Data.OrgMode.Types: [unClock] :: Clock -> (Maybe Timestamp, Maybe Duration)
+ Data.OrgMode.Types: [unLogbook] :: Logbook -> [Clock]
+ Data.OrgMode.Types: [unProperties] :: Properties -> HashMap Text Text
+ Data.OrgMode.Types: [unStateKeyword] :: StateKeyword -> Text
+ Data.OrgMode.Types: [yearMonthDay] :: DateTime -> YearMonthDay
+ Data.OrgMode.Types: [ymdDay] :: YearMonthDay -> {-# UNPACK #-} ~DayOfMonth
+ Data.OrgMode.Types: [ymdMonth] :: YearMonthDay -> {-# UNPACK #-} ~Month
+ Data.OrgMode.Types: [ymdYear] :: YearMonthDay -> {-# UNPACK #-} ~Year
+ Data.OrgMode.Types: data ActiveState
+ Data.OrgMode.Types: data BracketedDateTime
+ Data.OrgMode.Types: data DateTime
+ Data.OrgMode.Types: data Delay
+ Data.OrgMode.Types: data DelayType
+ Data.OrgMode.Types: data Document
+ Data.OrgMode.Types: data Drawer
+ Data.OrgMode.Types: data Headline
+ Data.OrgMode.Types: data PlanningKeyword
+ Data.OrgMode.Types: data Priority
+ Data.OrgMode.Types: data Repeater
+ Data.OrgMode.Types: data RepeaterType
+ Data.OrgMode.Types: data Section
+ Data.OrgMode.Types: data Stats
+ Data.OrgMode.Types: data TimePart
+ Data.OrgMode.Types: data TimeUnit
+ Data.OrgMode.Types: data Timestamp
+ Data.OrgMode.Types: data YearMonthDay :: *
+ Data.OrgMode.Types: instance Data.Aeson.Types.FromJSON.FromJSON Data.OrgMode.Types.ActiveState
+ Data.OrgMode.Types: instance Data.Aeson.Types.FromJSON.FromJSON Data.OrgMode.Types.Clock
+ Data.OrgMode.Types: instance Data.Aeson.Types.FromJSON.FromJSON Data.OrgMode.Types.DateTime
+ Data.OrgMode.Types: instance Data.Aeson.Types.FromJSON.FromJSON Data.OrgMode.Types.Delay
+ Data.OrgMode.Types: instance Data.Aeson.Types.FromJSON.FromJSON Data.OrgMode.Types.DelayType
+ Data.OrgMode.Types: instance Data.Aeson.Types.FromJSON.FromJSON Data.OrgMode.Types.Depth
+ Data.OrgMode.Types: instance Data.Aeson.Types.FromJSON.FromJSON Data.OrgMode.Types.Document
+ Data.OrgMode.Types: instance Data.Aeson.Types.FromJSON.FromJSON Data.OrgMode.Types.Drawer
+ Data.OrgMode.Types: instance Data.Aeson.Types.FromJSON.FromJSON Data.OrgMode.Types.Headline
+ Data.OrgMode.Types: instance Data.Aeson.Types.FromJSON.FromJSON Data.OrgMode.Types.Logbook
+ Data.OrgMode.Types: instance Data.Aeson.Types.FromJSON.FromJSON Data.OrgMode.Types.PlanningKeyword
+ Data.OrgMode.Types: instance Data.Aeson.Types.FromJSON.FromJSON Data.OrgMode.Types.Plannings
+ Data.OrgMode.Types: instance Data.Aeson.Types.FromJSON.FromJSON Data.OrgMode.Types.Priority
+ Data.OrgMode.Types: instance Data.Aeson.Types.FromJSON.FromJSON Data.OrgMode.Types.Properties
+ Data.OrgMode.Types: instance Data.Aeson.Types.FromJSON.FromJSON Data.OrgMode.Types.Repeater
+ Data.OrgMode.Types: instance Data.Aeson.Types.FromJSON.FromJSON Data.OrgMode.Types.RepeaterType
+ Data.OrgMode.Types: instance Data.Aeson.Types.FromJSON.FromJSON Data.OrgMode.Types.Section
+ Data.OrgMode.Types: instance Data.Aeson.Types.FromJSON.FromJSON Data.OrgMode.Types.StateKeyword
+ Data.OrgMode.Types: instance Data.Aeson.Types.FromJSON.FromJSON Data.OrgMode.Types.Stats
+ Data.OrgMode.Types: instance Data.Aeson.Types.FromJSON.FromJSON Data.OrgMode.Types.TimeUnit
+ Data.OrgMode.Types: instance Data.Aeson.Types.FromJSON.FromJSON Data.OrgMode.Types.Timestamp
+ Data.OrgMode.Types: instance Data.Aeson.Types.FromJSON.FromJSON Data.Thyme.Calendar.Internal.YearMonthDay
+ Data.OrgMode.Types: instance Data.Aeson.Types.ToJSON.ToJSON Data.OrgMode.Types.ActiveState
+ Data.OrgMode.Types: instance Data.Aeson.Types.ToJSON.ToJSON Data.OrgMode.Types.Clock
+ Data.OrgMode.Types: instance Data.Aeson.Types.ToJSON.ToJSON Data.OrgMode.Types.DateTime
+ Data.OrgMode.Types: instance Data.Aeson.Types.ToJSON.ToJSON Data.OrgMode.Types.Delay
+ Data.OrgMode.Types: instance Data.Aeson.Types.ToJSON.ToJSON Data.OrgMode.Types.DelayType
+ Data.OrgMode.Types: instance Data.Aeson.Types.ToJSON.ToJSON Data.OrgMode.Types.Depth
+ Data.OrgMode.Types: instance Data.Aeson.Types.ToJSON.ToJSON Data.OrgMode.Types.Document
+ Data.OrgMode.Types: instance Data.Aeson.Types.ToJSON.ToJSON Data.OrgMode.Types.Drawer
+ Data.OrgMode.Types: instance Data.Aeson.Types.ToJSON.ToJSON Data.OrgMode.Types.Headline
+ Data.OrgMode.Types: instance Data.Aeson.Types.ToJSON.ToJSON Data.OrgMode.Types.Logbook
+ Data.OrgMode.Types: instance Data.Aeson.Types.ToJSON.ToJSON Data.OrgMode.Types.PlanningKeyword
+ Data.OrgMode.Types: instance Data.Aeson.Types.ToJSON.ToJSON Data.OrgMode.Types.Plannings
+ Data.OrgMode.Types: instance Data.Aeson.Types.ToJSON.ToJSON Data.OrgMode.Types.Priority
+ Data.OrgMode.Types: instance Data.Aeson.Types.ToJSON.ToJSON Data.OrgMode.Types.Properties
+ Data.OrgMode.Types: instance Data.Aeson.Types.ToJSON.ToJSON Data.OrgMode.Types.Repeater
+ Data.OrgMode.Types: instance Data.Aeson.Types.ToJSON.ToJSON Data.OrgMode.Types.RepeaterType
+ Data.OrgMode.Types: instance Data.Aeson.Types.ToJSON.ToJSON Data.OrgMode.Types.Section
+ Data.OrgMode.Types: instance Data.Aeson.Types.ToJSON.ToJSON Data.OrgMode.Types.StateKeyword
+ Data.OrgMode.Types: instance Data.Aeson.Types.ToJSON.ToJSON Data.OrgMode.Types.Stats
+ Data.OrgMode.Types: instance Data.Aeson.Types.ToJSON.ToJSON Data.OrgMode.Types.TimeUnit
+ Data.OrgMode.Types: instance Data.Aeson.Types.ToJSON.ToJSON Data.OrgMode.Types.Timestamp
+ Data.OrgMode.Types: instance Data.Aeson.Types.ToJSON.ToJSON Data.Thyme.Calendar.Internal.YearMonthDay
+ Data.OrgMode.Types: instance Data.Hashable.Class.Hashable Data.OrgMode.Types.PlanningKeyword
+ Data.OrgMode.Types: instance GHC.Base.Monoid Data.OrgMode.Types.Logbook
+ Data.OrgMode.Types: instance GHC.Base.Monoid Data.OrgMode.Types.Properties
+ Data.OrgMode.Types: instance GHC.Classes.Eq Data.OrgMode.Types.ActiveState
+ Data.OrgMode.Types: instance GHC.Classes.Eq Data.OrgMode.Types.BracketedDateTime
+ Data.OrgMode.Types: instance GHC.Classes.Eq Data.OrgMode.Types.Clock
+ Data.OrgMode.Types: instance GHC.Classes.Eq Data.OrgMode.Types.DateTime
+ Data.OrgMode.Types: instance GHC.Classes.Eq Data.OrgMode.Types.Delay
+ Data.OrgMode.Types: instance GHC.Classes.Eq Data.OrgMode.Types.DelayType
+ Data.OrgMode.Types: instance GHC.Classes.Eq Data.OrgMode.Types.Depth
+ Data.OrgMode.Types: instance GHC.Classes.Eq Data.OrgMode.Types.Document
+ Data.OrgMode.Types: instance GHC.Classes.Eq Data.OrgMode.Types.Drawer
+ Data.OrgMode.Types: instance GHC.Classes.Eq Data.OrgMode.Types.Headline
+ Data.OrgMode.Types: instance GHC.Classes.Eq Data.OrgMode.Types.Logbook
+ Data.OrgMode.Types: instance GHC.Classes.Eq Data.OrgMode.Types.PlanningKeyword
+ Data.OrgMode.Types: instance GHC.Classes.Eq Data.OrgMode.Types.Plannings
+ Data.OrgMode.Types: instance GHC.Classes.Eq Data.OrgMode.Types.Priority
+ Data.OrgMode.Types: instance GHC.Classes.Eq Data.OrgMode.Types.Properties
+ Data.OrgMode.Types: instance GHC.Classes.Eq Data.OrgMode.Types.Repeater
+ Data.OrgMode.Types: instance GHC.Classes.Eq Data.OrgMode.Types.RepeaterType
+ Data.OrgMode.Types: instance GHC.Classes.Eq Data.OrgMode.Types.Section
+ Data.OrgMode.Types: instance GHC.Classes.Eq Data.OrgMode.Types.StateKeyword
+ Data.OrgMode.Types: instance GHC.Classes.Eq Data.OrgMode.Types.Stats
+ Data.OrgMode.Types: instance GHC.Classes.Eq Data.OrgMode.Types.TimePart
+ Data.OrgMode.Types: instance GHC.Classes.Eq Data.OrgMode.Types.TimeUnit
+ Data.OrgMode.Types: instance GHC.Classes.Eq Data.OrgMode.Types.Timestamp
+ Data.OrgMode.Types: instance GHC.Classes.Ord Data.OrgMode.Types.PlanningKeyword
+ Data.OrgMode.Types: instance GHC.Classes.Ord Data.OrgMode.Types.Priority
+ Data.OrgMode.Types: instance GHC.Classes.Ord Data.OrgMode.Types.TimePart
+ Data.OrgMode.Types: instance GHC.Enum.Enum Data.OrgMode.Types.PlanningKeyword
+ Data.OrgMode.Types: instance GHC.Generics.Generic Data.OrgMode.Types.ActiveState
+ Data.OrgMode.Types: instance GHC.Generics.Generic Data.OrgMode.Types.Clock
+ Data.OrgMode.Types: instance GHC.Generics.Generic Data.OrgMode.Types.DateTime
+ Data.OrgMode.Types: instance GHC.Generics.Generic Data.OrgMode.Types.Delay
+ Data.OrgMode.Types: instance GHC.Generics.Generic Data.OrgMode.Types.DelayType
+ Data.OrgMode.Types: instance GHC.Generics.Generic Data.OrgMode.Types.Depth
+ Data.OrgMode.Types: instance GHC.Generics.Generic Data.OrgMode.Types.Document
+ Data.OrgMode.Types: instance GHC.Generics.Generic Data.OrgMode.Types.Drawer
+ Data.OrgMode.Types: instance GHC.Generics.Generic Data.OrgMode.Types.Headline
+ Data.OrgMode.Types: instance GHC.Generics.Generic Data.OrgMode.Types.Logbook
+ Data.OrgMode.Types: instance GHC.Generics.Generic Data.OrgMode.Types.PlanningKeyword
+ Data.OrgMode.Types: instance GHC.Generics.Generic Data.OrgMode.Types.Plannings
+ Data.OrgMode.Types: instance GHC.Generics.Generic Data.OrgMode.Types.Priority
+ Data.OrgMode.Types: instance GHC.Generics.Generic Data.OrgMode.Types.Properties
+ Data.OrgMode.Types: instance GHC.Generics.Generic Data.OrgMode.Types.Repeater
+ Data.OrgMode.Types: instance GHC.Generics.Generic Data.OrgMode.Types.RepeaterType
+ Data.OrgMode.Types: instance GHC.Generics.Generic Data.OrgMode.Types.Section
+ Data.OrgMode.Types: instance GHC.Generics.Generic Data.OrgMode.Types.StateKeyword
+ Data.OrgMode.Types: instance GHC.Generics.Generic Data.OrgMode.Types.Stats
+ Data.OrgMode.Types: instance GHC.Generics.Generic Data.OrgMode.Types.TimeUnit
+ Data.OrgMode.Types: instance GHC.Generics.Generic Data.OrgMode.Types.Timestamp
+ Data.OrgMode.Types: instance GHC.Num.Num Data.OrgMode.Types.Depth
+ Data.OrgMode.Types: instance GHC.Read.Read Data.OrgMode.Types.ActiveState
+ Data.OrgMode.Types: instance GHC.Read.Read Data.OrgMode.Types.Priority
+ Data.OrgMode.Types: instance GHC.Show.Show Data.OrgMode.Types.ActiveState
+ Data.OrgMode.Types: instance GHC.Show.Show Data.OrgMode.Types.BracketedDateTime
+ Data.OrgMode.Types: instance GHC.Show.Show Data.OrgMode.Types.Clock
+ Data.OrgMode.Types: instance GHC.Show.Show Data.OrgMode.Types.DateTime
+ Data.OrgMode.Types: instance GHC.Show.Show Data.OrgMode.Types.Delay
+ Data.OrgMode.Types: instance GHC.Show.Show Data.OrgMode.Types.DelayType
+ Data.OrgMode.Types: instance GHC.Show.Show Data.OrgMode.Types.Depth
+ Data.OrgMode.Types: instance GHC.Show.Show Data.OrgMode.Types.Document
+ Data.OrgMode.Types: instance GHC.Show.Show Data.OrgMode.Types.Drawer
+ Data.OrgMode.Types: instance GHC.Show.Show Data.OrgMode.Types.Headline
+ Data.OrgMode.Types: instance GHC.Show.Show Data.OrgMode.Types.Logbook
+ Data.OrgMode.Types: instance GHC.Show.Show Data.OrgMode.Types.PlanningKeyword
+ Data.OrgMode.Types: instance GHC.Show.Show Data.OrgMode.Types.Plannings
+ Data.OrgMode.Types: instance GHC.Show.Show Data.OrgMode.Types.Priority
+ Data.OrgMode.Types: instance GHC.Show.Show Data.OrgMode.Types.Properties
+ Data.OrgMode.Types: instance GHC.Show.Show Data.OrgMode.Types.Repeater
+ Data.OrgMode.Types: instance GHC.Show.Show Data.OrgMode.Types.RepeaterType
+ Data.OrgMode.Types: instance GHC.Show.Show Data.OrgMode.Types.Section
+ Data.OrgMode.Types: instance GHC.Show.Show Data.OrgMode.Types.StateKeyword
+ Data.OrgMode.Types: instance GHC.Show.Show Data.OrgMode.Types.Stats
+ Data.OrgMode.Types: instance GHC.Show.Show Data.OrgMode.Types.TimePart
+ Data.OrgMode.Types: instance GHC.Show.Show Data.OrgMode.Types.TimeUnit
+ Data.OrgMode.Types: instance GHC.Show.Show Data.OrgMode.Types.Timestamp
+ Data.OrgMode.Types: newtype Clock
+ Data.OrgMode.Types: newtype Depth
+ Data.OrgMode.Types: newtype Logbook
+ Data.OrgMode.Types: newtype Plannings
+ Data.OrgMode.Types: newtype Properties
+ Data.OrgMode.Types: newtype StateKeyword
+ Data.OrgMode.Types: type Duration = (Hour, Minute)
+ Data.OrgMode.Types: type Tag = Text
- Data.OrgMode.Parse.Attoparsec.Time: parseClock :: Parser Text (Maybe Timestamp, Maybe Duration)
+ Data.OrgMode.Parse.Attoparsec.Time: parseClock :: Parser Text Clock
Files
- CHANGELOG +0/−35
- CHANGELOG.md +33/−0
- README.md +67/−0
- README.org +0/−44
- TODO.org +0/−15
- orgmode-parse.cabal +43/−32
- src/Data/OrgMode/Parse.hs +10/−19
- src/Data/OrgMode/Parse/Attoparsec/Document.hs +25/−12
- src/Data/OrgMode/Parse/Attoparsec/Drawer.hs +26/−0
- src/Data/OrgMode/Parse/Attoparsec/Drawer/Generic.hs +68/−0
- src/Data/OrgMode/Parse/Attoparsec/Drawer/Logbook.hs +38/−0
- src/Data/OrgMode/Parse/Attoparsec/Drawer/Property.hs +58/−0
- src/Data/OrgMode/Parse/Attoparsec/Headings.hs +0/−165
- src/Data/OrgMode/Parse/Attoparsec/Headline.hs +193/−0
- src/Data/OrgMode/Parse/Attoparsec/PropertyDrawer.hs +0/−59
- src/Data/OrgMode/Parse/Attoparsec/Section.hs +23/−29
- src/Data/OrgMode/Parse/Attoparsec/Time.hs +117/−111
- src/Data/OrgMode/Parse/Attoparsec/Util.hs +43/−0
- src/Data/OrgMode/Parse/Types.hs +0/−235
- src/Data/OrgMode/Types.hs +310/−0
- test/Document.hs +99/−0
- test/Drawer.hs +37/−0
- test/Headline.hs +26/−0
- test/Test.hs +5/−5
- test/Timestamps.hs +65/−0
- test/Util.hs +25/−0
- test/Weekdays.hs +267/−0
− CHANGELOG
@@ -1,35 +0,0 @@--*- mode: org -*---* Changelog-** 0.1.1.0-*** Bugfixes- - The weekday parser now correctly parses weekday appellations of- other languages (thank you nushio3!) using a combinator-style- version of the regex found in org-mode.-** 0.1.0.4-*** Miscellany- - Comment improvement wibbles.- - Adding the =Attoparsec= combinator modules to the export module- list in the cabal package definition.-** 0.1.0.3-*** Features- - Sub-headings are now parsed and tracked by its parent.- - Much more robust timestamp / clock / schedule parsing.--*** Miscellany- - A good mount of code cleanup and comment improvement.--** 0.0.2.1-*** Bugfixes- - [X] Fixing the import for the =Internal= module (instead of- re-exporting it in each parser module).-** 0.0.2.0-*** Features- - [X] Added parsers for the scheduled / deadline timestamps.-** 0.0.1.1-*** Features- - [X] Parsing of property drawer.- - [X] Tests for both drawer and heading parsers.-** 0.0.0.2-*** Features- - [X] Parsers for orgmode list headlines.
+ CHANGELOG.md view
@@ -0,0 +1,33 @@+0.2.0+- Fix timestamp parsing in headline and body, fixes #13+- Generalize drawer parser for logbook and generic drawers, fixes #14+- Reorganize the types, fixes #15++0.1.1.0+- The weekday parser now correctly parses weekday appellations of other+ languages (thank you nushio3!) using a combinator-style version of the regex+ found in org-mode.++0.1.0.4+- Comment improvement wibbles.+- Adding the =Attoparsec= combinator modules to the export module list in the+ cabal package definition.++0.1.0.3+- Sub-headings are now parsed and tracked by its parent.+- Much more robust timestamp / clock / schedule parsing.+- A good mount of code cleanup and comment improvement.++0.0.2.1+- [X] Fixing the import for the =Internal= module (instead of re-exporting it in+ each parser module).++0.0.2.0+- [X] Added parsers for the scheduled / deadline timestamps.++0.0.1.1+- [X] Parsing of property drawer.+- [X] Tests for both drawer and heading parsers.++0.0.0.2+- [X] Parsers for orgmode list headlines.
+ README.md view
@@ -0,0 +1,67 @@+# Welcome!++++`orgmode-parse` provides a top-level parser and collection of attoparsec parser+combinators for org-mode structured text.++- [What's Finished](#whats-finished)+- [What's Planned](#whats-planned)+- [Building](#building)+ +## What's Finished+We have built attoparsec parsers for parsing org-mode document structures and+meta-data. Here is a list of all the syntax features that have a complete+parsing implementation and not:++- [X] Headlines+ - [X] State keywords+ - [X] Priority indicator+ - [X] Title+ - [X] Status / progress indicator+ - [X] Tag list+- [X] Property drawers+- [X] State keyword changelogs+- [X] Scheduled and deadline timestamps (timestamp, range, duration, periodicity)+ - [X] Active and inactive timestamps+- [X] Clock timestamps+- [ ] Markup+ - [ ] Emphasis+ - [ ] Bold+ - [ ] Italic+ - [ ] Strikethrough+ - [ ] Underline+ - [ ] Superscript+ - [ ] Subscript+ - [ ] Code / monospaced+ - [ ] Tables+ - [ ] Lists+ - [ ] Unordered lists+ - [ ] Numbered lists+ - [ ] Checkbox modified lists+ - [ ] Blocks (src / quote / example blocks)++Parsing org-mode markup is currently being worked on.++## What's Planned (outside of what's not finished)+1. Modernizing this library and adding significantly more documentation to it+2. Writing a sister library, `orgmode-pretty`, providing a pretty printer+ implementation for an org-mode AST+3. Pandoc integration++## Building+There are a few ways to build this library if you're developing a patch:++- `stack build && stack test`, and+- `nix-build --no-out-link --attr orgmode-parse release.nix`++You can also use the `nix-shell` provided cabal environment for incremental+development:++```shell+$ nix-shell --attr orgmode-parse.env release.nix+$ cabal build+```++# License+[BSD3 Open Source Software License](https://github.com/digitalmentat/orgmode-parse/blob/master/LICENSE)
− README.org
@@ -1,44 +0,0 @@-* Welcome!- [[https://hackage.haskell.org/package/orgmode-parse][https://img.shields.io/hackage/v/orgmode-parse.svg?style=flat]]- [[https://travis-ci.org/digitalmentat/orgmode-parse][https://travis-ci.org/digitalmentat/orgmode-parse.svg?branch=master]]-- This is a reference implementation of an [[https://github.com/digitalmentat/orgmode-grammar/blob/master/SPECIFICATION.org][orgmode-grammar]] parser in- Haskell.--** What's Finished- We have built attoparsec parsers for parsing org-mode document- structures and meta-data. Here is a list of all the syntax features- that have a complete parsing implementation and not:-- - [X] Headings- - [X] State keywords- - [X] Priority indicator- - [X] Title- - [X] Status / progress indicator- - [X] Tag list- - [X] Property drawers- - [X] State keyword changelogs- - [X] Scheduled and deadline timestamps (timestamp, range,- duration, periodicity)- - [X] Active and inactive timestamps- - [X] Clock timestamps- - [ ] Markup- - [ ] Emphasis- - [ ] Bold- - [ ] Italic- - [ ] Strikethrough- - [ ] Underline- - [ ] Superscript- - [ ] Subscript- - [ ] Code / monospaced- - [ ] Tables- - [ ] Lists- - [ ] Unordered lists- - [ ] Numbered lists- - [ ] Checkbox modified lists- - [ ] Blocks (src / quote / example blocks)-- Org-mode markup is currently being worked on.--* License- [[https://github.com/digitalmentat/orgmode-parse/blob/master/LICENSE][BSD3 Open Source Software License]]
− TODO.org
@@ -1,15 +0,0 @@--*- mode: org -*---Please place stray thought TODOs in here.--* Enhance the Weekday Parser test.- At the moment, parserWeekdayTests for some locales are not- supported, because in such locales the weekdays strings-- - contain characters that are not lexically correct as Haskell strings.- - contain digits, which should also be rejected by emacs org-mode's parser.-- see test/Weekdays.hs and test/Timestamps.hs .-- Current test for parserWeekdayTests skips such cases. Whether or how- to support such locales are future work.
orgmode-parse.cabal view
@@ -1,5 +1,5 @@ Name: orgmode-parse-Version: 0.1.1.3+Version: 0.2.0 Author: Parnell Springmeyer <parnell@digitalmentat.com> Maintainer: Parnell Springmeyer <parnell@digitalmentat.com> License: BSD3@@ -9,7 +9,7 @@ flavored documents. Description: - <<https://travis-ci.org/digitalmentat/orgmode-parse.svg?branch=master>>+ <<https://travis-ci.org/ixmatus/orgmode-parse.svg?branch=master>> . `orgmode-parse` is a parsing library for the org-mode flavor of document markup.@@ -23,9 +23,8 @@ Extra-Source-Files: LICENSE- README.org- TODO.org- CHANGELOG+ CHANGELOG.md+ README.md Library Default-Language: Haskell2010@@ -34,26 +33,30 @@ -Wall -fwarn-tabs -funbox-strict-fields -fno-warn-orphans -fno-warn-unused-do-bind Exposed-Modules:- Data.OrgMode.Parse- Data.OrgMode.Parse.Types- Data.OrgMode.Parse.Attoparsec.Document- Data.OrgMode.Parse.Attoparsec.Headings- Data.OrgMode.Parse.Attoparsec.PropertyDrawer- Data.OrgMode.Parse.Attoparsec.Section- Data.OrgMode.Parse.Attoparsec.Time+ Data.OrgMode.Parse,+ Data.OrgMode.Parse.Attoparsec.Document,+ Data.OrgMode.Parse.Attoparsec.Headline,+ Data.OrgMode.Parse.Attoparsec.Drawer,+ Data.OrgMode.Parse.Attoparsec.Drawer.Logbook,+ Data.OrgMode.Parse.Attoparsec.Drawer.Property,+ Data.OrgMode.Parse.Attoparsec.Drawer.Generic,+ Data.OrgMode.Parse.Attoparsec.Section,+ Data.OrgMode.Parse.Attoparsec.Time,+ Data.OrgMode.Parse.Attoparsec.Util,+ Data.OrgMode.Types Build-Depends:- base >= 4.4 && < 5- , aeson >= 0.8.0.2- , attoparsec >= 0.12+ base >= 4.8 && < 5+ , aeson >= 0.11+ , attoparsec >= 0.13 , bytestring >= 0.10.4- , containers >= 0.5.5+ , containers >= 0.5.6 , free >= 4.9 , hashable >= 1.2 , old-locale >= 1.0- , text >= 1.0+ , text >= 1.2 , thyme >= 0.3- , unordered-containers >= 0.2+ , unordered-containers >= 0.2.7 Test-Suite tests Type: exitcode-stdio-1.0@@ -62,22 +65,30 @@ Ghc-Options: -Wall Main-Is: Test.hs Other-Modules:- Data.OrgMode.Parse+ Document,+ Headline,+ Drawer,+ Timestamps,+ Util,+ Weekdays Build-Depends:- base >= 4.4- , aeson >= 0.8- , bytestring >= 0.10- , text >= 1.0- , attoparsec >= 0.12- , hashable >= 1.2- , unordered-containers >= 0.2- , thyme >= 0.3- , old-locale >= 1.0- , HUnit >= 1.2.5.2- , tasty >= 0.8- , tasty-hunit >= 0.8.0.1- , containers+ base >= 4.8 && < 5+ , orgmode-parse+ , aeson >= 0.11+ , attoparsec >= 0.13+ , bytestring >= 0.10.4+ , containers >= 0.5.6+ , free >= 4.9+ , hashable >= 1.2+ , old-locale >= 1.0+ , text >= 1.2+ , thyme >= 0.3+ , unordered-containers >= 0.2.7+ , HUnit >= 1.3+ , tasty >= 0.11+ , tasty-hunit >= 0.9+ , neat-interpolation >= 0.3 Source-Repository head Type: git
src/Data/OrgMode/Parse.hs view
@@ -1,11 +1,11 @@ {-|-Module : Data.OrgMode.Parse.Attoparsec.Headings+Module : Data.OrgMode.Parse Copyright : © 2014 Parnell Springmeyer License : All Rights Reserved Maintainer : Parnell Springmeyer <parnell@digitalmentat.com> Stability : stable -Attoparsec combinators for orgmode documents.+Attoparsec combinators for parsing org-mode documents. -} module Data.OrgMode.Parse (@@ -13,30 +13,21 @@ -- * Parse OrgMode documents module Data.OrgMode.Parse.Attoparsec.Document --- * OrgMode Document structure-, module Data.OrgMode.Parse.Types- -- * Parse headlines-, module Data.OrgMode.Parse.Attoparsec.Headings+, module Data.OrgMode.Parse.Attoparsec.Headline -- * Parse headline metadata sections , module Data.OrgMode.Parse.Attoparsec.Section --- * Parse metadata property drawers-, module Data.OrgMode.Parse.Attoparsec.PropertyDrawer+-- * Parse drawers+, module Data.OrgMode.Parse.Attoparsec.Drawer -- * Parse metadata timestamps and modifiers , module Data.OrgMode.Parse.Attoparsec.Time ) where -import Data.OrgMode.Parse.Attoparsec.Document--import Data.OrgMode.Parse.Attoparsec.Section--import Data.OrgMode.Parse.Attoparsec.Headings--import Data.OrgMode.Parse.Attoparsec.PropertyDrawer--import Data.OrgMode.Parse.Attoparsec.Time--import Data.OrgMode.Parse.Types+import Data.OrgMode.Parse.Attoparsec.Document+import Data.OrgMode.Parse.Attoparsec.Drawer+import Data.OrgMode.Parse.Attoparsec.Headline+import Data.OrgMode.Parse.Attoparsec.Section+import Data.OrgMode.Parse.Attoparsec.Time
src/Data/OrgMode/Parse/Attoparsec/Document.hs view
@@ -1,19 +1,32 @@-module Data.OrgMode.Parse.Attoparsec.Document (- parseDocument-) where+-----------------------------------------------------------------------------+-- |+-- Module : Data.OrgMode.Parse.Attoparsec.Document+-- Copyright : © 2014 Parnell Springmeyer+-- License : All Rights Reserved+-- Maintainer : Parnell Springmeyer <parnell@digitalmentat.com>+-- Stability : stable+--+-- Top-level attoparsec parser for org-mode documents.+---------------------------------------------------------------------------- +module Data.OrgMode.Parse.Attoparsec.Document+( parseDocument+)+where+ import Control.Applicative ((<$>), (<*>)) import Data.Attoparsec.Text-import Data.Attoparsec.Types as TP-import Data.OrgMode.Parse.Attoparsec.Headings-import Data.OrgMode.Parse.Attoparsec.Section (nonHeaderLine)-import Data.OrgMode.Parse.Types-import Data.Text (Text, unlines)-import Prelude hiding (unlines)+import Data.Attoparsec.Types as Attoparsec+import Data.Text (Text)+import qualified Data.Text as Text +import Data.OrgMode.Parse.Attoparsec.Headline+import qualified Data.OrgMode.Parse.Attoparsec.Util as Util+import Data.OrgMode.Types+ -------------------------------------------------------------------------------parseDocument :: [Text] -> TP.Parser Text Document+parseDocument :: [Text] -> Attoparsec.Parser Text Document parseDocument otherKeywords = Document- <$> (unlines <$> many' nonHeaderLine)- <*> many' (headingBelowLevel otherKeywords 0)+ <$> (Text.unlines <$> many' Util.nonHeadline)+ <*> many' (headlineBelowDepth otherKeywords 0)
+ src/Data/OrgMode/Parse/Attoparsec/Drawer.hs view
@@ -0,0 +1,26 @@+{-|+Module : Data.OrgMode.Parse.Attoparsec.Drawer+Copyright : © 2017 Parnell Springmeyer+License : All Rights Reserved+Maintainer : Parnell Springmeyer <parnell@digitalmentat.com>+Stability : stable++Attoparsec combinators for parsing drawers in org-mode documents.+-}++module Data.OrgMode.Parse.Attoparsec.Drawer (++-- * Parse PROPERTY drawers+ module Data.OrgMode.Parse.Attoparsec.Drawer.Property++-- * Parse LOGBOOK drawers+, module Data.OrgMode.Parse.Attoparsec.Drawer.Logbook++-- * Parse generic drawers+, module Data.OrgMode.Parse.Attoparsec.Drawer.Generic++) where++import Data.OrgMode.Parse.Attoparsec.Drawer.Generic+import Data.OrgMode.Parse.Attoparsec.Drawer.Logbook+import Data.OrgMode.Parse.Attoparsec.Drawer.Property
+ src/Data/OrgMode/Parse/Attoparsec/Drawer/Generic.hs view
@@ -0,0 +1,68 @@+-----------------------------------------------------------------------------+-- |+-- Module : Data.OrgMode.Parse.Attoparsec.Drawer.Generic+-- Copyright : © 2017 Parnell Springmeyer+-- License : All Rights Reserved+-- Maintainer : Parnell Springmeyer <parnell@digitalmentat.com>+-- Stability : stable+--+-- Parsing combinators for org-mode section generic drawers.+----------------------------------------------------------------------------++{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE OverloadedStrings #-}++module Data.OrgMode.Parse.Attoparsec.Drawer.Generic+( parseDrawer+, parseDrawerDelim+, drawerEnd+)+where++import Control.Applicative ((*>), (<*))+import Data.Attoparsec.Text+import Data.Attoparsec.Types as Attoparsec+import Data.Text (Text)+import qualified Data.Text as Text+import Prelude hiding (concat, null,+ takeWhile)++import qualified Data.OrgMode.Parse.Attoparsec.Util as Util+import Data.OrgMode.Types++-- | Parse a user-defined drawer.+--+-- > :MYTEXT:+-- > whatever I want, can go in here except for headlines and drawers+-- > :END:+parseDrawer :: Attoparsec.Parser Text Drawer+parseDrawer =+ Drawer <$>+ parseDrawerName <*>+ (Text.unlines <$> manyTill Util.nonHeadline drawerEnd)++-- | Parse a user-defined drawer's name, e.g:+--+-- > :DRAWERNAME:+-- > my text in a drawer+-- > :END:+parseDrawerName :: Attoparsec.Parser Text Text+parseDrawerName =+ skipSpace *> skip (== ':') *>+ takeWhile1 (/= ':') <*+ skip (== ':') <* skipSpace++-- | Parse drawer delimiters, e.g the beginning and end of a property+-- drawer:+--+-- > :PROPERTIES:+-- > :END:+parseDrawerDelim :: Text -> Attoparsec.Parser Text Text+parseDrawerDelim v =+ skipSpace *> skip (== ':') *>+ asciiCI v <*+ skip (== ':') <* skipSpace++-- | Parse the @:END:@ of a drawer.+drawerEnd :: Attoparsec.Parser Text Text+drawerEnd = parseDrawerDelim "END"
+ src/Data/OrgMode/Parse/Attoparsec/Drawer/Logbook.hs view
@@ -0,0 +1,38 @@+-----------------------------------------------------------------------------+-- |+-- Module : Data.OrgMode.Parse.Attoparsec.Drawer.Logbook+-- Copyright : © 2017 Parnell Springmeyer+-- License : All Rights Reserved+-- Maintainer : Parnell Springmeyer <parnell@digitalmentat.com>+-- Stability : stable+--+-- Parsing combinators for org-mode section logbook drawers.+----------------------------------------------------------------------------++{-# LANGUAGE OverloadedStrings #-}++module Data.OrgMode.Parse.Attoparsec.Drawer.Logbook+( parseLogbook+)+where++import Control.Applicative ((*>))+import Data.Attoparsec.Text+import Data.Attoparsec.Types as Attoparsec+import Data.Text (Text)+import Prelude hiding (concat,+ null, takeWhile)++import Data.OrgMode.Parse.Attoparsec.Drawer.Generic as Drawer.Generic+import Data.OrgMode.Parse.Attoparsec.Time (parseClock)+import Data.OrgMode.Types++-- | Parse a @LOGBOOK@ drawer.+--+-- > :LOGBOOK:+-- > CLOCK: [2015-10-05 Mon 17:13]--[2015-10-05 Mon 17:14] => 0:01+-- > :END:+parseLogbook :: Attoparsec.Parser Text Logbook+parseLogbook = Logbook <$> (drawerBegin *> manyTill parseClock Drawer.Generic.drawerEnd)+ where+ drawerBegin = Drawer.Generic.parseDrawerDelim "LOGBOOK"
+ src/Data/OrgMode/Parse/Attoparsec/Drawer/Property.hs view
@@ -0,0 +1,58 @@+-----------------------------------------------------------------------------+-- |+-- Module : Data.OrgMode.Parse.Attoparsec.Drawer.Property+-- Copyright : © 2014 Parnell Springmeyer+-- License : All Rights Reserved+-- Maintainer : Parnell Springmeyer <parnell@digitalmentat.com>+-- Stability : stable+--+-- Parsing combinators for org-mode section property drawers.+----------------------------------------------------------------------------++{-# LANGUAGE OverloadedStrings #-}++module Data.OrgMode.Parse.Attoparsec.Drawer.Property+( parseProperties+, property+, PropertyKey+, PropertyVal+)+where++import Control.Applicative ((*>), (<*))+import Data.Attoparsec.Text as T+import Data.Attoparsec.Types as Attoparsec+import Data.HashMap.Strict (fromList)+import Data.Text (Text)+import qualified Data.Text as Text+import Prelude hiding (concat,+ null, takeWhile)++import Data.OrgMode.Parse.Attoparsec.Drawer.Generic as Drawer.Generic+import Data.OrgMode.Types++type PropertyKey = Text+type PropertyVal = Text++-- | Parse a @PROPERTY@ drawer.+--+-- > :PROPERTIES:+-- > :DATE: [2014-12-14 11:00]+-- > :NOTE: Something really crazy happened today!+-- > :END:+parseProperties :: Attoparsec.Parser Text Properties+parseProperties = Properties . fromList <$> (drawerBegin *> manyTill property Drawer.Generic.drawerEnd)+ where+ drawerBegin = Drawer.Generic.parseDrawerDelim "PROPERTIES"++-- | Parse a property of a drawer.+--+-- Properties *must* be a `:KEY: value` pair, the key can be of any+-- case and contain any characters except for newlines and colons+-- (since they delimit the start and end of the key).+property :: Attoparsec.Parser Text (PropertyKey, PropertyVal)+property = (,) <$> parseKey <*> parseVal+ where+ parseKey = skipSpace *> skip (== ':') *> takeWhile1 (/= ':') <* skip (== ':')+ parseVal = Text.strip <$> (skipSpace *> takeValue)+ takeValue = takeWhile1 (not . isEndOfLine)
− src/Data/OrgMode/Parse/Attoparsec/Headings.hs
@@ -1,165 +0,0 @@--------------------------------------------------------------------------------- |--- Module : Data.OrgMode.Parse.Attoparsec.Headings--- Copyright : © 2014 Parnell Springmeyer--- License : All Rights Reserved--- Maintainer : Parnell Springmeyer <parnell@digitalmentat.com>--- Stability : stable------ Parsing combinators for org-list headings.-------------------------------------------------------------------------------{-# LANGUAGE GeneralizedNewtypeDeriving #-}-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE ViewPatterns #-}--module Data.OrgMode.Parse.Attoparsec.Headings-( headingBelowLevel-, headingLevel-, headingPriority-, parseStats-, parseTags-)-where--import Control.Applicative (pure, (*>), (<$>), (<*),- (<*>), (<|>))-import Control.Monad (liftM5, void)-import Data.Attoparsec.Text as T-import Data.Attoparsec.Types as TP (Parser)-import Data.Maybe (fromMaybe)-import Data.Monoid (mempty)-import Data.Text as Text (Text, append,- init, last,- length, null,- splitOn, strip)-import Prelude hiding (concat, null,- sequence_, takeWhile,- unlines)-import Text.Printf--import Data.OrgMode.Parse.Attoparsec.Section-import Data.OrgMode.Parse.Types----- | Parse an org-mode heading and its contained entities (see <http://orgmode.org/worg/dev/org-syntax.html OrgSyntax>).------ Headers include a hierarchy level indicated by asterisks, optional--- todo states, priority level, %-done stats, and tags.------ > ** TODO [#B] Polish Poetry Essay [25%] :HOMEWORK:POLISH:WRITING:------ Headings may contain:------ - A section with Planning and Clock entries--- - A number of other not-yet-implemented entities (code blocks, lists)--- - Unstructured text--- - Other heading deeper in the hierarchy------ 'headingBelowLevel' takes a list of terms to consider, state--- keywords, and a minumum hierarchy depth. Use 0 to parse any--- heading.-headingBelowLevel :: [Text] -> LevelDepth -> TP.Parser Text Heading-headingBelowLevel stateKeywords depth = do- lvl <- headingLevel depth <* skipSpace'- td <- option Nothing (Just <$> parseStateKeyword stateKeywords <* skipSpace')- pr <- option Nothing (Just <$> headingPriority <* skipSpace')-- TitleMeta tl stats' (fromMaybe [] -> tags') <- takeTitleExtras-- sect <- parseSection- subs <- option [] $ many' (headingBelowLevel stateKeywords (depth + 1))-- skipSpace-- return $ Heading lvl td pr tl stats' tags' sect subs---- | Parse the asterisk indicated heading level until a space is--- reached.------ Constrain it to LevelDepth or its children.-headingLevel :: LevelDepth -> TP.Parser Text Level-headingLevel (LevelDepth d) = takeLevel >>= test- where- takeLevel = Text.length <$> takeWhile1 (== '*')- test l | l <= d = fail $ printf "Heading level of %d cannot be higher than depth %d" l d- | otherwise = return $ Level l---- | Parse the state indicator.------ > {`TODO` | `DONE` | custom }------ These can be custom so we're parsing additional state identifiers--- as Text.-parseStateKeyword :: [Text] -> TP.Parser Text StateKeyword-parseStateKeyword (map string -> sk) = StateKeyword <$> choice sk---- | Parse the priority indicator.------ If anything but these priority indicators are used the parser will--- fail:------ - @[#A]@--- - @[#B]@--- - @[#C]@-headingPriority :: TP.Parser Text Priority-headingPriority = start *> zipChoice <* end- where- zipChoice = choice (zipWith mkPParser "ABC" [A,B,C])- mkPParser c p = char c *> pure p- start = string "[#"- end = char ']'---- | Parse the title, optional stats block, and optional tag.------ Stats may be either [m/n] or [n%] and tags are colon-separated, e.g:--- > :HOMEWORK:POETRY:WRITING:-takeTitleExtras :: TP.Parser Text TitleMeta-takeTitleExtras =- liftM5 mkTitleMeta- titleStart- (optionalMetadata parseStats)- (optionalMetadata parseTags)- leftovers- (void $ endOfLine <|> endOfInput)- where- titleStart = takeTill (\c -> inClass "[:" c || isEndOfLine c)- leftovers = option mempty $ takeTill (== '\n')- optionalMetadata p = option Nothing (Just <$> p <* skipSpace')---mkTitleMeta :: Text -> Maybe Stats -> Maybe [Tag] -> Text -> () -> TitleMeta-mkTitleMeta start stats' tags' leftovers _ =- TitleMeta (transformTitle start leftovers) stats' tags'- where- transformTitle t l | null leftovers = strip t- | otherwise = append t l---- | Parse a stats block.------ Accepts either form: "[m/n]" or "[n%]" and there is no restriction--- on m or n other than that they are integers.-parseStats :: TP.Parser Text Stats-parseStats = sPct <|> sOf- where sPct = StatsPct- <$> (char '[' *> decimal <* string "%]")- sOf = StatsOf- <$> (char '[' *> decimal)- <*> (char '/' *> decimal <* char ']')---- | Parse a colon-separated list of Tags------ > :HOMEWORK:POETRY:WRITING:-parseTags :: TP.Parser Text [Tag]-parseTags = tags' >>= test- where- tags' = (char ':' *> takeWhile (/= '\n'))- test t- | Text.null t = fail "no data after ':'"- | (Text.last t /= ':' || Text.length t < 2) = fail "Not a valid tag set"- | otherwise = return (splitOn ":" (Text.init t))--skipSpace' :: TP.Parser Text ()-skipSpace' = void $ takeWhile spacePred- where- spacePred s = s == ' ' || s == '\t'
+ src/Data/OrgMode/Parse/Attoparsec/Headline.hs view
@@ -0,0 +1,193 @@+-----------------------------------------------------------------------------+-- |+-- Module : Data.OrgMode.Parse.Attoparsec.Headline+-- Copyright : © 2014 Parnell Springmeyer+-- License : All Rights Reserved+-- Maintainer : Parnell Springmeyer <parnell@digitalmentat.com>+-- Stability : stable+--+-- Parsing combinators for org-mode headlines.+----------------------------------------------------------------------------++{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE ViewPatterns #-}++module Data.OrgMode.Parse.Attoparsec.Headline+( headlineBelowDepth+, headlineDepth+, headingPriority+, parseStats+, parseTags+, mkTitleMeta+, TitleMeta+)+where++import Control.Applicative+import Data.Attoparsec.Text+import Data.Attoparsec.Types as Attoparsec (Parser)+import Data.Maybe+import Data.Monoid+import Data.Text (Text)+import qualified Data.Text as Text+import Prelude hiding (takeWhile)+import Text.Printf++import Data.OrgMode.Parse.Attoparsec.Section+import qualified Data.OrgMode.Parse.Attoparsec.Time as OrgMode.Time+import Data.OrgMode.Parse.Attoparsec.Util+import Data.OrgMode.Types++-- | Intermediate type for parsing titles in a headline after the+-- state keyword and priority have been parsed.+newtype TitleMeta = TitleMeta (Text, Maybe Stats, Maybe [Tag])+ deriving (Eq, Show)++-- | Parse an org-mode headline, its metadata, its section-body, and+-- any sub-headlines; please see+-- <http://orgmode.org/worg/dev/org-syntax.html org-syntax>.+--+-- Headline metadata includes a hierarchy level indicated by+-- asterisks, optional todo state keywords, an optional priority+-- level, %-done statistics, and tags; e.g:+--+-- > ** TODO [#B] Polish Poetry Essay [25%] :HOMEWORK:POLISH:WRITING:+--+-- Headlines may contain:+--+-- - A section with Planning and Clock entries+-- - A number of other not-yet-implemented entities (code blocks, lists)+-- - Unstructured text+-- - Sub-headlines+--+-- @headlineBelowDepth@ takes a list of terms to consider, state+-- keywords, and a minumum hierarchy depth.+--+-- Use a @Depth@ of 0 to parse any headline.+headlineBelowDepth :: [Text]+ -> Depth+ -> Attoparsec.Parser Text Headline+headlineBelowDepth stateKeywords d = do+ depth' <- headlineDepth d <* skipOnlySpace+ stateKey <- option Nothing (Just <$> parseStateKeyword stateKeywords <* skipOnlySpace)+ priority' <- option Nothing (Just <$> headingPriority <* skipOnlySpace)+ tstamp <- option Nothing (Just <$> OrgMode.Time.parseTimestamp <* skipOnlySpace)++ -- Parse the title and any metadata within it+ TitleMeta+ ( titleText+ , stats'+ , (fromMaybe [] -> tags')+ ) <- parseTitle++ section' <- parseSection+ subHeadlines' <- option [] $ many' (headlineBelowDepth stateKeywords (d + 1))++ skipSpace+ pure $ Headline+ { depth = depth'+ , stateKeyword = stateKey+ , priority = priority'+ , title = titleText+ , timestamp = tstamp+ , stats = stats'+ , tags = tags'+ , section = section'+ , subHeadlines = subHeadlines'+ }++-- | Parse the asterisk-indicated headline depth until a space is+-- encountered.+--+-- Constrain it to @Depth@.+headlineDepth :: Depth -> Attoparsec.Parser Text Depth+headlineDepth (Depth d) = takeDepth >>= test+ where+ takeDepth = Text.length <$> takeWhile1 (== '*')+ test n | n <= d = fail $ printf "Headline depth of %d cannot be higher than a depth constraint of %d" n d+ | otherwise = pure $ Depth n++-- | Parse the state indicator.+--+-- > {`TODO` | `DONE` | custom }+--+-- These can be custom so we're parsing additional state identifiers+-- as Text.+parseStateKeyword :: [Text] -> Attoparsec.Parser Text StateKeyword+parseStateKeyword (fmap string -> sk) = StateKeyword <$> choice sk++-- | Parse the priority indicator.+--+-- If anything but these priority indicators are used the parser will+-- fail:+--+-- - @[#A]@+-- - @[#B]@+-- - @[#C]@+headingPriority :: Attoparsec.Parser Text Priority+headingPriority = start *> zipChoice <* end+ where+ zipChoice = choice (zipWith mkPParser "ABC" [A,B,C])+ mkPParser c p = char c *> pure p+ start = string "[#"+ end = char ']'++-- | Parse the title, optional stats block, and optional tag.+--+-- Stats may be either [m/n] or [n%] and tags are colon-separated, e.g:+-- > :HOMEWORK:POETRY:WRITING:+parseTitle :: Attoparsec.Parser Text TitleMeta+parseTitle =+ mkTitleMeta <$>+ titleStart <*>+ (optMeta parseStats) <*>+ (optMeta parseTags) <*>+ -- Parse what's leftover AND till end of line or input; discarding+ -- everything but the leftovers+ leftovers <* (endOfLine <|> endOfInput)+ where+ titleStart = takeTill (\c -> inClass "[:" c || isEndOfLine c)+ leftovers = option mempty $ takeTill (== '\n')+ optMeta p = option Nothing (Just <$> p <* skipOnlySpace)++-- | Produce a triple consisting of a stripped start-of-title if there+-- are no leftovers after parsing (otherwise, recombine the two) and+-- the optional stats and tags.+mkTitleMeta :: Text -- ^ Start of title till the end of line+ -> Maybe Stats -- ^ Stats, e.g: [33%]+ -> Maybe [Tag] -- ^ Tags, e.g: :HOMEWORK:CODE:SLEEP:+ -> Text -- ^ Leftovers (may be empty) of the title+ -> TitleMeta+mkTitleMeta start stats' tags' leftovers =+ TitleMeta ((cleanTitle start leftovers), stats', tags')+ where+ cleanTitle t l+ | Text.null leftovers = Text.strip t+ | otherwise = Text.append t l++-- | Parse a statisticss block, e.g: [33%].+--+-- Accepts either form: "[m/n]" or "[n%]" and there is no restriction+-- on m or n other than that they are integers.+parseStats :: Attoparsec.Parser Text Stats+parseStats = pct <|> frac+ where+ pct = StatsPct+ <$> (char '[' *> decimal <* string "%]")+ frac = StatsOf+ <$> (char '[' *> decimal)+ <*> (char '/' *> decimal <* char ']')++-- | Parse a colon-separated list of tags.+--+-- > :HOMEWORK:POETRY:WRITING:+parseTags :: Attoparsec.Parser Text [Tag]+parseTags = tags' >>= test+ where+ tags' = (char ':' *> takeWhile (/= '\n'))+ test t+ | Text.null t = fail "no data after beginning ':'"+ | Text.last t /= ':' = fail $ Text.unpack $ "expected ':' at end of tag list but got: " `Text.snoc` Text.last t+ | Text.length t < 2 = fail $ Text.unpack $ "not a valid tag set: " <> t+ | otherwise = pure (Text.splitOn ":" (Text.init t))
− src/Data/OrgMode/Parse/Attoparsec/PropertyDrawer.hs
@@ -1,59 +0,0 @@--------------------------------------------------------------------------------- |--- Module : Data.OrgMode.Parse.Attoparsec.PropertyDrawer--- Copyright : © 2014 Parnell Springmeyer--- License : All Rights Reserved--- Maintainer : Parnell Springmeyer <parnell@digitalmentat.com>--- Stability : stable------ Parsing combinators for org-mode entry property drawers.-------------------------------------------------------------------------------{-# LANGUAGE OverloadedStrings #-}---module Data.OrgMode.Parse.Attoparsec.PropertyDrawer-( parseDrawer-, property-)-where--import Control.Applicative ((*>), (<*))-import Data.Attoparsec.Text as T-import Data.Attoparsec.Types as TP-import Data.HashMap.Strict (fromList)-import Data.Text as Text (Text, strip)-import Prelude hiding (concat, null, takeWhile)--import Data.OrgMode.Parse.Types--type PropertyKey = Text-type PropertyVal = Text---- | Parse a property drawer.------ > :PROPERTIES:--- > :DATE: [2014-12-14 11:00]--- > :NOTE: Something really crazy happened today!--- > :END:-parseDrawer :: TP.Parser Text Properties-parseDrawer = return . fromList =<< begin *> manyTill property end- where- begin = ident "PROPERTIES"- end = ident "END"- ident v = skipSpace *> skip (== ':') *>- asciiCI v <*- skip (== ':') <* skipSpace---- | Parse a property of a drawer.------ Properties *must* be a `:KEY: value` pair, the key can be of any--- case and contain any characters except for newlines and colons--- (since they delimit the start and end of the key).-property :: TP.Parser Text (PropertyKey, PropertyVal)-property = do- key <- skipSpace *> skip (== ':') *> takeWhile1 (/= ':') <* skip (== ':')- val <- skipSpace *> takeValue- return (key, strip val)- where- takeValue = takeWhile1 (not . isEndOfLine)
src/Data/OrgMode/Parse/Attoparsec/Section.hs view
@@ -6,45 +6,39 @@ -- Maintainer : Parnell Springmeyer <parnell@digitalmentat.com> -- Stability : stable ----- Parsing combinators for org-mode sections.+-- Parsing combinators for org-mode headline sections. ---------------------------------------------------------------------------- {-# LANGUAGE OverloadedStrings #-} module Data.OrgMode.Parse.Attoparsec.Section where -import Control.Applicative ((<$>), (<*),- (<*>), (<|>))-import Data.Attoparsec.Text as T-import Data.Attoparsec.Types as TP-import Data.Monoid (mempty)-import Data.Text (Text, pack,- unlines)-import Prelude hiding (unlines)+import Control.Applicative+import Data.Attoparsec.Text+import Data.Attoparsec.Types as Attoparsec+import Data.Monoid+import Data.Text (Text)+import qualified Data.Text as Text+import Prelude hiding (unlines) -import Data.OrgMode.Parse.Attoparsec.PropertyDrawer+import Data.OrgMode.Parse.Attoparsec.Drawer import Data.OrgMode.Parse.Attoparsec.Time-import Data.OrgMode.Parse.Types+import qualified Data.OrgMode.Parse.Attoparsec.Util as Util +import Data.OrgMode.Types+ -- | Parse a heading section ----- Heading sections contain optionally a property drawer,+-- Headline sections contain optionally a property drawer, -- a list of clock entries, code blocks (not yet implemented), -- plain lists (not yet implemented), and unstructured text.-parseSection :: TP.Parser Text Section-parseSection = Section- <$> (Plns <$> parsePlannings)- <*> many' parseClock- <*> option mempty parseDrawer- <*> (unlines <$> many' nonHeaderLine)- where---- | Parse a non-heading line of a section.-nonHeaderLine :: TP.Parser Text Text-nonHeaderLine = nonHeaderLine0 <|> nonHeaderLine1- where- nonHeaderLine0 = endOfLine >> return (pack "")- nonHeaderLine1 = pack <$> do- h <- notChar '*'- t <- manyTill anyChar endOfLine- return (h:t)+parseSection :: Attoparsec.Parser Text Section+parseSection =+ Section+ <$> option Nothing (Just <$> (skipSpace *> parseTimestamp <* skipSpace))+ <*> (Plns <$> parsePlannings)+ <*> many' parseClock+ <*> option mempty parseProperties+ <*> option mempty parseLogbook+ <*> many' parseDrawer+ <*> (Text.unlines <$> many' Util.nonHeadline)
src/Data/OrgMode/Parse/Attoparsec/Time.hs view
@@ -6,33 +6,42 @@ -- Maintainer : Parnell Springmeyer <parnell@digitalmentat.com> -- Stability : stable ----- Parsing combinators for org-mode active and inactive timestamps.+-- Parsing combinators for org-mode timestamps; both active and+-- inactive. ---------------------------------------------------------------------------- +{-# LANGUAGE DataKinds #-} {-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RecordWildCards #-} {-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE ViewPatterns #-} -module Data.OrgMode.Parse.Attoparsec.Time where+module Data.OrgMode.Parse.Attoparsec.Time+( parsePlannings+, parseClock+, parseTimestamp+)+where -import Control.Applicative (pure, some,- (*>), (<$>), (<*), (<*>), (<|>))+import Control.Applicative import Control.Monad (liftM)-import qualified Data.Attoparsec.ByteString as AB-import Data.Attoparsec.Text as T-import Data.Attoparsec.Types as TP (Parser)-import Data.Attoparsec.Combinator as TP+import qualified Data.Attoparsec.ByteString as Attoparsec.ByteString+import Data.Attoparsec.Combinator as Attoparsec+import Data.Attoparsec.Text+import Data.Attoparsec.Types as Attoparsec (Parser) import qualified Data.ByteString.Char8 as BS import Data.HashMap.Strict (HashMap, fromList) import Data.Maybe (listToMaybe)-import Data.Text as Text (Text, pack, unpack,- unwords)+import Data.Monoid+import Data.Text (Text)+import qualified Data.Text as Text import Data.Thyme.Format (buildTime, timeParser) import Data.Thyme.LocalTime (Hours, Minutes)-import Prelude hiding (concat, null, takeWhile,- unwords, words)+import Prelude hiding (concat, null, repeat,+ takeWhile, unwords, words) import System.Locale (defaultTimeLocale) -import Data.OrgMode.Parse.Types+import Data.OrgMode.Types -- | Parse a planning line. --@@ -41,14 +50,14 @@ -- the same line e.g: -- -- > DEADLINE: <2015-05-10 17:00> CLOSED: <2015-04-1612:00>-parsePlannings :: TP.Parser Text (HashMap PlanningKeyword Timestamp)+parsePlannings :: Attoparsec.Parser Text (HashMap PlanningKeyword Timestamp) parsePlannings = fromList <$> (many' (skipSpace *> planning <* skipSpace))- where planning :: TP.Parser Text (PlanningKeyword, Timestamp)- planning = (,) <$> pType <* char ':' <*> (skipSpace *> parseTimestamp)- pType = choice [string "SCHEDULED" *> pure SCHEDULED- ,string "DEADLINE" *> pure DEADLINE- ,string "CLOSED" *> pure CLOSED- ]+ where+ planning = (,) <$> pType <* char ':' <*> (skipSpace *> parseTimestamp)+ pType = choice [string "SCHEDULED" *> pure SCHEDULED+ ,string "DEADLINE" *> pure DEADLINE+ ,string "CLOSED" *> pure CLOSED+ ] -- | Parse a clock line. --@@ -56,8 +65,8 @@ -- have a timestamp, a duration, both, or neither e.g.: -- -- > CLOCK: [2014-12-10 Fri 2:30]--[2014-12-10 Fri 10:30] => 08:00-parseClock :: TP.Parser Text (Maybe Timestamp, Maybe Duration)-parseClock = (,) <$> (skipSpace *> string "CLOCK: " *> ts) <*> dur+parseClock :: Attoparsec.Parser Text Clock+parseClock = Clock <$> ((,) <$> (skipSpace *> string "CLOCK: " *> ts) <*> dur) where ts = option Nothing (Just <$> parseTimestamp) dur = option Nothing (Just <$> (string " => "@@ -75,47 +84,38 @@ -- -- Each timepoint includes an optional repeater flag and an optional -- delay flag.-parseTimestamp :: TP.Parser Text Timestamp+parseTimestamp :: Attoparsec.Parser Text Timestamp parseTimestamp = do (ts1, tsb1, act) <- transformBracketedDateTime <$> parseBracketedDateTime - -- Such ew, so gross, much clean, very needed blk2 <- liftM (maybe Nothing (Just . transformBracketedDateTime)) optionalBracketedDateTime - -- TODO: this is grody, I'd like to refactor this truth table logic- -- and make the transformations chainable and composable as opposed- -- to depending on case matching blocks. - Parnell+ -- TODO: refactor this case logic case (tsb1, blk2) of (Nothing, Nothing) ->- return (Timestamp ts1 act Nothing)+ pure (Timestamp ts1 act Nothing) (Nothing, Just (ts2, Nothing, _)) ->- return (Timestamp ts1 act (Just ts2))+ pure (Timestamp ts1 act (Just ts2)) (Nothing, Just _) ->+ -- TODO: improve error message with an example of what would+ -- cause this case fail "Illegal time range in second timerange timestamp" (Just (h',m'), Nothing) ->- return (Timestamp ts1 act+ pure (Timestamp ts1 act (Just $ ts1 {hourMinute = Just (h',m') ,repeater = Nothing ,delay = Nothing}))- (Just _, Just _) -> fail "Illegal mix of time range and timestamp range"+ (Just _, Just _) ->+ -- TODO: improve error message with an example of what would+ -- cause thise case+ fail "Illegal mix of time range and timestamp range" where optionalBracketedDateTime = option Nothing (Just <$> (string "--" *> parseBracketedDateTime)) -type Weekday = Text -data BracketedDateTime =- BracketedDateTime- { datePart :: YearMonthDay- , dayNamePart :: Maybe Weekday- , timePart :: Maybe TimePart- , repeat :: Maybe Repeater- , delayPart :: Maybe Delay- , isActive :: Bool- } deriving (Show, Eq)- -- | Parse a single time part. -- -- > [2015-03-27 Fri 10:20 +4h]@@ -126,7 +126,7 @@ -- - Whether there was a time interval in place of a single time -- (this will be handled upstream by parseTimestamp) -- - Whether the time is active or inactive-parseBracketedDateTime :: TP.Parser Text BracketedDateTime+parseBracketedDateTime :: Attoparsec.Parser Text BracketedDateTime parseBracketedDateTime = do openingBracket <- char '<' <|> char '[' brkDateTime <- BracketedDateTime <$>@@ -142,104 +142,110 @@ where optionalParse p = option Nothing (Just <$> p) <* skipSpace maybeListParse p = listToMaybe <$> many' p <* skipSpace- activeBracket = (=='<')+ activeBracket ((=='<') -> active) =+ if active then Active else Inactive finally bkd ob cb | complementaryBracket ob /= cb =- fail "Mismatched timestamp brackets"+ -- TODO: improve this error message with an+ -- example of what would cause this case+ fail "mismatched timestamp brackets" | otherwise = return bkd complementaryBracket '<' = '>' complementaryBracket '[' = ']' complementaryBracket x = x --- TODO: this function is also grody but it's better than having this--- logic in the primary parseBracketedDateTime function. - Parnell-transformBracketedDateTime :: BracketedDateTime -> (DateTime, Maybe (Hours, Minutes), Bool)-transformBracketedDateTime- (BracketedDateTime dp dn tp rp dly act) =- case tp of- Just (TimePart (Left (h,m))) ->- ( DateTime (YMD' dp) dn (Just (h,m)) rp dly- , Nothing- , act)- Just (TimePart (Right (t1, t2))) ->- ( DateTime (YMD' dp) dn (Just t1) rp dly- , Just t2- , act)- Nothing ->- ( DateTime (YMD' dp) dn Nothing rp dly- , Nothing- , act)+-- | Given a @BracketedDateTime@ data type, transform it into a triple+-- composed of a @DateTime@, possibly a @(Hours, Minutes)@ tuple+-- signifying the end of a timestamp range, and a boolean indic+transformBracketedDateTime :: BracketedDateTime+ -> (DateTime, Maybe (Hours, Minutes), ActiveState)+transformBracketedDateTime BracketedDateTime{..} =+ maybe dateStamp timeStamp timePart+ where+ defdt = DateTime datePart dayNamePart Nothing repeat delayPart+ timeStamp (AbsoluteTime (hs,ms)) =+ ( defdt { hourMinute = Just (hs,ms) }+ , Nothing+ , activeState+ )+ timeStamp (TimeStampRange (t0,t1)) =+ ( defdt { hourMinute = Just t0 }+ , Just t1+ , activeState+ )+ dateStamp = (defdt, Nothing, activeState) + -- | Parse a day name in the same way as org-mode does.-parseDay :: TP.Parser Text Text-parseDay = pack <$> some (TP.satisfyElem isDayChar)+--+-- The character set (@]+0123456789>\r\n -@) is based on a part of a+-- regexp named @org-ts-regexp0@ found in org.el.+parseDay :: Attoparsec.Parser Text Text+parseDay = Text.pack <$> some (Attoparsec.satisfyElem isDayChar) where isDayChar :: Char -> Bool isDayChar = (`notElem` nonDayChars)- nonDayChars :: String- nonDayChars = "]+0123456789>\r\n -"- -- The above syntax is based on [^]+0-9>\r\n -]+- -- a part of regexp named org-ts-regexp0- -- in org.el . ---type AbsoluteTime = (Hours, Minutes)-type TimestampRange = (AbsoluteTime, AbsoluteTime)--newtype TimePart = TimePart (Either AbsoluteTime TimestampRange)- deriving (Eq, Ord, Show)+ -- | This is based on: @[^]+0-9>\r\n -]+@, a part of a regexp+ -- named org-ts-regexp0 in org.el.+ nonDayChars = "]+0123456789>\r\n -" :: String -- | Parse the time-of-day part of a time part, as a single point or a -- time range.-parseTime' :: TP.Parser Text TimePart-parseTime' =- TimePart <$> choice [ Right <$> ((,) <$> parseHM <* char '-' <*> parseHM)- , Left <$> parseHM- ]+parseTime' :: Attoparsec.Parser Text TimePart+parseTime' = stampRng <|> stampAbs+ where+ stampRng = do+ beg <- parseHM <* char '-'+ end <- parseHM+ pure $ TimeStampRange (beg,end) + stampAbs = AbsoluteTime <$> parseHM+ -- | Parse the YYYY-MM-DD part of a time part.-parseDate :: TP.Parser Text YearMonthDay-parseDate = consumeDate >>= either failure success . dateParse+parseDate :: Attoparsec.Parser Text YearMonthDay+parseDate = consumeDate >>= either bad good . dateParse where- failure e = fail . unpack $ unwords ["Failure parsing date: ", pack e]- success t = return $ buildTime t- consumeDate = manyTill anyChar (char ' ')- dateParse = AB.parseOnly dpCombinator . BS.pack+ bad e = fail $ "failure parsing date: " <> e+ good t = pure $ buildTime t+ consumeDate = manyTill anyChar $ char ' '+ dateParse = Attoparsec.ByteString.parseOnly dpCombinator . BS.pack dpCombinator = timeParser defaultTimeLocale "%Y-%m-%d" -- | Parse a single @HH:MM@ point.-parseHM :: TP.Parser Text (Hours, Minutes)+parseHM :: Attoparsec.Parser Text (Hours, Minutes) parseHM = (,) <$> decimal <* char ':' <*> decimal -- | Parse the Timeunit part of a delay or repeater flag.-parseTimeUnit :: TP.Parser Text TimeUnit+parseTimeUnit :: Attoparsec.Parser Text TimeUnit parseTimeUnit =- choice [ char 'h' *> pure UnitHour- , char 'd' *> pure UnitDay- , char 'w' *> pure UnitWeek- , char 'm' *> pure UnitMonth- , char 'y' *> pure UnitYear- ]+ choice [ char 'h' *> pure UnitHour+ , char 'd' *> pure UnitDay+ , char 'w' *> pure UnitWeek+ , char 'm' *> pure UnitMonth+ , char 'y' *> pure UnitYear+ ] -- | Parse a repeater flag, e.g. @.+4w@, or @++1y@.-parseRepeater :: TP.Parser Text Repeater+parseRepeater :: Attoparsec.Parser Text Repeater parseRepeater =- Repeater- <$> choice[ string "++" *> pure RepeatCumulate- , char '+' *> pure RepeatCatchUp- , string ".+" *> pure RepeatRestart- ]- <*> decimal- <*> parseTimeUnit+ Repeater+ <$> choice+ [ string "++" *> pure RepeatCumulate+ , char '+' *> pure RepeatCatchUp+ , string ".+" *> pure RepeatRestart+ ]+ <*> decimal+ <*> parseTimeUnit -- | Parse a delay flag, e.g. @--1d@ or @-2w@.-parseDelay :: TP.Parser Text Delay+parseDelay :: Attoparsec.Parser Text Delay parseDelay =- Delay- <$> choice [ string "--" *> pure DelayFirst- , char '-' *> pure DelayAll- ]- <*> decimal- <*> parseTimeUnit+ Delay+ <$> choice+ [ string "--" *> pure DelayFirst+ , char '-' *> pure DelayAll+ ]+ <*> decimal+ <*> parseTimeUnit
+ src/Data/OrgMode/Parse/Attoparsec/Util.hs view
@@ -0,0 +1,43 @@+{-|+Module : Data.OrgMode.Parse.Attoparsec.Util+Copyright : © 2017 Parnell Springmeyer+License : All Rights Reserved+Maintainer : Parnell Springmeyer <parnell@digitalmentat.com>+Stability : stable++Attoparsec utilities.+-}++module Data.OrgMode.Parse.Attoparsec.Util+( skipOnlySpace+, nonHeadline+)+where++import Control.Applicative ((<|>))+import qualified Data.Attoparsec.Text as Attoparsec.Text+import Data.Attoparsec.Types (Parser)+import Data.Text (Text)+import qualified Data.Text as Text+++-- | Skip whitespace characters, only!+--+-- @Data.Attoparsec.Text.skipSpace@ uses the @isSpace@ predicate from+-- @Data.Char@ which also includes control characters such as a return+-- and newline which we need to *not* consume in some cases during+-- parsing.+skipOnlySpace :: Parser Text ()+skipOnlySpace = Attoparsec.Text.skipWhile spacePred+ where+ spacePred s = s == ' ' || s == '\t'++-- | Parse a non-heading line of a section.+nonHeadline :: Parser Text Text+nonHeadline = nonHeadline0 <|> nonHeadline1+ where+ nonHeadline0 = Attoparsec.Text.endOfLine *> pure (Text.pack "")+ nonHeadline1 = Text.pack <$> do+ h <- Attoparsec.Text.notChar '*'+ t <- Attoparsec.Text.manyTill Attoparsec.Text.anyChar Attoparsec.Text.endOfLine+ pure (h:t)
− src/Data/OrgMode/Parse/Types.hs
@@ -1,235 +0,0 @@-{-|-Module : Data.OrgMode.Parse.Types-Copyright : © 2014 Parnell Springmeyer-License : All Rights Reserved-Maintainer : Parnell Springmeyer <parnell@digitalmentat.com>-Stability : experimental--Types and utility functions.--}--{-# LANGUAGE DeriveGeneric #-}-{-# LANGUAGE GeneralizedNewtypeDeriving #-}-{-# LANGUAGE OverloadedStrings #-}--module Data.OrgMode.Parse.Types-( Document (..)-, Section (..)-, Level (..)-, Heading (..)-, Priority (..)-, Plannings (..)-, StateKeyword (..)-, Duration-, PlanningKeyword (..)-, Properties-, Timestamp (..)-, DateTime (..)-, Stats (..)-, Tag-, TimeUnit (..)-, RepeaterType (..)-, Repeater (..)-, DelayType (..)-, Delay (..)-, LevelDepth (..)-, TitleMeta (..)-, YearMonthDay(..)-, YearMonthDay'(..)-) where--import Control.Applicative-import Control.Monad (mzero)-import Data.Aeson ((.:), (.=))-import qualified Data.Aeson as A-import Data.Hashable (Hashable (..))-import Data.HashMap.Strict (HashMap, fromList, keys, toList)-import Data.Text (Text, pack)-import Data.Thyme.Calendar (YearMonthDay (..))-import Data.Thyme.LocalTime (Hour, Minute)-import Data.Traversable-import GHC.Generics--data Document = Document {- documentText :: Text -- ^ Text occurring before any Org headlines- , documentHeadings :: [Heading] -- ^ Toplevel Org headlines- } deriving (Show, Eq, Generic)--instance A.ToJSON Document where-instance A.FromJSON Document where--newtype LevelDepth = LevelDepth Int- deriving (Eq, Show, Num)--data TitleMeta = TitleMeta Text (Maybe Stats) (Maybe [Tag])- deriving (Eq, Show)--data Heading = Heading- { level :: Level -- ^ Org headline nesting level (1 is at the top)- , keyword :: Maybe StateKeyword -- ^ State of the headline (e.g. TODO, DONE)- , priority :: Maybe Priority --- , title :: Text -- properties- , stats :: Maybe Stats --- , tags :: [Tag] --- , section :: Section -- Next-line- , subHeadings :: [Heading] -- elements- } deriving (Show, Eq, Generic)--newtype Level = Level Int deriving (Eq, Show, Num, Generic)--type Properties = HashMap Text Text-type Clock = (Maybe Timestamp, Maybe Duration)--data Section = Section {- sectionPlannings :: Plannings- , sectionClocks :: [Clock]- , sectionProperties :: Properties- , sectionParagraph :: Text- } deriving (Show, Eq, Generic)---data Timestamp = Timestamp {- tsTime :: DateTime- , tsActive :: Bool- , tsEndTime :: Maybe DateTime- } deriving (Show, Eq, Generic)--instance A.ToJSON Timestamp where-instance A.FromJSON Timestamp where---newtype YearMonthDay' = YMD' YearMonthDay- deriving (Show, Eq, Generic)--instance A.ToJSON YearMonthDay' where- toJSON (YMD' (YearMonthDay y m d)) =- A.object ["ymdYear" .= y- ,"ymdMonth" .= m- ,"ymdDay" .= d]--instance A.FromJSON YearMonthDay' where- parseJSON (A.Object v) = do- y <- v .: "ymdYear"- m <- v .: "ymdMonth"- d <- v .: "ymdDay"- return (YMD' (YearMonthDay y m d))- parseJSON _ = mzero--data DateTime = DateTime {- yearMonthDay :: YearMonthDay'- , dayName :: Maybe Text- , hourMinute :: Maybe (Hour,Minute)- , repeater :: Maybe Repeater- , delay :: Maybe Delay- } deriving (Show, Eq, Generic)--instance A.ToJSON DateTime where-instance A.FromJSON DateTime where--data RepeaterType = RepeatCumulate | RepeatCatchUp | RepeatRestart- deriving (Show, Eq, Generic)--instance A.ToJSON RepeaterType-instance A.FromJSON RepeaterType--data Repeater = Repeater {- repeaterType :: RepeaterType- , repeaterValue :: Int- , repeaterUnit :: TimeUnit- } deriving (Show, Eq, Generic)--instance A.ToJSON Repeater where-instance A.FromJSON Repeater where--data DelayType = DelayAll | DelayFirst- deriving (Show, Eq, Generic)--instance A.ToJSON DelayType where-instance A.FromJSON DelayType where--data Delay = Delay {- delayType :: DelayType- , delayValue :: Int- , delayUnit :: TimeUnit- } deriving (Show, Eq, Generic)--instance A.ToJSON Delay where-instance A.FromJSON Delay where--data TimeUnit = UnitYear- | UnitWeek- | UnitMonth- | UnitDay- | UnitHour- deriving (Show, Eq, Generic)--instance A.ToJSON TimeUnit where-instance A.FromJSON TimeUnit where--------------------------------------------------------------------------------instance A.ToJSON Document where---instance A.FromJSON Document where--instance A.ToJSON Level where-instance A.FromJSON Level where--newtype StateKeyword = StateKeyword {unStateKeyword :: Text}- deriving (Show, Eq, Generic)--instance A.ToJSON StateKeyword where-instance A.FromJSON StateKeyword where---data PlanningKeyword = SCHEDULED | DEADLINE | CLOSED- deriving (Show, Eq, Enum, Ord, Generic)--instance A.ToJSON PlanningKeyword where-instance A.FromJSON PlanningKeyword where----instance (A.ToJSON k, A.ToJSON v) => A.ToJSON (HashMap k v) where--- toJSON hm = A.object hm--newtype Plannings = Plns (HashMap PlanningKeyword Timestamp)- deriving (Show, Eq, Generic)--instance A.ToJSON Plannings where- toJSON (Plns hm) = A.object $ map jPair (toList hm)- where jPair (k, v) = pack (show k) .= A.toJSON v--instance A.FromJSON Plannings where- parseJSON (A.Object v) = Plns . fromList <$> (traverse jPair (keys v))- where jPair k = v .: k- parseJSON _ = mzero--instance A.ToJSON Section where-instance A.FromJSON Section where--instance A.ToJSON Heading where-instance A.FromJSON Heading where--data Priority = A | B | C- deriving (Show, Read, Eq, Ord, Generic)--instance A.ToJSON Priority where-instance A.FromJSON Priority where-type Tag = Text--data Stats = StatsPct Int- | StatsOf Int Int- deriving (Show, Eq, Generic)--instance A.ToJSON Stats where-instance A.FromJSON Stats where--type Duration = (Hour,Minute)--instance Hashable PlanningKeyword where- hashWithSalt salt k = hashWithSalt salt (fromEnum k)---- -- This might be the form to use if we were supporting <diary> timestamps--- data Timestamp = Dairy Text--- | Time TimestampTime--- deriving (Show, Eq, Generic)---
+ src/Data/OrgMode/Types.hs view
@@ -0,0 +1,310 @@+{-|+Module : Data.OrgMode.Types+Copyright : © 2014 Parnell Springmeyer+License : All Rights Reserved+Maintainer : Parnell Springmeyer <parnell@digitalmentat.com>+Stability : experimental++Types for the AST of an org-mode document.+-}++{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE OverloadedStrings #-}++{-# OPTIONS -fno-warn-orphans #-}++module Data.OrgMode.Types+( ActiveState (..)+, BracketedDateTime (..)+, Clock (..)+, DateTime (..)+, Delay (..)+, DelayType (..)+, Depth (..)+, Document (..)+, Drawer (..)+, Duration+, Headline (..)+, Logbook (..)+, PlanningKeyword (..)+, Plannings (..)+, Priority (..)+, Properties (..)+, Repeater (..)+, RepeaterType (..)+, Section (..)+, StateKeyword (..)+, Stats (..)+, Tag+, TimePart (..)+, TimeUnit (..)+, Timestamp (..)+, YearMonthDay (..)+) where++import Control.Monad (mzero)+import Data.Aeson ((.:), (.=))+import qualified Data.Aeson as Aeson+import Data.Hashable (Hashable (..))+import Data.HashMap.Strict (HashMap, fromList, keys, toList)+import Data.Text (Text, pack)+import Data.Thyme.Calendar (YearMonthDay (..))+import Data.Thyme.LocalTime (Hour, Hours, Minute, Minutes)+import GHC.Generics++-- | Org-mode document.+data Document = Document+ { documentText :: Text -- ^ Text occurring before any Org headlines+ , documentHeadlines :: [Headline] -- ^ Toplevel Org headlines+ } deriving (Show, Eq, Generic)++instance Aeson.ToJSON Document+instance Aeson.FromJSON Document++-- | Headline within an org-mode document.+data Headline = Headline+ { depth :: Depth -- ^ Org headline nesting depth (1 is at the top), e.g: * or ** or ***+ , stateKeyword :: Maybe StateKeyword -- ^ State of the headline, e.g: TODO, DONE+ , priority :: Maybe Priority -- ^ Headline priority, e.g: [#A]+ , title :: Text -- ^ Primary text of the headline+ , timestamp :: Maybe Timestamp -- ^ A timestamp that may be embedded in the headline+ , stats :: Maybe Stats -- ^ Fraction of subtasks completed, e.g: [33%] or [1/2]+ , tags :: [Tag] -- ^ Tags on the headline+ , section :: Section -- ^ The body underneath a headline+ , subHeadlines :: [Headline] -- ^ A list of sub-headlines+ } deriving (Show, Eq, Generic)++-- | Headline nesting depth.+newtype Depth = Depth Int+ deriving (Eq, Show, Num, Generic)++instance Aeson.ToJSON Depth+instance Aeson.FromJSON Depth++-- | Section of text directly following a headline.+data Section = Section+ { sectionTimestamp :: Maybe Timestamp -- ^ A headline's section timestamp+ , sectionPlannings :: Plannings -- ^ A map of planning timestamps+ , sectionClocks :: [Clock] -- ^ A list of clocks+ , sectionProperties :: Properties -- ^ A map of properties from the :PROPERTY: drawer+ , sectionLogbook :: Logbook -- ^ A list of clocks from the :LOGBOOK: drawer+ , sectionDrawers :: [Drawer] -- ^ A list of parsed user-defined drawers+ , sectionParagraph :: Text -- ^ Arbitrary text+ } deriving (Show, Eq, Generic)++newtype Properties = Properties { unProperties :: HashMap Text Text }+ deriving (Show, Eq, Generic, Monoid)++instance Aeson.ToJSON Properties+instance Aeson.FromJSON Properties++newtype Logbook = Logbook { unLogbook :: [Clock] }+ deriving (Show, Eq, Generic, Monoid)++instance Aeson.ToJSON Logbook+instance Aeson.FromJSON Logbook++data Drawer = Drawer+ { name :: Text+ , contents :: Text+ } deriving (Show, Eq, Generic)++instance Aeson.ToJSON Drawer+instance Aeson.FromJSON Drawer++-- | Sum type indicating the active state of a timestamp.+data ActiveState+ = Active+ | Inactive+ deriving (Show, Eq, Read, Generic)++instance Aeson.ToJSON ActiveState+instance Aeson.FromJSON ActiveState++newtype Clock = Clock { unClock :: (Maybe Timestamp, Maybe Duration) }+ deriving (Show, Eq, Generic)++instance Aeson.ToJSON Clock+instance Aeson.FromJSON Clock++-- | A generic data type for parsed org-mode time stamps, e.g:+--+-- > <2015-03-27 Fri 10:20>+-- > [2015-03-27 Fri 10:20 +4h]+-- > <2015-03-27 Fri 10:20>--<2015-03-28 Sat 10:20>+data Timestamp = Timestamp+ { tsTime :: DateTime -- ^ A datetime stamp+ , tsActive :: ActiveState -- ^ Active or inactive?+ , tsEndTime :: Maybe DateTime -- ^ A end-of-range datetime stamp+ } deriving (Show, Eq, Generic)++instance Aeson.ToJSON Timestamp+instance Aeson.FromJSON Timestamp++instance Aeson.ToJSON YearMonthDay where+ toJSON (YearMonthDay y m d) =+ Aeson.object+ [ "ymdYear" .= y+ , "ymdMonth" .= m+ , "ymdDay" .= d+ ]++instance Aeson.FromJSON YearMonthDay where+ parseJSON (Aeson.Object v) = do+ y <- v .: "ymdYear"+ m <- v .: "ymdMonth"+ d <- v .: "ymdDay"+ pure (YearMonthDay y m d)+ parseJSON _ = mzero+++type Weekday = Text+type AbsTime = (Hours, Minutes)++-- | A data type for parsed org-mode bracketed datetime stamps, e.g:+--+-- > [2015-03-27 Fri 10:20 +4h]+data BracketedDateTime = BracketedDateTime+ { datePart :: YearMonthDay+ , dayNamePart :: Maybe Weekday+ , timePart :: Maybe TimePart+ , repeat :: Maybe Repeater+ , delayPart :: Maybe Delay+ , activeState :: ActiveState+ } deriving (Show, Eq)++-- | A sum type representing an absolute time part of a bracketed+-- org-mode datetime stamp or a time range between two absolute+-- timestamps.+data TimePart+ = AbsoluteTime AbsTime+ | TimeStampRange (AbsTime, AbsTime)+ deriving (Eq, Ord, Show)++-- | A data type for parsed org-mode datetime stamps.+--+-- TODO: why do we have this data type and BracketedDateTime? They+-- look almost exactly the same...+data DateTime = DateTime {+ yearMonthDay :: YearMonthDay+ , dayName :: Maybe Text+ , hourMinute :: Maybe (Hour,Minute)+ , repeater :: Maybe Repeater+ , delay :: Maybe Delay+ } deriving (Show, Eq, Generic)++instance Aeson.ToJSON DateTime+instance Aeson.FromJSON DateTime++-- | A sum type representing the repeater type of a repeater interval+-- in a org-mode timestamp.+data RepeaterType+ = RepeatCumulate+ | RepeatCatchUp+ | RepeatRestart+ deriving (Show, Eq, Generic)++instance Aeson.ToJSON RepeaterType+instance Aeson.FromJSON RepeaterType++-- | A data type representing a repeater interval in a org-mode+-- timestamp.+data Repeater = Repeater+ { repeaterType :: RepeaterType -- ^ Type of repeater+ , repeaterValue :: Int -- ^ Repeat value+ , repeaterUnit :: TimeUnit -- ^ Repeat time unit+ } deriving (Show, Eq, Generic)++instance Aeson.ToJSON Repeater+instance Aeson.FromJSON Repeater++-- | A sum type representing the delay type of a delay value.+data DelayType+ = DelayAll+ | DelayFirst+ deriving (Show, Eq, Generic)++instance Aeson.ToJSON DelayType+instance Aeson.FromJSON DelayType++-- | A data type representing a delay value.+data Delay = Delay+ { delayType :: DelayType -- ^ Type of delay+ , delayValue :: Int -- ^ Delay value+ , delayUnit :: TimeUnit -- ^ Delay time unit+ } deriving (Show, Eq, Generic)++instance Aeson.ToJSON Delay+instance Aeson.FromJSON Delay++-- | A sum type representing the time units of a delay.+data TimeUnit+ = UnitYear+ | UnitWeek+ | UnitMonth+ | UnitDay+ | UnitHour+ deriving (Show, Eq, Generic)++instance Aeson.ToJSON TimeUnit+instance Aeson.FromJSON TimeUnit++-- | A type representing a headline state keyword, e.g: @TODO@,+-- @DONE@, @WAITING@, etc.+newtype StateKeyword = StateKeyword {unStateKeyword :: Text}+ deriving (Show, Eq, Generic)++instance Aeson.ToJSON StateKeyword+instance Aeson.FromJSON StateKeyword++-- | A sum type representing the planning keywords.+data PlanningKeyword = SCHEDULED | DEADLINE | CLOSED+ deriving (Show, Eq, Enum, Ord, Generic)++instance Aeson.ToJSON PlanningKeyword+instance Aeson.FromJSON PlanningKeyword++-- | A type representing a map of planning timestamps.+newtype Plannings = Plns (HashMap PlanningKeyword Timestamp)+ deriving (Show, Eq, Generic)++instance Aeson.ToJSON Plannings where+ toJSON (Plns hm) = Aeson.object $ map jPair (toList hm)+ where jPair (k, v) = pack (show k) .= Aeson.toJSON v++instance Aeson.FromJSON Plannings where+ parseJSON (Aeson.Object v) = Plns . fromList <$> (traverse jPair (keys v))+ where jPair k = v .: k+ parseJSON _ = mzero++instance Aeson.ToJSON Section+instance Aeson.FromJSON Section++instance Aeson.ToJSON Headline+instance Aeson.FromJSON Headline++-- | A sum type representing the three default priorities: @A@, @B@,+-- and @C@.+data Priority = A | B | C+ deriving (Show, Read, Eq, Ord, Generic)++instance Aeson.ToJSON Priority+instance Aeson.FromJSON Priority+type Tag = Text++-- | A data type representing a stats value in a headline, e.g @[2/3]@+-- in this headline:+--+-- > * TODO [2/3] work on orgmode-parse+data Stats = StatsPct Int+ | StatsOf Int Int+ deriving (Show, Eq, Generic)++instance Aeson.ToJSON Stats+instance Aeson.FromJSON Stats++type Duration = (Hour,Minute)++instance Hashable PlanningKeyword where+ hashWithSalt salt k = hashWithSalt salt (fromEnum k)
+ test/Document.hs view
@@ -0,0 +1,99 @@+{-# LANGUAGE OverloadedStrings #-}++module Document where++import Data.Attoparsec.Text+import Data.Text+import qualified Data.Text as Text+import qualified Data.Text.IO as TextIO+import Test.Tasty+import Test.Tasty.HUnit++import Data.OrgMode.Parse.Attoparsec.Document+import Data.OrgMode.Parse.Attoparsec.Time+import Data.OrgMode.Types+import Util++parserSmallDocumentTests :: TestTree+parserSmallDocumentTests = testGroup "Attoparsec Small Document"+ [ testCase "Parse Empty Document" $+ testDocS "" (Document "" [])++ , testCase "Parse No Headline" $+ testDocS pText (Document pText [])++ , testCase "Parse Headline Sample A" $+ testDocS sampleAText sampleAParse++ , testCase "Parse Headline with Planning" $+ testDocS samplePText samplePParse++ , testCase "Parse Headline no \n" $+ testDocS "* T" (Document "" [emptyHeadline {title="T"}])++ , testCase "Parse Document from File" $+ testDocFile+ ]++ where+ testDocS s r = expectParse (parseDocument kw) s (Right r)+ testDocFile = do+ doc <- TextIO.readFile "test/test-document.org"+ assertBool "Expected to parse document" . parseSucceeded $ parseOnly (parseDocument kw) doc+ kw = ["TODO", "CANCELED", "DONE"]+ pText = "Paragraph text\n.No headline here.\n##--------\n"+ parseSucceeded (Right _) = True+ parseSucceeded (Left _ ) = False++sampleAText :: Text+sampleAText = Text.concat [sampleParagraph,"* Test1", spaces 20,":Hi there:\n"+ ,"*\n"+ ," *\n"+ ,"* Test2 :Two:Tags:\n"+ ]+sampleAParse :: Document+sampleAParse = Document+ sampleParagraph+ [emptyHeadline {title="Test1", tags=["Hi there"]}+ ,emptyHeadline {section=emptySection{sectionParagraph=" *\n"}}+ ,emptyHeadline {title="Test2", tags=["Two","Tags"]}+ ]++samplePText :: Text+samplePText = Text.concat ["* Test3\n"+ ," SCHEDULED: <2015-06-12 Fri>"+ ]++samplePParse :: Document+samplePParse = Document+ ""+ [emptyHeadline {title="Test3",section=emptySection{sectionPlannings=plns}}+ ]+ where+ plns :: Plannings+ plns = Plns con++ Right con = parseOnly parsePlannings "SCHEDULED: <2015-06-12 Fri>"++emptyHeadline :: Headline+emptyHeadline =+ Headline+ { depth = 1+ , stateKeyword = Nothing+ , priority = Nothing+ , title = ""+ , stats = Nothing+ , timestamp = Nothing+ , tags = []+ , section = emptySection+ , subHeadlines = []+ }++sampleParagraph :: Text+sampleParagraph = "This is some sample text in a paragraph which may contain * , : , and other special characters.\n\n"++spaces :: Int -> Text+spaces = flip Text.replicate " "++emptySection :: Section+emptySection = Section Nothing (Plns mempty) mempty mempty mempty mempty mempty
+ test/Drawer.hs view
@@ -0,0 +1,37 @@+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RankNTypes #-}++module Drawer where++import Data.OrgMode.Parse+import Test.Tasty+import Test.Tasty.HUnit++import Util++parserDrawerTests :: TestTree+parserDrawerTests = testGroup "Attoparsec PropertyDrawer"+ [ testCase "Parse a :PROPERTY: drawer" $+ testPropertyDrawer++ , testCase "Parse empty :PROPERTY: drawer" $+ (testParser parseProperties ":PROPERTIES:\n:END:\n")++ , testCase "Parse a :LOGBOOK: drawer" $+ testLogbookDrawer++ , testCase "Parse a user-defined drawer" $+ testGenericDrawer+ ]++testPropertyDrawer :: Assertion+testPropertyDrawer =+ testParser parseProperties ":PROPERTIES:\n :URL: http://someurl.com?query\n :notes: you should be taking them\n:END:\n"++testLogbookDrawer :: Assertion+testLogbookDrawer =+ testParser parseLogbook ":LOGBOOK:\n CLOCK: [2015-10-05 Mon 17:13] \n CLOCK: [2015-10-05 Mon 17:13]--[2015-10-05 Mon 17:14] => 0:01\n:END:\n"++testGenericDrawer :: Assertion+testGenericDrawer =+ testParser parseDrawer ":MYDRAWER:\n whatever I want can go in here, technically... \n:END:\n"
+ test/Headline.hs view
@@ -0,0 +1,26 @@+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RankNTypes #-}++module Headline where++import Data.OrgMode.Parse+import Test.Tasty+import Test.Tasty.HUnit++import Util++parserHeadlineTests :: TestTree+parserHeadlineTests = testGroup "Attoparsec Headline"+ [ (testCase "Parse Headline Bare" $ testHeadline "* This is a title\n")+ , (testCase "Parse Headline Bare with end colon" $ testHeadline "* This heading ends in a colon:")+ , (testCase "Parse Headline Bare w/ Depths" $ testHeadline "*** This is a title\n")+ , (testCase "Parse Headline w/ Priority" $ testHeadline "* [#A] An important heading\n")+ , (testCase "Parse Headline w/ Priority & State" $ testHeadline "* TODO [#A] An important heading with a state indicator\n")+ , (testCase "Parse Headline w/ State" $ testHeadline "* CANCELED An important heading with just state\n")+ , (testCase "Parse Headline w/ Keywords" $ testHeadline "* An important heading :WITH:KEYWORDS:\n")+ , (testCase "Parse Headline Full" $ testHeadline "* DONE [#B] A heading : with [[http://somelink.com][a link]] :WITH:KEYWORDS:\n")+ , (testCase "Parse Headline All But Title" $ testHeadline "* DONE [#A] :WITH:KEYWORDS:\n")+ , (testCase "Parse Headline w/ Timestamp" $ testHeadline "* TODO [#A] Pickup groceris on <2017-08-24 22:00>\n")+ ]+ where+ testHeadline = testParser (headlineBelowDepth ["TODO","CANCELED","DONE"] 0)
test/Test.hs view
@@ -3,11 +3,11 @@ module Main where -import Headings-import PropertyDrawer+import Document+import Drawer+import Headline import Test.Tasty import Timestamps-import Document main :: IO () main = defaultMain tests@@ -15,8 +15,8 @@ tests :: TestTree tests = testGroup "OrgMode Parser Tests"- [ parserHeadingTests- , parserPropertyDrawerTests+ [ parserHeadlineTests+ , parserDrawerTests , parserTimestampTests , parserSmallDocumentTests , parserWeekdayTests
+ test/Timestamps.hs view
@@ -0,0 +1,65 @@+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RankNTypes #-}++module Timestamps where++import Control.Applicative ((<*))+import Data.Attoparsec.Text (endOfLine)+import Data.HashMap.Strict+import Data.Monoid ((<>))+import Data.OrgMode.Parse+import qualified Data.Text as T+import Test.Tasty+import Test.Tasty.HUnit+import Weekdays (weekdays)++import Data.OrgMode.Types+import Util++parserPlanningTests :: TestTree+parserPlanningTests = testGroup "Attoparsec Planning"+ [ (testCase "Parse Planning Schedule" $ testPlanning "SCHEDULED: <2004-02-29 Sun>")+ , (testCase "Parse Planning Deadline" $ testPlanning "DEADLINE: <2004-02-29 Sun>")+ , (testCase "Parse Planning Full" $ testPlanning "SCHEDULED: <2004-02-29 Sun +1w>")+ , (testCase "Parse Sample Schedule" $ testPlanningS sExampleStrA sExampleResA)+ ]+ where+ testPlanning t = testParser parsePlannings t+ testPlanningS t r = expectParse parsePlannings t (Right r)++ (sExampleStrA, sExampleResA) =+ ("SCHEDULED: <2004-02-29 Sun 10:20 +1w -2d>"+ ,(fromList [(SCHEDULED, Timestamp+ (DateTime+ (YearMonthDay 2004 2 29)+ (Just "Sun")+ (Just (10,20))+ (Just (Repeater RepeatCumulate 1 UnitWeek))+ (Just (Delay DelayAll 2 UnitDay))+ ) Active Nothing)]))++parserTimestampTests :: TestTree+parserTimestampTests = testGroup "Attoparsec Timestamp"+ [ (testCase "Parse Timestamp Appointment" $ testTimestamp "<2004-02-29 Sun>\n")+ , (testCase "Parse Timestamp Recurring" $ testTimestamp "<2004-02-29 Sun +1w>\n")+ ]+ where+ testTimestamp t = testParser (parseTimestamp <* endOfLine) t+++parserWeekdayTests :: TestTree+parserWeekdayTests = testGroup "Attoparsec Weekday"+ [testCase ("Parse Weekday in " ++ loc) $ mkTest w+ | (loc,ws) <- weekdays, w <- ws, isOrgParsable w]+ where+ dayChars = "]+0123456789>\r\n -" :: String+ isOrgParsable w = T.find (\c -> c `elem` dayChars) w == Nothing+ mkTest w = expectParse parseTimestamp str (Right res)+ where+ str = "<2004-02-29 " <> w <> " 10:20>"+ res = Timestamp (DateTime+ (YearMonthDay 2004 2 29)+ (Just w)+ (Just (10,20))+ Nothing+ Nothing) Active Nothing
+ test/Util.hs view
@@ -0,0 +1,25 @@+module Util where++import Data.Attoparsec.Text+import Data.Attoparsec.Types as TP+import Data.Either+import Data.Text as T+import Test.HUnit++testParser :: (TP.Parser Text a) -> String -> Assertion+testParser f v = fromEither (parseOnly f $ T.pack v)++expectParse :: (Eq a, Show a) => TP.Parser Text a -- ^ Parser under test+ -> Text -- ^ Message under test+ -> Either String a -- ^ Expected parse result+ -> Assertion+expectParse p t (Left _) = assertBool "Expected parse failure"+ (isLeft (parseOnly p t))+expectParse p t a = assertBool msg (r == a)+ where r = parseOnly p t+ msg = Prelude.unwords+ ["Expected parse to", show a, ". Got", show r]++fromEither :: Either String a -> Assertion+fromEither (Left e) = assertBool e False+fromEither (Right _) = assertBool "" True
+ test/Weekdays.hs view
@@ -0,0 +1,267 @@+{-# LANGUAGE OverloadedStrings #-}+module Weekdays where++import qualified Data.Text as T++weekdays :: [(String, [T.Text])]+weekdays = [+ ("aa_DJ.UTF-8", ["kam", "gum", "sab", "aca", "etl", "tal", "arb"]),+ ("aa_ER", ["Kam", "Gum", "Sab", "Aca", "Etl", "Tal", "Arb"]),+ ("aa_ER@saaho", ["Cam", "Jum", "Qun", "Nab", "San", "Sal", "Rab"]),+ ("aa_ET", ["Kam", "Gum", "Sab", "Aca", "Etl", "Tal", "Arb"]),+ ("af_ZA.UTF-8", ["Do", "Vr", "Sa", "So", "Ma", "Di", "Wo"]),+ ("am_ET", ["ሐሙስ", "ዓርብ", "ቅዳሜ", "እሑድ", "ሰኞ ", "ማክሰ", "ረቡዕ"]),+ ("an_ES.UTF-8", ["chu", "bie", "sab", "dom", "lun", "mar", "mie"]),+ ("ar_AE.UTF-8", ["خ", "ج", "س", "ح", "ن", "ث", "ر"]),+ ("ar_BH.UTF-8", ["خ", "ج", "س", "ح", "ن", "ث", "ر"]),+ ("ar_DZ.UTF-8", ["خ", "ج", "س", "ح", "ن", "ث", "ر"]),+ ("ar_EG.UTF-8", ["خ", "ج", "س", "ح", "ن", "ث", "ر"]),+ ("ar_IN", ["خ", "ج", "س", "ح", "ن", "ث", "ر"]),+ ("ar_IQ.UTF-8", ["خ", "ج", "س", "ح", "ن", "ث", "ر"]),+ ("ar_JO.UTF-8", ["الخميس", "الجمعة", "السبت", "الأحد", "الاثنين", "الثلاثاء", "الأربعاء"]),+ ("ar_KW.UTF-8", ["خ", "ج", "س", "ح", "ن", "ث", "ر"]),+ ("ar_LB.UTF-8", ["الخميس", "الجمعة", "السبت", "الأحد", "الاثنين", "الثلاثاء", "الأربعاء"]),+ ("ar_LY.UTF-8", ["خ", "ج", "س", "ح", "ن", "ث", "ر"]),+ ("ar_MA.UTF-8", ["خ", "ج", "س", "ح", "ن", "ث", "ر"]),+ ("ar_OM.UTF-8", ["خ", "ج", "س", "ح", "ن", "ث", "ر"]),+ ("ar_QA.UTF-8", ["خ", "ج", "س", "ح", "ن", "ث", "ر"]),+ ("ar_SA.UTF-8", ["Thu", "Fri", "Sat", "Sun", "Mon", "Tue", "Wed"]),+ ("ar_SD.UTF-8", ["خ", "ج", "س", "ح", "ن", "ث", "ر"]),+ ("ar_SY.UTF-8", ["الخميس", "الجمعة", "السبت", "الأحد", "الاثنين", "الثلاثاء", "الأربعاء"]),+ ("ar_TN.UTF-8", ["خ", "ج", "س", "ح", "ن", "ث", "ر"]),+ ("ar_YE.UTF-8", ["خ", "ج", "س", "ح", "ن", "ث", "ر"]),+ ("az_AZ.UTF-8", ["cax", "cüm", "şnb", "baz", "ber", "çax", "çər"]),+ ("as_IN.UTF-8", ["বৃহষ্পতি", "শুক্ৰ", "শনি", "দেও", "সোম", "মঙ্গল", "বুধ"]),+ ("ast_ES.UTF-8", ["xue", "vie", "sáb", "dom", "llu", "mar", "mié"]),+ ("be_BY.UTF-8", ["Чцв", "Пят", "Суб", "Няд", "Пан", "Аўт", "Срд"]),+ ("be_BY@latin", ["Čać", "Pia", "Sub", "Nia", "Pan", "Aŭt", "Sie"]),+ ("bem_ZM", ["Thu", "Fri", "Sat", "Sun", "Mon", "Tue", "Wed"]),+ ("ber_DZ", ["dör", "beş", "alt", "baz", "bir", "iki", "üçü"]),+ ("ber_MA", ["dör", "beş", "alt", "baz", "bir", "iki", "üçü"]),+ ("bg_BG.UTF-8", ["чт", "пт", "сб", "нд", "пн", "вт", "ср"]),+ ("bn_BD", ["বৃহঃ", "শুক্র", "শনি", "রবি", "সোম", "মঙ্গল", "বুধ"]),+ ("bn_IN", ["বৃহস্পতি", "শুক্র", "শনি", "রবি", "সোম", "মঙ্গল", "বুধ"]),+ ("bo_CN", ["པུར་", "སངས་", "སྤེན་", "ཉི་", "ཟླ་", "མིར་", "ལྷག་"]),+ ("bo_IN", ["པུར་", "སངས་", "སྤེན་", "ཉི་", "ཟླ་", "མིར་", "ལྷག་"]),+ ("br_FR.UTF-8", ["yao", "gwe", "sad", "sul", "lun", "meu", "mer"]),+ ("bs_BA.UTF-8", ["Čet", "Pet", "Sub", "Ned", "Pon", "Uto", "Sri"]),+ ("byn_ER", ["ኣምድ", "ኣርብ", "ሰ/ሽ", "ሰ/ቅ", "ሰኑ", "ሰሊጝ", "ለጓ"]),+ ("ca_AD.UTF-8", ["dj", "dv", "ds", "dg", "dl", "dt", "dc"]),+ ("ca_ES.UTF-8", ["dj", "dv", "ds", "dg", "dl", "dt", "dc"]),+ ("ca_ES.UTF-8@valencia", ["dj", "dv", "ds", "dg", "dl", "dt", "dc"]),+ ("ca_FR.UTF-8", ["dj", "dv", "ds", "dg", "dl", "dt", "dc"]),+ ("ca_IT.UTF-8", ["dj", "dv", "ds", "dg", "dl", "dt", "dc"]),+ ("crh_UA", ["Caq", "Cum", "Cer", "Baz", "Ber", "Sal", "Çar"]),+ ("cs_CZ.UTF-8", ["Čt", "Pá", "So", "Ne", "Po", "Út", "St"]),+ ("csb_PL", ["czw", "pią", "sob", "nie", "pòn", "wtó", "str"]),+ ("cv_RU", ["kş", "er", "šm", "vr", "tn", "yt", "jn"]),+ ("cy_GB.UTF-8", ["Iau", "Gwe", "Sad", "Sul", "Llu", "Maw", "Mer"]),+ ("da_DK.UTF-8", ["tor", "fre", "lør", "søn", "man", "tir", "ons"]),+ ("de_AT.UTF-8", ["Don", "Fre", "Sam", "Son", "Mon", "Die", "Mit"]),+ ("de_BE.UTF-8", ["Don", "Fre", "Sam", "Son", "Mon", "Die", "Mit"]),+ ("de_CH.UTF-8", ["Don", "Fre", "Sam", "Son", "Mon", "Die", "Mit"]),+ ("de_DE.UTF-8", ["Do", "Fr", "Sa", "So", "Mo", "Di", "Mi"]),+ ("de_LI.UTF-8", ["Don", "Fre", "Sam", "Son", "Mon", "Die", "Mit"]),+ ("de_LU.UTF-8", ["Don", "Fre", "Sam", "Son", "Mon", "Die", "Mit"]),+ ("dv_MV", ["ބުރާސްފަތި", "ހުކުރު", "ހޮނިހިރު", "އާދީއްތަ", "ހޯމަ", "އަންގާރަ", "ބުދަ"]),+ ("dz_BT", ["སངས་", "སྤེན་", "ཉི་", "ཟླ་", "མིར་", "ལྷག་", "པུར་"]),+ ("el_GR.UTF-8", ["Πεμ", "Παρ", "Σαβ", "Κυρ", "Δευ", "Τρι", "Τετ"]),+ ("el_CY.UTF-8", ["Πεμ", "Παρ", "Σαβ", "Κυρ", "Δευ", "Τρι", "Τετ"]),+ ("en_AG", ["Thu", "Fri", "Sat", "Sun", "Mon", "Tue", "Wed"]),+ ("en_AU.UTF-8", ["Thu", "Fri", "Sat", "Sun", "Mon", "Tue", "Wed"]),+ ("en_BW.UTF-8", ["Thu", "Fri", "Sat", "Sun", "Mon", "Tue", "Wed"]),+ ("en_CA.UTF-8", ["Thu", "Fri", "Sat", "Sun", "Mon", "Tue", "Wed"]),+ ("en_DK.UTF-8", ["Thu", "Fri", "Sat", "Sun", "Mon", "Tue", "Wed"]),+ ("en_GB.UTF-8", ["Thu", "Fri", "Sat", "Sun", "Mon", "Tue", "Wed"]),+ ("en_HK.UTF-8", ["Thu", "Fri", "Sat", "Sun", "Mon", "Tue", "Wed"]),+ ("en_IE.UTF-8", ["Thu", "Fri", "Sat", "Sun", "Mon", "Tue", "Wed"]),+ ("en_IN", ["Thu", "Fri", "Sat", "Sun", "Mon", "Tue", "Wed"]),+ ("en_NG", ["Thu", "Fri", "Sat", "Sun", "Mon", "Tue", "Wed"]),+ ("en_NZ.UTF-8", ["Thu", "Fri", "Sat", "Sun", "Mon", "Tue", "Wed"]),+ ("en_PH.UTF-8", ["Thu", "Fri", "Sat", "Sun", "Mon", "Tue", "Wed"]),+ ("en_SG.UTF-8", ["Thu", "Fri", "Sat", "Sun", "Mon", "Tue", "Wed"]),+ ("en_US.UTF-8", ["Thu", "Fri", "Sat", "Sun", "Mon", "Tue", "Wed"]),+ ("en_ZA.UTF-8", ["Thu", "Fri", "Sat", "Sun", "Mon", "Tue", "Wed"]),+ ("en_ZM", ["Thu", "Fri", "Sat", "Sun", "Mon", "Tue", "Wed"]),+ ("en_ZW.UTF-8", ["Thu", "Fri", "Sat", "Sun", "Mon", "Tue", "Wed"]),+ ("eo.UTF-8", ["ĵaŭ", "ven", "sab", "dim", "lun", "mar", "mer"]),+ ("es_AR.UTF-8", ["jue", "vie", "sáb", "dom", "lun", "mar", "mié"]),+ ("es_BO.UTF-8", ["jue", "vie", "sáb", "dom", "lun", "mar", "mié"]),+ ("es_CL.UTF-8", ["jue", "vie", "sáb", "dom", "lun", "mar", "mié"]),+ ("es_CO.UTF-8", ["jue", "vie", "sáb", "dom", "lun", "mar", "mié"]),+ ("es_CR.UTF-8", ["jue", "vie", "sáb", "dom", "lun", "mar", "mié"]),+ ("es_DO.UTF-8", ["jue", "vie", "sáb", "dom", "lun", "mar", "mié"]),+ ("es_EC.UTF-8", ["jue", "vie", "sáb", "dom", "lun", "mar", "mié"]),+ ("es_ES.UTF-8", ["jue", "vie", "sáb", "dom", "lun", "mar", "mié"]),+ ("es_GT.UTF-8", ["jue", "vie", "sáb", "dom", "lun", "mar", "mié"]),+ ("es_HN.UTF-8", ["jue", "vie", "sáb", "dom", "lun", "mar", "mié"]),+ ("es_MX.UTF-8", ["jue", "vie", "sáb", "dom", "lun", "mar", "mié"]),+ ("es_NI.UTF-8", ["jue", "vie", "sáb", "dom", "lun", "mar", "mié"]),+ ("es_PA.UTF-8", ["jue", "vie", "sáb", "dom", "lun", "mar", "mié"]),+ ("es_PE.UTF-8", ["jue", "vie", "sáb", "dom", "lun", "mar", "mié"]),+ ("es_PR.UTF-8", ["jue", "vie", "sáb", "dom", "lun", "mar", "mié"]),+ ("es_PY.UTF-8", ["jue", "vie", "sáb", "dom", "lun", "mar", "mié"]),+ ("es_SV.UTF-8", ["jue", "vie", "sáb", "dom", "lun", "mar", "mié"]),+ ("es_US.UTF-8", ["jue", "vie", "sáb", "dom", "lun", "mar", "mié"]),+ ("es_UY.UTF-8", ["jue", "vie", "sáb", "dom", "lun", "mar", "mié"]),+ ("es_VE.UTF-8", ["jue", "vie", "sáb", "dom", "lun", "mar", "mié"]),+ ("et_EE.UTF-8", ["N", "R", "L", "P", "E", "T", "K"]),+ ("eu_ES.UTF-8", ["og.", "or.", "lr.", "ig.", "al.", "ar.", "az."]),+ ("eu_FR.UTF-8", ["og.", "or.", "lr.", "ig.", "al.", "ar.", "az."]),+-- TODO: lexical error in Haskell+-- ("fa_IR", ["پنجشنبه", "جمعه", "شنبه", "یکشنبه", "دوشنبه", "سهشنبه", "چهارشنبه"]),+ ("ff_SN", ["naa", "mwd", "hbi", "dew", "aaɓ", "maw", "nje"]),+ ("fi_FI.UTF-8", ["to", "pe", "la", "su", "ma", "ti", "ke"]),+ ("fil_PH", ["Huw", "Biy", "Sab", "Lin", "Lun", "Mar", "Miy"]),+ ("fo_FO.UTF-8", ["hós", "frí", "ley", "sun", "mán", "týs", "mik"]),+ ("fr_BE.UTF-8", ["jeu", "ven", "sam", "dim", "lun", "mar", "mer"]),+ ("fr_CA.UTF-8", ["jeu", "ven", "sam", "dim", "lun", "mar", "mer"]),+ ("fr_CH.UTF-8", ["jeu", "ven", "sam", "dim", "lun", "mar", "mer"]),+ ("fr_FR.UTF-8", ["jeu.", "ven.", "sam.", "dim.", "lun.", "mar.", "mer."]),+ ("fr_LU.UTF-8", ["jeu", "ven", "sam", "dim", "lun", "mar", "mer"]),+ ("fur_IT", ["Joi", "Vin", "Sab", "Dom", "Lun", "Mar", "Mia"]),+ ("fy_NL", ["To", "Fr", "Sn", "Sn", "Mo", "Ti", "Wo"]),+ ("fy_DE", ["Ddg", "Fdg", "Swd", "Sdg", "Mdg", "Dsg", "Mwk"]),+ ("ga_IE.UTF-8", ["Déar", "Aoine", "Sath", "Domh", "Luan", "Máirt", "Céad"]),+ ("gd_GB.UTF-8", ["Diar", "Diha", "Disa", "Dido", "Dilu", "Dim", "Dic"]),+ ("gez_ER", ["ሐሙስ", "ዓርበ", "ቀዳሚ", "እኁድ", "ሰኑይ", "ሠሉስ", "ራብዕ"]),+ ("gez_ER@abegede", ["ሐሙስ", "ዓርበ", "ቀዳሚ", "እኁድ", "ሰኑይ", "ሠሉስ", "ራብዕ"]),+ ("gez_ET", ["ሐሙስ", "ዓርበ", "ቀዳሚ", "እኁድ", "ሰኑይ", "ሠሉስ", "ራብዕ"]),+ ("gez_ET@abegede", ["ሐሙስ", "ዓርበ", "ቀዳሚ", "እኁድ", "ሰኑይ", "ሠሉስ", "ራብዕ"]),+ ("gl_ES.UTF-8", ["Xov", "Ven", "Sáb", "Dom", "Lun", "Mar", "Mér"]),+ ("gu_IN", ["ગુરુ", "શુક્ર", "શનિ", "રવિ", "સોમ", "મંગળ", "બુધ"]),+ ("gv_GB.UTF-8", ["Jerd", "Jeh", "Jes", "Jed", "Jel", "Jem", "Jerc"]),+ ("ha_NG", ["Alh", "Jum", "Asa", "Lah", "Lit", "Tal", "Lar"]),+ ("he_IL.UTF-8", ["ה'", "ו'", "ש'", "א'", "ב'", "ג'", "ד'"]),+ ("hi_IN", ["गुरु ", "शुक्र ", "शनि ", "रवि ", "सोम ", "मंगल ", "बुध "]),+ ("hne_IN", ["बिर ", "सुक", "सनि", "इत ", "सोम ", "मंग ", "बुध "]),+ ("hr_HR.UTF-8", ["Čet", "Pet", "Sub", "Ned", "Pon", "Uto", "Sri"]),+ ("hsb_DE.UTF-8", ["Št", "Pj", "So", "Nj", "Pó", "Wu", "Sr"]),+ ("ht_HT", ["jEd.", "van.", "sam.", "dim.", "lEn.", "mad.", "mèk."]),+ ("hu_HU.UTF-8", ["cs", "p", "szo", "v", "h", "k", "sze"]),+ ("hy_AM", ["Հնգ", "Ուր", "Շբթ", "Կրկ", "Երկ", "Երք", "Չրք"]),+ ("ia", ["jov", "ven", "sab", "dom", "lun", "mar", "mer"]),+ ("id_ID.UTF-8", ["Kam", "Jum", "Sab", "Min", "Sen", "Sel", "Rab"]),+ ("ig_NG", ["tọs", "fra", "sat", "sọn", "mọn", "tuz", "wen"]),+ ("ik_CA", ["Sis", "Tal", "Maq", "Min", "Sav", "Ila", "Qit"]),+ ("is_IS.UTF-8", ["fim", "fös", "lau", "sun", "mán", "þri", "mið"]),+ ("it_CH.UTF-8", ["gio", "ven", "sab", "dom", "lun", "mar", "mer"]),+ ("it_IT.UTF-8", ["gio", "ven", "sab", "dom", "lun", "mar", "mer"]),+ ("iu_CA", ["ᕿ", "ᐅ", "ᓯ", "ᓈ", "ᓇ", "ᓕ", "ᐱ"]),+ ("iw_IL.UTF-8", ["ה'", "ו'", "ש'", "א'", "ב'", "ג'", "ד'"]),+ ("ja_JP.UTF-8", ["木", "金", "土", "日", "月", "火", "水"]),+ ("ka_GE.UTF-8", ["ხუთ", "პარ", "შაბ", "კვი", "ორშ", "სამ", "ოთხ"]),+ ("kk_KZ.UTF-8", ["Бс", "Жм", "Сн", "Жк", "Дс", "Сс", "Ср"]),+ ("kl_GL.UTF-8", ["sis", "tal", "arf", "sab", "ata", "mar", "pin"]),+ ("km_KH", ["ព្រ", "សុ", "ស", "អា", "ច", "អ", "ពុ"]),+ ("kn_IN", ["ಗು", "ಶು", "ಶ", "ರ", "ಸೋ", "ಮಂ", "ಬು"]),+ ("ko_KR.UTF-8", ["목", "금", "토", "일", "월", "화", "수"]),+ ("kok_IN", ["बेरेसतार", "शुकरार", "शेनवार", "आयतार", "सोमार", "मंगळवार", "बुधवार"]),+ ("ks_IN", ["برىسوار", "جمع", "بٹوار", "آتهوار", "ژءنتروار", "بوءںوار", "بودهوار"]),+ ("ks_IN@devanagari", ["ब्रस््", "जुम", "बट", "आथ्", "चन्दर्", "बोम्", "बोघ"]),+ ("ku_TR.UTF-8", ["Pş", "În", "Ş", "Yş", "Dş", "Sş", "Çş"]),+ ("kw_GB.UTF-8", ["Yow", "Gwe", "Sad", "Sul", "Lun", "Mth", "Mhr"]),+ ("ky_KG", ["бш", "жм", "иш", "жк", "дш", "ше", "ша"]),+ ("lg_UG.UTF-8", ["Lw4", "Lw5", "Lw6", "Sab", "Bal", "Lw2", "Lw3"]),+-- TODO: lexical error in Haskell+-- ("li_BE", ["dón", "vri", "zo", "zón", "mao", "dae", "goo"]),+-- ("li_NL", ["dón", "vri", "zo", "zón", "mao", "dae", "goo"]),+ ("lo_LA", ["ພຫ.", "ສ.", "ສ.", "ອາ.", "ຈ.", "ຄ.", "ພ."]),+ ("lt_LT.UTF-8", ["Kt", "Pn", "Št", "Sk", "Pr", "An", "Tr"]),+ ("lv_LV.UTF-8", ["C ", "Pk", "S ", "Sv", "P ", "O ", "T "]),+ ("mai_IN", ["गुरु ", "शुक्र ", "शनि ", "रवि ", "सोम ", "मंगल ", "बुध "]),+ ("mg_MG.UTF-8", ["lkm", "zom", "sab", "lhd", "lts", "tlt", "lrb"]),+ ("mi_NZ.UTF-8", ["Tāi", "Pa", "Hā", "Ta", "Ma", "Tū", "We"]),+ ("mk_MK.UTF-8", ["чет", "пет", "саб", "нед", "пон", "вто", "сре"]),+ ("ml_IN", ["വ്യാ", "വെ", "ശ", "ഞാ", "തി", "ചൊ", "ബു"]),+ ("mn_MN", ["Пү", "Ба", "Бя", "Ня", "Да", "Мя", "Лх"]),+ ("mr_IN", ["गुरु", "शुक्र", "शनि", "रवि", "सोम", "मंगळ", "बुध"]),+ ("ms_MY.UTF-8", ["Kha", "Jum", "Sab", "Ahd", "Isn", "Sel", "Rab"]),+ ("mt_MT.UTF-8", ["Ħam", "Ġim", "Sib", "Ħad", "Tne", "Tli", "Erb"]),+ ("my_MM", ["တေး", "သော", "နေ", "နွေ", "လာ", "ဂါ", "ဟူး"]),+ ("nan_TW@latin", ["p4", "p5", "p6", "lp", "p1", "p2", "p3"]),+ ("nb_NO.UTF-8", ["to.", "fr.", "lø.", "sø.", "ma.", "ti.", "on."]),+ ("nds_DE", ["Dunn", "Free", "Svd.", "Sdag", "Maan", "Ding", "Migg"]),+ ("nds_NL", ["Ddg", "Fdg", "Swd", "Sdg", "Mdg", "Dsg", "Mwk"]),+ ("ne_NP", ["बिहि ", "शुक्र ", "शनि ", "आइत ", "सोम ", "मंगल ", "बुध "]),+ ("nl_AW", ["do", "vr", "za", "zo", "ma", "di", "wo"]),+ ("nl_BE.UTF-8", ["do", "vr", "za", "zo", "ma", "di", "wo"]),+ ("nl_NL.UTF-8", ["do", "vr", "za", "zo", "ma", "di", "wo"]),+ ("nn_NO.UTF-8", ["to.", "fr.", "la.", "su.", "må.", "ty.", "on."]),+ ("nr_ZA", ["Ne", "Hla", "Gqi", "Son", "Mvu", "Bil", "Tha"]),+ ("nso_ZA", ["Ne", "Hla", "Mok", "Son", "Moš", "Bed", "Rar"]),+ ("oc_FR.UTF-8", ["jòu", "ven", "sab", "dim", "lun", "mar", "mec"]),+ ("om_ET", ["Kam", "Jim", "San", "Dil", "Wix", "Qib", "Rob"]),+ ("om_KE.UTF-8", ["Kam", "Jim", "San", "Dil", "Wix", "Qib", "Rob"]),+ ("or_IN", ["ଗୁରୁ", "ଶୁକ୍ର", "ଶନି", "ରବି", "ସୋମ", "ମଙ୍ଗଳ", "ବୁଧ"]),+ ("os_RU", ["Цпр", "Мрб", "Сбт", "Хцб", "Крс", "Дцг", "Æрт"]),+ ("pa_IN", ["ਵੀਰ ", "ਸ਼ੁੱਕਰ ", "ਸ਼ਨਿੱਚਰ ", "ਐਤ ", "ਸੋਮ ", "ਮੰਗਲ ", "ਬੁੱਧ "]),+ ("pa_PK", ["جمعرات", "جمعه", "هفته", "اتوار", "پير", "منگل", "بدھ"]),+ ("pap_AN", ["ra", "bi", "sa", "do", "lu", "ma", "we"]),+ ("pl_PL.UTF-8", ["czw", "pią", "sob", "nie", "pon", "wto", "śro"]),+ ("ps_AF", ["پ.", "ج.", "ش.", "ی.", "د.", "س.", "چ."]),+ ("pt_BR.UTF-8", ["Qui", "Sex", "Sáb", "Dom", "Seg", "Ter", "Qua"]),+ ("pt_PT.UTF-8", ["Qui", "Sex", "Sáb", "Dom", "Seg", "Ter", "Qua"]),+ ("ro_RO.UTF-8", ["Jo", "Vi", "Sb", "Du", "Lu", "Ma", "Mi"]),+ ("ru_RU.UTF-8", ["Чтв", "Птн", "Сбт", "Вск", "Пнд", "Втр", "Срд"]),+ ("ru_UA.UTF-8", ["Чтв", "Птн", "Суб", "Вск", "Пнд", "Вто", "Срд"]),+ ("rw_RW", ["Kan", "Gnu", "Gnd", "Mwe", "Mbe", "Kab", "Gtu"]),+ ("sa_IN", ["बृहस्पतिः", "शुक्र", "शनि:", "रविः", "सोम:", "मंगल:", "बुध:"]),+ ("sc_IT", ["Jòb", "Cen", "Sàb", "Dom", "Lun", "Mar", "Mèr"]),+ ("sd_IN", ["وسپت", "جُمو", "ڇنڇر", "آرتوارُ", "سومرُ", "منگلُ", "ٻُڌرُ"]),+ ("sd_IN@devanagari", ["विस्पति", "जुमो", "छंछस", "आर्तवारू", "सूमरू", "मंगलू", "ॿुधरू"]),+ ("se_NO", ["duor", "bear", "láv", "sotn", "vuos", "maŋ", "gask"]),+ ("shs_CA", ["Sme", "Sts", "Stq", "Sxe", "Spe", "Sel", "Ske"]),+-- TODO: lexical error in Haskell+-- ("si_LK", ["බ්ර", "සි", "සෙ", "ඉ", "ස", "අ", "බ"]),+ ("sid_ET", ["Ham", "Arb", "Qid", "Sam", "San", "Mak", "Row"]),+ ("sk_SK.UTF-8", ["Št", "Pi", "So", "Ne", "Po", "Ut", "St"]),+ ("sl_SI.UTF-8", ["čet", "pet", "sob", "ned", "pon", "tor", "sre"]),+ ("so_DJ.UTF-8", ["kha", "jim", "sab", "axa", "isn", "sal", "arb"]),+ ("so_ET", ["Kha", "Jim", "Sab", "Axa", "Isn", "Sal", "Arb"]),+ ("so_KE.UTF-8", ["Kha", "Jim", "Sab", "Axa", "Isn", "Sal", "Arb"]),+ ("so_SO.UTF-8", ["Kha", "Jim", "Sab", "Axa", "Isn", "Sal", "Arb"]),+ ("sq_AL.UTF-8", ["Enj ", "Pre ", "Sht ", "Die ", "Hën ", "Mar ", "Mër "]),+ ("sq_MK", ["Enj ", "Pre ", "Sht ", "Die ", "Hën ", "Mar ", "Mër "]),+ ("sr_ME", ["чет", "пет", "суб", "нед", "пон", "уто", "сри"]),+ ("sr_RS", ["чет", "пет", "суб", "нед", "пон", "уто", "сре"]),+ ("sr_RS@latin", ["čet", "pet", "sub", "ned", "pon", "uto", "sre"]),+ ("ss_ZA", ["Ne", "Hla", "Mgc", "Son", "Mso", "Bil", "Tsa"]),+ ("st_ZA.UTF-8", ["Ne", "Hla", "Moq", "Son", "Mma", "Bed", "Rar"]),+ ("sv_FI.UTF-8", ["tor", "fre", "lör", "sön", "mån", "tis", "ons"]),+ ("sv_SE.UTF-8", ["tor", "fre", "lör", "sön", "mån", "tis", "ons"]),+ ("sw_KE", ["Alh", "Ij", "J1", "J2", "J3", "J4", "J5"]),+ ("sw_TZ", ["Alh", "Ij", "J1", "J2", "J3", "J4", "J5"]),+ ("ta_IN", ["வி", "வெ", "ச", "ஞா", "தி", "செ", "பு"]),+ ("te_IN", ["గురు", "శుక్ర", "శని", "ఆది", "సోమ", "మంగళ", "బుధ"]),+ ("tg_TJ.UTF-8", ["Чтв", "Птн", "Сбт", "Вск", "Пнд", "Втр", "Срд"]),+ ("th_TH.UTF-8", ["พฤ.", "ศ.", "ส.", "อา.", "จ.", "อ.", "พ."]),+ ("ti_ER", ["ሓሙስ", "ዓርቢ", "ቀዳም", "ሰንበ", "ሰኑይ", "ሰሉስ", "ረቡዕ"]),+ ("ti_ET", ["ሓሙስ", "ዓርቢ", "ቀዳም", "ሰንበ", "ሰኑይ", "ሰሉስ", "ረቡዕ"]),+ ("tig_ER", ["ከሚሽ", "ጅምዓ", "ሰ/ን", "ሰ/ዓ", "ሰኖ ", "ታላሸ", "ኣረር"]),+ ("tk_TM", ["Sog", "Ann", "Ruh", "Dyn", "Baş", "Yaş", "Hoş"]),+ ("tl_PH.UTF-8", ["Huw", "Biy", "Sab", "Lin", "Lun", "Mar", "Miy"]),+ ("tn_ZA", ["Ne", "Tlh", "Mat", "Tsh", "Mos", "Bed", "Rar"]),+ ("tr_CY.UTF-8", ["Prş", "Cum", "Cts", "Paz", "Pzt", "Sal", "Çrş"]),+ ("tr_TR.UTF-8", ["Prş", "Cum", "Cts", "Paz", "Pzt", "Sal", "Çrş"]),+ ("ts_ZA", ["Ne", "Tlh", "Mug", "Son", "Mus", "Bir", "Har"]),+ ("tt_RU.UTF-8", ["Пәнҗ", "Җом", "Шим", "Якш", "Дыш", "Сиш", "Чәрш"]),+ ("tt_RU.UTF-8@iqtelif", ["Pen", "Com", "Şim", "Yek", "Düş", "Siş", "Çer"]),+ ("ug_CN", ["Thu", "Fri", "Sat", "Sun", "Mon", "Tue", "Wed"]),+ ("uk_UA.UTF-8", ["чт", "пт", "сб", "нд", "пн", "вт", "ср"]),+ ("ur_PK", ["جمعرات", "جمعه", "هفته", "اتوار", "پير", "منگل", "بدھ"]),+ ("uz_UZ.UTF-8", ["Pay", "Ju", "Sha", "Yak", "Du", "Se", "Cho"]),+ ("uz_UZ@cyrillic", ["Пай", "Жум", "Шан", "Якш", "Душ", "Сеш", "Чор"]),+ ("ve_ZA", ["ṋa", "Ṱan", "Mug", "Swo", "Mus", "Vhi", "Rar"]),+ ("vi_VN", ["T5", "T6", "T7", "CN", "T2", "T3", "T4"]),+ ("wa_BE.UTF-8", ["dju", "vén", "sem", "dim", "lon", "mår", "mie"]),+ ("wo_SN", ["alx", "ajj", "gaa", "dib", "alt", "tal", "all"]),+ ("xh_ZA.UTF-8", ["Sin", "Hla", "Mgq", "Caw", "Mvu", "Bin", "Tha"]),+ ("yi_US.UTF-8", ["דאָנ'", "פֿרײַ'", "שבת", "זונ'", "מאָנ'", "דינ'", "מיט'"]),+ ("yo_NG", ["THU", "FRI", "SAT", "SUN", "MON", "TUE", "WED"]),+ ("zh_CN.UTF-8", ["四", "五", "六", "日", "一", "二", "三"]),+ ("zh_HK.UTF-8", ["四", "五", "六", "日", "一", "二", "三"]),+ ("zh_SG.UTF-8", ["星期四", "星期五", "星期六", "星期日", "星期一", "星期二", "星期三"]),+ ("zh_TW.UTF-8", ["四", "五", "六", "日", "一", "二", "三"]),+ ("zu_ZA.UTF-8", ["Sin", "Hla", "Mgq", "Son", "Mso", "Bil", "Tha"])+ ]