-
Notifications
You must be signed in to change notification settings - Fork 1
/
Entry.hs
53 lines (48 loc) · 1.63 KB
/
Entry.hs
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
module Entry
( Entry (..)
, loadEntry
) where
import qualified Data.ByteString.Char8 as S
import Data.Time (Day)
import Data.Text (unpack, pack, Text)
import Data.Text.Encoding (decodeUtf8With)
import Data.Text.Encoding.Error (lenientDecode)
import Model (TopicFormat (..))
toString :: S.ByteString -> String
toString = unpack . decodeUtf8With lenientDecode
data EntryFormat = EFHtml String | EFMarkdown String
deriving Show
loadEntry :: FilePath -> S.ByteString -> IO Entry
loadEntry file content = do
putStrLn $ "Loading " ++ file
let takeLine s =
let (x, y) = S.break (== '\n') s
in (toString $ S.takeWhile (/= '\r') x, S.drop 1 y)
let (firstLine, content') = takeLine content
(format, body) <-
case firstLine of
"!markdown" -> do
let (title, body) = takeLine content'
return (EFMarkdown title, body)
'!':x -> error $ "Unknown first line: " ++ x
_ -> return (EFHtml firstLine, content')
let (date', body') = takeLine body
date <- case reads date' of
(d, _):_ -> return d
_ -> error $ "Invalid date for " ++ file ++ ": " ++ date'
let (format', title) =
case format of
EFHtml title' -> (TFHtml, title')
EFMarkdown title' -> (TFMarkdown, title')
return Entry
{ entryTitle = pack title
, entryDay = date
, entryContent = pack $ toString body'
, entryFormat = format'
}
data Entry = Entry
{ entryTitle :: Text
, entryDay :: Day
, entryContent :: Text
, entryFormat :: TopicFormat
}