{-# LANGUAGE LambdaCase #-}

-- |
-- Module      :  Text.MMark.Trans
-- Copyright   :  © 2017–present Mark Karpov
-- License     :  BSD 3 clause
--
-- Maintainer  :  Mark Karpov <markkarpov92@gmail.com>
-- Stability   :  experimental
-- Portability :  portable
--
-- MMark block\/inline transformation helpers.
module Text.MMark.Trans
  ( applyBlockTrans,
    applyInlineTrans,
  )
where

import Data.Monoid hiding ((<>))
import Text.MMark.Type

-- | Apply block transformation in the @'Endo' 'Bni'@ form to a block 'Bni'.
applyBlockTrans :: Endo Bni -> Bni -> Bni
applyBlockTrans :: Endo Bni -> Bni -> Bni
applyBlockTrans trans :: Endo Bni
trans@(Endo Bni -> Bni
f) = \case
  Blockquote [Bni]
xs -> Bni -> Bni
f ([Bni] -> Bni
forall a. [Block a] -> Block a
Blockquote ([Bni] -> [Bni]
s [Bni]
xs))
  OrderedList Word
w NonEmpty [Bni]
xs -> Bni -> Bni
f (Word -> NonEmpty [Bni] -> Bni
forall a. Word -> NonEmpty [Block a] -> Block a
OrderedList Word
w ([Bni] -> [Bni]
s ([Bni] -> [Bni]) -> NonEmpty [Bni] -> NonEmpty [Bni]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> NonEmpty [Bni]
xs))
  UnorderedList NonEmpty [Bni]
xs -> Bni -> Bni
f (NonEmpty [Bni] -> Bni
forall a. NonEmpty [Block a] -> Block a
UnorderedList ([Bni] -> [Bni]
s ([Bni] -> [Bni]) -> NonEmpty [Bni] -> NonEmpty [Bni]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> NonEmpty [Bni]
xs))
  Bni
other -> Bni -> Bni
f Bni
other
  where
    s :: [Bni] -> [Bni]
s = (Bni -> Bni) -> [Bni] -> [Bni]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Endo Bni -> Bni -> Bni
applyBlockTrans Endo Bni
trans)

-- | Apply inline transformation in the @'Endo' 'Inline'@ form to an
-- 'Inline'.
applyInlineTrans :: Endo Inline -> Inline -> Inline
applyInlineTrans :: Endo Inline -> Inline -> Inline
applyInlineTrans trans :: Endo Inline
trans@(Endo Inline -> Inline
f) = \case
  Emphasis NonEmpty Inline
xs -> Inline -> Inline
f (NonEmpty Inline -> Inline
Emphasis (NonEmpty Inline -> NonEmpty Inline
s NonEmpty Inline
xs))
  Strong NonEmpty Inline
xs -> Inline -> Inline
f (NonEmpty Inline -> Inline
Strong (NonEmpty Inline -> NonEmpty Inline
s NonEmpty Inline
xs))
  Strikeout NonEmpty Inline
xs -> Inline -> Inline
f (NonEmpty Inline -> Inline
Strikeout (NonEmpty Inline -> NonEmpty Inline
s NonEmpty Inline
xs))
  Subscript NonEmpty Inline
xs -> Inline -> Inline
f (NonEmpty Inline -> Inline
Subscript (NonEmpty Inline -> NonEmpty Inline
s NonEmpty Inline
xs))
  Superscript NonEmpty Inline
xs -> Inline -> Inline
f (NonEmpty Inline -> Inline
Superscript (NonEmpty Inline -> NonEmpty Inline
s NonEmpty Inline
xs))
  Link NonEmpty Inline
xs URI
uri Maybe Text
mt -> Inline -> Inline
f (NonEmpty Inline -> URI -> Maybe Text -> Inline
Link (NonEmpty Inline -> NonEmpty Inline
s NonEmpty Inline
xs) URI
uri Maybe Text
mt)
  Image NonEmpty Inline
xs URI
uri Maybe Text
mt -> Inline -> Inline
f (NonEmpty Inline -> URI -> Maybe Text -> Inline
Image (NonEmpty Inline -> NonEmpty Inline
s NonEmpty Inline
xs) URI
uri Maybe Text
mt)
  Inline
other -> Inline -> Inline
f Inline
other
  where
    s :: NonEmpty Inline -> NonEmpty Inline
s = (Inline -> Inline) -> NonEmpty Inline -> NonEmpty Inline
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Endo Inline -> Inline -> Inline
applyInlineTrans Endo Inline
trans)