module Hakyllbars.Util where

import Control.Applicative (Alternative, empty)
import Data.Char
import Data.String.Utils as S
import Hakyllbars.Common

dropIndex :: FilePath -> FilePath
dropIndex :: [Char] -> [Char]
dropIndex [Char]
url = case [Char] -> ([Char], [Char])
splitFileName [Char]
url of
  ([Char]
p, [Char]
"index.html") -> [Char] -> [Char]
takeDirectory [Char]
p
  ([Char], [Char])
_ -> [Char]
url

stripSuffix :: String -> String -> String
stripSuffix :: [Char] -> [Char] -> [Char]
stripSuffix [Char]
suffix [Char]
text =
  if forall a. Int -> [a] -> [a]
drop Int
prefixLength [Char]
text forall a. Eq a => a -> a -> Bool
== [Char]
suffix
    then [Char]
prefix
    else [Char]
text
  where
    prefixLength :: Int
prefixLength = forall (t :: * -> *) a. Foldable t => t a -> Int
length [Char]
text forall a. Num a => a -> a -> a
- forall (t :: * -> *) a. Foldable t => t a -> Int
length [Char]
suffix
    prefix :: [Char]
prefix = forall a. Int -> [a] -> [a]
take Int
prefixLength [Char]
text

splitAndStrip ::
  -- | The delimiter to split the input string on.
  String ->
  -- | The string to split.
  String ->
  -- | The list of strings split from the input.
  [String]
splitAndStrip :: [Char] -> [Char] -> [[Char]]
splitAndStrip [Char]
d = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [Char] -> [Char]
S.strip forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Eq a => [a] -> [a] -> [[a]]
S.split [Char]
d

sequenceRules :: [Rules ()] -> Rules ()
sequenceRules :: [Rules ()] -> Rules ()
sequenceRules = forall (t :: * -> *) (f :: * -> *) a.
(Foldable t, Applicative f) =>
t (f a) -> f ()
sequenceA_

splitWordsBy :: (Char -> Bool) -> String -> [String]
splitWordsBy :: (Char -> Bool) -> [Char] -> [[Char]]
splitWordsBy Char -> Bool
_ [] = []
splitWordsBy Char -> Bool
f [Char]
xs = forall a. (a -> Bool) -> [a] -> [a]
takeWhile (Bool -> Bool
not forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Bool
f) [Char]
xs forall a. a -> [a] -> [a]
: (Char -> Bool) -> [Char] -> [[Char]]
splitWordsBy Char -> Bool
f (forall a. (a -> Bool) -> [a] -> [a]
dropWhile Char -> Bool
f [Char]
xs)

splitWordsByHumps :: String -> [String]
splitWordsByHumps :: [Char] -> [[Char]]
splitWordsByHumps [Char]
"" = []
splitWordsByHumps xss :: [Char]
xss@(Char
x : [Char]
_)
  | Char -> Bool
isUpper Char
x =
      let prefix :: [Char]
prefix = forall a. (a -> Bool) -> [a] -> [a]
takeWhile Char -> Bool
isUpper [Char]
xss
          rest :: [Char]
rest = forall a. (a -> Bool) -> [a] -> [a]
dropWhile Char -> Bool
isUpper [Char]
xss
       in if forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Char]
rest
            then [[Char]
prefix]
            else
              let currentLength :: Int
currentLength = forall (t :: * -> *) a. Foldable t => t a -> Int
length [Char]
prefix forall a. Num a => a -> a -> a
- Int
1
                  currentWord :: [Char]
currentWord = forall a. Int -> [a] -> [a]
take Int
currentLength [Char]
prefix
                  restWords :: [[Char]]
restWords = [Char] -> [[Char]]
splitWordsByHumps [Char]
rest
                  nextWord :: [Char]
nextWord = forall a. Int -> [a] -> [a]
drop Int
currentLength [Char]
prefix forall a. [a] -> [a] -> [a]
++ forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat (forall a. Int -> [a] -> [a]
take Int
1 [[Char]]
restWords)
               in [[Char]
y | [Char]
y <- [[Char]
currentWord, [Char]
nextWord], Bool -> Bool
not (forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Char]
y)] forall a. [a] -> [a] -> [a]
++ forall a. Int -> [a] -> [a]
drop Int
1 [[Char]]
restWords
  | Bool
otherwise =
      let currentWord :: [Char]
currentWord = forall a. (a -> Bool) -> [a] -> [a]
takeWhile (Bool -> Bool
not forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Bool
isUpper) [Char]
xss
          rest :: [Char]
