module Hakyll.Convert.OutputFormat
(validOutputFormat, formatPath)
where
import Data.Default
import Data.Time.Format (formatTime, defaultTimeLocale)
import System.FilePath
import Hakyll.Convert.Common
import qualified Data.Text as T
import qualified Data.Map.Strict as M
validOutputFormat :: T.Text -> Bool
validOutputFormat format
| T.null format = False
| otherwise =
case formatPath format def of
Just _ -> True
Nothing -> False
formatPath :: T.Text -> DistilledPost -> Maybe T.Text
formatPath format post = helper [] format >>= return.T.concat
where
helper acc input =
case T.uncons input of
Just ('%', rest) ->
case T.uncons rest of
Just (ch, rest2) ->
if ch `M.member` acceptableFormats
then let formatter = acceptableFormats M.! ch
in helper ((formatter post):acc) rest2
else Nothing
Just (ch, rest) -> helper ((T.singleton ch):acc) rest
Nothing -> Just $ reverse acc
acceptableFormats :: M.Map Char (DistilledPost -> T.Text)
acceptableFormats = M.fromList [
('%', const $ T.singleton '%')
, ('o', fmtOriginalPath)
, ('s', fmtSlug)
, ('y', fmtYear2)
, ('Y', fmtYear4)
, ('m', fmtMonth)
, ('d', fmtDay)
, ('H', fmtHour)
, ('M', fmtMinute)
, ('S', fmtSecond)
]
fmtOriginalPath post =
T.pack
. dropTrailingSlash
. dropExtensions
$ chopUri (dpUri post)
where
dropTrailingSlash = reverse . dropWhile (== '/') . reverse
chopUri (dropPrefix "http://" -> ("",rest)) =
joinPath $ drop 1
$ splitPath rest
chopUri u = error $
"We've wrongly assumed that blog post URIs start with http://, but we got: " ++ u
dropPrefix :: Eq a => [a] -> [a] -> ([a],[a])
dropPrefix (x:xs) (y:ys) | x == y = dropPrefix xs ys
dropPrefix left right = (left,right)
fmtSlug post =
T.reverse
. (T.takeWhile (/= '/'))
. T.reverse
$ fmtOriginalPath post
fmtDate format = T.pack . (formatTime defaultTimeLocale format) . dpDate
fmtYear2 = fmtDate "%y"
fmtYear4 = fmtDate "%Y"
fmtMonth = fmtDate "%m"
fmtDay = fmtDate "%d"
fmtHour = fmtDate "%H"
fmtMinute = fmtDate "%M"
fmtSecond = fmtDate "%S"