-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsite.hs
270 lines (228 loc) · 8.77 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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
--------------------------------------------------------------------------------
{-# LANGUAGE OverloadedStrings #-}
import Control.Applicative ()
import Control.Monad (void)
import Data.Monoid ()
import System.FilePath (takeBaseName, takeDirectory, (</>))
import Text.Pandoc
import Text.Parsec
import Text.Parsec.String
import Hakyll
--------------------------------------------------------------------------------
main :: IO ()
main = hakyll $ do
-- copy index.html to build directory (only for GH pages)
match "index.html" $ do
route idRoute
compile copyFileCompiler
-- copy CNAME file to build directory
match "CNAME" $ do
route idRoute
compile copyFileCompiler
-- copy image files to build directory
match "images/*" $ do
route idRoute
compile copyFileCompiler
-- copy PDF files to build directory
match "pdfs/*" $ do
route idRoute
compile copyFileCompiler
-- compress CSS files
match "css/*" $ do
route idRoute
compile compressCssCompiler
-- compile citation files
match "*.bib" $ compile $ biblioCompiler
match "*.csl" $ compile $ cslCompiler
-- compile templates
match "templates/*" $ compile templateCompiler
-- compile TOCs for pages that have multiple sections
match (fromList ["motivation.md", -- en
"motivacion.md", -- es
"technical-overview.md", -- en
"resumen-tecnico.md", -- es
"notes/getting-into-shapes-with-shacl.md",
"2016-workshop.md", "2017-workshop.md"]) $ version "toc" $
compile $ pandocCompilerWith defaultHakyllReaderOptions
defaultHakyllWriterOptions {
writerTableOfContents = True
, writerTemplate = Just (
-- all this insanity to turn a string
-- literal into a pandoc Template...
either error id $
either (error . show) id $
Text.Pandoc.runPure $
Text.Pandoc.runWithDefaultPartials $
Text.Pandoc.compileTemplate "" "$toc$"
)
}
-- compile English pages with citations (optional) and TOCs
match (fromList ["motivation.md",
"publications.md",
"technical-overview.md",
"notes/getting-into-shapes-with-shacl.md",
"2016-workshop.md", "2017-workshop.md"]) $ do
route $ niceRoute
compile $ citeCompiler >>= enPageCompiler tocCtx
-- compile Spanish pages with citations (optional) and TOCs
match (fromList ["motivacion.md",
"resumen-tecnico.md"]) $ do
route $ niceRoute
compile $ citeCompiler >>= esPageCompiler tocCtx
-- compile other pages
match "*.md" $ do
route $ niceRoute
compile $ pandocCompiler >>= enPageCompiler defaultContext
-- compile guide articles
match "guide/*.md" $ compile pandocCompiler
-- generate guide page from guide sections
create ["guide/index.html"] $ do
route idRoute
compile $ do
sections <- loadAll "guide/*.md"
let indexCtx =
listField "sections" defaultContext (return sections) `mappend`
mconcat [ constField "title" "Guide to using PeriodO"
, constField "guide" "true"
] `mappend`
defaultContext
makeItem ""
>>= loadAndApplyTemplate "templates/guide.html" indexCtx
>>= enPageCompiler indexCtx
-- compile index sections in English and Spanish
match "index-sections-en/*" $ compile pandocCompiler
match "index-sections-es/*" $ compile pandocCompiler
-- generate English index page from index sections
create ["en/index.html"] $ do
route idRoute
compile $ do
sections <- loadAll "index-sections-en/*"
let indexCtx =
listField "sections" defaultContext (return sections) `mappend`
mconcat [ constField "title" "Periods, Organized"
, constField "home" "true"
] `mappend`
defaultContext
makeItem ""
>>= loadAndApplyTemplate "templates/index-en.html" indexCtx
>>= enPageCompiler indexCtx
-- generate Spanish index page from index sections
create ["es/index.html"] $ do
route idRoute
compile $ do
sections <- loadAll "index-sections-es/*"
let indexCtx =
listField "sections" defaultContext (return sections) `mappend`
mconcat [ constField "title" "Periodos, Organizados"
, constField "home" "true"
] `mappend`
defaultContext
makeItem ""
>>= loadAndApplyTemplate "templates/index-es.html" indexCtx
>>= esPageCompiler indexCtx
-- redirects of legacy URLs
create ["data-model/index.html"] $ do
route idRoute
compile $ do
let ctx =
mconcat [ constField "title" "Data Model"
, constField "location" "/technical-overview/#periods"
] `mappend`
defaultContext
makeItem ""
>>= loadAndApplyTemplate "templates/redirect.html" ctx
create ["old-guide/index.html"] $ do
route idRoute
compile $ do
let ctx =
mconcat [ constField "title" "Guide to using PeriodO"
, constField "location" "/guide/"
] `mappend`
defaultContext
makeItem ""
>>= loadAndApplyTemplate "templates/redirect.html" ctx
-- utilities -------------------------------------------------------------------
-- standard English page compiler
enPageCompiler :: Context String -> Item String -> Compiler (Item String)
enPageCompiler ctx item =
loadAndApplyTemplate "templates/default-en.html" ctx item
>>= applyKeywords
>>= relativizeUrls
-- standard Spanish page compiler
esPageCompiler :: Context String -> Item String -> Compiler (Item String)
esPageCompiler ctx item =
loadAndApplyTemplate "templates/default-es.html" ctx item
>>= applyKeywords
>>= relativizeUrls
-- compiler for Markdown files with citations
citeCompiler :: Compiler (Item String)
citeCompiler = do
csl <- load "chicago-author-date.csl"
bib <- load "refs.bib"
getResourceBody
>>= readPandocBiblio defaultHakyllReaderOptions csl bib
>>= return . writePandoc
-- template context with a TOC variable
tocCtx :: Context String
tocCtx = mconcat [ field "toc" $ \item ->
loadBody ((itemIdentifier item) {
identifierVersion = Just "toc" })
, defaultContext
]
-- replace a foo/bar.md by foo/bar/index.html
-- this way the url looks like: foo/bar in most browsers
niceRoute :: Routes
niceRoute = customRoute createIndexRoute
where
createIndexRoute ident =
takeDirectory p </> takeBaseName p </> "index.html"
where p=toFilePath ident
-- SVG keyword -----------------------------------------------------------------
-- based on https://xinitrc.de/2013/06/22/3.26-Lightyears-away.html
-- parsing
newtype Keywords = Keywords
{ unKeyword :: [KeywordElement]
} deriving (Show, Eq)
data KeywordElement
= Chunk String
| SVG String String String
deriving (Show, Eq)
readKeywords :: String -> Keywords
readKeywords input = case parse keywords "" input of
Left err -> error $ "Cannot parse keywords: " ++ show err
Right t -> t
keywords :: Parser Keywords
keywords = Keywords <$> many1 (chunk <|> svg)
chunk :: Parser KeywordElement
chunk = Chunk <$> many1 (noneOf "§")
svg :: Parser KeywordElement
svg = try $ do
void $ string "§svg("
cls <- many1 $ noneOf ","
void $ string ", "
alt <- many1 $ noneOf ","
void $ string ", "
file <-many1 $ noneOf ")"
void $ string ")§"
return $ SVG cls alt file
-- compiling
applyKeywords :: Item String -> Compiler (Item String)
applyKeywords item = do
body <- applyKeywords' $ readKeywords $ itemBody item
return $ itemSetBody body item
applyKeywords' :: Keywords -> Compiler String
applyKeywords' kws = do
items <- mapM applyKWs $ unKeyword kws
return $ concatMap itemBody items
where
applyKWs (Chunk c) = makeItem c
applyKWs (SVG cls alt file) = svgCompiler cls alt file
svgCompiler :: String -> String -> String -> Compiler (Item String)
empty :: String
empty = ""
svgCompiler cls alt file =
makeItem empty >>= loadAndApplyTemplate "templates/svg.html" (
mconcat [ constField "cls" cls
, constField "alt" alt
, constField "file" file
])