----------------------------------------------------------------------------- -- | -- Module : Data.OrgMode.Parse.Attoparsec.Drawer.Generic -- Copyright : © 2017 Parnell Springmeyer -- License : All Rights Reserved -- Maintainer : Parnell Springmeyer -- Stability : stable -- -- Parsing combinators for org-mode section generic drawers. ---------------------------------------------------------------------------- {-# 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 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 (== ':') <* Util.skipOnlySpace -- | Parse the @:END:@ of a drawer. drawerEnd :: Attoparsec.Parser Text Text drawerEnd = parseDrawerDelim "END"