packages feed

neat-interpolation-0.2.0: src/NeatInterpolation/Parsing.hs

module NeatInterpolation.Parsing where

import NeatInterpolation.Prelude hiding (try, (<|>), many)
import Text.Parsec hiding (Line)
-- import qualified Data.Attoparsec.Text as AP

data Line = 
  Line {lineIndent :: Int, lineContents :: [LineContent]}
  deriving (Show)

data LineContent = 
  LineContentText [Char] |
  LineContentIdentifier [Char]
  deriving (Show)


parseLines :: [Char] -> Either ParseError [Line]
parseLines = parse lines "NeatInterpolation.Parsing.parseLines"
  where
    lines = sepBy line newline <* eof
    line = Line <$> countIndent <*> many content
    countIndent = fmap length $ try $ lookAhead $ many $ char ' '
    content = try identifier <|> contentText
    identifier = fmap LineContentIdentifier $ 
      string "$" *> many1 (alphaNum <|> char '\'' <|> char '_')
    contentText = do
      text <- manyTill anyChar end
      if null text
        then fail "Empty text"
        else return $ LineContentText $ text
      where
        end = 
          (void $ try $ lookAhead identifier) <|> 
          (void $ try $ lookAhead newline) <|> 
          eof