diff options
author | Jasper Van der Jeugt <m@jaspervdj.be> | 2017-06-19 11:57:23 +0200 |
---|---|---|
committer | Jasper Van der Jeugt <m@jaspervdj.be> | 2017-06-19 11:57:23 +0200 |
commit | 67ecff7ad383640bc73d64edc2506c7cc648a134 (patch) | |
tree | 6d328e43c3ab86c29a2d775fabaa23618c16fb51 /lib/Hakyll/Core/Util | |
parent | 2df3209bafa08e6b77ee4a8598fc503269513527 (diff) | |
download | hakyll-67ecff7ad383640bc73d64edc2506c7cc648a134.tar.gz |
Move src/ to lib/, put Init.hs in src/
Diffstat (limited to 'lib/Hakyll/Core/Util')
-rw-r--r-- | lib/Hakyll/Core/Util/File.hs | 56 | ||||
-rw-r--r-- | lib/Hakyll/Core/Util/Parser.hs | 32 | ||||
-rw-r--r-- | lib/Hakyll/Core/Util/String.hs | 78 |
3 files changed, 166 insertions, 0 deletions
diff --git a/lib/Hakyll/Core/Util/File.hs b/lib/Hakyll/Core/Util/File.hs new file mode 100644 index 0000000..9db6b11 --- /dev/null +++ b/lib/Hakyll/Core/Util/File.hs @@ -0,0 +1,56 @@ +-------------------------------------------------------------------------------- +-- | A module containing various file utility functions +module Hakyll.Core.Util.File + ( makeDirectories + , getRecursiveContents + , removeDirectory + ) where + + +-------------------------------------------------------------------------------- +import Control.Monad (filterM, forM, when) +import System.Directory (createDirectoryIfMissing, + doesDirectoryExist, getDirectoryContents, + removeDirectoryRecursive) +import System.FilePath (takeDirectory, (</>)) + + +-------------------------------------------------------------------------------- +-- | Given a path to a file, try to make the path writable by making +-- all directories on the path. +makeDirectories :: FilePath -> IO () +makeDirectories = createDirectoryIfMissing True . takeDirectory + + +-------------------------------------------------------------------------------- +-- | Get all contents of a directory. +getRecursiveContents :: (FilePath -> IO Bool) -- ^ Ignore this file/directory + -> FilePath -- ^ Directory to search + -> IO [FilePath] -- ^ List of files found +getRecursiveContents ignore top = go "" + where + isProper x + | x `elem` [".", ".."] = return False + | otherwise = not <$> ignore x + + go dir = do + dirExists <- doesDirectoryExist (top </> dir) + if not dirExists + then return [] + else do + names <- filterM isProper =<< getDirectoryContents (top </> dir) + paths <- forM names $ \name -> do + let rel = dir </> name + isDirectory <- doesDirectoryExist (top </> rel) + if isDirectory + then go rel + else return [rel] + + return $ concat paths + + +-------------------------------------------------------------------------------- +removeDirectory :: FilePath -> IO () +removeDirectory fp = do + e <- doesDirectoryExist fp + when e $ removeDirectoryRecursive fp diff --git a/lib/Hakyll/Core/Util/Parser.hs b/lib/Hakyll/Core/Util/Parser.hs new file mode 100644 index 0000000..c4b2f8d --- /dev/null +++ b/lib/Hakyll/Core/Util/Parser.hs @@ -0,0 +1,32 @@ +-------------------------------------------------------------------------------- +-- | Parser utilities +module Hakyll.Core.Util.Parser + ( metadataKey + , reservedKeys + ) where + + +-------------------------------------------------------------------------------- +import Control.Applicative ((<|>)) +import Control.Monad (guard, mzero, void) +import qualified Text.Parsec as P +import Text.Parsec.String (Parser) + + +-------------------------------------------------------------------------------- +metadataKey :: Parser String +metadataKey = do + -- Ensure trailing '-' binds to '$' if present. + let hyphon = P.try $ do + void $ P.char '-' + x <- P.lookAhead P.anyChar + guard $ x /= '$' + pure '-' + + i <- (:) <$> P.letter <*> P.many (P.alphaNum <|> P.oneOf "_." <|> hyphon) + if i `elem` reservedKeys then mzero else return i + + +-------------------------------------------------------------------------------- +reservedKeys :: [String] +reservedKeys = ["if", "else", "endif", "for", "sep", "endfor", "partial"] diff --git a/lib/Hakyll/Core/Util/String.hs b/lib/Hakyll/Core/Util/String.hs new file mode 100644 index 0000000..23bdd39 --- /dev/null +++ b/lib/Hakyll/Core/Util/String.hs @@ -0,0 +1,78 @@ +{-# LANGUAGE FlexibleContexts #-} +-------------------------------------------------------------------------------- +-- | Miscellaneous string manipulation functions. +module Hakyll.Core.Util.String + ( trim + , replaceAll + , splitAll + , needlePrefix + ) where + + +-------------------------------------------------------------------------------- +import Data.Char (isSpace) +import Data.List (isPrefixOf) +import Data.Maybe (listToMaybe) +import Text.Regex.TDFA ((=~~)) + + +-------------------------------------------------------------------------------- +-- | Trim a string (drop spaces, tabs and newlines at both sides). +trim :: String -> String +trim = reverse . trim' . reverse . trim' + where + trim' = dropWhile isSpace + + +-------------------------------------------------------------------------------- +-- | A simple (but inefficient) regex replace funcion +replaceAll :: String -- ^ Pattern + -> (String -> String) -- ^ Replacement (called on capture) + -> String -- ^ Source string + -> String -- ^ Result +replaceAll pattern f source = replaceAll' source + where + replaceAll' src = case listToMaybe (src =~~ pattern) of + Nothing -> src + Just (o, l) -> + let (before, tmp) = splitAt o src + (capture, after) = splitAt l tmp + in before ++ f capture ++ replaceAll' after + + +-------------------------------------------------------------------------------- +-- | A simple regex split function. The resulting list will contain no empty +-- strings. +splitAll :: String -- ^ Pattern + -> String -- ^ String to split + -> [String] -- ^ Result +splitAll pattern = filter (not . null) . splitAll' + where + splitAll' src = case listToMaybe (src =~~ pattern) of + Nothing -> [src] + Just (o, l) -> + let (before, tmp) = splitAt o src + in before : splitAll' (drop l tmp) + + + +-------------------------------------------------------------------------------- +-- | Find the first instance of needle (must be non-empty) in haystack. We +-- return the prefix of haystack before needle is matched. +-- +-- Examples: +-- +-- > needlePrefix "cd" "abcde" = "ab" +-- +-- > needlePrefix "ab" "abc" = "" +-- +-- > needlePrefix "ab" "xxab" = "xx" +-- +-- > needlePrefix "a" "xx" = "xx" +needlePrefix :: String -> String -> Maybe String +needlePrefix needle haystack = go [] haystack + where + go _ [] = Nothing + go acc xss@(x:xs) + | needle `isPrefixOf` xss = Just $ reverse acc + | otherwise = go (x : acc) xs |