{-# LANGUAGE FlexibleContexts #-} module Hcompta.Format.JCC.Common.Read where import Control.Applicative ((<$>)) import Control.Monad (void) import Data.Bool import Data.Char (Char) import qualified Data.Char import Data.String (fromString) import Data.Text (Text) import Data.Typeable () import Prelude (($)) import qualified Text.Parsec as R hiding ( char , anyChar , crlf , newline , noneOf , oneOf , satisfy , space , spaces , string , tab ) import Text.Parsec (Stream, ParsecT, (<|>), ()) import qualified Hcompta.Lib.Parsec as R -- * Read characters is_space :: Char -> Bool is_space c = case Data.Char.generalCategory c of Data.Char.Space -> True _ -> False space :: Stream s m Char => ParsecT s u m Char space = R.satisfy is_space is_char :: Char -> Bool is_char c = case Data.Char.generalCategory c of Data.Char.UppercaseLetter -> True Data.Char.LowercaseLetter -> True Data.Char.TitlecaseLetter -> True Data.Char.ModifierLetter -> True Data.Char.OtherLetter -> True Data.Char.NonSpacingMark -> True Data.Char.SpacingCombiningMark -> True Data.Char.EnclosingMark -> True Data.Char.DecimalNumber -> True Data.Char.LetterNumber -> True Data.Char.OtherNumber -> True Data.Char.ConnectorPunctuation -> True Data.Char.DashPunctuation -> True Data.Char.OpenPunctuation -> True Data.Char.ClosePunctuation -> True Data.Char.InitialQuote -> True Data.Char.FinalQuote -> True Data.Char.OtherPunctuation -> True Data.Char.MathSymbol -> True Data.Char.CurrencySymbol -> True Data.Char.ModifierSymbol -> True Data.Char.OtherSymbol -> True Data.Char.Space -> False Data.Char.LineSeparator -> False Data.Char.ParagraphSeparator -> False Data.Char.Control -> False Data.Char.Format -> False Data.Char.Surrogate -> False Data.Char.PrivateUse -> False Data.Char.NotAssigned -> False char :: Stream s m Char => ParsecT s u m Char char = R.satisfy is_char is_char_active :: Char -> Bool is_char_active c = case c of '/' -> True '\\' -> True '!' -> True '?' -> True '\'' -> True '"' -> True '&' -> True '|' -> True '-' -> True '+' -> True '.' -> True ':' -> True '=' -> True '<' -> True '>' -> True '@' -> True '#' -> True '(' -> True ')' -> True '[' -> True ']' -> True '{' -> True '}' -> True '~' -> True '*' -> True '^' -> True ';' -> True ',' -> True _ -> False char_active :: Stream s m Char => ParsecT s u m Char char_active = R.satisfy is_char_active is_char_passive :: Char -> Bool is_char_passive c = is_char c && not (is_char_active c) char_passive :: Stream s m Char => ParsecT s u m Char char_passive = R.satisfy is_char_passive word :: Stream s m Char => ParsecT s u m Text word = fromString <$> R.many char_passive words :: Stream s m Char => ParsecT s u m [Text] words = R.many_separated word space name :: Stream s m Char => ParsecT s u m Text name = fromString <$> R.many1 char_passive tabulation :: Stream s m Char => ParsecT s u m Char tabulation = R.char '\t' hspace :: Stream s m Char => ParsecT s u m Char hspace = R.char ' ' hspaces :: Stream s m Char => ParsecT s u m () hspaces = void $ R.many hspace hspaces1 :: Stream s m Char => ParsecT s u m () hspaces1 = void $ R.many1 hspace eol :: Stream s m Char => ParsecT s u m () eol = ((R.<|>) (void $ R.char '\n') (void $ R.try $ R.string "\r\n")) "eol" line :: Stream s m Char => ParsecT s u m Text line = fromString <$> R.manyTill char (R.lookAhead eol <|> R.eof) -- R.many (R.notFollowedBy eol >> char)