Skip to content

Commit

Permalink
Upgrade to Hakyll 4 and fix that damn indenting
Browse files Browse the repository at this point in the history
  • Loading branch information
ocharles committed Feb 10, 2013
1 parent 5cd8554 commit d206a82
Show file tree
Hide file tree
Showing 22 changed files with 119 additions and 102 deletions.
68 changes: 39 additions & 29 deletions hakyll.hs
Original file line number Diff line number Diff line change
@@ -1,48 +1,58 @@
{-# LANGUAGE Arrows, OverloadedStrings #-}
import Control.Arrow
{-# LANGUAGE OverloadedStrings #-}
import Control.Applicative
import Control.Monad
import Data.Monoid
import Hakyll
import Text.Pandoc

main :: IO ()
main = hakyll $ do
match "templates/*.html" $ compile templateCompiler
match "templates/*" $
compile $ templateCompiler

match "css/***.css" $ route idRoute >> compile copyFileCompiler
match "img/***" $ route idRoute >> compile copyFileCompiler
match "css/***.css" $ do
route idRoute
compile copyFileCompiler

match "img/***" $ do
route idRoute
compile copyFileCompiler

match "posts/***.md" $ do
route $ setExtension "html"
compile $ (pageCompilerWith defaultParserState withToc)
>>> arr (renderDateField "date" "%Y-%m-%d" "Date Unknown")
>>> applyTemplateCompiler "templates/post.html"
>>> applyTemplateCompiler "templates/default.html"
>>> relativizeUrlsCompiler
compile $ pandocCompiler
>>= saveSnapshot "content"
>>= loadAndApplyTemplate "templates/post.html" defaultContext
>>= loadAndApplyTemplate "templates/default.html" defaultContext
>>= relativizeUrls

match "index.html" $ route idRoute
create "index.html" $ constA mempty
>>> arr (setField "title" "Posts")
>>> setFieldPageList recentFirst
"templates/postitem.html" "posts" "posts/*"
>>> applyTemplateCompiler "templates/posts.html"
>>> applyTemplateCompiler "templates/default.html"
>>> relativizeUrlsCompiler
create ["index.html"] $ do
route idRoute
compile $ do
posts <- recentFirst <$> loadAll "posts/*"
postItem <- loadBody "templates/postitem.html"
postStr <- applyTemplateList postItem defaultContext posts
makeItem ""
>>= loadAndApplyTemplate "templates/posts.html"
(constField "posts" postStr <> defaultContext)
>>= loadAndApplyTemplate "templates/default.html"
(constField "title" "Posts" <> defaultContext)
>>= relativizeUrls

match "posts.rss" $ route idRoute
create "posts.rss" $
requireAll_ "posts/*"
>>> mapCompiler (arr $ copyBodyToField "description")
>>> renderRss feedConfiguration
create ["posts.rss"] $ do
route idRoute
compile $ do
posts <- take 10 . recentFirst <$> loadAllSnapshots "posts/*" "content"
renderRss feedConfiguration
(bodyField "description" <> defaultContext)
posts
where
postContext = dateField "date" "%Y-%m-%d"

feedConfiguration = FeedConfiguration
{ feedTitle = "Inside ocharles"
, feedDescription = "MusicBrainz hacker. Haskell geek. Wannabe mathematician. Electronic music fanatic."
, feedAuthorName = "Oliver Charles"
, feedRoot = "http://ocharles.org.uk/blog"
, feedAuthorEmail = "ollie@ocharles.org.uk"
}

withToc = defaultWriterOptions
{ writerTableOfContents = True
, writerTemplate = "<div id=\"TOC\"><h2>Table of contents</h2>\n$toc$</div>$body$"
, writerStandalone = True
}
10 changes: 5 additions & 5 deletions posts/2012-12-02-digestive-functors.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ arguments to a function, where the arguments themselves come from some sort of
side effect - in this case the form evaluation. Let's have a look at an example:

```haskell
data Category = Category { catName :: Text }
data Category = Category { catName :: Text }

data BlogPost = BlogPost { postTitle :: Text
, postBody :: Text
Expand All @@ -51,7 +51,7 @@ validation! We don't want to accept `BlogPosts` which have no title or body, for
example, so lets start by fixing that:

```haskell
postForm :: Monad m => Form Html m BlogPost
postForm :: Monad m => Form Html m BlogPost
postForm = BlogPost
<$> "title" .: nonEmptyText
<*> "body" .: nonEmptyText
Expand All @@ -75,7 +75,7 @@ use this in our `postForm` to lookup categories, and only allow `BlogPosts` to
be created in a valid category:

```haskell
postForm :: Form Text BlogWebsite BlogPost
postForm :: Form Text BlogWebsite BlogPost
postForm = BlogPost
<$> "title" .: nonEmptyText
<*> "body" .: nonEmptyText
Expand Down Expand Up @@ -104,7 +104,7 @@ to lookup form fields in. Lets use
for the rendering, first:

```haskell
renderForm :: View Html -> Html
renderForm :: View Html -> Html
renderForm v = do
form v "POST" $ do
H.p $ do
Expand All @@ -129,7 +129,7 @@ Finally, lets put it all together with a Snap action, so we can actually serve
stuff:

```haskell
blogPostHandler :: Handler BlogWebsite BlogWebsite ()
blogPostHandler :: Handler BlogWebsite BlogWebsite ()
blogPostHandler = do
(view, result) <- runForm "blog-post" blogPost
case result of
Expand Down
8 changes: 4 additions & 4 deletions posts/2012-12-03-postgresql-simple.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ any other great mythical figure, he's chosen to write it in Haskell. Here are
the data types he has to work with:

```haskell
data Present = Present { presentName :: Text }
data Present = Present { presentName :: Text }

data Location = Location { locLat :: Double
, locLong :: Double
Expand All @@ -45,7 +45,7 @@ out of the database though, and in order to map an SQL row to a Haskell
data-type, we can use the `FromRow` class:

```haskell
instance FromRow Present where
instance FromRow Present where
fromRow = Present <$> field

instance FromRow Child where
Expand All @@ -64,7 +64,7 @@ field is not null (such as `presentName`).
Armed with our new `FromRow` instances, we can pluck things out of the database:

```haskell
allChildren :: Connection -> IO [Child]
allChildren :: Connection -> IO [Child]
allChildren c = query_ c "SELECT name, loc_lat, loc_long FROM child"

allPresents :: Connection -> IO [Present]
Expand Down Expand Up @@ -92,7 +92,7 @@ that polls the database, but using notifications, we can be much elegant, and
performant!

```haskell
santaNotifier :: Connection -> IO ()
santaNotifier :: Connection -> IO ()
santaNotifier c = listen >> loop
where
listen = query c "LISTEN presents"
Expand Down
4 changes: 2 additions & 2 deletions posts/2012-12-04-errors.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ personally find the `note` and `hush` combinators very useful - this pair of
combinators make it a breeze to jump between Maybe and Either as you need.

```haskell
askAge :: IO (Either String Int)
askAge :: IO (Either String Int)
askAge = note "Invalid input" . readMay <$> getLine
```

Expand All @@ -39,7 +39,7 @@ wrong. Here's a (not at all contrived) script which optimistically tries to prin
the 5th line from any file the user wishes:

```haskell
main :: IO ()
main :: IO ()
main = runScript $ do
filename <- hoistEither =<< note usage . headMay <$> scriptIO getArgs
scriptIO $ readFile filename >>= putStrLn . line5
Expand Down
2 changes: 1 addition & 1 deletion posts/2012-12-05-24-days-of-hackage-hlint.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ fmap (map toUpper) getLine
HLint rightfully suggests:

```
Warning: Use <$>
Warning: Use <$>
Found:
fmap (map toUpper) getLine
Why not:
Expand Down
6 changes: 3 additions & 3 deletions posts/2012-12-06-containers.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ As a quick example, lets assume we have a function that does some IO to give us
a mapping from a `Person` to a `Set` of their favourite `Colour`s.

```haskell
peopleFavColours :: IO (Map Person (Set Colour))
peopleFavColours :: IO (Map Person (Set Colour))
peopleFavColours = ...
```

Expand All @@ -43,7 +43,7 @@ into a new set. Hmm, this "smashing" together sounds exactly like something a
`fold`, perhaps with a `Monoid` instance...

```haskell
allFavColours :: IO (Set Colour)
allFavColours :: IO (Set Colour)
allFavColours = fold <$> peopleFavColours
```

Expand All @@ -58,7 +58,7 @@ like `mapM_`. Again, the trusty `Foldable` type class can help us out, with
`mapM_ :: (Foldable t, Monad m) => (a -> m b) -> t a -> m ()`:

```haskell
showColours :: IO ()
showColours :: IO ()
showColours = allFavColours >>= mapM_ print
```

Expand Down
2 changes: 1 addition & 1 deletion posts/2012-12-07-24-days-of-hackage-aeson.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ problem.
I think it's time for an example!

```haskell
data Cheese = Cheese { cheeseMaturity :: Maturity
data Cheese = Cheese { cheeseMaturity :: Maturity
, cheeseWeight :: Double
-- etc
}
Expand Down
8 changes: 4 additions & 4 deletions posts/2012-12-08-24-days-of-hackage.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ many people swear by it.
Let's dig in with an example!

```haskell
absAverage :: [Double] -> Double
absAverage :: [Double] -> Double
absAverage ds = sum ds / fromIntegral (length ds)
```

Expand All @@ -36,7 +36,7 @@ all values in a list. So, lets write a property to make sure this is correct:


```haskell
quickCheck1 :: IO ()
quickCheck1 :: IO ()
quickCheck1 = quickCheck $ \x -> absAverage x >= 0

> quickCheck1
Expand All @@ -52,7 +52,7 @@ doesn't make sense for empty lists. We can weaken the property a bit to only
consider non-empty lists:

```haskell
quickCheck2 :: IO ()
quickCheck2 :: IO ()
quickCheck2 = quickCheck $ \x -> length x > 1 ==> absAverage x >= 0

> quickCheck2
Expand All @@ -64,7 +64,7 @@ Huh, a failure again... Oh! I forgot to actually take the `abs` value of each
element of `ds` in my original function, lets get that fixed...

```haskell
absAverage :: [Double] -> Double
absAverage :: [Double] -> Double
absAverage ds = sum (map abs ds) / fromIntegral (length ds)

> quickCheck2
Expand Down
12 changes: 6 additions & 6 deletions posts/2012-12-09-24-days-of-hackage-lens.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ little unclear, and it's easiest to see what `lens` gives you from an
example:

```haskell
data Point = Point
data Point = Point
{ _x, _y :: Double } deriving (Show)

data Monster = Monster
Expand All @@ -36,7 +36,7 @@ location, and we presumably want them to move around. To move the `ogre` without
`lens`, it might look like:

```haskell
λ> ogre { _monsterLocation = (_monsterLocation ogre) {
λ> ogre { _monsterLocation = (_monsterLocation ogre) {
_x = _x (_monsterLocation ogre) + 1
} }
Monster {_monsterLocation = Point {_x = 1.0, _y = 0.0}}
Expand All @@ -46,7 +46,7 @@ URGH! All of that, just to move 1 to the right?! Lets see how this looks with
`lens`:

```haskell
λ> monsterLocation.x +~ 1 $ ogre
λ> monsterLocation.x +~ 1 $ ogre
Monster {_monsterLocation = Point {_x = 1.0, _y = 0.0}}
```

Expand All @@ -65,7 +65,7 @@ answer at all, depending on the data that is viewed through them.
Natural numbers are a good example of this:

```haskell
nat :: SimplePrism Integer Natural
nat :: SimplePrism Integer Natural
nat = prism toInteger $ \ i ->
if i < 0
then Left i
Expand All @@ -76,7 +76,7 @@ Now we can ask if an `Int` is a `Natural`, by trying to view an `Int` through
the `nat` prism:

```haskell
λ> 5 ^? nat
λ> 5 ^? nat
Just 5

λ> (-5) ^? nat
Expand All @@ -91,7 +91,7 @@ number. It sounds tricky, and that we'd likely need conditionals to pull it off,
but not so with `lens`!

```haskell
λ> both.nat *~ 2 $ (-3,4)
λ> both.nat *~ 2 $ (-3,4)
(-3,8)

λ> both.nat *~ 2 $ (8,4)
Expand Down
12 changes: 6 additions & 6 deletions posts/2012-12-10-24-days-of-hackage-parsec.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ our own ISRC parser. First of all, we need to parse the country code. That's
just two uppercase characters, so lets write that parser:

```haskell
countryCode = count 2 upper
countryCode = count 2 upper
```

Simple! This parser requires two uppercase characters, so we've combined the
Expand All @@ -34,7 +34,7 @@ succeeds, it will return the two uppercase characters that it parsed. Moving on,
the next section of data we need to parse is "a three character alphanumeric registrant code":

```haskell
regCode = count 3 upperNum
regCode = count 3 upperNum
where upperNum = upper <|> digit
```

Expand All @@ -47,20 +47,20 @@ try another.
Next, we take the last two digits of the year of registration:

```haskell
regYear = count 2 digit
regYear = count 2 digit
```

And finally, we take the five digit number identifying the recording:

```haskell
recordingId = count 5 digit
recordingId = count 5 digit
```

All that we need to do now is thread all these parsers together, and we're done!
One option could be to do the following:

```haskell
data ISRC = ISRC { isrcCountryCode :: String
data ISRC = ISRC { isrcCountryCode :: String
, isrcRegCode :: String
, isrcRegYear :: Int
, isrcRecording :: Int
Expand Down Expand Up @@ -90,7 +90,7 @@ normalization, so I can get by just sequencing these parsers and then stitching
things back together:

```haskell
isrcParser₂ = mconcat <$>
isrcParser₂ = mconcat <$>
sequence [ countryCode, regCode, regYear, recordingId ]
<* eof

Expand Down
4 changes: 2 additions & 2 deletions posts/2012-12-11-24-day-of-hackage-ekg.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Reusing the example of [helping Santa](/posts/2012-12-03-postgresql-simple.html)
from the `postgresql-simple` article, lets add some monitoring:

```haskell
main :: IO ()
main :: IO ()
main = forkServer "localhost" 8000 >> santaNotifier
```

Expand All @@ -37,7 +37,7 @@ to track application specific metrics, and have them graphed in real time!
Perhaps we want to have a counter for every time we notify Santa:

```haskell
main :: IO ()
main :: IO ()
main = do
ekg <- forkServer "localhost" 8000
getCounter "notifications" ekg >>= santaNotifier
Expand Down
Loading

0 comments on commit d206a82

Please sign in to comment.