1 {-# LANGUAGE OverloadedStrings #-}
2 {-# LANGUAGE TypeFamilies #-}
3 {-# LANGUAGE ViewPatterns #-}
4 module Language.TCT.Token where
7 import Data.Char (Char)
8 import Data.Eq (Eq(..))
9 import Data.Function ((.))
10 import Data.Foldable (foldMap, foldr)
11 import Data.Maybe (Maybe(..))
12 import Data.Semigroup (Semigroup(..))
13 import Data.Sequence (Seq)
15 import Data.Text (Text)
16 import Data.Text.Buildable (Buildable(..))
17 import Data.Text.Lazy.Builder (Builder)
18 import GHC.Exts (IsList(..))
19 import Text.Show (Show(..))
20 import qualified Data.Char as Char
21 import qualified Data.Sequence as Seq
22 import qualified Data.Text as Text
24 import Language.TCT.Cell
25 import Language.TCT.Elem
30 | TokenPair !Pair !Tokens
34 deriving (Eq, Ord, Show)
36 instance Buildable Token where
37 build (TokenPlain t) = build t
38 build (TokenTag t) = "#"<>build t
39 build (TokenLink lnk) = build lnk
40 build (TokenEscape c) = "\\"<>build c
41 build (TokenPair p ts) = build c<>buildTokens ts<>build o
42 where (o,c) = pairBorders p ts
44 buildTokens :: Tokens -> Builder
45 buildTokens = foldr (\a -> (<> build (unCell a))) ""
48 type Tokens = Seq (Cell Token)
51 instance Semigroup Tokens where
52 Tokens (Seq.viewr -> xs:>TokenPlain x) <>
53 Tokens (Seq.viewl -> TokenPlain y:<ys) =
54 Tokens (xs<>(TokenPlain (x<>y)<|ys))
55 Tokens x <> Tokens y = Tokens (x<>y)
56 instance Monoid Tokens where
57 mempty = Tokens mempty
59 instance Buildable Tokens where
60 build (Tokens ts) = foldr (\a -> (<> build a)) "" ts
61 instance IsList Tokens where
62 type Item Tokens = Token
63 fromList = Tokens . fromList
64 toList (Tokens ts) = toList ts
66 unTokens :: Tokens -> Seq Token
67 unTokens (Tokens ts) = ts
70 -- | Build 'Tokens' from many 'Token's.
71 tokens :: [Cell Token] -> Tokens
74 -- | Build 'Tokens' from one 'Token'.
75 tokens1 :: Cell Token -> Tokens
76 tokens1 = Seq.singleton
78 tokensPlainEmpty :: Tokens
79 tokensPlainEmpty = Seq.singleton (cell1 (TokenPlain ""))
81 isTokenWhite :: Token -> Bool
82 isTokenWhite (TokenPlain t) = Text.all Char.isSpace t
83 isTokenWhite _ = False
85 unTokenElem :: Tokens -> Maybe (Cell (Elem,Attrs,Tokens))
87 case toList (Seq.dropWhileR (isTokenWhite . unCell) ts) of
88 [Cell bp ep (TokenPair (PairElem e as) toks)] -> Just (Cell bp ep (e,as,toks))
91 isTokenElem :: Tokens -> Bool
93 case toList (Seq.dropWhileR (isTokenWhite . unCell) ts) of
94 [unCell -> TokenPair PairElem{} _] -> True
102 = PairHash -- ^ @#value#@
103 | PairElem !Elem !Attrs -- ^ @<elem n0=v0 n1=v1>value</elem>@
104 | PairStar -- ^ @*value*@
105 | PairSlash -- ^ @/value/@
106 | PairUnderscore -- ^ @_value_@
107 | PairDash -- ^ @-value-@
108 | PairBackquote -- ^ @`value`@
109 | PairSinglequote -- ^ @'value'@
110 | PairDoublequote -- ^ @"value"@
111 | PairFrenchquote -- ^ @«value»@
112 | PairParen -- ^ @(value)@
113 | PairBrace -- ^ @{value}@
114 | PairBracket -- ^ @[value]@
115 deriving (Eq, Ord, Show)
117 pairBorders :: Pair -> Tokens -> (Text,Text)
122 then ("<"<>e<>foldMap f attrs<>"/>","")
123 else ("<"<>e<>foldMap f attrs<>">","</"<>e<>">")
124 where f (attr_white,Attr{..}) =
130 PairHash -> ("#","#")
131 PairStar -> ("*","*")
132 PairSlash -> ("/","/")
133 PairUnderscore -> ("_","_")
134 PairDash -> ("-","-")
135 PairBackquote -> ("`","`")
136 PairSinglequote -> ("'","'")
137 PairDoublequote -> ("\"","\"")
138 PairFrenchquote -> ("«","»")
139 PairParen -> ("(",")")
140 PairBrace -> ("{","}")
141 PairBracket -> ("[","]")