module Penny.Copper.Number (isNumChar, number, render) where import Control.Applicative ((<$>), (<*>)) import Data.Text ( pack, cons, snoc, Text ) import Text.Parsec ( char, satisfy, many, between, ()) import Text.Parsec.Text ( Parser ) import Penny.Copper.Util (rangeLettersToSymbols) import qualified Penny.Lincoln.Bits as B import Penny.Lincoln.TextNonEmpty ( TextNonEmpty ( TextNonEmpty ) ) import qualified Penny.Lincoln.TextNonEmpty as TNE isNumChar :: Char -> Bool isNumChar c = allowed && not banned where allowed = rangeLettersToSymbols c || c == ' ' banned = c == ')' number :: Parser B.Number number = between (char '(') (char ')') p "number" where p = (\c cs -> B.Number (TextNonEmpty c (pack cs))) <$> satisfy isNumChar <*> many (satisfy isNumChar) render :: B.Number -> Maybe Text render (B.Number tne) = if TNE.all isNumChar tne then Just $ '(' `cons` TNE.toText tne `snoc` ')' else Nothing