on master help sign in
Added pure render function.
commitef7ccb15149862e1213ed66a31d65fc577c32d58 authorJasper Van der Jeugt <jaspervdj@gmail.com> dateTue 12 Jan 2010, 12:26 (17 years ago) parent36b0b72
2 files changed+73−52
src/Text/Hakyll/Render.hs+5−52 src/Text/Hakyll/Render/Internal.hs+68
src/Text/Hakyll/Render.hs+5−52
@@ -10,22 +10,18 @@ module Text.Hakyll.Render
1010 , css
1111 ) where
1212
13−import qualified Data.Map as M
14−import Data.List (isPrefixOf)
1513import Control.Monad (unless, liftM, foldM)
16−import Data.Char (isAlpha)
17−import Data.Maybe (fromMaybe)
1814
1915import System.Directory (copyFile)
2016import System.IO
2117
22−import Text.Hakyll.Context (Context, ContextManipulation)
18+import Text.Hakyll.Context (ContextManipulation)
2319import Text.Hakyll.Page
2420import Text.Hakyll.Renderable
2521import Text.Hakyll.File
2622import Text.Hakyll.CompressCSS
2723
28−import Control.Parallel.Strategies (rnf, ($|))
24+import Text.Hakyll.Render.Internal
2925
3026-- | Execute an IO action only when the cache is invalid.
3127depends :: FilePath -- ^ File to be rendered or created.
@@ -36,30 +32,6 @@ depends file dependencies action = do
3632 valid <- isCacheValid (toDestination file) dependencies
3733 unless valid action
3834
39−-- | Substitutes `$identifiers` in the given string by values from the given
40−-- "Context". When a key is not found, it is left as it is. You can here
41−-- specify the characters used to replace escaped dollars `$$`.
42−substitute :: String -> String -> Context -> String
43−substitute _ [] _ = []
44−substitute escaper string context
45− | "$$" `isPrefixOf` string = escaper ++ substitute' (tail tail')
46− | "$" `isPrefixOf` string = substituteKey
47− | otherwise = (head string) : (substitute' tail')
48− where
49− tail' = tail string
50− (key, rest) = break (not . isAlpha) tail'
51− replacement = fromMaybe ('$' : key) $ M.lookup key context
52− substituteKey = replacement ++ substitute' rest
53− substitute' str = substitute escaper str context
54−
55−-- | "substitute" for use during a chain.
56−regularSubstitute :: String -> Context -> String
57−regularSubstitute = substitute "$$"
58−
59−-- | "substitute" for the end of a chain (just before writing).
60−finalSubstitute :: String -> Context -> String
61−finalSubstitute = substitute "$"
62−
6335-- | Render to a Page.
6436render :: Renderable a
6537 => FilePath -- ^ Template to use for rendering.
@@ -75,16 +47,9 @@ renderWith :: Renderable a
7547 -> a -- ^ Renderable object to render with given template.
7648 -> IO Page -- ^ The body of the result will contain the render.
7749renderWith manipulation templatePath renderable = do
78− handle <- openFile templatePath ReadMode
79− templateString <- hGetContents handle
80− context <- liftM manipulation $ toContext renderable
81− -- Ignore $root when substituting here. We will only replace that in the
82− -- final render (just before writing).
83− let contextIgnoringRoot = M.insert "root" "$root" context
84− body = regularSubstitute templateString contextIgnoringRoot
85− -- Force the body to be rendered before closing the handle.
86− seq (($|) id rnf body) $ hClose handle
87− return $ fromContext (M.insert "body" body context)
50+ template <- readFile templatePath
51+ context <- toContext renderable
52+ return $ pureRenderWith manipulation template context
8853
8954-- | Render each renderable with the given template, then concatenate the
9055-- result.
@@ -124,18 +89,6 @@ renderChainWith manipulation templates renderable =
12489 result <- foldM (flip render) (fromContext initialPage) templates
12590 writePage result
12691
127−-- | Write a page to the site destination.
128−writePage :: Page -> IO ()
129−writePage page = do
130− let destination = toDestination url
131− makeDirectories destination
132− writeFile destination body
133− where
134− url = getURL page
135−    -- Substitute $root here, just before writing.
136−    body = finalSubstitute (getBody page)
137−                           (M.singleton "root" $ toRoot url)
138−
13992-- | Mark a certain file as static, so it will just be copied when the site is
14093-- generated.
14194static :: FilePath -> IO ()
src/Text/Hakyll/Render/Internal.hsnew file+68
@@ -0,0 +1,68 @@
1+-- | Internal module do some low-level rendering.
2+module Text.Hakyll.Render.Internal
3+ ( substitute
4+ , regularSubstitute
5+ , finalSubstitute
6+ , pureRenderWith
7+ , writePage
8+ ) where
9+
10+import qualified Data.Map as M
11+import Text.Hakyll.Context (Context, ContextManipulation)
12+import Data.List (isPrefixOf)
13+import Data.Char (isAlpha)
14+import Data.Maybe (fromMaybe)
15+import Control.Parallel.Strategies (rnf, ($|))
16+import Text.Hakyll.Renderable
17+import Text.Hakyll.Page
18+import Text.Hakyll.File
19+
20+-- | Substitutes `$identifiers` in the given string by values from the given
21+-- "Context". When a key is not found, it is left as it is. You can here
22+-- specify the characters used to replace escaped dollars `$$`.
23+substitute :: String -> String -> Context -> String
24+substitute _ [] _ = []
25+substitute escaper string context
26+ | "$$" `isPrefixOf` string = escaper ++ substitute' (tail tail')
27+ | "$" `isPrefixOf` string = substituteKey
28+ | otherwise = (head string) : (substitute' tail')
29+ where
30+ tail' = tail string
31+ (key, rest) = break (not . isAlpha) tail'
32+ replacement = fromMaybe ('$' : key) $ M.lookup key context
33+ substituteKey = replacement ++ substitute' rest
34+ substitute' str = substitute escaper str context
35+
36+-- | "substitute" for use during a chain.
37+regularSubstitute :: String -> Context -> String
38+regularSubstitute = substitute "$$"
39+
40+-- | "substitute" for the end of a chain (just before writing).
41+finalSubstitute :: String -> Context -> String
42+finalSubstitute = substitute "$"
43+
44+-- | A pure render function.
45+pureRenderWith :: ContextManipulation -- ^ Manipulation to apply on the context.
46+ -> String -- ^ Template to use for rendering.
47+ -> Context -- ^ Renderable object to render with given template.
48+ -> Page -- ^ The body of the result will contain the render.
49+pureRenderWith manipulation template context =
50+ -- Ignore $root when substituting here. We will only replace that in the
51+ -- final render (just before writing).
52+ let contextIgnoringRoot = M.insert "root" "$root" (manipulation context)
53+ body = regularSubstitute template contextIgnoringRoot
54+ -- Force the body to be rendered.
55+ in ($|) fromContext rnf (M.insert "body" body context)
56+
57+-- | Write a page to the site destination. Final action after render
58+-- chains and such.
59+writePage :: Page -> IO ()
60+writePage page = do
61+ let destination = toDestination url
62+ makeDirectories destination
63+ writeFile destination body
64+ where
65+ url = getURL page
66+    -- Substitute $root here, just before writing.
67+    body = finalSubstitute (getBody page)
68+                           (M.singleton "root" $ toRoot url)