-
Notifications
You must be signed in to change notification settings - Fork 0
/
site.hs
151 lines (124 loc) · 5.26 KB
/
site.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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
--------------------------------------------------------------------------------
{-# LANGUAGE OverloadedStrings #-}
import Control.Arrow ((&&&))
import qualified Data.Map.Strict as M
import Data.Maybe (maybeToList)
import Data.Monoid (mappend)
import System.FilePath
import Text.Pandoc
import Text.Pandoc.Definition
import Text.Pandoc.Walk
import Hakyll
--------------------------------------------------------------------------------
main :: IO ()
main = hakyllWith config $ do
match "images/**" $ do
route idRoute
compile copyFileCompiler
match "css/**" $ do
route idRoute
compile compressCssCompiler
match (fromList ["links.markdown", "contact.markdown"]) $ do
route $ setExtension "html"
compile $ pandocCompiler
>>= loadAndApplyTemplate "templates/default.html" blogCtx
>>= relativizeUrls
tags <- buildTags "posts/*" (fromCapture "tags/*.html")
tagsRules tags $ \tag pattern -> do
let title = "Posts tagged \"" ++ tag ++ "\""
route idRoute
compile $ do
posts <- recentFirst =<< loadAll pattern
let tagCtx =
constField "title" title `mappend`
listField "posts" postCtx (return posts) `mappend`
blogCtx
makeItem ""
>>= loadAndApplyTemplate "templates/tags.html" tagCtx
>>= loadAndApplyTemplate "templates/default.html" tagCtx
>>= relativizeUrls
match "posts/*" $ do
route $ setExtension "html"
compile $ do
snippetMap <- oSnippetsMap <$> loadAll ("code/**" .||. "site.hs")
pandocCompilerWithCodeInsertion snippetMap
>>= loadAndApplyTemplate "templates/post.html" (postCtxWithTags tags)
>>= loadAndApplyTemplate "templates/default.html" (postCtxWithTags tags)
>>= relativizeUrls
create ["archive.html"] $ do
route idRoute
compile $ do
posts <- recentFirst =<< loadAll "posts/*"
let archiveCtx =
constField "title" "Archives" `mappend`
listField "posts" postCtx (return posts) `mappend`
blogCtx
makeItem ""
>>= loadAndApplyTemplate "templates/archive.html" archiveCtx
>>= loadAndApplyTemplate "templates/default.html" archiveCtx
>>= relativizeUrls
create ["tags.html"] $ do
route idRoute
compile $ do
let tagsCtx =
constField "title" "Tags collection" `mappend`
listField "tags" postCtx (traverse (makeItem . fst) (tagsMap tags)) `mappend`
blogCtx
makeItem ""
>>= loadAndApplyTemplate "templates/tag-list.html" tagsCtx
>>= loadAndApplyTemplate "templates/default.html" tagsCtx
>>= relativizeUrls
match "index.html" $ do
route idRoute
compile $ do
posts <- recentFirst =<< loadAll "posts/*"
let indexCtx =
listField "posts" postCtx (return (take 3 posts)) `mappend`
constField "title" "Home" `mappend`
blogCtx
getResourceBody
>>= applyAsTemplate indexCtx
>>= loadAndApplyTemplate "templates/default.html" indexCtx
>>= relativizeUrls
match "code/**" $ do
route idRoute
compile getResourceString
match "sources/**" $ do
route idRoute
compile copyFileCompiler
match "site.hs" $ do
compile getResourceString
match "templates/*" $ compile templateBodyCompiler
--------------------------------------------------------------------------------
config :: Configuration
config = defaultConfiguration
{ deployCommand = "rsync --size-only -ave 'ssh -p 22' _site/ [email protected]:.blog/"
}
blogCtx :: Context String
blogCtx =
constField "blog_title" "Tobi's blog" `mappend`
constField "blog_name" "My blog about programming and other stuff" `mappend`
defaultContext
postCtx :: Context String
postCtx =
dateField "date" "%B %e, %Y" `mappend`
blogCtx
postCtxWithTags :: Tags -> Context String
postCtxWithTags tags = tagsField "tags" tags `mappend` postCtx
oSnippetsMap :: [Item String] -> M.Map FilePath String
oSnippetsMap is = M.fromList kvs
where kvs = map ((toFilePath . itemIdentifier) &&& itemBody) is
pandocCompilerWithCodeInsertion :: M.Map FilePath String -> Compiler (Item String)
pandocCompilerWithCodeInsertion snippetMap =
pandocCompilerWithTransform defaultHakyllReaderOptions defaultHakyllWriterOptions (codeInclude snippetMap)
codeInclude :: M.Map FilePath String -> Pandoc -> Pandoc
codeInclude snippetMap = walk $ \block -> case block of
div@(Div (_,cs,_) _) -> if "code-include" `elem` cs
then codeBlockFromDiv snippetMap div
else block
_ -> block
codeBlockFromDiv snippetMap div@(Div (_,_,kvs) _) =
let classes = maybeToList $ lookup "lexer" kvs
content = lookup "file" kvs >>= (`M.lookup` snippetMap)
in maybe Null (CodeBlock ("",classes,[])) content
codeBlockFromDiv _ _ = Null