summaryrefslogtreecommitdiff
path: root/src/Hakyll/Web/Util/String.hs
blob: 0dde74a9b030ddb5822a33d53d1c3633d89d3fa2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
-- | Miscellaneous string manipulation functions.
--
module Hakyll.Web.Util.String
    ( trim
    , replaceAll
    , splitAll
    , toUrl
    , toSiteRoot
    ) where

import Data.Char (isSpace)
import Data.Maybe (listToMaybe)

import System.FilePath (splitPath, takeDirectory, joinPath)
import Text.Regex.PCRE ((=~~))

-- | 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)

-- | Convert a filepath to an URL starting from the site root
--
-- Example:
--
-- > toUrl "foo/bar.html"
--
-- Result:
--
-- > "/foo/bar.html"
--
toUrl :: FilePath -> String
toUrl = ('/' :)

-- | Get the relative url to the site root, for a given (absolute) url
--
toSiteRoot :: String -> String
toSiteRoot = emptyException . joinPath . map parent . splitPath . takeDirectory
  where
    parent = const ".."
    emptyException [] = "."
    emptyException x  = x