-
-
Notifications
You must be signed in to change notification settings - Fork 34
/
Copy pathEmoji.hs
69 lines (60 loc) · 1.88 KB
/
Emoji.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeFamilies #-}
module Commonmark.Extensions.Emoji
( HasEmoji(..)
, emojiSpec )
where
import Commonmark.Types
import Commonmark.Tokens
import Commonmark.Syntax
import Commonmark.Inlines
import Commonmark.SourceMap
import Commonmark.TokParsers
import Commonmark.Html
import Commonmark.Nodes
import Text.Emoji (emojiFromAlias)
import Text.Parsec
import Data.Text (Text)
import Data.Typeable (Typeable)
emojiSpec :: (Monad m, IsBlock il bl, IsInline il, HasEmoji il)
=> SyntaxSpec m il bl
emojiSpec = mempty
{ syntaxInlineParsers = [withAttributes parseEmoji]
}
class HasEmoji a where
emoji :: Text -- the ascii keyword
-> Text -- the emoji characters
-> a
instance HasEmoji (Html a) where
emoji kw t = addAttribute ("class", "emoji") .
addAttribute ("data-emoji", kw) $
htmlInline "span" $ Just $ htmlText t
instance (HasEmoji i, Monoid i) => HasEmoji (WithSourceMap i) where
emoji kw t = emoji kw t <$ addName "emoji"
parseEmoji :: (Monad m, HasEmoji a) => InlineParser m a
parseEmoji = try $ do
symbol ':'
ts <- many1 $ satisfyWord (const True)
<|> symbol '_'
<|> symbol '+'
<|> symbol '-'
symbol ':'
let kw = untokenize ts
case emojiFromAlias kw of
Nothing -> fail "emoji not found"
Just t -> return $! emoji kw t
data NodeTypeEmoji a
= NodeEmoji Text Text
deriving (Show)
instance Typeable a => NodeType NodeTypeEmoji a where
type FromNodeType NodeTypeEmoji a = HasEmoji a
fromNodeType = \case
NodeEmoji kw t -> emoji kw t
instance ToPlainText (NodeTypeEmoji a) where
toPlainText = \case
NodeEmoji kw _ -> ":" <> kw <> ":"
instance (Typeable a, HasEmoji a) => HasEmoji (Nodes a) where
emoji kw t = singleNode $ NodeEmoji kw t