module Text.BBCode.Internal.Helper
  ( module Text.BBCode.Internal.Helper
  , module Control.Lens
  , module Data.Text
  , module Data.String
  , module Text.BBCode.Internal.Types
  )
where

import Control.Lens hiding (List)
import Data.String (IsString, fromString)
import Data.Text (Text)
import Text.BBCode.Internal.Types

{- | Get representation of element in form of @IsString a => a@
@elName HR == "hr"@
@elName Align == "align"@
@elName ListElement == "*"@
-}
elName :: IsString a => El -> a
-- Void elements
elName :: forall a. IsString a => El -> a
elName El
HR = a
"hr"
elName El
BR = a
"br"
elName El
Clear = a
"clear"
elName El
ListElement = a
"*"
-- No argumets
elName El
Bold = a
"b"
elName El
Italic = a
"i"
elName El
Underline = a
"u"
elName El
Strikethrough = a
"s"
elName El
Indent = a
"indent"
elName El
NFO = a
"nfo"
elName El
Oneline = a
"oneline"
elName El
Code = a
"code"
elName El
Preformatted = a
"pre"
-- Optional argument
elName El
Box = a
"box"
elName El
Image = a
"img"
elName El
Quote = a
"quote"
elName El
Spoiler = a
"spoiler"
elName El
List = a
"list"
-- One argument
elName El
Color = a
"color"
elName El
Size = a
"size"
elName El
URL = a
"url"
elName El
Align = a
"align"
elName El
Font = a
"font"

{- | Elements that can be opening
e.g. @HR@: @"[hr]"@ or @Bold@: @"[bold]"@
-}
elementOpenings :: [El]
elementOpenings :: [El]
elementOpenings = [El
HR .. El
Font]

{- | Elements that can be opening and can take argument
e.g. @Box@: @"[box=right]"@
-}
elementArgOpenings :: [El]
elementArgOpenings :: [El]
elementArgOpenings = [El
Box .. El
Font]

{- | Elements that can be closing
e.g. @Bold@: @"[/bold]"@
-}
elementClosings :: [El]
elementClosings :: [El]
elementClosings = [El
Bold .. El
Font]

show' :: (Show a, IsString b) => a -> b
show' :: forall a b. (Show a, IsString b) => a -> b
show' = forall a. IsString a => String -> a
fromString forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> String
show
{-# INLINE show' #-}

surround :: Text -> Text -> Text
surround :: Text -> Text -> Text
surround Text
s Text
x = forall a. Monoid a => [a] -> a
mconcat [Text
s, Text
x, Text
s]
{-# INLINE surround #-}

opening :: El -> Text
opening :: El -> Text
opening = (\Text
x -> forall a. Monoid a => [a] -> a
mconcat [Text
"[", Text
x, Text
"]"]) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. IsString a => El -> a
elName
{-# INLINE opening #-}

openingArg :: El -> Text -> Text
openingArg :: El -> Text -> Text
openingArg El
el Text
arg = forall a. Monoid a => [a] -> a
mconcat [Text
"[", forall a. IsString a => El -> a
elName El
el, Text
"=", Text
arg, Text
"]"]
{-# INLINE openingArg #-}

closing :: El -> Text
closing :: El -> Text
closing El
x = forall a. Monoid a => [a] -> a
mconcat [Text
"[/", forall a. IsString a => El -> a
elName El
x, Text
"]"]
{-# INLINE closing #-}

wrap :: El -> Text -> Text
wrap :: El -> Text -> Text
wrap El
el Text
x = forall a. Monoid a => [a] -> a
mconcat [Text
"[", forall a. IsString a => El -> a
elName El
el, Text
"]", Text
x, Text
"[/", forall a. IsString a => El -> a
elName El
el, Text
"]"]
{-# INLINE wrap #-}

wrapArg :: El -> Text -> Text -> Text
wrapArg :: El -> Text -> Text -> Text
wrapArg El
el Text
arg Text
x = forall a. Monoid a => [a] -> a
mconcat [Text
"[", forall a. IsString a => El -> a
elName El
el, Text
"=", Text
arg, Text
"]", Text
x, Text
"[/", forall a. IsString a => El -> a
elName El
el, Text
"]"]

-- | Combine two predicates with OR
(|||) :: (a -> Bool) -> (a -> Bool) -> (a -> Bool)
||| :: forall a. (a -> Bool) -> (a -> Bool) -> a -> Bool
(|||) a -> Bool
pL a -> Bool
pR a
c = a -> Bool
pL a
c Bool -> Bool -> Bool
|| a -> Bool
pR a
c
{-# INLINE (|||) #-}