{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE ViewPatterns #-}
module Language.TCT.Token where
import Data.Bool
import Data.Char (Char)
import Data.Eq (Eq(..))
import Data.Function (($), (.))
import Data.Foldable (foldMap, foldr)
import Data.Maybe (Maybe(..))
import Data.Semigroup (Semigroup(..))
import Data.Sequence (Seq)
import Data.Ord (Ord)
import Data.Text (Text)
import Data.Text.Buildable (Buildable(..))
import Data.Text.Lazy.Builder (Builder)
import Data.TreeSeq.Strict (Tree(..), Trees)
import GHC.Exts (IsList(..))
import Text.Show (Show(..))
import qualified Data.Char as Char
import qualified Data.Sequence as Seq
import qualified Data.Text as Text
import Language.TCT.Cell
import Language.TCT.Elem
-- * Type 'Token'
type Token = Tree (Cell TokenKey) (Cell TokenValue)
-- ** Type 'Tokens'
type Tokens = Seq Token
-- ** Type 'TokenKey'
type TokenKey = Pair
data Pair
= PairHash -- ^ @#value#@
| PairElem !Elem !Attrs -- ^ @value@
| PairStar -- ^ @*value*@
| PairSlash -- ^ @/value/@
| PairUnderscore -- ^ @_value_@
| PairDash -- ^ @-value-@
| PairBackquote -- ^ @`value`@
| PairSinglequote -- ^ @'value'@
| PairDoublequote -- ^ @"value"@
| PairFrenchquote -- ^ @«value»@
| PairParen -- ^ @(value)@
| PairBrace -- ^ @{value}@
| PairBracket -- ^ @[value]@
deriving (Eq,Ord,Show)
-- ** Type 'TokenValue'
data TokenValue
= TokenPlain !Text
| TokenTag !Tag
| TokenEscape !Char
| TokenLink !Text
deriving (Eq,Ord,Show)
-- *** Type 'Tag'
type Tag = Text
-- | Build 'Tokens' from many 'Token's.
tokens :: [Token] -> Tokens
tokens = Seq.fromList
-- | Build 'Tokens' from one 'Token'.
tokens1 :: Token -> Tokens
tokens1 = Seq.singleton
tokensPlainEmpty :: Tokens
tokensPlainEmpty = tokens1 $ Tree0 $ cell1 $ TokenPlain ""
isTokenWhite :: Token -> Bool
isTokenWhite (Tree0 (unCell -> TokenPlain t)) = Text.all Char.isSpace t
isTokenWhite _ = False
unTokenElem :: Tokens -> Maybe (Cell (Elem,Attrs,Tokens))
unTokenElem toks =
case toList $ Seq.dropWhileR isTokenWhite toks of
[TreeN (Cell bp ep (PairElem e as)) ts] -> Just (Cell bp ep (e,as,ts))
_ -> Nothing
isTokenElem :: Tokens -> Bool
isTokenElem toks =
case toList $ Seq.dropWhileR isTokenWhite toks of
[TreeN (unCell -> PairElem{}) _] -> True
_ -> False
pairBorders :: TokenKey -> Tokens -> (Text,Text)
pairBorders p ts =
case p of
PairElem e attrs ->
if Seq.null ts
then ("<"<>e<>foldMap f attrs<>"/>","")
else ("<"<>e<>foldMap f attrs<>">",""<>e<>">")
where f (attr_white,Attr{..}) =
attr_white <>
attr_name <>
attr_open <>
attr_value <>
attr_close
PairHash -> ("#","#")
PairStar -> ("*","*")
PairSlash -> ("/","/")
PairUnderscore -> ("_","_")
PairDash -> ("-","-")
PairBackquote -> ("`","`")
PairSinglequote -> ("'","'")
PairDoublequote -> ("\"","\"")
PairFrenchquote -> ("«","»")
PairParen -> ("(",")")
PairBrace -> ("{","}")
PairBracket -> ("[","]")
{-
instance Buildable Token where
build (TokenPlain t) = build t
build (TokenTag t) = "#"<>build t
build (TokenLink lnk) = build lnk
build (TokenEscape c) = "\\"<>build c
build (TokenPair p ts) = build c<>buildTokens ts<>build o
where (o,c) = pairBorders p ts
buildTokens :: Tokens -> Builder
buildTokens = foldr (\a -> (<> build (unCell a))) ""
instance Semigroup Tokens where
Tokens (Seq.viewr -> xs:>TokenPlain x) <>
Tokens (Seq.viewl -> TokenPlain y:(TokenPlain (x<>y)<|ys))
Tokens x <> Tokens y = Tokens (x<>y)
instance Monoid Tokens where
mempty = Tokens mempty
mappend = (<>)
instance Buildable Tokens where
build (Tokens ts) = foldr (\a -> (<> build a)) "" ts
instance IsList Tokens where
type Item Tokens = Token
fromList = Tokens . fromList
toList (Tokens ts) = toList ts
unTokens :: Tokens -> Seq Token
unTokens (Tokens ts) = ts
-}