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 (TrimR:Chunk str :: String
str:ts :: [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 str :: String
str:TrimL:ts :: [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 (t :: TemplateElement
t:ts :: [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 t :: [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 (TrimL:ts :: [TemplateElement]
ts) = [TemplateElement] -> [TemplateElement]
process [TemplateElement]
ts
process ts :: [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 TrimR [] = []
trailing x :: TemplateElement
x xs :: [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 (TrimR:TrimL:ts :: [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 (t :: TemplateElement
t:ts :: [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 (TrimR:TrimR:ts :: [TemplateElement]
ts) = [TemplateElement] -> [TemplateElement]
process (TemplateElement
TrimRTemplateElement -> [TemplateElement] -> [TemplateElement]
forall a. a -> [a] -> [a]
:[TemplateElement]
ts)
process (TrimL:TrimL:ts :: [TemplateElement]
ts) = [TemplateElement] -> [TemplateElement]
process (TemplateElement
TrimLTemplateElement -> [TemplateElement] -> [TemplateElement]
forall a. a -> [a] -> [a]
:[TemplateElement]
ts)
process (t :: TemplateElement
t:ts :: [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 _ [] = []
recurse f :: [TemplateElement] -> [TemplateElement]
f (x :: TemplateElement
x:xs :: [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 y :: TemplateElement
y = case TemplateElement
y of
If e :: TemplateExpr
e tb :: [TemplateElement]
tb eb :: 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 e :: TemplateExpr
e t :: [TemplateElement]
t s :: 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
y