rest = forall a. (a -> Bool) -> [a] -> [a]
dropWhile (Bool -> Bool
not forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Bool
isUpper) [Char]
xss
       in [Char]
currentWord forall a. a -> [a] -> [a]
: [Char] -> [[Char]]
splitWordsByHumps [Char]
rest

kebabToWords :: String -> [String]
kebabToWords :: [Char] -> [[Char]]
kebabToWords = (Char -> Bool) -> [Char] -> [[Char]]
splitWordsBy (forall a. Eq a => a -> a -> Bool
== Char
'-')

wordsToKebab :: [String] -> String
wordsToKebab :: [[Char]] -> [Char]
wordsToKebab = forall a. [a] -> [[a]] -> [a]
intercalate [Char]
"-"

camelToWords :: String -> [String]
camelToWords :: [Char] -> [[Char]]
camelToWords = [Char] -> [[Char]]
splitWordsByHumps

wordsToCamel :: [String] -> String
wordsToCamel :: [[Char]] -> [Char]
wordsToCamel [] = []
wordsToCamel [[Char]]
wss = [[Char]] -> [Char]
go forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Char -> Char
toLower forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [[Char]]
wss
  where
    go :: [[Char]] -> [Char]
go [] = []
    go ([Char]
w : [[Char]]
ws) = [Char]
w forall a. [a] -> [a] -> [a]
++ [[Char]] -> [Char]
firstToUpper [[Char]]
ws
    firstToUpper :: [[Char]] -> [Char]
firstToUpper = forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap \case
      (Char
w : [Char]
ws) -> Char -> Char
toUpper Char
w forall a. a -> [a] -> [a]
: [Char]
ws
      [] -> []

snakeToWords :: String -> [String]
snakeToWords :: [Char] -> [[Char]]
snakeToWords = (Char -> Bool) -> [Char] -> [[Char]]
splitWordsBy (forall a. Eq a => a -> a -> Bool
== Char
'_')

wordsToSnake :: [String] -> String
wordsToSnake :: [[Char]] -> [Char]
wordsToSnake = forall a. [a] -> [[a]] -> [a]
intercalate [Char]
"_"

camelToKebab :: String -> String
camelToKebab :: [Char] -> [Char]
camelToKebab = [[Char]] -> [Char]
wordsToKebab forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> [[Char]]
camelToWords

kebabToCamel :: String -> String
kebabToCamel :: [Char] -> [Char]
kebabToCamel = [[Char]] -> [Char]
wordsToCamel forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> [[Char]]
kebabToWords

snakeToCamel :: String -> String
snakeToCamel :: [Char] -> [Char]
snakeToCamel = [[Char]] -> [Char]
wordsToCamel forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> [[Char]]
snakeToWords

kebabToSnake :: String -> String
kebabToSnake :: [Char] -> [Char]
kebabToSnake = [[Char]] -> [Char]
wordsToSnake forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> [[Char]]
kebabToWords

snakeToKebab :: String -> String
snakeToKebab :: [Char] -> [Char]
snakeToKebab = [[Char]] -> [Char]
wordsToKebab forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> [[Char]]
snakeToWords

firstAlt :: (Foldable m, Alternative n) => m (n a) -> n a
firstAlt :: forall (m :: * -> *) (n :: * -> *) a.
(Foldable m, Alternative n) =>
m (n a) -> n a
firstAlt = forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
(<|>) forall (f :: * -> *) a. Alternative f => f a
empty

uncurry3 :: (a -> b -> c -> d) -> (a, b, c) -> d
uncurry3 :: forall a b c d. (a -> b -> c -> d) -> (a, b, c) -> d
uncurry3 a -> b -> c -> d
f (a
x, b
y, c
z) = a -> b -> c -> d
f a
x b
y c
z

curry3 :: ((a, b, c) -> d) -> a -> b -> c -> d
curry3 :: forall a b c d. ((a, b, c) -> d) -> a -> b -> c -> d
curry3 (a, b, c) -> d
f a
x b
y c
z = (a, b, c) -> d
f (a
x, b
y, c
z)

maybeHead :: [a] -> Maybe a
maybeHead :: forall a. [a] -> Maybe a
maybeHead (a
x : [a]
_) = forall a. a -> Maybe a
Just a
x
maybeHead [a]
_ = forall a. Maybe a
Nothing

commas :: [String] -> String
commas :: [[Char]] -> [Char]
commas [[Char]]
xs = [Char]
"[" forall a. [a] -> [a] -> [a]
++ forall a. [a] -> [[a]] -> [a]
intercalate [Char]
", " [[Char]]
xs forall a. [a] -> [a] -> [a]
++ [Char]
"]"