orgmode-parse-0.2.2: src/Data/OrgMode/Parse/Attoparsec/Drawer/Property.hs
-----------------------------------------------------------------------------
-- |
-- 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 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)