hakyll-favicon (empty) → 0.1.0
raw patch · 7 files changed
+282/−0 lines, 7 filesdep +basedep +filepathdep +hakyllsetup-changed
Dependencies added: base, filepath, hakyll, hakyll-favicon
Files
- LICENSE +30/−0
- README.md +70/−0
- Setup.hs +2/−0
- example/site.hs +23/−0
- hakyll-favicon.cabal +44/−0
- src/Hakyll/Favicon.hs +111/−0
- test/Spec.hs +2/−0
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright Elie Genard (c) 2017++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 Elie Genard 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.
+ README.md view
@@ -0,0 +1,70 @@+# hakyll-favicon [](https://travis-ci.org/elaye/hakyll-favicon)++This library allows you to easily add favicons to your hakyll website.+You provide one SVG image and the library will convert it to different resolutions and generate the corresponding html.++## Dependencies++This library depends on `ImageMagick` to convert the images.++## Usage++First, add a `faviconsRules` that points to your main favicon in your `Site.hs` file like this:++```+main = hakyll $ do+ faviconsRules "images/favicon.svg" -- path to your favicon+ ...+```++Second, add a `favicons` field in your template `head`:++```+<head>+ ...+ $favicons$+</head>+```++Finally add the favicons context to your template context:++```+main = hakyll $ do+ ...+ match "index.html" $ do+ ...+ let ctx = ... `mappend`+ ... `mappend`+ faviconsField `mappend` -- add this+ defaultContext+ ...+```++The [example](example/) directory provides a minimal working example of this.++## Example++First, build the example:++ stack build++Then build the example page:++ stack exec example build+ +Or you can start a local server to serve the generated page:++ stack exec example watch++## Generated favicons++The following favicons are generated:++target | format | sizes | description+-------------|--------|--------|------------+all | .ico | 32, 64 | basic favicon+all | .png | 32 | basic favicon+iOS | .png | 144 | third-generation iPad with high-resolution Retina display+iOS | .png | 114 | iPhone with high-resolution Retina display+iOS | .png | 72 | first- and second-generation iPad+iOS, Android | .png | 57 | non-Retina iPhone, iPod Touch, and Android 2.1+ devices
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ example/site.hs view
@@ -0,0 +1,23 @@+{-# LANGUAGE OverloadedStrings #-}+import Hakyll+import Hakyll.Favicon (faviconsRules, faviconsField)++main :: IO ()+main = do++ let config = defaultConfiguration+ { destinationDirectory = "example/site"+ , providerDirectory = "example"+ , storeDirectory = "example/_cache"+ , inMemoryCache = True+ }++ hakyllWith config $ do+ faviconsRules "images/favicon.svg"++ match "index.html" $ do+ route idRoute+ compile $ do+ let ctx = faviconsField `mappend` defaultContext+ getResourceBody >>= applyAsTemplate ctx+
+ hakyll-favicon.cabal view
@@ -0,0 +1,44 @@+name: hakyll-favicon+version: 0.1.0+-- synopsis:+description: Generate favicons for Hakyll websites+homepage: https://github.com/elaye/hakyll-favicon#README.md+license: BSD3+license-file: LICENSE+author: Elie Genard+maintainer: elaye.github.io@gmail.com+copyright: 2017 Elie Genard+category: Web+build-type: Simple+extra-source-files: README.md+cabal-version: >=1.10++library+ hs-source-dirs: src+ exposed-modules: Hakyll.Favicon+ build-depends: base >= 4.7 && < 5+ , hakyll+ , filepath+ default-language: Haskell2010++executable example+ hs-source-dirs: example+ main-is: site.hs+ ghc-options: -threaded -rtsopts -with-rtsopts=-N+ build-depends: base+ , hakyll-favicon+ , hakyll+ default-language: Haskell2010++test-suite hakyll-favicon-test+ type: exitcode-stdio-1.0+ hs-source-dirs: test+ main-is: Spec.hs+ build-depends: base+ , hakyll-favicon+ ghc-options: -threaded -rtsopts -with-rtsopts=-N+ default-language: Haskell2010++source-repository head+ type: git+ location: https://github.com/elaye/hakyll-favicon
+ src/Hakyll/Favicon.hs view
@@ -0,0 +1,111 @@+module Hakyll.Favicon+( faviconsField+, faviconsRules+) where++import Data.Monoid ((<>))+import Data.List (intersperse)++import Hakyll+import System.FilePath (takeExtension, (</>))++import Debug.Trace (traceShow)++newtype IconSize = IconSize Int++instance Show IconSize where+ show (IconSize s) = show s++data IconType = Basic IconSize | Ico [IconSize] | IOS IconSize++data Favicon = Favicon IconType++favicons :: [Favicon]+favicons =+ [ Favicon (Ico [IconSize 32, IconSize 64])+ -- basic favicon+ , Favicon (Basic (IconSize 32))+ -- third-generation iPad with high-resolution Retina display+ , Favicon (IOS (IconSize 144))+ -- iPhone with high-resolution Retina display+ , Favicon (IOS (IconSize 114))+ -- first- and second-generation iPad+ , Favicon (IOS (IconSize 72))+ -- non-Retina iPhone, iPod Touch, and Android 2.1+ devices+ , Favicon (IOS (IconSize 57))+ ]++iosTemplate :: Compiler (Item String)+iosTemplate = makeItem "<link rel=\"apple-touch-icon-precomposed\" sizes=\"$size$x$size$\" href=\"$src$\">"++icoTemplate :: Compiler (Item String)+icoTemplate = makeItem "<link rel=\"shortcut icon\" href=\"favicon.ico\" type=\"image/x-icon\">"++basicTemplate :: Compiler (Item String)+basicTemplate = makeItem "<link rel=\"shortcut icon\" href=\"$src$\">"++faviconsField :: Context String+faviconsField = field "favicons" $ \_ -> do+ itemBody <$> faviconsCompiler favicons++faviconsCompiler :: [Favicon] -> Compiler (Item String)+faviconsCompiler favicons = do+ htmls <- mapM faviconCompiler favicons :: (Compiler [Item String])+ makeItem $ concatMap itemBody htmls++faviconCompiler :: Favicon -> Compiler (Item String)+faviconCompiler favicon@(Favicon faviconType) = case faviconType of+ Ico _ -> icoTemplate >>= applyAsTemplate ctx+ IOS size -> iosTemplate >>= applyAsTemplate (ctx <> constField "size" (show size))+ Basic _ -> basicTemplate >>= applyAsTemplate ctx+ where ctx = constField "src" (toUrl (faviconPath favicon))++faviconName :: Favicon -> String+faviconName (Favicon (Ico _)) = "favicon.ico"+faviconName (Favicon (IOS size)) = "favicon" ++ show size ++ ".png"+faviconName (Favicon (Basic size)) = "favicon" ++ show size ++ ".png"++faviconPath :: Favicon -> FilePath+faviconPath favicon@(Favicon (Ico _)) = faviconName favicon+faviconPath favicon = "images" </> "favicons" </> faviconName favicon+faviconPath favicon = "images" </> "favicons" </> faviconName favicon++faviconsRules :: Pattern -> Rules ()+faviconsRules ptn = match ptn $ mapM_ processFavicon favicons++processFavicon :: Favicon -> Rules ()+processFavicon favicon@(Favicon (Ico sizes)) = processIco favicon sizes+processFavicon favicon@(Favicon (IOS size)) = processPng favicon size+processFavicon favicon@(Favicon (Basic size)) = processPng favicon size++processIco :: Favicon -> [IconSize] -> Rules ()+processIco favicon sizes = version ("ico-" ++ concat (intersperse "-" (show <$> sizes))) $ do+ route $ customRoute $ \_ -> faviconPath favicon+ let+ cmd = "convert"+ args =+ [ "-background"+ , "none"+ , "svg:-"+ , "-define"+ , concat ["icon:auto-resize=", concat (intersperse "," (show <$> sizes))]+ , "+repage"+ , "ico:-"+ ]+ compile $ getResourceLBS >>= withItemBody (unixFilterLBS cmd args)++processPng :: Favicon -> IconSize -> Rules ()+processPng favicon (IconSize size) = version ("png" ++ show size) $ do+ route $ customRoute $ \_ -> faviconPath favicon+ let+ cmd = "convert"+ args =+ [ "-background"+ , "none"+ , "svg:-"+ , "-resize"+ , concat [show size, "x", show size, "!"]+ , "+repage"+ , "png:-"+ ]+ compile $ getResourceLBS >>= withItemBody (unixFilterLBS cmd args)
+ test/Spec.hs view
@@ -0,0 +1,2 @@+main :: IO ()+main = putStrLn "Test suite not yet implemented"