Shpadoinkle-backend-static (empty) → 0.0.0.1
raw patch · 5 files changed
+141/−0 lines, 5 filesdep +Shpadoinkledep +basedep +compactable
Dependencies added: Shpadoinkle, base, compactable, text
Files
- CHANGELOG.md +0/−0
- LICENSE +26/−0
- README.md +25/−0
- Shpadoinkle-backend-static.cabal +36/−0
- Shpadoinkle/Backend/Static.hs +54/−0
+ CHANGELOG.md view
+ LICENSE view
@@ -0,0 +1,26 @@+Shpadoinkle Static, I think I know exactly what it means+Copyright © 2019 Isaac Shpaira+All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:+1. Redistributions of source code must retain the above copyright+notice, this list of conditions and the following disclaimer.+2. 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.+3. Neither the name of the <`3:organization`> nor the+names of its contributors may be used to endorse or promote products+derived from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY <|2|> ''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 <|2|> 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,25 @@+# Shpadoinkle Backend Static+++[](https://gitlab.com/fresheyeball/Shpadoinkle-backend-static)+[](https://hackage.haskell.org/package/Shpadoinkle-backend-static)+[](http://packdeps.haskellers.com/reverse/Shpadoinkle-backend-static)+[](https://matrix.hackage.haskell.org/#/package/Shpadoinkle-backend-static)++This module provides a static rendering backend that translates Shpadoinkle `Html` into `Text`.++For example++```haskell+page :: Html' a+page = h "div" [ ("class", PText "header" ) ]+ [ h "h1" [] [ text "Trappers!" ] ]++main = putStrLn $ unpack $ renderStatic page+```++will output++```html+<div class="header"><h1>Trappers!</h1></div>+```
+ Shpadoinkle-backend-static.cabal view
@@ -0,0 +1,36 @@+cabal-version: 1.12++-- This file has been generated from package.yaml by hpack version 0.32.0.+--+-- see: https://github.com/sol/hpack+--+-- hash: 5590704ab7a49919350e8e04d7f232fe9b8684d70c22468511488f4a2906c8c3++name: Shpadoinkle-backend-static+version: 0.0.0.1+synopsis: A backend for rendering Shpadoinkle as Text.+description: Shpadoinkle's static backend, renders Html as Text. Event listeners are ignored. This is useful when rendering on the server, or for static site generation.+category: Web+author: Isaac Shapira+maintainer: fresheyeball@protonmail.com+license: BSD3+license-file: LICENSE+build-type: Simple+extra-source-files:+ README.md+ CHANGELOG.md++library+ exposed-modules:+ Shpadoinkle.Backend.Static+ other-modules:+ Paths_Shpadoinkle_backend_static+ hs-source-dirs:+ ./.+ ghc-options: -Wall -Wcompat -fwarn-redundant-constraints -fwarn-incomplete-uni-patterns -fwarn-tabs -fwarn-incomplete-record-updates -fwarn-identities+ build-depends:+ Shpadoinkle <0.1+ , base >=4.12.0 && <4.13+ , compactable >=0.1.2 && <0.2+ , text >=1.2.3 && <1.3+ default-language: Haskell2010
+ Shpadoinkle/Backend/Static.hs view
@@ -0,0 +1,54 @@+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE OverloadedStrings #-}+++module Shpadoinkle.Backend.Static ( renderStatic ) where+++import Control.Compactable+import Data.Monoid ((<>))+import Data.Text++import Shpadoinkle hiding (name, props, text)+++renderStatic :: Html m a -> Text+renderStatic = \case+ Node tag props _ | isSelfClosing tag+ -> renderSelfClosing tag props+ Node tag props cs -> renderWrapping tag props cs+ Potato _ -> mempty+ TextNode t -> t+++isSelfClosing :: Text -> Bool+isSelfClosing = flip elem+ [ "area", "base", "br", "embed", "hr", "iframe"+ , "img", "input", "link", "meta", "param", "source", "track" ]+++renderWrapping :: Text -> [(Text, Prop m a)] -> [Html m a] -> Text+renderWrapping tag props cs = renderOpening tag props <> ">"+ <> mconcat (renderStatic <$> cs) <> "</" <> tag <> ">"+++renderSelfClosing :: Text -> [(Text, Prop m a)] -> Text+renderSelfClosing tag props = renderOpening tag props <> " />"+++renderOpening :: Text -> [(Text, Prop m a)] -> Text+renderOpening tag props = let ps = renderProps props in+ "<" <> tag <> (if Data.Text.null ps then mempty else " " <> ps)+++renderProps :: [(Text, Prop m a)] -> Text+renderProps = Data.Text.unwords . fmapMaybe (uncurry renderProp)+++renderProp :: Text -> Prop m a -> Maybe Text+renderProp name = \case+ PListener _ -> Nothing+ PText t -> Just $ name <> "=\"" <> t <> "\""+ PFlag True -> Just name+ PFlag False -> Nothing+