-- | This module contains some utility functions for building
-- attributes.
module Text.Pandoc.Filter.Utils.AttrBuilder (
  -- * Attribute builders
  addClass,
  addClasses,
  addKVPair,
  addKVPairs,
  setId,
) where

import Text.Pandoc.Utils.String

import Data.Bifunctor         (bimap, first, second)
import Data.Text              (Text)
import Text.Pandoc.Definition

-- | Append a new class to attributes.
addClass
  :: Attr -- ^ Original attributes.
  -> Text -- ^ Name of the class.
  -> Attr -- ^ New attributes.
attr :: Attr
attr addClass :: Attr -> Text -> Attr
`addClass` cls :: Text
cls = ([Text] -> [Text]) -> Attr -> Attr
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first (Text -> Text
forall a. IsText a => Text -> a
fromText Text
clsText -> [Text] -> [Text]
forall a. a -> [a] -> [a]
:) Attr
attr
  -- (i, fromText newCls:cls, p)

-- | Append a list of classes to attributes.
addClasses
  :: Attr   -- ^ Original attributes.
  -> [Text] -- ^ A list of class names.
  -> Attr   -- ^ New attributes.
attr :: Attr
attr addClasses :: Attr -> [Text] -> Attr
`addClasses` clses :: [Text]
clses = ([Text] -> [Text]) -> Attr -> Attr
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first ((Text -> Text) -> [Text] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map Text -> Text
forall a. IsText a => Text -> a
fromText [Text]
clses[Text] -> [Text] -> [Text]
forall a. Semigroup a => a -> a -> a
<>) Attr
attr

-- | Append a new key-value pair to attributes.
addKVPair
  :: Attr         -- ^ Original attributes.
  -> (Text, Text) -- ^ A key-value pair.
  -> Attr         -- ^ New attributes.
attr :: Attr
attr addKVPair :: Attr -> (Text, Text) -> Attr
`addKVPair` p :: (Text, Text)
p = ([(Text, Text)] -> [(Text, Text)]) -> Attr -> Attr
forall (p :: * -> * -> *) b c a.
Bifunctor p =>
(b -> c) -> p a b -> p a c
second ((Text -> Text) -> (Text -> Text) -> (Text, Text) -> (Text, Text)
forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap Text -> Text
forall a. IsText a => Text -> a
fromText Text -> Text
forall a. IsText a => Text -> a
fromText (Text, Text)
p(Text, Text) -> [(Text, Text)] -> [(Text, Text)]
forall a. a -> [a] -> [a]
:) Attr
attr

-- | Append new key-value pairs to attributes.
addKVPairs
  :: Attr           -- ^ Original attributes.
  -> [(Text, Text)] -- ^ A list of key-value pairs.
  -> Attr           -- ^ New attributes.
attr :: Attr
attr addKVPairs :: Attr -> [(Text, Text)] -> Attr
`addKVPairs` ps :: [(Text, Text)]
ps = ([(Text, Text)] -> [(Text, Text)]) -> Attr -> Attr
forall (p :: * -> * -> *) b c a.
Bifunctor p =>
(b -> c) -> p a b -> p a c
second (((Text, Text) -> (Text, Text)) -> [(Text, Text)] -> [(Text, Text)]
forall a b. (a -> b) -> [a] -> [b]
map ((Text -> Text) -> (Text -> Text) -> (Text, Text) -> (Text, Text)
forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap Text -> Text
forall a. IsText a => Text -> a
fromText Text -> Text
forall a. IsText a => Text -> a
fromText) [(Text, Text)]
ps [(Text, Text)] -> [(Text, Text)] -> [(Text, Text)]
forall a. Semigroup a => a -> a -> a
<>) Attr
attr

-- | Set the id of attributes.
setId
  :: Attr -- ^ Original attributes.
  -> Text -- ^ The id of the attrbute.
  -> Attr -- ^ New attributes.
(_, cls :: [Text]
cls, p :: [(Text, Text)]
p) setId :: Attr -> Text -> Attr
`setId` i :: Text
i = (Text
i, [Text]
cls, [(Text, Text)]
p)