mirror of
https://github.com/simonmichael/hledger.git
synced 2024-09-18 17:57:11 +03:00
site: commit and use hakyll-std, a generic site builder
This commit is contained in:
parent
7d81ca0e8f
commit
f788c53217
24
Makefile
24
Makefile
@ -817,19 +817,27 @@ $(call def-help-subsection,DOCUMENTATION:)
|
||||
# \
|
||||
# )
|
||||
|
||||
site: \
|
||||
$(call def-help,site, generate the hledger.org website with hakyll-std (a generic hakyll script) ) #olddocs
|
||||
-cd doc/site; hakyll build
|
||||
doc/site/hakyll-std hakyll-std: \
|
||||
doc/site/hakyll-std.hs \
|
||||
doc/site/TableOfContents.hs \
|
||||
doc/site/hakyll-std.cabal \
|
||||
doc/site/stack.yaml \
|
||||
$(call def-help,hakyll-std, build a generic hakyll site builder script )
|
||||
cd doc/site; stack ghc hakyll-std
|
||||
|
||||
site-clean: \
|
||||
site: doc/site/hakyll-std \
|
||||
$(call def-help,site, generate the hledger.org website with hakyll-std )
|
||||
-cd doc/site; ./hakyll-std build
|
||||
|
||||
site-clean: doc/site/hakyll-std \
|
||||
$(call def-help,site-clean, remove hakyll-generated files (& take down the website) ) #cleanolddocs
|
||||
-cd doc/site; hakyll clean
|
||||
-cd doc/site; ./hakyll-std clean
|
||||
# rm -rf doc/site/_site/*
|
||||
|
||||
# XXX hakyll preview/watch mostly don't live-update any more
|
||||
site-preview: \
|
||||
# XXX hakyll watch & preview mostly don't live-update any more
|
||||
site-preview: doc/site/hakyll-std \
|
||||
$(call def-help,site-preview, run a hakyll server to preview the website ) #doc/site/site
|
||||
cd doc/site; hakyll preview
|
||||
-cd doc/site; ./hakyll-std watch # -h hledger.org
|
||||
|
||||
# site-view: site \
|
||||
# $(call def-help,site-view,\
|
||||
|
30
doc/site/LICENSE
Normal file
30
doc/site/LICENSE
Normal file
@ -0,0 +1,30 @@
|
||||
Copyright (c) 2015
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials provided
|
||||
with the distribution.
|
||||
|
||||
* Neither the name of Your name here nor the names of other
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
2
doc/site/Setup.hs
Normal file
2
doc/site/Setup.hs
Normal file
@ -0,0 +1,2 @@
|
||||
import Distribution.Simple
|
||||
main = defaultMain
|
82
doc/site/TableOfContents.hs
Normal file
82
doc/site/TableOfContents.hs
Normal file
@ -0,0 +1,82 @@
|
||||
{-# LANGUAGE OverloadedStrings #-}
|
||||
-- from https://github.com/blaenk/blaenk.github.io
|
||||
|
||||
module TableOfContents (
|
||||
tableOfContents,
|
||||
ignoreTOC,
|
||||
collectHeaders,
|
||||
removeTOCMarker
|
||||
) where
|
||||
|
||||
import Text.Pandoc
|
||||
import Text.Pandoc.Walk (walk, query)
|
||||
|
||||
import Data.List (groupBy)
|
||||
import Data.Tree (Forest, Tree(Node))
|
||||
import Data.Monoid ((<>), mconcat)
|
||||
import Data.Function (on)
|
||||
import Data.Maybe (fromMaybe)
|
||||
|
||||
import Text.Blaze.Html (preEscapedToHtml, (!))
|
||||
import Text.Blaze.Html.Renderer.String (renderHtml)
|
||||
import qualified Text.Blaze.Html5 as H
|
||||
import qualified Text.Blaze.Html5.Attributes as A
|
||||
|
||||
headerLevel :: Block -> Int
|
||||
headerLevel (Header level _ _) = level
|
||||
headerLevel _ = error "not a header"
|
||||
|
||||
ignoreTOC :: Block -> Block
|
||||
ignoreTOC (Header level (ident, classes, params) inline) =
|
||||
Header level (ident, "notoc" : classes, params) inline
|
||||
ignoreTOC x = x
|
||||
|
||||
removeTOCMarker :: Block -> Block
|
||||
removeTOCMarker (BulletList (( (( Plain ((Str "toc"):_)):_)):_)) = Null
|
||||
removeTOCMarker x = x
|
||||
|
||||
collectHeaders :: Block -> [Block]
|
||||
collectHeaders header@(Header _ (_, classes, _) _) =
|
||||
if "notoc" `elem` classes
|
||||
then []
|
||||
else [header]
|
||||
collectHeaders _ = []
|
||||
|
||||
groupByHierarchy :: [Block] -> Forest Block
|
||||
groupByHierarchy = map (\(x:xs) -> Node x (groupByHierarchy xs)) . groupBy ((<) `on` headerLevel)
|
||||
|
||||
markupHeader :: Tree Block -> H.Html
|
||||
markupHeader (Node (Header _ (ident, _, keyvals) inline) headers)
|
||||
| headers == [] = H.li $ link
|
||||
| otherwise = H.li $ link <> (H.ol $ markupHeaders headers)
|
||||
where render x = writeHtmlString def (Pandoc nullMeta [(Plain x)])
|
||||
section = fromMaybe (render inline) (lookup "toc" keyvals)
|
||||
link = H.a ! A.href (H.toValue $ "#" ++ ident) $ preEscapedToHtml section
|
||||
markupHeader _ = error "what"
|
||||
|
||||
markupHeaders :: Forest Block -> H.Html
|
||||
markupHeaders = mconcat . map markupHeader
|
||||
|
||||
createTable :: Forest Block -> H.Html
|
||||
createTable headers =
|
||||
(H.nav ! A.id "toc") $ do
|
||||
H.p "Contents"
|
||||
H.ol $ markupHeaders headers
|
||||
|
||||
generateTOC :: [Block] -> String -> Block -> Block
|
||||
generateTOC [] _ x = x
|
||||
generateTOC headers alignment x@(BulletList (( (( Plain ((Str "toc"):_)):_)):_))
|
||||
| alignment == "right" = render . (! A.class_ "right-toc") . table $ headers
|
||||
| alignment == "left" = render . table $ headers
|
||||
| otherwise = x
|
||||
where render = (RawBlock "html") . renderHtml
|
||||
table = createTable . groupByHierarchy
|
||||
generateTOC _ _ x = x
|
||||
|
||||
tableOfContents :: String -> Pandoc -> Pandoc
|
||||
tableOfContents alignment ast =
|
||||
if alignment /= "off"
|
||||
then let headers = query collectHeaders ast
|
||||
in walk (generateTOC headers alignment) ast
|
||||
else walk ignoreTOC ast
|
||||
|
39
doc/site/hakyll-std.cabal
Normal file
39
doc/site/hakyll-std.cabal
Normal file
@ -0,0 +1,39 @@
|
||||
name: hakyll-std
|
||||
version: 0.1.0
|
||||
synopsis: Generic hakyll site builder script.
|
||||
description: Generic hakyll site builder script.
|
||||
homepage: http://github.com/simonmichael/hledger
|
||||
license: BSD3
|
||||
license-file: LICENSE
|
||||
author: Simon Michael
|
||||
maintainer: simon@joyful.com
|
||||
-- copyright:
|
||||
category: Web
|
||||
build-type: Simple
|
||||
-- extra-source-files:
|
||||
cabal-version: >=1.10
|
||||
|
||||
-- library
|
||||
-- hs-source-dirs: src
|
||||
-- build-depends: base >= 4.7 && < 5
|
||||
-- default-language: Haskell2010
|
||||
|
||||
executable hakyll-std
|
||||
default-language: Haskell2010
|
||||
ghc-options: -threaded -rtsopts -with-rtsopts=-N
|
||||
hs-source-dirs: .
|
||||
main-is: hakyll-std.hs
|
||||
other-modules: TableOfContents
|
||||
build-depends: base >= 4.7 && < 5
|
||||
,hakyll >=4.7
|
||||
,pandoc >=1.15
|
||||
,pandoc-types
|
||||
,process
|
||||
,directory
|
||||
,data-default
|
||||
,blaze-html
|
||||
,containers
|
||||
|
||||
-- source-repository head
|
||||
-- type: git
|
||||
-- location: https://github.com/simonmichael/hledger
|
146
doc/site/hakyll-std.hs
Executable file
146
doc/site/hakyll-std.hs
Executable file
@ -0,0 +1,146 @@
|
||||
#!/usr/bin/env stack
|
||||
-- stack --resolver nightly-2015-07-01 --install-ghc runghc --package hakyll --package pandoc
|
||||
{-# LANGUAGE OverloadedStrings #-}
|
||||
{- |
|
||||
|
||||
A simple hakyll website builder suitable for software project sites,
|
||||
intended to be used as-is without recompilation. Functionality:
|
||||
|
||||
- copies these static files to _site/ :
|
||||
*.{html,htm,css,js,gif,jpg,jpeg,png}
|
||||
{css,img,js,files}/** (** means everything below)
|
||||
site/{css,img,js,files,etc}/**
|
||||
doc/**.{html,htm,txt,gif,jpg,jpeg,png}
|
||||
|
||||
- renders these markdown files to _site/*.html :
|
||||
*.{md,mdwn,markdown}
|
||||
doc/**.{md,mdwn,markdown}
|
||||
|
||||
- applies this template file to markdown content:
|
||||
site.tmpl or site/site.tmpl (the first found)
|
||||
|
||||
- a single markdown list item containing the word "toc" is replaced by
|
||||
a table of contents based on headings
|
||||
|
||||
- syntax highlighting of fenced code blocks in markdown is enabled
|
||||
(if you provide suitable kate styles, eg a syntax.css)
|
||||
|
||||
Usage:
|
||||
|
||||
$ hakyll-std [--help|clean|build|preview|...] # standard hakyll options
|
||||
|
||||
-}
|
||||
|
||||
import Control.Monad
|
||||
import Data.Default
|
||||
import Hakyll
|
||||
import System.Directory
|
||||
import System.Environment (getArgs)
|
||||
import System.Exit (exitSuccess)
|
||||
import System.Process (system)
|
||||
-- import Text.Highlighting.Kate (pygments, kate, espresso, tango, haddock, monochrome, zenburn)
|
||||
import Text.Pandoc.Options
|
||||
|
||||
import TableOfContents (tableOfContents)
|
||||
|
||||
import Debug.Trace
|
||||
strace :: Show a => a -> a
|
||||
strace a = trace (show a) a
|
||||
|
||||
filesToCopy =
|
||||
["site/css/**"
|
||||
,"site/js/**"
|
||||
,"site/img/**"
|
||||
,"site/images/**"
|
||||
,"site/fonts/**"
|
||||
,"site/files/**"
|
||||
,"site/etc/**"
|
||||
,"site/*.html"
|
||||
,"site/*.htm"
|
||||
,"site/*.gif"
|
||||
,"site/*.jpg"
|
||||
,"site/*.jpeg"
|
||||
,"site/*.png"
|
||||
,"site/*.css"
|
||||
,"site/*.js"
|
||||
,"css/**"
|
||||
,"js/**"
|
||||
,"img/**"
|
||||
,"images/**"
|
||||
,"fonts/**"
|
||||
,"files/**"
|
||||
,"doc/**.html"
|
||||
,"doc/**.htm"
|
||||
,"doc/**.txt"
|
||||
,"doc/**.gif"
|
||||
,"doc/**.jpg"
|
||||
,"doc/**.jpeg"
|
||||
,"doc/**.png"
|
||||
,"*.html"
|
||||
,"*.htm"
|
||||
,"*.css"
|
||||
,"*.js"
|
||||
,"*.gif"
|
||||
,"*.jpg"
|
||||
,"*.jpeg"
|
||||
,"*.png"
|
||||
]
|
||||
|
||||
filesToRender =
|
||||
["*.md"
|
||||
,"*.mdwn"
|
||||
,"*.markdown"
|
||||
,"doc/**.md"
|
||||
,"doc/**.mdwn"
|
||||
,"doc/**.markdown"
|
||||
]
|
||||
|
||||
-- http://hackage.haskell.org/package/pandoc-1.13/docs/src/Text-Pandoc-Options.html#ReaderOptions
|
||||
pandocReaderOptions = def
|
||||
|
||||
-- http://hackage.haskell.org/package/pandoc-1.13/docs/src/Text-Pandoc-Options.html#WriterOptions
|
||||
pandocWriterOptions = def
|
||||
{writerHighlight=True
|
||||
-- this would change the value of pandoc's $highlight-css$ var
|
||||
-- for now, let the user provide these styles
|
||||
-- ,writerHighlightStyle=tango
|
||||
}
|
||||
|
||||
pandocTransform = tableOfContents "right"
|
||||
|
||||
main = do
|
||||
args <- getArgs
|
||||
when (any (`elem` args) ["--version"]) $ do
|
||||
putStrLn "hakyll standard site builder v0.1"
|
||||
exitSuccess
|
||||
|
||||
hakyll $ do
|
||||
|
||||
match (foldl1 (.||.) filesToCopy) $ route idRoute >> compile copyFileCompiler
|
||||
|
||||
-- there might or might not be a site template in ./ or ./site/
|
||||
mtmpl <- preprocess $ do
|
||||
t1 <- doesFileExist "site.tmpl"
|
||||
t2 <- doesFileExist "site/site.tmpl"
|
||||
return $ case (t1, t2) of (False, True) -> Just "site/site.tmpl"
|
||||
(True, _) -> Just "site.tmpl"
|
||||
(False, False) -> Nothing
|
||||
case mtmpl of
|
||||
Just tmpl -> match tmpl $ compile templateCompiler
|
||||
Nothing -> return ()
|
||||
|
||||
match (foldl1 (.||.) filesToRender) $ do
|
||||
route $ setExtension "html"
|
||||
compile $
|
||||
pandocCompilerWithTransformM pandocReaderOptions pandocWriterOptions (return . pandocTransform)
|
||||
>>= (case mtmpl of
|
||||
Just tmpl -> loadAndApplyTemplate (fromCapture tmpl "") defaultContext
|
||||
Nothing -> return)
|
||||
>>= relativizeUrls
|
||||
|
||||
-- this fails the first time after a clean because it runs before README.html generation
|
||||
-- when ("build" `elem` args) $ preprocess linkReadmeToIndex
|
||||
|
||||
-- can't do anything here, hakyll exits
|
||||
|
||||
linkReadmeToIndex = system "ln -sf README.html _site/index.html" >> return ()
|
6
doc/site/stack.yaml
Normal file
6
doc/site/stack.yaml
Normal file
@ -0,0 +1,6 @@
|
||||
# stack.yaml for hakyll-std
|
||||
extra-deps: []
|
||||
resolver: nightly-2015-07-01
|
||||
flags: {}
|
||||
packages:
|
||||
- '.'
|
Loading…
Reference in New Issue
Block a user