Setup a blog with Hakyll

Reference:
Hakyll. And it’s using
Pandoc library that
can convert documents between different formats.

Install

Hakyll Website:

1
2
3
4
5
6
7
8
9
10
11
# Create the skeleton website
$ stack install --only-dependencies
$ hakyll-init site
$ cd site

# Generate the website
$ stack build
$ stack exec site build

# Preview
$ ./site watch

Code Highlighting

Change the CSS/defaut to use pre-generated CSS from Pandoc to do syntax highlighting:

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
code {
font-size: 14px;
background-color: #f9f8fa;
line-height: 100%;
}

pre {
background-color: #f9f8fa;
border: 2px solid #bbb;
padding: 6px 10px;
border-radius: 5px;
overflow-x: auto;
}


/* Generated by pandoc. */
table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode, table.sourceCode pre
{
margin: 0;
padding: 0;
border: 0;
vertical-align: baseline;
border: none;
}
td.lineNumbers {
border-right: 1px solid #AAAAAA;
text-align: right; color: #AAAAAA;
padding-right: 5px;
padding-left: 5px;
}
td.sourceCode { padding-left: 5px; }
.sourceCode span.kw { color: #007020; font-weight: bold; }
.sourceCode span.dt { color: #902000; }
.sourceCode span.dv { color: #40a070; }
.sourceCode span.bn { color: #40a070; }
.sourceCode span.fl { color: #40a070; }
.sourceCode span.ch { color: #4070a0; }
.sourceCode span.st { color: #4070a0; }
.sourceCode span.co { color: #60a0b0; font-style: italic; }
.sourceCode span.ot { color: #007020; }
.sourceCode span.al { color: red; font-weight: bold; }
.sourceCode span.fu { color: #06287e; }
.sourceCode span.re { }
.sourceCode span.er { color: red; font-weight: bold; }

Math

Mostly followed this
blog post.

Write the site.hs file at the import module block:

1
2
import qualified Data.Set as S
import Text.Pandoc.Options

here it’s needed to tell the pages-hakyll.cabal that we added depends

1
2
3
4
5
executable site
main-is: site.hs
build-depends: base == 4.*, hakyll == 4.9.*, pandoc, containers
ghc-options: -threaded
default-language: Haskell2010

Creat the compiler pandocMathCompiler

1
2
3
4
5
6
7
8
9
10
pandocMathCompiler =
let mathExtensions = [Ext_tex_math_dollars, Ext_tex_math_double_backslash,
Ext_latex_macros]
defaultExtensions = writerExtensions defaultHakyllWriterOptions
newExtensions = foldr S.insert defaultExtensions mathExtensions
writerOptions = defaultHakyllWriterOptions {
writerExtensions = newExtensions,
writerHTMLMathMethod = MathJax ""
}
in pandocCompilerWith defaultHakyllReaderOptions writerOptions

Add the Mathjax in the template default.html:

1
2
<script type="text/javascript"
src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>

Math test:

$E = mc^2$

$$\Delta_A(\lambda)=\det(\lambda I-A)$$

\begin{aligned}
\dot{x} & = \sigma(y-x) \\
\dot{y} & = -\beta z + xy
\end{aligned}

Add tags

This blog shows the steps.

Change the 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
    -- build up tags
tags <- buildTags "posts/*" (fromCapture "tags/*.html")

-- generate tag page
tagsRules tags $ \tag pattern -> do
let title = "Posts tagged \"" ++ tag ++ "\""
route idRoute
compile $ do
posts <- recentFirst =<< loadAll pattern
let ctx = constField "title" title
`mappend` listField "posts" postCtx (return posts)
`mappend` defaultContext

makeItem ""
>>= loadAndApplyTemplate "templates/tag.html" ctx
>>= loadAndApplyTemplate "templates/default.html" ctx
>>= relativizeUrls

match "posts/*" $ do
route $ setExtension "html"
compile $ pandocCompiler
>>= loadAndApplyTemplate "templates/post.html" (postCtxWithTags tags)
>>= loadAndApplyTemplate "templates/default.html" (postCtxWithTags tags)
>>= relativizeUrls

-------- after the postCtx --------

postCtxWithTags :: Tags -> Context String
postCtxWithTags tags = tagsField "tags" tags `mappend` postCtx

also need to change template/post.html and create a tag page template/tag.html.