module Penny.Copper.Tags ( isTagChar, tags, render )where import Control.Applicative ((<$>), (*>), (<*>)) import qualified Data.Text as X import Text.Parsec (char, satisfy, many, ()) import Text.Parsec.Text ( Parser ) import Penny.Copper.Util (lexeme, rangeLettersNumbers) import qualified Penny.Lincoln.Bits as B import qualified Penny.Lincoln.TextNonEmpty as TNE isTagChar :: Char -> Bool isTagChar = rangeLettersNumbers tagChar :: Parser Char tagChar = satisfy isTagChar tag :: Parser B.Tag tag = (char '*' *> (f <$> tagChar <*> many tagChar)) e where f t ts = B.Tag $ TNE.TextNonEmpty t (X.pack ts) e = "tag" tags :: Parser B.Tags tags = B.Tags <$> many (lexeme tag) renderTag :: B.Tag -> Maybe X.Text renderTag (B.Tag t) = if TNE.all isTagChar t then Just $ X.cons '*' (TNE.toText t) else Nothing render :: B.Tags -> Maybe X.Text render (B.Tags ts) = X.intercalate (X.singleton ' ') <$> mapM renderTag ts