summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--data/example/index.html2
-rw-r--r--hakyll.cabal37
-rw-r--r--src/Hakyll/Commands.hs37
-rw-r--r--src/Hakyll/Core/Compiler/Internal.hs3
-rw-r--r--src/Hakyll/Core/Configuration.hs6
-rw-r--r--src/Hakyll/Core/Dependencies.hs6
-rw-r--r--src/Hakyll/Core/Metadata.hs14
-rw-r--r--src/Hakyll/Core/Provider/Internal.hs7
-rw-r--r--src/Hakyll/Core/Provider/Metadata.hs37
-rw-r--r--src/Hakyll/Core/Rules/Default.hs24
-rw-r--r--src/Hakyll/Core/Runtime.hs5
-rw-r--r--src/Hakyll/Core/UnixFilter.hs19
-rw-r--r--src/Hakyll/Init.hs60
-rw-r--r--src/Hakyll/Main.hs22
-rw-r--r--src/Hakyll/Preview/Server.hs7
-rw-r--r--src/Hakyll/Web/Html.hs1
-rw-r--r--src/Hakyll/Web/Paginate.hs147
-rw-r--r--src/Hakyll/Web/Pandoc.hs1
-rw-r--r--src/Hakyll/Web/Tags.hs8
-rw-r--r--src/Hakyll/Web/Template/List.hs24
-rw-r--r--tests/Hakyll/Core/Dependencies/Tests.hs3
-rw-r--r--tests/Hakyll/Core/Provider/GlobalMetadata/Tests.hs31
-rw-r--r--tests/Hakyll/Web/Html/Tests.hs2
-rw-r--r--tests/TestSuite.hs2
-rw-r--r--tests/data/metadata27
-rw-r--r--tests/data/posts/2013-10-18-metadata-test.md4
-rw-r--r--tests/data/posts/2013-10-18-metadata-test.md.metadata2
-rw-r--r--tests/data/posts/metadata20
-rw-r--r--web/examples.markdown22
-rw-r--r--web/releases.markdown27
-rw-r--r--web/tutorials/01-installation.markdown2
-rw-r--r--web/tutorials/faq.markdown3
-rw-r--r--web/tutorials/using-clay-with-hakyll.markdown17
34 files changed, 320 insertions, 311 deletions
diff --git a/.gitignore b/.gitignore
index d0ce029..7e47278 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,6 +8,8 @@
TAGS
dist
tags
+cabal.sandbox.config
+.cabal-sandbox/
# Ignore test builds.
tests/Main
diff --git a/data/example/index.html b/data/example/index.html
index 16a42f9..6dd191d 100644
--- a/data/example/index.html
+++ b/data/example/index.html
@@ -13,4 +13,4 @@ title: Home
<h2>Posts</h2>
$partial("templates/post-list.html")$
-<p>…or you can find more in the <a href="/archive.html">archives</a>.
+<p>…or you can find more in the <a href="/archive.html">archives</a>.</p>
diff --git a/hakyll.cabal b/hakyll.cabal
index 9173bac..0f0398f 100644
--- a/hakyll.cabal
+++ b/hakyll.cabal
@@ -1,5 +1,5 @@
Name: hakyll
-Version: 4.4.3.2
+Version: 4.6.0.0
Synopsis: A static website compiler library
Description:
@@ -132,7 +132,6 @@ Library
Hakyll.Core.Provider.Metadata
Hakyll.Core.Provider.MetadataCache
Hakyll.Core.Rules.Internal
- Hakyll.Core.Rules.Default
Hakyll.Core.Runtime
Hakyll.Core.Store
Hakyll.Core.Util.File
@@ -143,8 +142,8 @@ Library
Build-Depends:
base >= 4 && < 5,
binary >= 0.5 && < 0.8,
- blaze-html >= 0.5 && < 0.7,
- blaze-markup >= 0.5.1 && < 0.6,
+ blaze-html >= 0.5 && < 0.8,
+ blaze-markup >= 0.5.1 && < 0.7,
bytestring >= 0.9 && < 0.11,
cmdargs >= 0.10 && < 0.11,
containers >= 0.3 && < 0.6,
@@ -154,17 +153,17 @@ Library
directory >= 1.0 && < 1.3,
filepath >= 1.0 && < 1.4,
lrucache >= 1.1.1 && < 1.2,
- mtl >= 1 && < 2.2,
- network >= 2.4 && < 2.5,
+ mtl >= 1 && < 2.3,
+ network >= 2.4 && < 2.6,
old-locale >= 1.0 && < 1.1,
old-time >= 1.0 && < 1.2,
- pandoc >= 1.12 && < 1.13,
- pandoc-citeproc >= 0.1 && < 0.3,
+ pandoc >= 1.12.4 && < 1.13,
+ pandoc-citeproc >= 0.1 && < 0.4,
parsec >= 3.0 && < 3.2,
process >= 1.0 && < 1.3,
random >= 1.0 && < 1.1,
regex-base >= 0.93 && < 0.94,
- regex-tdfa >= 1.1 && < 1.2,
+ regex-tdfa >= 1.1 && < 1.3,
tagsoup >= 0.13.1 && < 0.14,
text >= 0.11 && < 1.2,
time >= 1.1 && < 1.5
@@ -192,7 +191,7 @@ Library
If flag(checkExternal)
Build-depends:
- http-conduit >= 1.8 && < 2.1,
+ http-conduit >= 2.1 && < 2.2,
http-types >= 0.7 && < 0.9
Cpp-options:
-DCHECK_EXTERNAL
@@ -222,15 +221,15 @@ Test-suite hakyll-tests
Build-Depends:
HUnit >= 1.2 && < 1.3,
- QuickCheck >= 2.4 && < 2.7,
+ QuickCheck >= 2.4 && < 2.8,
test-framework >= 0.4 && < 0.9,
test-framework-hunit >= 0.3 && < 0.4,
test-framework-quickcheck2 >= 0.3 && < 0.4,
-- Copy pasted from hakyll dependencies:
base >= 4 && < 5,
binary >= 0.5 && < 0.8,
- blaze-html >= 0.5 && < 0.7,
- blaze-markup >= 0.5.1 && < 0.6,
+ blaze-html >= 0.5 && < 0.8,
+ blaze-markup >= 0.5.1 && < 0.7,
bytestring >= 0.9 && < 0.11,
cmdargs >= 0.10 && < 0.11,
containers >= 0.3 && < 0.6,
@@ -240,17 +239,17 @@ Test-suite hakyll-tests
directory >= 1.0 && < 1.3,
filepath >= 1.0 && < 1.4,
lrucache >= 1.1.1 && < 1.2,
- mtl >= 1 && < 2.2,
- network >= 2.4 && < 2.5,
+ mtl >= 1 && < 2.3,
+ network >= 2.4 && < 2.6,
old-locale >= 1.0 && < 1.1,
old-time >= 1.0 && < 1.2,
- pandoc >= 1.12 && < 1.13,
- pandoc-citeproc >= 0.1 && < 0.3,
+ pandoc >= 1.12.4 && < 1.13,
+ pandoc-citeproc >= 0.1 && < 0.4,
parsec >= 3.0 && < 3.2,
process >= 1.0 && < 1.3,
random >= 1.0 && < 1.1,
regex-base >= 0.93 && < 0.94,
- regex-tdfa >= 1.1 && < 1.2,
+ regex-tdfa >= 1.1 && < 1.3,
tagsoup >= 0.13.1 && < 0.14,
text >= 0.11 && < 1.2,
time >= 1.1 && < 1.5
@@ -278,7 +277,7 @@ Test-suite hakyll-tests
If flag(checkExternal)
Build-depends:
- http-conduit >= 1.8 && < 2.1,
+ http-conduit >= 2.1 && < 2.2,
http-types >= 0.7 && < 0.9
Cpp-options:
-DCHECK_EXTERNAL
diff --git a/src/Hakyll/Commands.hs b/src/Hakyll/Commands.hs
index 7951f4e..8db889c 100644
--- a/src/Hakyll/Commands.hs
+++ b/src/Hakyll/Commands.hs
@@ -9,13 +9,15 @@ module Hakyll.Commands
, rebuild
, server
, deploy
- , watch
+ , watch
) where
--------------------------------------------------------------------------------
import System.Exit (exitWith, ExitCode)
+import System.IO.Error (catchIOError)
import Control.Applicative
+import Control.Monad (void)
import Control.Concurrent
--------------------------------------------------------------------------------
@@ -67,7 +69,7 @@ preview :: Configuration -> Verbosity -> Rules a -> Int -> IO ()
#ifdef PREVIEW_SERVER
preview conf verbosity rules port = do
deprecatedMessage
- watch conf verbosity port True rules
+ watch conf verbosity "0.0.0.0" port True rules
where
deprecatedMessage = mapM_ putStrLn [ "The preview command has been deprecated."
, "Use the watch command for recompilation and serving."
@@ -80,22 +82,27 @@ preview _ _ _ _ = previewServerDisabled
--------------------------------------------------------------------------------
-- | Watch and recompile for changes
-watch :: Configuration -> Verbosity -> Int -> Bool -> Rules a -> IO ()
+watch :: Configuration -> Verbosity -> String -> Int -> Bool -> Rules a -> IO ()
#ifdef WATCH_SERVER
-watch conf verbosity port runServer rules = do
- watchUpdates conf update
- _ <- forkIO (server')
- loop
+watch conf verbosity host port runServer rules = do
+#ifndef mingw32_HOST_OS
+ _ <- forkIO $ watchUpdates conf update
+#else
+ -- Force windows users to compile with -threaded flag, as otherwise
+ -- thread is blocked indefinitely.
+ catchIOError (void $ forkOS $ watchUpdates conf update) $ do
+ fail $ "Hakyll.Commands.watch: Could not start update watching " ++
+ "thread. Did you compile with -threaded flag?"
+#endif
+ server'
where
update = do
(_, ruleSet) <- run conf verbosity rules
return $ rulesPattern ruleSet
-
loop = threadDelay 100000 >> loop
-
- server' = if runServer then server conf port else return ()
+ server' = if runServer then server conf host port else loop
#else
-watch _ _ _ _ _ = watchServerDisabled
+watch _ _ _ _ _ _ = watchServerDisabled
#endif
--------------------------------------------------------------------------------
@@ -106,15 +113,15 @@ rebuild conf verbosity rules =
--------------------------------------------------------------------------------
-- | Start a server
-server :: Configuration -> Int -> IO ()
+server :: Configuration -> String -> Int -> IO ()
#ifdef PREVIEW_SERVER
-server conf port = do
+server conf host port = do
let destination = destinationDirectory conf
- staticServer destination preServeHook port
+ staticServer destination preServeHook host port
where
preServeHook _ = return ()
#else
-server _ _ = previewServerDisabled
+server _ _ _ = previewServerDisabled
#endif
diff --git a/src/Hakyll/Core/Compiler/Internal.hs b/src/Hakyll/Core/Compiler/Internal.hs
index 259cd35..8424d69 100644
--- a/src/Hakyll/Core/Compiler/Internal.hs
+++ b/src/Hakyll/Core/Compiler/Internal.hs
@@ -248,5 +248,6 @@ compilerGetMatches :: Pattern -> Compiler [Identifier]
compilerGetMatches pattern = do
universe <- compilerUniverse <$> compilerAsk
let matching = filterMatches pattern $ S.toList universe
- compilerTellDependencies [PatternDependency pattern matching]
+ set' = S.fromList matching
+ compilerTellDependencies [PatternDependency pattern set']
return matching
diff --git a/src/Hakyll/Core/Configuration.hs b/src/Hakyll/Core/Configuration.hs
index f9927de..52b23ec 100644
--- a/src/Hakyll/Core/Configuration.hs
+++ b/src/Hakyll/Core/Configuration.hs
@@ -69,6 +69,11 @@ data Configuration = Configuration
, -- | Use an in-memory cache for items. This is faster but uses more
-- memory.
inMemoryCache :: Bool
+ , -- | Override default host for preview server. Default is "127.0.0.1",
+ -- which binds only on the loopback address.
+ -- One can also override the host as a command line argument:
+ -- ./site preview -h "0.0.0.0"
+ previewHost :: String
, -- | Override default port for preview server. Default is 8000.
-- One can also override the port as a command line argument:
-- ./site preview -p 1234
@@ -91,6 +96,7 @@ defaultConfiguration = Configuration
, deployCommand = "echo 'No deploy command specified' && exit 1"
, deploySite = system . deployCommand
, inMemoryCache = True
+ , previewHost = "127.0.0.1"
, previewPort = 8000
}
where
diff --git a/src/Hakyll/Core/Dependencies.hs b/src/Hakyll/Core/Dependencies.hs
index 7597e61..ebb6fd0 100644
--- a/src/Hakyll/Core/Dependencies.hs
+++ b/src/Hakyll/Core/Dependencies.hs
@@ -32,7 +32,7 @@ import Hakyll.Core.Identifier.Pattern
--------------------------------------------------------------------------------
data Dependency
- = PatternDependency Pattern [Identifier]
+ = PatternDependency Pattern (Set Identifier)
| IdentifierDependency Identifier
deriving (Show, Typeable)
@@ -91,7 +91,7 @@ dependenciesFor id' = do
return $ concatMap dependenciesFor' $ fromMaybe [] $ M.lookup id' facts
where
dependenciesFor' (IdentifierDependency i) = [i]
- dependenciesFor' (PatternDependency _ is) = is
+ dependenciesFor' (PatternDependency _ is) = S.toList is
--------------------------------------------------------------------------------
@@ -116,7 +116,7 @@ checkChangedPatterns = do
go _ ds (IdentifierDependency i) = return $ IdentifierDependency i : ds
go id' ds (PatternDependency p ls) = do
universe <- ask
- let ls' = filterMatches p universe
+ let ls' = S.fromList $ filterMatches p universe
if ls == ls'
then return $ PatternDependency p ls : ds
else do
diff --git a/src/Hakyll/Core/Metadata.hs b/src/Hakyll/Core/Metadata.hs
index a123c18..3ce854f 100644
--- a/src/Hakyll/Core/Metadata.hs
+++ b/src/Hakyll/Core/Metadata.hs
@@ -5,7 +5,6 @@ module Hakyll.Core.Metadata
, getMetadataField
, getMetadataField'
, makePatternDependency
- , metadataFiles
) where
@@ -13,7 +12,7 @@ module Hakyll.Core.Metadata
import Control.Monad (forM)
import Data.Map (Map)
import qualified Data.Map as M
-import System.FilePath.Posix ((</>), takeDirectory)
+import qualified Data.Set as S
--------------------------------------------------------------------------------
@@ -62,13 +61,4 @@ getMetadataField' identifier key = do
makePatternDependency :: MonadMetadata m => Pattern -> m Dependency
makePatternDependency pattern = do
matches' <- getMatches pattern
- return $ PatternDependency pattern matches'
-
---------------------------------------------------------------------------------
--- | Returns a list of all directory-wise metadata files, subdir first, global last
-metadataFiles :: Identifier -> [Identifier]
-metadataFiles identifier = local : go (takeDirectory $ toFilePath identifier) where
- go "." = [fromFilePath "metadata"]
- go dir = fromFilePath (dir </> "metadata") : go (takeDirectory dir)
- local = fromFilePath $ toFilePath identifier ++ ".metadata"
-
+ return $ PatternDependency pattern (S.fromList matches')
diff --git a/src/Hakyll/Core/Provider/Internal.hs b/src/Hakyll/Core/Provider/Internal.hs
index fdf1342..34400fd 100644
--- a/src/Hakyll/Core/Provider/Internal.hs
+++ b/src/Hakyll/Core/Provider/Internal.hs
@@ -31,8 +31,7 @@ import Data.Maybe (fromMaybe)
import Data.Monoid (mempty)
import Data.Set (Set)
import qualified Data.Set as S
-import Data.Time (Day (..), UTCTime (..),
- secondsToDiffTime)
+import Data.Time (Day (..), UTCTime (..))
import Data.Typeable (Typeable)
import System.Directory (getModificationTime)
import System.FilePath (addExtension, (</>))
@@ -62,11 +61,11 @@ newtype BinaryTime = BinaryTime {unBinaryTime :: UTCTime}
--------------------------------------------------------------------------------
instance Binary BinaryTime where
put (BinaryTime (UTCTime (ModifiedJulianDay d) dt)) =
- put d >> put (floor dt :: Integer)
+ put d >> put (toRational dt)
get = fmap BinaryTime $ UTCTime
<$> (ModifiedJulianDay <$> get)
- <*> (secondsToDiffTime <$> get)
+ <*> (fromRational <$> get)
--------------------------------------------------------------------------------
diff --git a/src/Hakyll/Core/Provider/Metadata.hs b/src/Hakyll/Core/Provider/Metadata.hs
index 889291f..7e4d7ed 100644
--- a/src/Hakyll/Core/Provider/Metadata.hs
+++ b/src/Hakyll/Core/Provider/Metadata.hs
@@ -20,8 +20,6 @@ import System.IO as IO
import Text.Parsec ((<?>))
import qualified Text.Parsec as P
import Text.Parsec.String (Parser)
-import System.FilePath.Posix
-import Control.Monad (liftM)
--------------------------------------------------------------------------------
@@ -30,7 +28,7 @@ import Hakyll.Core.Metadata
import Hakyll.Core.Provider.Internal
import Hakyll.Core.Util.Parser
import Hakyll.Core.Util.String
-import Hakyll.Core.Identifier.Pattern
+
--------------------------------------------------------------------------------
loadMetadata :: Provider -> Identifier -> IO (Metadata, Maybe String)
@@ -44,9 +42,7 @@ loadMetadata p identifier = do
Nothing -> return M.empty
Just mi' -> loadMetadataFile $ resourceFilePath p mi'
- gmd <- loadGlobalMetadata p identifier
-
- return (M.unions [md, gmd], body)
+ return (M.union md emd, body)
where
normal = setVersion Nothing identifier
fp = resourceFilePath p identifier
@@ -137,32 +133,3 @@ page = do
metadata' <- P.option [] metadataBlock
body <- P.many P.anyChar
return (metadata', body)
-
-
---------------------------------------------------------------------------------
--- | Load directory-wise metadata
-loadGlobalMetadata :: Provider -> Identifier -> IO Metadata
-loadGlobalMetadata p fp = liftM M.fromList $ loadgm fp where
- loadgm :: Identifier -> IO [(String, String)]
- loadgm = liftM concat . mapM loadOne . reverse . filter (resourceExists p) . metadataFiles
- loadOne mfp =
- let path = resourceFilePath p mfp
- dir = takeDirectory $ toFilePath mfp
- -- TODO: It might be better to print warning and continue
- in either (error.show) (findMetadata dir) . P.parse namedMetadata path <$> readFile path
- findMetadata dir =
- concatMap snd . filter (flip matches fp . fromGlob . normalise . combine dir . fst)
-
-namedMetadata :: Parser [(String, [(String, String)])]
-namedMetadata = liftA2 (:) (namedMetadataBlock False) $ P.many $ namedMetadataBlock True
-
-namedMetadataBlock :: Bool -> Parser (String, [(String, String)])
-namedMetadataBlock isNamed = do
- name <- if isNamed
- then P.many1 (P.char '-') *> P.many inlineSpace *> P.manyTill P.anyChar newline
- else pure "**"
- metadata' <- metadata
- P.skipMany P.space
- return (name, metadata')
-
-
diff --git a/src/Hakyll/Core/Rules/Default.hs b/src/Hakyll/Core/Rules/Default.hs
deleted file mode 100644
index fee78c5..0000000
--- a/src/Hakyll/Core/Rules/Default.hs
+++ /dev/null
@@ -1,24 +0,0 @@
-{-# LANGUAGE OverloadedStrings #-}
-module Hakyll.Core.Rules.Default
- ( internalRules
- , addMetadataDependencies
- )
-where
-import Hakyll.Core.Rules
-import Hakyll.Core.Compiler
-import Hakyll.Core.Compiler.Internal (compilerTellDependencies)
-import Hakyll.Core.Metadata (getMatches, metadataFiles)
-import Hakyll.Core.Identifier.Pattern(fromList)
-
-internalRules :: Rules ()
-internalRules = do
- match "metadata" $ compile $ makeItem ()
- match "**/metadata" $ compile $ makeItem ()
- match "**.metadata" $ compile $ makeItem ()
-
---------------------------------------------------------------------------------
-addMetadataDependencies :: Compiler ()
-addMetadataDependencies =
- compilerTellDependencies . map IdentifierDependency =<< getMatches . fromList =<< fmap metadataFiles getUnderlying
-
-
diff --git a/src/Hakyll/Core/Runtime.hs b/src/Hakyll/Core/Runtime.hs
index 12285ad..824d11b 100644
--- a/src/Hakyll/Core/Runtime.hs
+++ b/src/Hakyll/Core/Runtime.hs
@@ -35,7 +35,6 @@ import qualified Hakyll.Core.Logger as Logger
import Hakyll.Core.Provider
import Hakyll.Core.Routes
import Hakyll.Core.Rules.Internal
-import Hakyll.Core.Rules.Default
import Hakyll.Core.Store (Store)
import qualified Hakyll.Core.Store as Store
import Hakyll.Core.Util.File
@@ -54,7 +53,7 @@ run config verbosity rules = do
provider <- newProvider store (shouldIgnoreFile config) $
providerDirectory config
Logger.message logger "Running rules..."
- ruleSet <- runRules (rules >> internalRules) provider
+ ruleSet <- runRules rules provider
-- Get old facts
mOldFacts <- Store.get store factsKey
@@ -187,7 +186,7 @@ chase trail id'
config <- runtimeConfiguration <$> ask
Logger.debug logger $ "Processing " ++ show id'
- let compiler = addMetadataDependencies >> todo M.! id'
+ let compiler = todo M.! id'
read' = CompilerRead
{ compilerConfig = config
, compilerUnderlying = id'
diff --git a/src/Hakyll/Core/UnixFilter.hs b/src/Hakyll/Core/UnixFilter.hs
index 34b2ecb..edc8eac 100644
--- a/src/Hakyll/Core/UnixFilter.hs
+++ b/src/Hakyll/Core/UnixFilter.hs
@@ -1,3 +1,5 @@
+{-# LANGUAGE CPP #-}
+
--------------------------------------------------------------------------------
-- | A Compiler that supports unix filters.
module Hakyll.Core.UnixFilter
@@ -20,7 +22,6 @@ import System.IO (Handle, hClose, hFlush, hGetContents,
hPutStr, hSetEncoding, localeEncoding)
import System.Process
-
--------------------------------------------------------------------------------
import Hakyll.Core.Compiler
@@ -105,8 +106,22 @@ unixFilterIO :: Monoid o
-> i
-> IO (o, String, ExitCode)
unixFilterIO writer reader programName args input = do
+ -- The problem on Windows is that `proc` is unable to execute
+ -- batch stubs (eg. anything created using 'gem install ...') even if its in
+ -- `$PATH`. A solution to this issue is to execute the batch file explicitly
+ -- using `cmd /c batchfile` but there is no rational way to know where said
+ -- batchfile is on the system. Hence, we detect windows using the
+ -- CPP and instead of using `proc` to create the process, use `shell`
+ -- which will be able to execute everything `proc` can
+ -- as well as batch files.
+#ifdef mingw32_HOST_OS
+ let pr = shell $ unwords (programName : args)
+#else
+ let pr = proc programName args
+#endif
+
(Just inh, Just outh, Just errh, pid) <-
- createProcess (proc programName args)
+ createProcess pr
{ std_in = CreatePipe
, std_out = CreatePipe
, std_err = CreatePipe
diff --git a/src/Hakyll/Init.hs b/src/Hakyll/Init.hs
index d50c6f6..51ba14b 100644
--- a/src/Hakyll/Init.hs
+++ b/src/Hakyll/Init.hs
@@ -5,11 +5,15 @@ module Main
--------------------------------------------------------------------------------
+import Control.Arrow (first)
import Control.Monad (forM_)
-import System.Directory (copyFile)
+import Data.Char (isAlphaNum, isNumber)
+import Data.List (intercalate)
+import Data.Version (Version(..))
+import System.Directory (copyFile, canonicalizePath)
import System.Environment (getArgs, getProgName)
import System.Exit (exitFailure)
-import System.FilePath ((</>))
+import System.FilePath ((</>), splitDirectories)
--------------------------------------------------------------------------------
@@ -26,12 +30,52 @@ main = do
files <- getRecursiveContents (const $ return False) srcDir
case args of
- [dstDir] -> forM_ files $ \file -> do
- let dst = dstDir </> file
- src = srcDir </> file
- putStrLn $ "Creating " ++ dst
- makeDirectories dst
- copyFile src dst
+ [dstDir] -> do
+ forM_ files $ \file -> do
+ let dst = dstDir </> file
+ src = srcDir </> file
+ putStrLn $ "Creating " ++ dst
+ makeDirectories dst
+ copyFile src dst
+ -- canonicalizePath is safe because the destination
+ -- directory should exist at this point
+ canonicalizePath dstDir >>= createCabal
_ -> do
putStrLn $ "Usage: " ++ progName ++ " <directory>"
exitFailure
+
+
+createCabal :: FilePath -> IO ()
+createCabal dstDir = do
+ putStrLn $ "Creating " ++ name ++ ".cabal"
+ writeFile (dstDir </> name ++ ".cabal") $ unlines [
+ "name: " ++ name
+ , "version: 0.1.0.0"
+ , "build-type: Simple"
+ , "cabal-version: >= 1.10"
+ , ""
+ , "executable site"
+ , " main-is: site.hs"
+ , " build-depends: base == 4.*"
+ , " , hakyll == " ++ version' ++ ".*"
+ , " ghc-options: -threaded"
+ , " default-language: Haskell2010"
+ ]
+ where
+ -- Major hakyll version
+ version' = intercalate "." . take 2 . map show $ versionBranch version
+ -- last is safe here as the path is canonicalised and "/" is just
+ -- a very rare but possible corner case
+ name = case last (splitDirectories dstDir) of
+ "/" -> fallbackName
+ x -> repair (fallbackName ++) id x
+ -- Package name repair code comes from
+ -- cabal-install.Distribution.Client.Init.Heuristics
+ repair invalid valid x = case dropWhile (not . isAlphaNum) x of
+ "" -> repairComponent ""
+ x' -> let (c, r) = first repairComponent $ break (not . isAlphaNum) x'
+ in c ++ repairRest r
+ where repairComponent c | all isNumber c = invalid c
+ | otherwise = valid c
+ repairRest = repair id ('-' :)
+ fallbackName = "site"
diff --git a/src/Hakyll/Main.hs b/src/Hakyll/Main.hs
index 86516cb..e0c8d4e 100644
--- a/src/Hakyll/Main.hs
+++ b/src/Hakyll/Main.hs
@@ -48,8 +48,8 @@ hakyllWith conf rules = do
Help _ -> showHelp
Preview _ p -> Commands.preview conf verbosity' rules p
Rebuild _ -> Commands.rebuild conf verbosity' rules >>= exitWith
- Server _ _ -> Commands.server conf (port args')
- Watch _ p s -> Commands.watch conf verbosity' p (not s) rules
+ Server _ _ _ -> Commands.server conf (host args') (port args')
+ Watch _ _ p s -> Commands.watch conf verbosity' (host args') p (not s) rules
--------------------------------------------------------------------------------
@@ -67,8 +67,8 @@ data HakyllArgs
| Help {verbose :: Bool}
| Preview {verbose :: Bool, port :: Int}
| Rebuild {verbose :: Bool}
- | Server {verbose :: Bool, port :: Int}
- | Watch {verbose :: Bool, port :: Int, no_server :: Bool }
+ | Server {verbose :: Bool, host :: String, port :: Int}
+ | Watch {verbose :: Bool, host :: String, port :: Int, no_server :: Bool }
deriving (Data, Typeable, Show)
@@ -84,13 +84,14 @@ hakyllArgs conf = modes
, (Preview (verboseFlag def) (portFlag defaultPort)) &=
help "[Deprecated] Please use the watch command"
, (Rebuild $ verboseFlag def) &= help "Clean and build again"
- , (Server (verboseFlag def) (portFlag defaultPort)) &=
+ , (Server (verboseFlag def) (hostFlag defaultHost) (portFlag defaultPort)) &=
help "Start a preview server"
- , (Watch (verboseFlag def) (portFlag defaultPort) (noServerFlag False) &=
+ , (Watch (verboseFlag def) (hostFlag defaultHost) (portFlag defaultPort) (noServerFlag False) &=
help "Autocompile on changes and start a preview server. You can watch and recompile without running a server with --no-server.")
] &= help "Hakyll static site compiler" &= program progName
- where defaultPort = Config.previewPort conf
-
+ where
+ defaultHost = Config.previewHost conf
+ defaultPort = Config.previewPort conf
--------------------------------------------------------------------------------
verboseFlag :: Data a => a -> a
@@ -104,6 +105,11 @@ noServerFlag x = x &= help "Disable the built-in web server"
{-# INLINE noServerFlag #-}
--------------------------------------------------------------------------------
+hostFlag :: Data a => a -> a
+hostFlag x = x &= help "Host to bind on"
+{-# INLINE hostFlag #-}
+
+--------------------------------------------------------------------------------
portFlag :: Data a => a -> a
portFlag x = x &= help "Port to listen on"
{-# INLINE portFlag #-}
diff --git a/src/Hakyll/Preview/Server.hs b/src/Hakyll/Preview/Server.hs
index 14cf377..ef1c3c5 100644
--- a/src/Hakyll/Preview/Server.hs
+++ b/src/Hakyll/Preview/Server.hs
@@ -8,6 +8,7 @@ module Hakyll.Preview.Server
--------------------------------------------------------------------------------
import Control.Monad.Trans (liftIO)
+import qualified Data.ByteString.Char8 as B
import qualified Snap.Core as Snap
import qualified Snap.Http.Server as Snap
import qualified Snap.Util.FileServe as Snap
@@ -31,13 +32,15 @@ static directory preServe =
-- | Main method, runs a static server in the given directory
staticServer :: FilePath -- ^ Directory to serve
-> (FilePath -> IO ()) -- ^ Pre-serve hook
+ -> String -- ^ Host to bind on
-> Int -- ^ Port to listen on
-> IO () -- ^ Blocks forever
-staticServer directory preServe port =
+staticServer directory preServe host port =
Snap.httpServe config $ static directory preServe
where
-- Snap server config
- config = Snap.setPort port
+ config = Snap.setBind (B.pack host)
+ $ Snap.setPort port
$ Snap.setAccessLog Snap.ConfigNoLog
$ Snap.setErrorLog Snap.ConfigNoLog
$ Snap.emptyConfig
diff --git a/src/Hakyll/Web/Html.hs b/src/Hakyll/Web/Html.hs
index ba62eb8..1abd742 100644
--- a/src/Hakyll/Web/Html.hs
+++ b/src/Hakyll/Web/Html.hs
@@ -125,6 +125,7 @@ toSiteRoot = emptyException . joinPath . map parent
emptyException x = x
relevant "." = False
relevant "/" = False
+ relevant "./" = False
relevant _ = True
diff --git a/src/Hakyll/Web/Paginate.hs b/src/Hakyll/Web/Paginate.hs
index eafd3a9..cd35a2d 100644
--- a/src/Hakyll/Web/Paginate.hs
+++ b/src/Hakyll/Web/Paginate.hs
@@ -3,8 +3,8 @@
module Hakyll.Web.Paginate
( PageNumber
, Paginate (..)
- , buildPaginate
, buildPaginateWith
+ , paginateEvery
, paginateRules
, paginateContext
) where
@@ -12,10 +12,9 @@ module Hakyll.Web.Paginate
--------------------------------------------------------------------------------
import Control.Monad (forM_)
-import Data.List (unfoldr)
import qualified Data.Map as M
import Data.Monoid (mconcat)
-import Text.Printf (printf)
+import qualified Data.Set as S
--------------------------------------------------------------------------------
@@ -36,99 +35,93 @@ type PageNumber = Int
--------------------------------------------------------------------------------
-- | Data about paginators
data Paginate = Paginate
- { paginatePages :: M.Map PageNumber [Identifier]
- , paginatePlaces :: M.Map Identifier PageNumber
+ { paginateMap :: M.Map PageNumber [Identifier]
, paginateMakeId :: PageNumber -> Identifier
, paginateDependency :: Dependency
} deriving (Show)
--------------------------------------------------------------------------------
-buildPaginate :: MonadMetadata m
- => Pattern
- -> m Paginate
-buildPaginate pattern = do
- idents <- getMatches pattern
- let pagPages = M.fromList $ zip [1 ..] (map return idents)
- pagPlaces = M.fromList $ zip idents [1 ..]
- makeId pn = case M.lookup pn pagPages of
- Just [id'] -> id'
- _ -> error $
- "Hakyll.Web.Paginate.buildPaginate: " ++
- "invalid page number: " ++ show pn
-
- return $ Paginate pagPages pagPlaces makeId
- (PatternDependency pattern idents)
+paginateNumPages :: Paginate -> Int
+paginateNumPages = M.size . paginateMap
--------------------------------------------------------------------------------
-buildPaginateWith :: MonadMetadata m
- => Int
- -> (PageNumber -> Identifier)
- -> Pattern
- -> m Paginate
-buildPaginateWith n makeId pattern = do
- -- TODO: there is no sensible order for `ids` here, for now it's random;
- -- but it should be `resectFirst` order because most recent posts should
- -- correspond to 1st paginator page and oldest one to last page
- idents <- getMatches pattern
- let pages = flip unfoldr idents $ \xs ->
- if null xs then Nothing else Just (splitAt n xs)
- nPages = length pages
- paginatePages' = zip [1..] pages
- pagPlaces' =
- [(ident, idx) | (idx,ids) <- paginatePages', ident <- ids] ++
- [(makeId i, i) | i <- [1 .. nPages]]
-
- return $ Paginate (M.fromList paginatePages') (M.fromList pagPlaces') makeId
- (PatternDependency pattern idents)
+paginateEvery :: Int -> [a] -> [[a]]
+paginateEvery n = go
+ where
+ go [] = []
+ go xs = let (y, ys) = splitAt n xs in y : go ys
--------------------------------------------------------------------------------
-paginateRules :: Paginate -> (PageNumber -> Pattern -> Rules ()) -> Rules ()
-paginateRules paginator rules =
- forM_ (M.toList $ paginatePages paginator) $ \(idx, identifiers) ->
- create [paginateMakeId paginator idx] $
- rulesExtraDependencies [paginateDependency paginator] $
- rules idx $ fromList identifiers
+buildPaginateWith
+ :: MonadMetadata m
+ => ([Identifier] -> m [[Identifier]]) -- ^ Group items into pages
+ -> Pattern -- ^ Select items to paginate
+ -> (PageNumber -> Identifier) -- ^ Identifiers for the pages
+ -> m Paginate
+buildPaginateWith grouper pattern makeId = do
+ ids <- getMatches pattern
+ idGroups <- grouper ids
+ let idsSet = S.fromList ids
+ return Paginate
+ { paginateMap = M.fromList (zip [1 ..] idGroups)
+ , paginateMakeId = makeId
+ , paginateDependency = PatternDependency pattern idsSet
+ }
--------------------------------------------------------------------------------
--- | Takes first, current, last page and produces index of next page
-type RelPage = PageNumber -> PageNumber -> PageNumber -> Maybe PageNumber
+paginateRules :: Paginate -> (PageNumber -> Pattern -> Rules ()) -> Rules ()
+paginateRules paginator rules =
+ forM_ (M.toList $ paginateMap paginator) $ \(idx, identifiers) ->
+ rulesExtraDependencies [paginateDependency paginator] $
+ create [paginateMakeId paginator idx] $
+ rules idx $ fromList identifiers
--------------------------------------------------------------------------------
-paginateField :: Paginate -> String -> RelPage -> Context a
-paginateField pag fieldName relPage = field fieldName $ \item ->
- let identifier = itemIdentifier item
- in case M.lookup identifier (paginatePlaces pag) of
- Nothing -> fail $ printf
- "Hakyll.Web.Paginate: there is no page %s in paginator map."
- (show identifier)
- Just pos -> case relPage 1 pos nPages of
- Nothing -> fail "Hakyll.Web.Paginate: No page here."
- Just pos' -> do
- let nextId = paginateMakeId pag pos'
- mroute <- getRoute nextId
- case mroute of
- Nothing -> fail $ printf
- "Hakyll.Web.Paginate: unable to get route for %s."
- (show nextId)
- Just rt -> return $ toUrl rt
- where
- nPages = M.size (paginatePages pag)
+-- | Get the identifier for a certain page by passing in the page number.
+paginatePage :: Paginate -> PageNumber -> Maybe Identifier
+paginatePage pag pageNumber
+ | pageNumber < 1 = Nothing
+ | pageNumber > (paginateNumPages pag) = Nothing
+ | otherwise = Just $ paginateMakeId pag pageNumber
--------------------------------------------------------------------------------
-paginateContext :: Paginate -> Context a
-paginateContext pag = mconcat
- [ paginateField pag "firstPage"
- (\f c _ -> if c <= f then Nothing else Just f)
- , paginateField pag "previousPage"
- (\f c _ -> if c <= f then Nothing else Just (c - 1))
- , paginateField pag "nextPage"
- (\_ c l -> if c >= l then Nothing else Just (c + 1))
- , paginateField pag "lastPage"
- (\_ c l -> if c >= l then Nothing else Just l)
+-- | A default paginate context which provides the following keys:
+--
+--
+paginateContext :: Paginate -> PageNumber -> Context a
+paginateContext pag currentPage = mconcat
+ [ field "firstPageNum" $ \_ -> otherPage 1 >>= num
+ , field "firstPageUrl" $ \_ -> otherPage 1 >>= url
+ , field "previousPageNum" $ \_ -> otherPage (currentPage - 1) >>= num
+ , field "previousPageUrl" $ \_ -> otherPage (currentPage - 1) >>= url
+ , field "nextPageNum" $ \_ -> otherPage (currentPage + 1) >>= num
+ , field "nextPageUrl" $ \_ -> otherPage (currentPage + 1) >>= url
+ , field "lastPageNum" $ \_ -> otherPage lastPage >>= num
+ , field "lastPageUrl" $ \_ -> otherPage lastPage >>= url
+ , field "currentPageNum" $ \i -> thisPage i >>= num
+ , field "currentPageUrl" $ \i -> thisPage i >>= url
+ , constField "numPages" $ show $ paginateNumPages pag
]
+ where
+ lastPage = paginateNumPages pag
+
+ thisPage i = return (currentPage, itemIdentifier i)
+ otherPage n
+ | n == currentPage = fail $ "This is the current page: " ++ show n
+ | otherwise = case paginatePage pag n of
+ Nothing -> fail $ "No such page: " ++ show n
+ Just i -> return (n, i)
+
+ num :: (Int, Identifier) -> Compiler String
+ num = return . show . fst
+
+ url :: (Int, Identifier) -> Compiler String
+ url (n, i) = getRoute i >>= \mbR -> case mbR of
+ Just r -> return $ toUrl r
+ Nothing -> fail $ "No URL for page: " ++ show n
diff --git a/src/Hakyll/Web/Pandoc.hs b/src/Hakyll/Web/Pandoc.hs
index 1615167..78df1df 100644
--- a/src/Hakyll/Web/Pandoc.hs
+++ b/src/Hakyll/Web/Pandoc.hs
@@ -53,6 +53,7 @@ readPandocWith ropt item = fmap (reader ropt (itemFileType item)) item
LaTeX -> readLaTeX ro
LiterateHaskell t' -> reader (addExt ro Ext_literate_haskell) t'
Markdown -> readMarkdown ro
+ OrgMode -> readOrg ro
Rst -> readRST ro
Textile -> readTextile ro
_ -> error $
diff --git a/src/Hakyll/Web/Tags.hs b/src/Hakyll/Web/Tags.hs
index 0fa182c..0887856 100644
--- a/src/Hakyll/Web/Tags.hs
+++ b/src/Hakyll/Web/Tags.hs
@@ -71,6 +71,7 @@ import qualified Data.Map as M
import Data.Maybe (catMaybes, fromMaybe)
import Data.Monoid (mconcat)
import Data.Ord (comparing)
+import qualified Data.Set as S
import System.FilePath (takeBaseName, takeDirectory)
import Text.Blaze.Html (toHtml, toValue, (!))
import Text.Blaze.Html.Renderer.String (renderHtml)
@@ -124,7 +125,8 @@ buildTagsWith :: MonadMetadata m
buildTagsWith f pattern makeId = do
ids <- getMatches pattern
tagMap <- foldM addTags M.empty ids
- return $ Tags (M.toList tagMap) makeId (PatternDependency pattern ids)
+ let set' = S.fromList ids
+ return $ Tags (M.toList tagMap) makeId (PatternDependency pattern set')
where
-- Create a tag map for one page
addTags tagMap id' = do
@@ -148,8 +150,8 @@ buildCategories = buildTagsWith getCategory
tagsRules :: Tags -> (String -> Pattern -> Rules ()) -> Rules ()
tagsRules tags rules =
forM_ (tagsMap tags) $ \(tag, identifiers) ->
- create [tagsMakeId tags tag] $
- rulesExtraDependencies [tagsDependency tags] $
+ rulesExtraDependencies [tagsDependency tags] $
+ create [tagsMakeId tags tag] $
rules tag $ fromList identifiers
diff --git a/src/Hakyll/Web/Template/List.hs b/src/Hakyll/Web/Template/List.hs
index f9ccc08..1f2a570 100644
--- a/src/Hakyll/Web/Template/List.hs
+++ b/src/Hakyll/Web/Template/List.hs
@@ -13,6 +13,8 @@ module Hakyll.Web.Template.List
, applyJoinTemplateList
, chronological
, recentFirst
+ , sortChronological
+ , sortRecentFirst
) where
@@ -25,6 +27,7 @@ import System.Locale (defaultTimeLocale)
--------------------------------------------------------------------------------
import Hakyll.Core.Compiler
+import Hakyll.Core.Identifier
import Hakyll.Core.Item
import Hakyll.Core.Metadata
import Hakyll.Web.Template
@@ -65,7 +68,24 @@ chronological =
sortByM f xs = liftM (map fst . sortBy (comparing snd)) $
mapM (\x -> liftM (x,) (f x)) xs
+
--------------------------------------------------------------------------------
-- | The reverse of 'chronological'
-recentFirst :: (MonadMetadata m, Functor m) => [Item a] -> m [Item a]
-recentFirst = fmap reverse . chronological
+recentFirst :: MonadMetadata m => [Item a] -> m [Item a]
+recentFirst = liftM reverse . chronological
+
+
+--------------------------------------------------------------------------------
+-- | Version of 'chronological' which doesn't need the actual items.
+sortChronological
+ :: MonadMetadata m => [Identifier] -> m [Identifier]
+sortChronological ids =
+ liftM (map itemIdentifier) $ chronological [Item i () | i <- ids]
+
+
+--------------------------------------------------------------------------------
+-- | Version of 'recentFirst' which doesn't need the actual items.
+sortRecentFirst
+ :: MonadMetadata m => [Identifier] -> m [Identifier]
+sortRecentFirst ids =
+ liftM (map itemIdentifier) $ recentFirst [Item i () | i <- ids]
diff --git a/tests/Hakyll/Core/Dependencies/Tests.hs b/tests/Hakyll/Core/Dependencies/Tests.hs
index d6e3094..efa848b 100644
--- a/tests/Hakyll/Core/Dependencies/Tests.hs
+++ b/tests/Hakyll/Core/Dependencies/Tests.hs
@@ -38,7 +38,8 @@ oldFacts = M.fromList
, ("posts/02.md",
[])
, ("index.md",
- [ PatternDependency "posts/*" ["posts/01.md", "posts/02.md"]
+ [ PatternDependency "posts/*"
+ (S.fromList ["posts/01.md", "posts/02.md"])
, IdentifierDependency "posts/01.md"
, IdentifierDependency "posts/02.md"
])
diff --git a/tests/Hakyll/Core/Provider/GlobalMetadata/Tests.hs b/tests/Hakyll/Core/Provider/GlobalMetadata/Tests.hs
deleted file mode 100644
index 289e2ac..0000000
--- a/tests/Hakyll/Core/Provider/GlobalMetadata/Tests.hs
+++ /dev/null
@@ -1,31 +0,0 @@
---------------------------------------------------------------------------------
-{-# LANGUAGE OverloadedStrings #-}
-module Hakyll.Core.Provider.GlobalMetadata.Tests
- ( tests
- ) where
-
---------------------------------------------------------------------------------
-import qualified Data.Map as M
-import Control.Monad (forM_)
-import Test.Framework (Test, testGroup)
-import Test.HUnit (Assertion, (@=?))
-
-
---------------------------------------------------------------------------------
-import Hakyll.Core.Provider (resourceMetadata)
-import TestSuite.Util
-
---------------------------------------------------------------------------------
-tests :: Test
-tests = testGroup "Hakyll.Core.Provider.GlobalMetadata.Tests" $
- fromAssertions "page" [testPage]
-
-testPage :: Assertion
-testPage = do
- store <- newTestStore
- provider <- newTestProvider store
-
- metadata <- resourceMetadata provider "posts/2013-10-18-metadata-test.md"
- forM_ ["1", "2", "3", "4", "5", "6", "7", "8"] $ \a ->
- Just a @=? M.lookup ('a':a) metadata
-
diff --git a/tests/Hakyll/Web/Html/Tests.hs b/tests/Hakyll/Web/Html/Tests.hs
index e150ea2..bad5ebc 100644
--- a/tests/Hakyll/Web/Html/Tests.hs
+++ b/tests/Hakyll/Web/Html/Tests.hs
@@ -59,6 +59,8 @@ tests = testGroup "Hakyll.Web.Html.Tests" $ concat
, "." @=? toSiteRoot "index.html"
, "." @=? toSiteRoot "/index.html"
, "../.." @=? toSiteRoot "foo/bar/qux"
+ , ".." @=? toSiteRoot "./foo/bar.html"
+ , ".." @=? toSiteRoot "/foo/./bar.html"
]
, fromAssertions "isExternal"
diff --git a/tests/TestSuite.hs b/tests/TestSuite.hs
index 9cc446e..3622301 100644
--- a/tests/TestSuite.hs
+++ b/tests/TestSuite.hs
@@ -12,7 +12,6 @@ import Test.Framework (defaultMain)
import qualified Hakyll.Core.Dependencies.Tests
import qualified Hakyll.Core.Identifier.Tests
import qualified Hakyll.Core.Provider.Metadata.Tests
-import qualified Hakyll.Core.Provider.GlobalMetadata.Tests
import qualified Hakyll.Core.Provider.Tests
import qualified Hakyll.Core.Routes.Tests
import qualified Hakyll.Core.Rules.Tests
@@ -33,7 +32,6 @@ main = defaultMain
[ Hakyll.Core.Dependencies.Tests.tests
, Hakyll.Core.Identifier.Tests.tests
, Hakyll.Core.Provider.Metadata.Tests.tests
- , Hakyll.Core.Provider.GlobalMetadata.Tests.tests
, Hakyll.Core.Provider.Tests.tests
, Hakyll.Core.Routes.Tests.tests
, Hakyll.Core.Rules.Tests.tests
diff --git a/tests/data/metadata b/tests/data/metadata
deleted file mode 100644
index 1145976..0000000
--- a/tests/data/metadata
+++ /dev/null
@@ -1,27 +0,0 @@
---- posts/2013-10-18-metadata-test.md
-a1: 8
-a2: 8
-a3: 8
-a4: 8
-a5: 8
-a6: 8
-a7: 8
-a8: 8
-
---- posts/*
-a1: 7
-a2: 7
-a3: 7
-a4: 7
-a5: 7
-a6: 7
-a7: 7
-
---- **
-a1: 6
-a2: 6
-a3: 6
-a4: 6
-a5: 6
-a6: 6
-
diff --git a/tests/data/posts/2013-10-18-metadata-test.md b/tests/data/posts/2013-10-18-metadata-test.md
deleted file mode 100644
index 86a3e67..0000000
--- a/tests/data/posts/2013-10-18-metadata-test.md
+++ /dev/null
@@ -1,4 +0,0 @@
----
-a1: 1
----
-Nothing interesting here.
diff --git a/tests/data/posts/2013-10-18-metadata-test.md.metadata b/tests/data/posts/2013-10-18-metadata-test.md.metadata
deleted file mode 100644
index 7ee78b6..0000000
--- a/tests/data/posts/2013-10-18-metadata-test.md.metadata
+++ /dev/null
@@ -1,2 +0,0 @@
-a1: 2
-a2: 2
diff --git a/tests/data/posts/metadata b/tests/data/posts/metadata
deleted file mode 100644
index 4a1be71..0000000
--- a/tests/data/posts/metadata
+++ /dev/null
@@ -1,20 +0,0 @@
---- **
-a1: 5
-a2: 5
-a3: 5
-a4: 5
-a5: 5
-
---- *
-a1: 4
-a2: 4
-a3: 4
-a4: 4
-
---- 2013-10-18-metadata-test.md
-a1: 3
-a2: 3
-a3: 3
-
---- nonexistent
-a3: 0
diff --git a/web/examples.markdown b/web/examples.markdown
index 113bd25..e13670e 100644
--- a/web/examples.markdown
+++ b/web/examples.markdown
@@ -77,6 +77,26 @@ this list. This list has no particular ordering.
[source](http://hub.darcs.net/co-dan/website)
- <http://www.gwern.net/>,
[source](https://github.com/gwern/gwern.net)
+- <http://www.rohanjain.in/>,
+ [source](https://github.com/crodjer/rohanjain.in)
+- <http://www.corentindupont.info/>,
+ [source](https://github.com/cdupont/CorentinDupont-WebPage)
+- <http://jelv.is>,
+ [source](https://github.com/TikhonJelvis/website)
+- <https://secure.plaimi.net/>,
+ [source](https://github.com/plaimi/www)
+- <http://duplode.github.io/>,
+ [source](https://github.com/duplode/duplode.github.io/tree/sources)
+- <http://maseek.codes>,
+ [source](https://github.com/maseek/maseek-codes)
+- <http://listx.github.io>,
+ [source](https://github.com/listx/listx_blog)
+- <http://kyle.marek-spartz.org>,
+ [source](https://github.com/zeckalpha/kyle.marek-spartz.org)
+- <http://ladatura-corsets.com/>,
+ [source](https://github.com/dsferruzza/datura-corsets)
+- <http://reichertbrothers.com/>,
+ [source](https://github.com/rbros/reichertbrothers.com)
## Hakyll 3.X
@@ -106,8 +126,6 @@ this list. This list has no particular ordering.
[source](http://gitorious.org/shakthimaan-blog)
- <http://www.alfredodinapoli.com/>,
[source](https://github.com/CharlesStain/alfredodinapoli.com)
-- <http://www.rohanjain.in/>,
- [source](https://github.com/crodjer/rohanjain.in)
- <http://datahackermd.com>,
[source](http://github.com/akshayjshah/datahackermd)
- <http://michaelxavier.net>,
diff --git a/web/releases.markdown b/web/releases.markdown
index 7277ea9..cc704f1 100644
--- a/web/releases.markdown
+++ b/web/releases.markdown
@@ -4,6 +4,33 @@ title: Releases
# Releases
+## Hakyll 4.5.3.0
+
+- Bump Pandoc to 1.12.4 to include the org-mode reader.
+
+## Hakyll 4.5.2.0
+
+- Fix rebuilding everything issue with latest directory (contribution by Jorge
+ Israel Peña)
+- Fix issue with `toSiteRoot` (contribution by Izzy Cecil)
+- Fix issue with tag dependencies, slightly improve caching
+
+## Hakyll 4.5.0.0
+
+- Fix issue with syntax highlighting and line numbers (contribution by Adelbert
+ Chang)
+- Improve documentation for `Context` (contribution by Daniil Frumin)
+- Added `IsString` instance for `Template`
+- Added the `pandocCompilerWithTransformM` function (contribution by Daniil
+ Frumin)
+- Make `./site check` return the right exit code (contribution by Andres Loeh)
+- Use OS threads to make `./site watch` work nicely on Windows (contribution by
+ Simonas Kazlauskas)
+- Make the `unixFilter` function work better on windows by calling `shell`
+ (contribution by Collin J. Doering)
+- Add a command-line flag to bind on a user-specified host (contribution by
+ chrisdotcode)
+
## Hakyll 4.4.3.0
- Fix issue when using `metadataRoute` after other custom routes
diff --git a/web/tutorials/01-installation.markdown b/web/tutorials/01-installation.markdown
index c02a86e..5421c73 100644
--- a/web/tutorials/01-installation.markdown
+++ b/web/tutorials/01-installation.markdown
@@ -49,7 +49,7 @@ The file `site.hs` holds the configuration of your site, as an executable
haskell program. We can compile and run it like this:
$ cd my-site
- $ ghc --make site.hs
+ $ ghc --make -threaded site.hs
$ ./site build
If you installed `hakyll` with a preview server (this is the default), you can
diff --git a/web/tutorials/faq.markdown b/web/tutorials/faq.markdown
index 66dd4e6..87c1a92 100644
--- a/web/tutorials/faq.markdown
+++ b/web/tutorials/faq.markdown
@@ -24,6 +24,9 @@ using something like:
You should also add this to your `.profile`, or whatever config file you use.
+On Windows, running `chcp 65001` before running your Hakyll executable has been
+reported to work.
+
## "File name does not match module name" on Mac OS
Hakyll.hs:1:1:
diff --git a/web/tutorials/using-clay-with-hakyll.markdown b/web/tutorials/using-clay-with-hakyll.markdown
index e557c3d..c676a80 100644
--- a/web/tutorials/using-clay-with-hakyll.markdown
+++ b/web/tutorials/using-clay-with-hakyll.markdown
@@ -13,15 +13,25 @@ the CSS. This would be an example of such a file:
``` haskell
{-# LANGUAGE OverloadedStrings #-}
import Clay
-import qualified Data.Text.Lazy.IO as T
test :: Css
test = ...
main :: IO ()
-main = T.putStr $ render test
+main = putCss test
```
+If you prefer the compact version, you're going to have an extra import:
+
+
+``` haskell
+import qualified Data.Text.Lazy.IO as T
+
+main :: IO ()
+main = T.putStr $ renderWith compact test
+```
+
+
Let's assume such a file is called `css/foo.hs`. In our compiled site, we want
to map this to `css/foo.css`. Hence, the route is a simple `setExtension`. For
compilation, we simply pass the Clay file through `runghc` with no options.
@@ -30,6 +40,9 @@ compilation, we simply pass the Clay file through `runghc` with no options.
match "css/*.hs" $ do
route $ setExtension "css"
compile $ getResourceString >>= withItemBody (unixFilter "runghc" [])
+
+-- cabal sandbox users can use (unixFilter "cabal" ["exec", "runghc"])
+-- given that you've added cabal to your PATH
```
The major advantage of using this method (as opposed to importing the Clay files