diff options
| -rw-r--r-- | .gitignore | 2 | ||||
| -rw-r--r-- | blog.cabal | 5 | ||||
| -rw-r--r-- | blog.nix | 4 | ||||
| -rw-r--r-- | lists/default.md.do | 41 | ||||
| l--------- | lists/dirty-haskell/001 | 1 | ||||
| l--------- | lists/dirty-haskell/002 | 1 | ||||
| -rw-r--r-- | lists/dirty-haskell/title | 1 | ||||
| l--------- | lists/zz_all/001 | 1 | ||||
| l--------- | lists/zz_all/002 | 1 | ||||
| l--------- | lists/zz_all/003 | 1 | ||||
| -rw-r--r-- | lists/zz_all/title | 1 | ||||
| -rw-r--r-- | provider/css/default.css | 40 | ||||
| -rw-r--r-- | provider/index.html | 8 | ||||
| -rw-r--r-- | provider/index.md | 3 | ||||
| -rw-r--r-- | provider/posts/blog-documentation.md (renamed from posts/blog-documentation.md) | 8 | ||||
| -rw-r--r-- | provider/posts/blog-rss.md (renamed from posts/blog-rss.md) | 6 | ||||
| -rw-r--r-- | provider/posts/pwutil.md (renamed from posts/pwutil.md) | 5 | ||||
| -rw-r--r-- | provider/templates/default.html | 22 | ||||
| -rw-r--r-- | provider/templates/index.html | 9 | ||||
| -rw-r--r-- | provider/templates/post-list.html | 7 | ||||
| -rw-r--r-- | provider/templates/tag.html | 2 | ||||
| -rw-r--r-- | src/Site.hs | 123 | ||||
| -rw-r--r-- | templates/default.html | 55 | 
23 files changed, 234 insertions, 113 deletions
| @@ -1 +1,3 @@ | |||
| 1 | /result | 1 | /result | 
| 2 | /_cache/ | ||
| 3 | /_site/ | ||
| @@ -17,7 +17,12 @@ build-type: Simple | |||
| 17 | cabal-version: >=1.10 | 17 | cabal-version: >=1.10 | 
| 18 | 18 | ||
| 19 | executable site | 19 | executable site | 
| 20 | default-language: Haskell2010 | ||
| 20 | hs-source-dirs: src | 21 | hs-source-dirs: src | 
| 21 | main-is: Site.hs | 22 | main-is: Site.hs | 
| 22 | build-depends: base >=4.7 && <4.8 | 23 | build-depends: base >=4.7 && <4.8 | 
| 23 | , hakyll >=4.6 && <5 | 24 | , hakyll >=4.6 && <5 | 
| 25 | , containers >=0.5 && <0.6 | ||
| 26 | , pandoc >=1.13 && <2 | ||
| 27 | , data-default >=0.5 && <0.6 | ||
| 28 | , filepath >=1.3 && <2 | ||
| @@ -1,7 +1,7 @@ | |||
| 1 | # This file was auto-generated by cabal2nix. Please do NOT edit manually! | 1 | # This file was auto-generated by cabal2nix. Please do NOT edit manually! | 
| 2 | 2 | ||
| 3 | { mkDerivation, stdenv | 3 | { mkDerivation, stdenv | 
| 4 | , hakyll | 4 | , hakyll, containers, pandoc, data-default, filepath | 
| 5 | }: | 5 | }: | 
| 6 | 6 | ||
| 7 | mkDerivation { | 7 | mkDerivation { | 
| @@ -11,7 +11,7 @@ mkDerivation { | |||
| 11 | isExecutable = true; | 11 | isExecutable = true; | 
| 12 | isLibrary = false; | 12 | isLibrary = false; | 
| 13 | buildDepends = [ | 13 | buildDepends = [ | 
| 14 | hakyll | 14 | hakyll containers pandoc data-default filepath | 
| 15 | ]; | 15 | ]; | 
| 16 | license = stdenv.lib.licenses.publicDomain; | 16 | license = stdenv.lib.licenses.publicDomain; | 
| 17 | } | 17 | } | 
diff --git a/lists/default.md.do b/lists/default.md.do deleted file mode 100644 index 55abe6f..0000000 --- a/lists/default.md.do +++ /dev/null  | |||
| @@ -1,41 +0,0 @@ | |||
| 1 | #!/usr/bin/env bash | ||
| 2 | redo-ifchange "$2/title" | ||
| 3 | |||
| 4 | POSTS=() | ||
| 5 | while read -r -d $'\0'; do | ||
| 6 | post=$(realpath --relative-to=. "$REPLY") | ||
| 7 | POSTS+=("$post") | ||
| 8 | done < <(find "$2" -maxdepth 1 -mindepth 1 -not -name 'title' -not -name 'preview' -print0 | sort -z) | ||
| 9 | |||
| 10 | for x in "${POSTS[@]}"; do | ||
| 11 | printf "%s\0%s\0" "$x" "${x%.md}.html" | ||
| 12 | done | xargs -r -0 redo-ifchange | ||
| 13 | |||
| 14 | TITLE=$(< $2/title) | ||
| 15 | |||
| 16 | cat <<EOF | ||
| 17 | % $(< "$2/title") | ||
| 18 | |||
| 19 | EOF | ||
| 20 | |||
| 21 | POST_TITLES=() | ||
| 22 | for x in "${POSTS[@]}"; do | ||
| 23 | title=$(pandoc -t json "$x" | ../build/extract-title.hs) | ||
| 24 | POST_TITLES+=("$title") | ||
| 25 | done | ||
| 26 | |||
| 27 | for n in $(seq 0 $((${#POSTS[@]}-1))); do | ||
| 28 | printf "* [%s](%s)\n" "${POST_TITLES[$n]}" "${POSTS[$n]%.md}.html" | ||
| 29 | done | ||
| 30 | |||
| 31 | >"$2/preview" | ||
| 32 | prev_no=3 | ||
| 33 | if [[ ${#POSTS[@]} -gt $prev_no ]]; then | ||
| 34 | printf "* …\n" >> "$2/preview" | ||
| 35 | else | ||
| 36 | prev_no=${#POSTS[@]} | ||
| 37 | fi | ||
| 38 | |||
| 39 | for n in $(seq $prev_no -1 1); do | ||
| 40 | printf "* [%s](%s)\n" "${POST_TITLES[-$n]}" "${POSTS[-$n]%.md}.html" >>"$2/preview" | ||
| 41 | done | ||
diff --git a/lists/dirty-haskell/001 b/lists/dirty-haskell/001 deleted file mode 120000 index 92c240d..0000000 --- a/lists/dirty-haskell/001 +++ /dev/null  | |||
| @@ -1 +0,0 @@ | |||
| 1 | ../../posts/blog-documentation.md \ No newline at end of file | ||
diff --git a/lists/dirty-haskell/002 b/lists/dirty-haskell/002 deleted file mode 120000 index ed24126..0000000 --- a/lists/dirty-haskell/002 +++ /dev/null  | |||
| @@ -1 +0,0 @@ | |||
| 1 | ../../posts/blog-rss.md \ No newline at end of file | ||
diff --git a/lists/dirty-haskell/title b/lists/dirty-haskell/title deleted file mode 100644 index e40f49c..0000000 --- a/lists/dirty-haskell/title +++ /dev/null  | |||
| @@ -1 +0,0 @@ | |||
| 1 | Blog Software | ||
diff --git a/lists/zz_all/001 b/lists/zz_all/001 deleted file mode 120000 index 92c240d..0000000 --- a/lists/zz_all/001 +++ /dev/null  | |||
| @@ -1 +0,0 @@ | |||
| 1 | ../../posts/blog-documentation.md \ No newline at end of file | ||
diff --git a/lists/zz_all/002 b/lists/zz_all/002 deleted file mode 120000 index ed24126..0000000 --- a/lists/zz_all/002 +++ /dev/null  | |||
| @@ -1 +0,0 @@ | |||
| 1 | ../../posts/blog-rss.md \ No newline at end of file | ||
diff --git a/lists/zz_all/003 b/lists/zz_all/003 deleted file mode 120000 index 1057f2c..0000000 --- a/lists/zz_all/003 +++ /dev/null  | |||
| @@ -1 +0,0 @@ | |||
| 1 | ../../posts/pwutil.md \ No newline at end of file | ||
diff --git a/lists/zz_all/title b/lists/zz_all/title deleted file mode 100644 index 73a5267..0000000 --- a/lists/zz_all/title +++ /dev/null  | |||
| @@ -1 +0,0 @@ | |||
| 1 | All Posts | ||
diff --git a/provider/css/default.css b/provider/css/default.css new file mode 100644 index 0000000..7b89107 --- /dev/null +++ b/provider/css/default.css  | |||
| @@ -0,0 +1,40 @@ | |||
| 1 | body { | ||
| 2 | margin: auto; | ||
| 3 | padding-right: 1em; | ||
| 4 | padding-left: 1em; | ||
| 5 | font: normal 1.1em monospace; | ||
| 6 | max-width: 60em; | ||
| 7 | text-align: justify; | ||
| 8 | } | ||
| 9 | |||
| 10 | .display-math { | ||
| 11 | display: block; | ||
| 12 | margin-top: 0.2em; | ||
| 13 | margin-bottm: 0.2em; | ||
| 14 | text-align: center; | ||
| 15 | } | ||
| 16 | |||
| 17 | .inline-math { | ||
| 18 | display: inline; | ||
| 19 | } | ||
| 20 | |||
| 21 | a { | ||
| 22 | color: inherit; | ||
| 23 | } | ||
| 24 | |||
| 25 | p { | ||
| 26 | margin-bottom: 0 | ||
| 27 | } | ||
| 28 | |||
| 29 | p + p { | ||
| 30 | text-indent: 1.5em; | ||
| 31 | margin-top: 0; | ||
| 32 | } | ||
| 33 | |||
| 34 | pre { | ||
| 35 | margin-left: 1.5em; | ||
| 36 | } | ||
| 37 | |||
| 38 | p code { | ||
| 39 | font-style:italic; | ||
| 40 | } \ No newline at end of file | ||
diff --git a/provider/index.html b/provider/index.html new file mode 100644 index 0000000..8eb184f --- /dev/null +++ b/provider/index.html  | |||
| @@ -0,0 +1,8 @@ | |||
| 1 | $body$ | ||
| 2 | <ul> | ||
| 3 | $for(tags)$ | ||
| 4 | <li> | ||
| 5 | $body$ | ||
| 6 | </li> | ||
| 7 | $endfor$ | ||
| 8 | </ul> | ||
diff --git a/provider/index.md b/provider/index.md new file mode 100644 index 0000000..53a06bc --- /dev/null +++ b/provider/index.md  | |||
| @@ -0,0 +1,3 @@ | |||
| 1 | This is a blog. | ||
| 2 | It contains things. | ||
| 3 | Send other things to <blog@dirty-haskell.org> if you so choose. | ||
diff --git a/posts/blog-documentation.md b/provider/posts/blog-documentation.md index 7db843d..b0d4af6 100644 --- a/posts/blog-documentation.md +++ b/provider/posts/blog-documentation.md  | |||
| @@ -1,5 +1,9 @@ | |||
| 1 | % On the Origin of dirty-haskell.org | 1 | --- | 
| 2 | title: On the Origin of dirty-haskell.org | ||
| 3 | published: 2015-03-12 | ||
| 4 | tags: Blog Software | ||
| 5 | --- | ||
| 2 | 6 | ||
| 3 | The software used is a trivially modified version of the one powering [math.kleen.org](http://math.kleen.org/lists/blog.html). | 7 | The software used is a trivially modified version of the one powering [math.kleen.org](http://math.kleen.org/lists/blog.html). | 
| 4 | 8 | ||
| 5 | The title is without deeper meaning. \ No newline at end of file | 9 | The title is without deeper meaning. | 
diff --git a/posts/blog-rss.md b/provider/posts/blog-rss.md index 4e8cb24..095ff56 100644 --- a/posts/blog-rss.md +++ b/provider/posts/blog-rss.md  | |||
| @@ -1,4 +1,8 @@ | |||
| 1 | % dirty-haskell.org´s rss feeds | 1 | --- | 
| 2 | title: dirty-haskell.org´s rss feeds | ||
| 3 | published: 2015-03-29 | ||
| 4 | tags: Blog Software | ||
| 5 | --- | ||
| 2 | 6 | ||
| 3 | I extended the software suite inherited from [math.kleen.org](http://math.kleen.org) to include support for rss feeds. | 7 | I extended the software suite inherited from [math.kleen.org](http://math.kleen.org) to include support for rss feeds. | 
| 4 | The heart of the issue is a ~80 line haskell script I chose to call, in a bout of creativity, "generate-rss.hs". | 8 | The heart of the issue is a ~80 line haskell script I chose to call, in a bout of creativity, "generate-rss.hs". | 
diff --git a/posts/pwutil.md b/provider/posts/pwutil.md index 176ffdc..a4b3757 100644 --- a/posts/pwutil.md +++ b/provider/posts/pwutil.md  | |||
| @@ -1,4 +1,7 @@ | |||
| 1 | % A Tool to Manage a Set of YAML Objects Representing Account Information — pwutil | 1 | --- | 
| 2 | title: A Tool to Manage a Set of YAML Objects Representing Account Information — pwutil | ||
| 3 | published: 2015-04-07 | ||
| 4 | --- | ||
| 2 | 5 | ||
| 3 | A long time ago I wrote a bunch of scripts (first in bash, then zsh, and later perl) to manage a, sometimes encrypted, file containing account information I get asked to create and remember on a daily basis—accounts for shopping websites spring to mind. | 6 | A long time ago I wrote a bunch of scripts (first in bash, then zsh, and later perl) to manage a, sometimes encrypted, file containing account information I get asked to create and remember on a daily basis—accounts for shopping websites spring to mind. | 
| 4 | 7 | ||
diff --git a/provider/templates/default.html b/provider/templates/default.html new file mode 100644 index 0000000..14497b2 --- /dev/null +++ b/provider/templates/default.html  | |||
| @@ -0,0 +1,22 @@ | |||
| 1 | <!DOCTYPE html> | ||
| 2 | <html$if(lang)$ lang="$lang$"$endif$> | ||
| 3 | <head> | ||
| 4 | <meta charset="utf-8"> | ||
| 5 | <meta name="generator" content="pandoc"> | ||
| 6 | <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes"> | ||
| 7 | <title>$if(title)$$title$$endif$</title> | ||
| 8 | <style type="text/css">code{white-space: pre;}</style> | ||
| 9 | <!--[if lt IE 9]> | ||
| 10 | <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script> | ||
| 11 | <![endif]--> | ||
| 12 | <link rel="stylesheet" href="/css/default.css"> | ||
| 13 | </head> | ||
| 14 | <body> | ||
| 15 | $if(title)$ | ||
| 16 | <header> | ||
| 17 | <h1 class="title"><a href="/" title="dirty-haskell.org">dirty-haskell.org</a>: $title$</h1> | ||
| 18 | </header> | ||
| 19 | $endif$ | ||
| 20 | $body$ | ||
| 21 | </body> | ||
| 22 | </html> | ||
diff --git a/provider/templates/index.html b/provider/templates/index.html new file mode 100644 index 0000000..0eea806 --- /dev/null +++ b/provider/templates/index.html  | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | $body$ | ||
| 2 | |||
| 3 | <ul> | ||
| 4 | $for(tags)$ | ||
| 5 | <li> | ||
| 6 | $body$ | ||
| 7 | </li> | ||
| 8 | $endfor$ | ||
| 9 | </ul> | ||
diff --git a/provider/templates/post-list.html b/provider/templates/post-list.html new file mode 100644 index 0000000..4d50d4d --- /dev/null +++ b/provider/templates/post-list.html  | |||
| @@ -0,0 +1,7 @@ | |||
| 1 | <ul> | ||
| 2 | $for(posts)$ | ||
| 3 | <li> | ||
| 4 | $if(ellipsis)$…$else$<a href="$url$">$title$</a>$endif$ | ||
| 5 | </li> | ||
| 6 | $endfor$ | ||
| 7 | </ul> | ||
diff --git a/provider/templates/tag.html b/provider/templates/tag.html new file mode 100644 index 0000000..8854cdd --- /dev/null +++ b/provider/templates/tag.html  | |||
| @@ -0,0 +1,2 @@ | |||
| 1 | <a href="$url$">$title$</a>$if(rss)$ (<a href="$rss$">RSS</a>)$endif$ | ||
| 2 | $body$ | ||
diff --git a/src/Site.hs b/src/Site.hs index d1afbce..dde7047 100644 --- a/src/Site.hs +++ b/src/Site.hs  | |||
| @@ -1,16 +1,131 @@ | |||
| 1 | {-# LANGUAGE OverloadedStrings #-} | 1 | {-# LANGUAGE OverloadedStrings, RankNTypes, StandaloneDeriving, FlexibleInstances #-} | 
| 2 | 2 | ||
| 3 | import Hakyll | 3 | import Hakyll | 
| 4 | 4 | ||
| 5 | import Data.Monoid (Monoid(..), mconcat, (<>)) | ||
| 6 | import Control.Monad (liftM) | ||
| 7 | import Data.Char (toLower, isSpace, isAlphaNum) | ||
| 8 | import Data.Maybe (mapMaybe, fromMaybe) | ||
| 9 | import Data.Map (Map) | ||
| 10 | import qualified Data.Map as Map | ||
| 11 | import Data.List (take, reverse) | ||
| 12 | import Data.Default | ||
| 13 | import Text.Pandoc.Options (WriterOptions(..), ObfuscationMethod(..)) | ||
| 14 | import Control.Applicative (Alternative(..), Applicative(..)) | ||
| 15 | |||
| 16 | import System.FilePath (replaceExtension) | ||
| 17 | |||
| 5 | main :: IO () | 18 | main :: IO () | 
| 6 | main = hakyllWith config $ do | 19 | main = hakyllWith config $ do | 
| 7 | match "/posts/*" $ do | 20 | match "templates/*" $ compile templateCompiler | 
| 21 | |||
| 22 | match "css/*" $ do | ||
| 23 | route idRoute | ||
| 24 | compile copyFileCompiler | ||
| 25 | |||
| 26 | match "posts/*" $ do | ||
| 8 | route $ setExtension ".html" | 27 | route $ setExtension ".html" | 
| 9 | compile $ do | 28 | compile $ do | 
| 29 | getResourceBody >>= saveSnapshot "content" | ||
| 10 | pandocCompiler | 30 | pandocCompiler | 
| 11 | >>= saveSnapshot "content" | ||
| 12 | >>= loadAndApplyTemplate "templates/default.html" defaultContext | 31 | >>= loadAndApplyTemplate "templates/default.html" defaultContext | 
| 13 | >>= relativizeUrls | 32 | >>= relativizeUrls | 
| 14 | 33 | ||
| 34 | tags <- buildTags "posts/*" tagTranslation' >>= addTag "All Posts" "posts/*" | ||
| 35 | |||
| 36 | tagsRules tags $ \tag pattern -> do | ||
| 37 | route idRoute | ||
| 38 | compile $ do | ||
| 39 | let ctx = mconcat [ constField "title" tag | ||
| 40 | , listField "posts" defaultContext $ chronological =<< loadAll pattern | ||
| 41 | , defaultContext | ||
| 42 | ] | ||
| 43 | makeItem "" | ||
| 44 | >>= loadAndApplyTemplate "templates/post-list.html" ctx | ||
| 45 | >>= loadAndApplyTemplate "templates/default.html" ctx | ||
| 46 | >>= relativizeUrls | ||
| 47 | |||
| 48 | let | ||
| 49 | tags' = tags { tagsMakeId = fromFilePath . (`replaceExtension` "rss") . toFilePath . tagsMakeId tags} | ||
| 50 | |||
| 51 | tagsRules tags' $ \tag pattern -> do | ||
| 52 | route idRoute | ||
| 53 | compile $ do | ||
| 54 | let | ||
| 55 | feedCtx = mconcat [ bodyField "description" | ||
| 56 | , defaultContext | ||
| 57 | ] | ||
| 58 | renderRss (feedConfig tag) feedCtx =<< loadAllSnapshots pattern "content" | ||
| 59 | |||
| 60 | match "index.md" $ do | ||
| 61 | route $ setExtension ".html" | ||
| 62 | compile $ do | ||
| 63 | let ctx = mconcat [ listField "tags" defaultContext $ mapM (\(k, _) -> renderTag k tags) $ tagsMap tags | ||
| 64 | , constField "title" "Index" | ||
| 65 | , defaultContext | ||
| 66 | ] | ||
| 67 | item <- getResourceBody | ||
| 68 | pandocCompilerWith def (def { writerEmailObfuscation = NoObfuscation }) | ||
| 69 | >>= loadAndApplyTemplate "templates/index.html" ctx | ||
| 70 | >>= loadAndApplyTemplate "templates/default.html" ctx | ||
| 71 | >>= relativizeUrls | ||
| 72 | |||
| 73 | deriving instance Eq (Item String) | ||
| 74 | |||
| 75 | feedConfig :: String -> FeedConfiguration | ||
| 76 | feedConfig tagName = FeedConfiguration { feedTitle = "dirty-haskell.org: " ++ tagName | ||
| 77 | , feedDescription = "dirty-haskell.org — A Blog." | ||
| 78 | , feedAuthorName = "G. Kleen" | ||
| 79 | , feedAuthorEmail = "blog@dirty-haskell.org" | ||
| 80 | , feedRoot = "https://dirty-haskell.org" | ||
| 81 | } | ||
| 82 | |||
| 83 | renderTag :: String -- ^ Tag name | ||
| 84 | -> Tags | ||
| 85 | -> Compiler (Item String) | ||
| 86 | renderTag tag tags = do | ||
| 87 | ellipsisItem <- makeItem "" | ||
| 88 | let | ||
| 89 | ids = fromMaybe [] $ lookup tag $ tagsMap tags | ||
| 90 | postCtx = mconcat [ listField "posts" (ellipsisContext ellipsisItem) $ liftM (withEllipsis ellipsisItem) $ chronological =<< mapM load ids | ||
| 91 | , constField "title" tag | ||
| 92 | , constField "rss" ("tags/" ++ tagTranslation tag ++ ".rss") | ||
| 93 | , constField "url" ("tags/" ++ tagTranslation tag ++ ".html") | ||
| 94 | , defaultContext | ||
| 95 | ] | ||
| 96 | makeItem "" | ||
| 97 | >>= loadAndApplyTemplate "templates/post-list.html" postCtx | ||
| 98 | >>= loadAndApplyTemplate "templates/tag.html" postCtx | ||
| 99 | where | ||
| 100 | ellipsisContext item = mconcat [ boolField "ellipsis" (== item) | ||
| 101 | , defaultContext | ||
| 102 | ] | ||
| 103 | boolField name f = field name (\i -> if f i | ||
| 104 | then pure (error $ unwords ["no string value for bool field:",name]) | ||
| 105 | else empty) | ||
| 106 | withEllipsis ellipsisItem xs | ||
| 107 | | length xs > max = [ellipsisItem] ++ takeEnd (max - 1) xs | ||
| 108 | | otherwise = xs | ||
| 109 | takeEnd i = reverse . take i . reverse | ||
| 110 | max = 4 | ||
| 111 | |||
| 112 | tagTranslation' :: String -> Identifier | ||
| 113 | tagTranslation' = fromCapture "tags/*.html" . tagTranslation | ||
| 114 | |||
| 115 | tagTranslation :: String -> String | ||
| 116 | tagTranslation = mapMaybe charTrans | ||
| 117 | where | ||
| 118 | charTrans c | ||
| 119 | | isSpace c = Just $ '-' | ||
| 120 | | isAlphaNum c = Just $ toLower c | ||
| 121 | | otherwise = Nothing | ||
| 122 | |||
| 123 | addTag :: MonadMetadata m => String -> Pattern -> Tags -> m Tags | ||
| 124 | addTag name pattern tags = do | ||
| 125 | ids <- getMatches pattern | ||
| 126 | return $ tags { tagsMap = tagsMap tags ++ [(name, ids)] } | ||
| 127 | |||
| 15 | config :: Configuration | 128 | config :: Configuration | 
| 16 | config = defaultConfiguration | 129 | config = defaultConfiguration { providerDirectory = "provider" | 
| 130 | , deployCommand = "rsync -av --progress -c --delete-delay -m _site/ gkleen@surtr.yggdrasil.li:/var/www/dirty-haskell.org/" | ||
| 131 | } | ||
diff --git a/templates/default.html b/templates/default.html deleted file mode 100644 index 970848f..0000000 --- a/templates/default.html +++ /dev/null  | |||
| @@ -1,55 +0,0 @@ | |||
| 1 | <!DOCTYPE html> | ||
| 2 | <html$if(lang)$ lang="$lang$"$endif$> | ||
| 3 | <head> | ||
| 4 | <meta charset="utf-8"> | ||
| 5 | <meta name="generator" content="pandoc"> | ||
| 6 | <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes"> | ||
| 7 | $for(author-meta)$ | ||
| 8 | <meta name="author" content="$author-meta$"> | ||
| 9 | $endfor$ | ||
| 10 | $if(date-meta)$ | ||
| 11 | <meta name="dcterms.date" content="$date-meta$"> | ||
| 12 | $endif$ | ||
| 13 | <title>$if(title-prefix)$$title-prefix$ - $endif$$pagetitle$</title> | ||
| 14 | <style type="text/css">code{white-space: pre;}</style> | ||
| 15 | <!--[if lt IE 9]> | ||
| 16 | <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script> | ||
| 17 | <![endif]--> | ||
| 18 | $if(quotes)$ | ||
| 19 | <style type="text/css">q { quotes: "“" "”" "‘" "’"; }</style> | ||
| 20 | $endif$ | ||
| 21 | $if(highlighting-css)$ | ||
| 22 | <style type="text/css"> | ||
| 23 | $highlighting-css$ | ||
| 24 | </style> | ||
| 25 | $endif$ | ||
| 26 | $for(css)$ | ||
| 27 | <link rel="stylesheet" href="$css$"> | ||
| 28 | $endfor$ | ||
| 29 | $if(math)$ | ||
| 30 | $math$ | ||
| 31 | $endif$ | ||
| 32 | $for(header-includes)$ | ||
| 33 | $header-includes$ | ||
| 34 | $endfor$ | ||
| 35 | </head> | ||
| 36 | <body> | ||
| 37 | $for(include-before)$ | ||
| 38 | $include-before$ | ||
| 39 | $endfor$ | ||
| 40 | $if(title)$ | ||
| 41 | <header> | ||
| 42 | <h1 class="title"><a href="/" title="dirty-haskell.org">dirty-haskell.org</a>: $title$</h1> | ||
| 43 | </header> | ||
| 44 | $endif$ | ||
| 45 | $if(toc)$ | ||
| 46 | <nav id="$idprefix$TOC"> | ||
| 47 | $toc$ | ||
| 48 | </nav> | ||
| 49 | $endif$ | ||
| 50 | $body$ | ||
| 51 | $for(include-after)$ | ||
| 52 | $include-after$ | ||
| 53 | $endfor$ | ||
| 54 | </body> | ||
| 55 | </html> | ||
