module Hakyll.Web.Template.Internal.Trim
( trim
) where
import Data.Char (isSpace)
import Data.List (dropWhileEnd)
import Hakyll.Web.Template.Internal.Element
trim :: [TemplateElement] -> [TemplateElement]
trim :: [TemplateElement] -> [TemplateElement]
trim = [TemplateElement] -> [TemplateElement]
cleanse ([TemplateElement] -> [TemplateElement])
-> ([TemplateElement] -> [TemplateElement])
-> [TemplateElement]
-> [TemplateElement]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [TemplateElement] -> [TemplateElement]
canonicalize
cleanse :: [TemplateElement] -> [TemplateElement]
cleanse :: [TemplateElement] -> [TemplateElement]
cleanse = ([TemplateElement] -> [TemplateElement])
-> [TemplateElement] -> [TemplateElement]
recurse [TemplateElement] -> [TemplateElement]
cleanse ([TemplateElement] -> [TemplateElement])
-> ([TemplateElement] -> [TemplateElement])
-> [TemplateElement]
-> [TemplateElement]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [TemplateElement] -> [TemplateElement]
process
where process :: [TemplateElement] -> [TemplateElement]
process [] = []
process (TemplateElement
TrimR:Chunk String
str:[TemplateElement]
ts) = let str' :: String
str' = (Char -> Bool) -> String -> String
forall a. (a -> Bool) -> [a] -> [a]
dropWhile Char -> Bool
isSpace String
str
in if String -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
str'
then [TemplateElement] -> [TemplateElement]
process [TemplateElement]
ts
else [TemplateElement] -> [TemplateElement]
process ([TemplateElement] -> [TemplateElement])
-> [TemplateElement] -> [TemplateElement]
forall a b. (a -> b) -> a -> b
$ String -> TemplateElement
Chunk String
str'TemplateElement -> [TemplateElement] -> [TemplateElement]
forall a. a -> [a] -> [a]
:[TemplateElement]
ts
process (Chunk String
str:TemplateElement
TrimL:[TemplateElement]
ts) = let str' :: String
str' = (Char -> Bool) -> String -> String
forall a. (a -> Bool) -> [a] -> [a]
dropWhileEnd Char -> Bool
isSpace String
str
in if String -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
str'
then [TemplateElement] -> [TemplateElement]
process [TemplateElement]
ts
else String -> TemplateElement
Chunk String
str'TemplateElement -> [TemplateElement] -> [TemplateElement]
forall a. a -> [a] -> [a]
:[TemplateElement] -> [TemplateElement]
process [TemplateElement]
ts
process (TemplateElement
t:[TemplateElement]
ts) = TemplateElement
tTemplateElement -> [TemplateElement] -> [TemplateElement]
forall a. a -> [a] -> [a]
:[TemplateElement] -> [TemplateElement]
process [TemplateElement]
ts
canonicalize :: [TemplateElement] -> [TemplateElement]
canonicalize :: [TemplateElement] -> [TemplateElement]
canonicalize = [TemplateElement] -> [TemplateElement]
go
where go :: [TemplateElement] -> [TemplateElement]
go [TemplateElement]
t = let t' :: [TemplateElement]
t' = [TemplateElement] -> [TemplateElement]
redundant ([TemplateElement] -> [TemplateElement])
-> ([TemplateElement] -> [TemplateElement])
-> [TemplateElement]
-> [TemplateElement]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [TemplateElement] -> [TemplateElement]
swap ([TemplateElement] -> [TemplateElement])
-> [TemplateElement] -> [TemplateElement]
forall a b. (a -> b) -> a -> b
$ [TemplateElement] -> [TemplateElement]
dedupe [TemplateElement]
t
in if [TemplateElement]
t [TemplateElement] -> [TemplateElement] -> Bool
forall a. Eq a => a -> a -> Bool
== [TemplateElement]
t' then [TemplateElement]
t else [TemplateElement] -> [TemplateElement]
go [TemplateElement]
t'
redundant :: [TemplateElement] -> [TemplateElement]
redundant :: [TemplateElement] -> [TemplateElement]
redundant = ([TemplateElement] -> [TemplateElement])
-> [TemplateElement] -> [TemplateElement]
recurse [TemplateElement] -> [TemplateElement]
redundant ([TemplateElement] -> [TemplateElement])
-> ([TemplateElement] -> [TemplateElement])
-> [TemplateElement]
-> [TemplateElement]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [TemplateElement] -> [TemplateElement]
process
where
process :: [TemplateElement] -> [TemplateElement]
process (TemplateElement
TrimL:[TemplateElement]
ts) = [TemplateElement] -> [TemplateElement]
process [TemplateElement]
ts
process [TemplateElement]
ts = (TemplateElement -> [TemplateElement] -> [TemplateElement])
-> [TemplateElement] -> [TemplateElement] -> [TemplateElement]
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr TemplateElement -> [TemplateElement] -> [TemplateElement]
trailing [] [TemplateElement]
ts
where trailing :: TemplateElement -> [TemplateElement] -> [TemplateElement]
trailing TemplateElement
TrimR [] = []
trailing TemplateElement
x [TemplateElement]
xs = TemplateElement
xTemplateElement -> [TemplateElement] -> [TemplateElement]
forall a. a -> [a] -> [a]
:[TemplateElement]
xs
swap :: [TemplateElement] -> [TemplateElement]
swap :: [TemplateElement] -> [TemplateElement]
swap = ([TemplateElement] -> [TemplateElement])
-> [TemplateElement] -> [TemplateElement]
recurse [TemplateElement] -> [TemplateElement]
swap ([TemplateElement] -> [TemplateElement])
-> ([TemplateElement] -> [TemplateElement])
-> [TemplateElement]
-> [TemplateElement]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [TemplateElement] -> [TemplateElement]
process
where process :: [TemplateElement] -> [TemplateElement]
process [] = []
process (TemplateElement
TrimR:TemplateElement
TrimL:[TemplateElement]
ts) = TemplateElement
TrimLTemplateElement -> [TemplateElement] -> [TemplateElement]
forall a. a -> [a] -> [a]
:[TemplateElement] -> [TemplateElement]
process (TemplateElement
TrimRTemplateElement -> [TemplateElement] -> [TemplateElement]
forall a. a -> [a] -> [a]
:[TemplateElement]
ts)
process (TemplateElement
t:[TemplateElement]
ts) = TemplateElement
tTemplateElement -> [TemplateElement] -> [TemplateElement]
forall a. a -> [a] -> [a]
:[TemplateElement] -> [TemplateElement]
process [TemplateElement]
ts
dedupe :: [TemplateElement] -> [TemplateElement]
dedupe :: [TemplateElement] -> [TemplateElement]
dedupe = ([TemplateElement] -> [TemplateElement])
-> [TemplateElement] -> [TemplateElement]
recurse [TemplateElement] -> [TemplateElement]
dedupe ([TemplateElement] -> [TemplateElement])
-> ([TemplateElement] -> [TemplateElement])
-> [TemplateElement]
-> [TemplateElement]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [TemplateElement] -> [TemplateElement]
process
where process :: [TemplateElement] -> [TemplateElement]
process [] = []
process (TemplateElement
TrimR:TemplateElement
TrimR:[TemplateElement]
ts) = [TemplateElement] -> [TemplateElement]
process (TemplateElement
TrimRTemplateElement -> [TemplateElement] -> [TemplateElement]
forall a. a -> [a] -> [a]
:[TemplateElement]
ts)
process (TemplateElement
TrimL:TemplateElement
TrimL:[TemplateElement]
ts) = [TemplateElement] -> [TemplateElement]
process (TemplateElement
TrimLTemplateElement -> [TemplateElement] -> [TemplateElement]
forall a. a -> [a] -> [a]
:[TemplateElement]
ts)
process (TemplateElement
t:[TemplateElement]
ts) = TemplateElement
tTemplateElement -> [TemplateElement] -> [TemplateElement]
forall a. a -> [a] -> [a]
:[TemplateElement] -> [TemplateElement]
process [TemplateElement]
ts
recurse :: ([TemplateElement] -> [TemplateElement])
-> [TemplateElement]
-> [TemplateElement]
recurse :: ([TemplateElement] -> [TemplateElement])
-> [TemplateElement] -> [TemplateElement]
recurse [TemplateElement] -> [TemplateElement]
_ [] = []
recurse [TemplateElement] -> [TemplateElement]
f (TemplateElement
x:[TemplateElement]
xs) = TemplateElement -> TemplateElement
process TemplateElement
xTemplateElement -> [TemplateElement] -> [TemplateElement]
forall a. a -> [a] -> [a]
:([TemplateElement] -> [TemplateElement])
-> [TemplateElement] -> [TemplateElement]
recurse [TemplateElement] -> [TemplateElement]
f [TemplateElement]
xs
where process :: TemplateElement -> TemplateElement
process TemplateElement
y = case TemplateElement
y of
If TemplateExpr
e [TemplateElement]
tb Maybe [TemplateElement]
eb -> TemplateExpr
-> [TemplateElement] -> Maybe [TemplateElement] -> TemplateElement
If TemplateExpr
e ([TemplateElement] -> [TemplateElement]
f [TemplateElement]
tb) ([TemplateElement] -> [TemplateElement]
f ([TemplateElement] -> [TemplateElement])
-> Maybe [TemplateElement] -> Maybe [TemplateElement]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe [TemplateElement]
eb)
For TemplateExpr
e [TemplateElement]
t Maybe [TemplateElement]
s -> TemplateExpr
-> [TemplateElement] -> Maybe [TemplateElement] -> TemplateElement
For TemplateExpr
e ([TemplateElement] -> [TemplateElement]
f [TemplateElement]
t) ([TemplateElement] -> [TemplateElement]
f ([TemplateElement] -> [TemplateElement])
-> Maybe [TemplateElement] -> Maybe [TemplateElement]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe [TemplateElement]
s)
TemplateElement
_ -> TemplateElement
y