{-# LANGUAGE CPP #-}
{-# LANGUAGE BangPatterns #-}
module Commonmark.ReferenceMap
( ReferenceMap(..)
, LinkInfo(..)
, emptyReferenceMap
, insertReference
, lookupReference
) where
import Data.Text (Text)
import qualified Data.Text as T
import qualified Data.Map.Strict as M
import Data.Dynamic
import Commonmark.Types
#if !MIN_VERSION_base(4,13,0)
import Data.Typeable (Typeable)
#endif
newtype ReferenceMap = ReferenceMap { unReferenceMap :: M.Map Text [Dynamic] }
deriving (Show)
data LinkInfo = LinkInfo{ linkDestination :: !Text
, linkTitle :: !Text
, linkAttributes :: !Attributes }
deriving (Show, Typeable)
emptyReferenceMap :: ReferenceMap
emptyReferenceMap = ReferenceMap M.empty
insertReference :: Typeable a
=> Text
-> a
-> ReferenceMap
-> ReferenceMap
insertReference label x (ReferenceMap m) =
ReferenceMap (M.insertWith (\new old -> old ++ new)
(T.toCaseFold $! normalizeSpaces label) [toDyn x] m)
lookupReference :: Typeable a
=> Text
-> ReferenceMap
-> Maybe a
lookupReference label (ReferenceMap m) =
getFirst $! M.lookup (T.toCaseFold $! normalizeSpaces label) m
where getFirst Nothing = Nothing
getFirst (Just []) = Nothing
getFirst (Just (x:xs)) = case fromDynamic x of
Just !v -> Just v
Nothing -> getFirst (Just xs)
normalizeSpaces :: Text -> Text
normalizeSpaces = T.unwords . T.words