module Penny.Copper.Util where
import Control.Applicative ((<*), pure, (<$))
import qualified Data.Char as C
import qualified Data.Foldable as F
import qualified Data.List.NonEmpty as NE
import qualified Data.Text as X
import qualified Penny.Lincoln.HasText as HT
import qualified Penny.Lincoln.TextNonEmpty as TNE
import Text.Parsec (char, many, skipMany)
import Text.Parsec.Text (Parser)
rangeLettersToSymbols :: Char -> Bool
rangeLettersToSymbols c = case C.generalCategory c of
C.UppercaseLetter -> True
C.LowercaseLetter -> True
C.TitlecaseLetter -> True
C.ModifierLetter -> True
C.OtherLetter -> True
C.DecimalNumber -> True
C.LetterNumber -> True
C.OtherNumber -> True
C.ConnectorPunctuation -> True
C.DashPunctuation -> True
C.OpenPunctuation -> True
C.ClosePunctuation -> True
C.InitialQuote -> True
C.FinalQuote -> True
C.OtherPunctuation -> True
C.MathSymbol -> True
C.CurrencySymbol -> True
C.ModifierSymbol -> True
C.OtherSymbol -> True
_ -> False
rangeLetters :: Char -> Bool
rangeLetters c = case C.generalCategory c of
C.UppercaseLetter -> True
C.LowercaseLetter -> True
C.TitlecaseLetter -> True
C.ModifierLetter -> True
C.OtherLetter -> True
_ -> False
rangeMathCurrency :: Char -> Bool
rangeMathCurrency c = case C.generalCategory c of
C.MathSymbol -> True
C.CurrencySymbol -> True
_ -> False
rangeSymbols :: Char -> Bool
rangeSymbols c = case C.generalCategory c of
C.MathSymbol -> True
C.CurrencySymbol -> True
C.ModifierSymbol -> True
C.OtherSymbol -> True
_ -> False
rangeLettersNumbers :: Char -> Bool
rangeLettersNumbers c = case C.generalCategory c of
C.UppercaseLetter -> True
C.LowercaseLetter -> True
C.TitlecaseLetter -> True
C.ModifierLetter -> True
C.OtherLetter -> True
C.DecimalNumber -> True
C.LetterNumber -> True
C.OtherNumber -> True
_ -> False
lexeme :: Parser a -> Parser a
lexeme p = p <* skipMany (char ' ')
eol :: Parser ()
eol = pure ()
<* skipMany (char ' ')
<* char '\n'
<* skipMany (char ' ')
spaces :: Parser ()
spaces = () <$ many (char ' ')
checkText ::
HT.HasText a
=> NE.NonEmpty ((Char -> Bool), b)
-> a
-> Maybe b
checkText ps a = let
t = HT.text a
results = fmap (g . f) ps where
f (p, b) = (X.find (not . p) t, b)
g (p, b) = case p of
Nothing -> Right b
Just c -> Left c
folder x y = case x of
Right b -> Right b
Left _ -> y
in case F.foldr1 folder results of
Left _ -> Nothing
Right b -> return b
listIsOK ::
HT.HasTextNonEmptyList a
=> (Char -> Bool)
-> a
-> Bool
listIsOK p = F.all (TNE.all p) . HT.textNonEmptyList
firstCharOfListIsOK ::
HT.HasTextNonEmptyList a
=> (Char -> Bool)
-> a
-> Bool
firstCharOfListIsOK p ls = let
firstText = NE.head . HT.textNonEmptyList $ ls
in p (TNE.first firstText)
renMaybe :: Maybe a -> (a -> Maybe X.Text) -> Maybe X.Text
renMaybe mx f = case mx of
Nothing -> Just X.empty
Just a -> f a
txtWords :: [X.Text] -> X.Text
txtWords xs = case filter (not . X.null) xs of
[] -> X.empty
rs -> X.unwords rs