packages feed

lucid-colonnade 1.0.1 → 1.0.2

raw patch · 4 files changed

+291/−124 lines, 4 filesdep +vectordep ~basedep ~colonnadedep ~lucidsetup-changednew-uploaderPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependencies added: vector

Dependency ranges changed: base, colonnade, lucid, text

API changes (from Hackage documentation)

- Lucid.Colonnade: instance Data.Semigroup.Semigroup d => Data.Semigroup.Semigroup (Lucid.Colonnade.Cell d)
- Lucid.Colonnade: instance d ~ () => Data.String.IsString (Lucid.Colonnade.Cell d)
+ Lucid.Colonnade: charCell :: Char -> Cell ()
+ Lucid.Colonnade: encodeBodySized :: (Foldable f, Monoid d) => (a -> [Attribute]) -> [Attribute] -> Colonnade (Sized Int h) a (Cell d) -> f a -> Html ()
+ Lucid.Colonnade: encodeCellTableSized :: (Headedness h, Foldable f, Monoid d) => [Attribute] -> Colonnade (Sized Int h) a (Cell d) -> f a -> Html ()
+ Lucid.Colonnade: instance (d GHC.Types.~ ()) => Data.String.IsString (Lucid.Colonnade.Cell d)
+ Lucid.Colonnade: instance GHC.Base.Semigroup d => GHC.Base.Semigroup (Lucid.Colonnade.Cell d)
+ Lucid.Colonnade: sectioned :: (Foldable f, Headedness h, Foldable g, Monoid c) => [Attribute] -> Maybe ([Attribute], [Attribute]) -> [Attribute] -> (a -> [Attribute]) -> (b -> Cell c) -> Colonnade h a (Cell c) -> f (b, g a) -> Html ()
- Lucid.Colonnade: Cell :: ![Attribute] -> !(Html d) -> Cell d
+ Lucid.Colonnade: Cell :: ![Attribute] -> !Html d -> Cell d
- Lucid.Colonnade: [cellHtml] :: Cell d -> !(Html d)
+ Lucid.Colonnade: [cellHtml] :: Cell d -> !Html d

Files

+ CHANGELOG.md view
@@ -0,0 +1,6 @@+# Revision history for lucid-colonnade++## 1.0.2 -- 2024-03-06++* Update package metadata.+* Export `charCell`.
− Setup.hs
@@ -1,2 +0,0 @@-import Distribution.Simple-main = defaultMain
lucid-colonnade.cabal view
@@ -1,28 +1,36 @@-name: lucid-colonnade-version: 1.0.1-synopsis: Helper functions for using lucid with colonnade-description: Lucid and colonnade-homepage: https://github.com/andrewthad/colonnade#readme-license: BSD3-license-file: LICENSE-author: Andrew Martin-maintainer: andrew.thaddeus@gmail.com-copyright: 2017 Andrew Martin-category: web-build-type: Simple-cabal-version: >=1.10+cabal-version:   3.0+name:            lucid-colonnade+version:         1.0.2+synopsis:        Helper functions for using lucid with colonnade+description:     Helper functions for using lucid with colonnade.+homepage:        https://github.com/byteverse/lucid-colonnade+bug-reports:     https://github.com/byteverse/lucid-colonnade/issues+license:         BSD-3-Clause+license-file:    LICENSE+author:          Andrew Martin+maintainer:      amartin@layer3com.com+copyright:       2017 Andrew Martin+category:        web+build-type:      Simple+extra-doc-files: CHANGELOG.md+tested-with:     GHC ==9.4.8 || ==9.6.3 || ==9.8.1 +common build-settings+  default-language: Haskell2010+  ghc-options:      -Wall -Wunused-packages+  build-depends:    base >=4.8 && <5+ library-  hs-source-dirs: src-  exposed-modules:-    Lucid.Colonnade+  import:          build-settings+  ghc-options:     -O2+  hs-source-dirs:  src+  exposed-modules: Lucid.Colonnade   build-depends:-      base >= 4.9 && < 5-    , colonnade >= 1.1.1 && < 1.3-    , lucid >= 2.9 && < 3.0-    , text >= 1.2 && < 1.3-  default-language: Haskell2010+    , colonnade  >=1.1.1+    , lucid      >=2.9+    , text       >=1.2+    , vector     >=0.10  source-repository head   type:     git-  location: https://github.com/andrewthad/colonnade+  location: git://github.com/byteverse/lucid-colonnade.git
src/Lucid/Colonnade.hs view
@@ -1,60 +1,73 @@ {-# LANGUAGE BangPatterns #-}+{-# LANGUAGE CPP #-}+{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-} --- | Build HTML tables using @lucid@ and @colonnade@. It is---   recommended that users read the documentation for @colonnade@ first,---   since this library builds on the abstractions introduced there.---   Also, look at the docs for @blaze-colonnade@. These two---   libraries are similar, but blaze offers an HTML pretty printer---   which makes it possible to doctest examples. Since lucid---   does not offer such facilities, examples are omitted here.+{- | Build HTML tables using @lucid@ and @colonnade@. It is+  recommended that users read the documentation for @colonnade@ first,+  since this library builds on the abstractions introduced there.+  Also, look at the docs for @blaze-colonnade@. These two+  libraries are similar, but blaze offers an HTML pretty printer+  which makes it possible to doctest examples. Since lucid+  does not offer such facilities, examples are omitted here.+-} module Lucid.Colonnade   ( -- * Apply     encodeHtmlTable   , encodeCellTable+  , encodeCellTableSized   , encodeTable+     -- * Cell     -- $build-  , Cell(..)+  , Cell (..)+  , charCell   , htmlCell   , stringCell   , textCell   , lazyTextCell   , builderCell   , htmlFromCell+  , encodeBodySized+  , sectioned+     -- * Discussion     -- $discussion   ) where -import Colonnade (Colonnade,Headed,Headless,Fascia,Cornice)-import Data.Text (Text)+#if MIN_VERSION_base(4,18,0)+#else+import Control.Applicative (liftA2)+#endif+import Colonnade (Colonnade) import Control.Monad-import Data.Semigroup-import Data.Monoid hiding ((<>)) import Data.Foldable-import Data.String (IsString(..))-import Data.Maybe (listToMaybe)-import Data.Char (isSpace)-import Control.Applicative (liftA2)-import Lucid-import qualified Data.List as List+import Data.String (IsString (..))+import Data.Text (Text)+import Lucid hiding (for_)+ import qualified Colonnade.Encode as E+import qualified Data.Text as T import qualified Data.Text as Text import qualified Data.Text.Lazy as LText import qualified Data.Text.Lazy.Builder as TBuilder+import qualified Data.Vector as V --- $build------ The 'Cell' type is used to build a 'Colonnade' that --- has 'Html' content inside table cells and may optionally--- have attributes added to the @\<td\>@ or @\<th\>@ elements--- that wrap this HTML content.+{- $build --- | The attributes that will be applied to a @\<td\>@ and---   the HTML content that will go inside it. When using---   this type, remember that 'Attribute', defined in @blaze-markup@,---   is actually a collection of attributes, not a single attribute.+The 'Cell' type is used to build a 'Colonnade' that+has 'Html' content inside table cells and may optionally+have attributes added to the @\<td\>@ or @\<th\>@ elements+that wrap this HTML content.+-}++{- | The attributes that will be applied to a @\<td\>@ and+  the HTML content that will go inside it. When using+  this type, remember that 'Attribute', defined in @blaze-markup@,+  is actually a collection of attributes, not a single attribute.+-} data Cell d = Cell   { cellAttribute :: ![Attribute]   , cellHtml :: !(Html d)@@ -63,12 +76,12 @@ instance (d ~ ()) => IsString (Cell d) where   fromString = stringCell -instance Semigroup d => Semigroup (Cell d) where+instance (Semigroup d) => Semigroup (Cell d) where   Cell a1 c1 <> Cell a2 c2 = Cell (mappend a1 a2) (liftA2 (<>) c1 c2) -instance Monoid d => Monoid (Cell d) where+instance (Monoid d) => Monoid (Cell d) where   mempty = Cell mempty (return mempty)-  mappend (Cell a1 c1) (Cell a2 c2) = Cell (mappend a1 a2) (liftA2 mappend c1 c2)+  mappend = (<>)  -- | Create a 'Cell' from a 'Widget' htmlCell :: Html d -> Cell d@@ -94,104 +107,246 @@ builderCell :: TBuilder.Builder -> Cell () builderCell = lazyTextCell . TBuilder.toLazyText --- | Encode a table. Table cell element do not have ---   any attributes applied to them.-encodeHtmlTable :: -     (E.Headedness h, Foldable f, Monoid d)-  => [Attribute] -- ^ Attributes of @\<table\>@ element-  -> Colonnade h a (Html d) -- ^ How to encode data as columns-  -> f a -- ^ Collection of data-  -> Html d-encodeHtmlTable = encodeTable-  (E.headednessPure ([],[])) mempty (const mempty) (\el -> el [])+{- | Encode a table. Table cell element do not have+  any attributes applied to them.+-}+encodeHtmlTable ::+  (E.Headedness h, Foldable f, Monoid d) =>+  -- | Attributes of @\<table\>@ element+  [Attribute] ->+  -- | How to encode data as columns+  Colonnade h a (Html d) ->+  -- | Collection of data+  f a ->+  Html d+encodeHtmlTable =+  encodeTable+    (E.headednessPure ([], []))+    mempty+    (const mempty)+    (\el -> el []) --- | Encode a table. Table cells may have attributes applied---   to them-encodeCellTable :: -     (E.Headedness h, Foldable f, Monoid d)-  => [Attribute] -- ^ Attributes of @\<table\>@ element-  -> Colonnade h a (Cell d) -- ^ How to encode data as columns-  -> f a -- ^ Collection of data-  -> Html d-encodeCellTable = encodeTable-  (E.headednessPure ([],[])) mempty (const mempty) htmlFromCell+{- | Encode a table. Table cells may have attributes applied+  to them+-}+encodeCellTable ::+  (E.Headedness h, Foldable f, Monoid d) =>+  -- | Attributes of @\<table\>@ element+  [Attribute] ->+  -- | How to encode data as columns+  Colonnade h a (Cell d) ->+  -- | Collection of data+  f a ->+  Html d+encodeCellTable =+  encodeTable+    (E.headednessPure ([], []))+    mempty+    (const mempty)+    htmlFromCell --- | Encode a table. This handles a very general case and---   is seldom needed by users. One of the arguments provided is---   used to add attributes to the generated @\<tr\>@ elements.---   The elements of type @d@ produced by generating html are---   strictly combined with their monoidal append function.---   However, this type is nearly always @()@.-encodeTable :: forall f h a d c.-     (Foldable f, E.Headedness h, Monoid d)-  => h ([Attribute],[Attribute]) -- ^ Attributes of @\<thead\>@ and its @\<tr\>@-  -> [Attribute] -- ^ Attributes of @\<tbody\>@ element-  -> (a -> [Attribute]) -- ^ Attributes of each @\<tr\>@ element-  -> (([Attribute] -> Html d -> Html d) -> c -> Html d) -- ^ Wrap content and convert to 'Html'-  -> [Attribute] -- ^ Attributes of @\<table\>@ element-  -> Colonnade h a c -- ^ How to encode data as a row-  -> f a -- ^ Collection of data-  -> Html d+encodeCellTableSized ::+  (E.Headedness h, Foldable f, Monoid d) =>+  -- | Attributes of @\<table\>@ element+  [Attribute] ->+  -- | How to encode data as columns+  Colonnade (E.Sized Int h) a (Cell d) ->+  -- | Collection of data+  f a ->+  Html ()+encodeCellTableSized =+  encodeTableSized+    (E.headednessPure ([], []))+    mempty+    (const mempty)+    htmlFromCell++{- | Encode a table. This handles a very general case and+  is seldom needed by users. One of the arguments provided is+  used to add attributes to the generated @\<tr\>@ elements.+  The elements of type @d@ produced by generating html are+  strictly combined with their monoidal append function.+  However, this type is nearly always @()@.+-}+encodeTable ::+  forall f h a d c.+  (Foldable f, E.Headedness h, Monoid d) =>+  -- | Attributes of @\<thead\>@ and its @\<tr\>@+  h ([Attribute], [Attribute]) ->+  -- | Attributes of @\<tbody\>@ element+  [Attribute] ->+  -- | Attributes of each @\<tr\>@ element+  (a -> [Attribute]) ->+  -- | Wrap content and convert to 'Html'+  (([Attribute] -> Html d -> Html d) -> c -> Html d) ->+  -- | Attributes of @\<table\>@ element+  [Attribute] ->+  -- | How to encode data as a row+  Colonnade h a c ->+  -- | Collection of data+  f a ->+  Html d encodeTable mtheadAttrs tbodyAttrs trAttrs wrapContent tableAttrs colonnade xs =   table_ tableAttrs $ do     d1 <- case E.headednessExtractForall of       Nothing -> return mempty       Just extractForall -> do-        let (theadAttrs,theadTrAttrs) = extract mtheadAttrs+        let (theadAttrs, theadTrAttrs) = extract mtheadAttrs         thead_ theadAttrs $ tr_ theadTrAttrs $ do           foldlMapM' (wrapContent th_ . extract . E.oneColonnadeHead) (E.getColonnade colonnade)-        where+       where         extract :: forall y. h y -> y         extract = E.runExtractForall extractForall     d2 <- encodeBody trAttrs wrapContent tbodyAttrs colonnade xs     return (mappend d1 d2) -encodeBody :: (Foldable f, Monoid d)-  => (a -> [Attribute]) -- ^ Attributes of each @\<tr\>@ element-  -> (([Attribute] -> Html d -> Html d) -> c -> Html d) -- ^ Wrap content and convert to 'Html'-  -> [Attribute] -- ^ Attributes of @\<tbody\>@ element-  -> Colonnade h a c -- ^ How to encode data as a row-  -> f a -- ^ Collection of data-  -> Html d+encodeBody ::+  (Foldable f, Monoid d) =>+  -- | Attributes of each @\<tr\>@ element+  (a -> [Attribute]) ->+  -- | Wrap content and convert to 'Html'+  (([Attribute] -> Html d -> Html d) -> c -> Html d) ->+  -- | Attributes of @\<tbody\>@ element+  [Attribute] ->+  -- | How to encode data as a row+  Colonnade h a c ->+  -- | Collection of data+  f a ->+  Html d encodeBody trAttrs wrapContent tbodyAttrs colonnade xs = do   tbody_ tbodyAttrs $ do     flip foldlMapM' xs $ \x -> do       tr_ (trAttrs x) $ E.rowMonadic colonnade (wrapContent td_) x +encodeBodySized ::+  (Foldable f, Monoid d) =>+  (a -> [Attribute]) ->+  [Attribute] ->+  Colonnade (E.Sized Int h) a (Cell d) ->+  f a ->+  Html ()+encodeBodySized trAttrs tbodyAttrs colonnade collection = tbody_ tbodyAttrs $ do+  for_ collection $ \a -> tr_ (trAttrs a) $ do+    E.rowMonoidalHeader+      colonnade+      ( \(E.Sized sz _) (Cell cattr content) ->+          void $ td_ (setColspanOrHide sz cattr) content+      )+      a++encodeTableSized ::+  forall f h a d.+  (Foldable f, E.Headedness h, Monoid d) =>+  -- | Attributes of @\<thead\>@ and its @\<tr\>@+  h ([Attribute], [Attribute]) ->+  -- | Attributes of @\<tbody\>@ element+  [Attribute] ->+  -- | Attributes of each @\<tr\>@ element+  (a -> [Attribute]) ->+  -- | Wrap content and convert to 'Html'+  (([Attribute] -> Html d -> Html d) -> (Cell d) -> Html d) ->+  -- | Attributes of @\<table\>@ element+  [Attribute] ->+  -- | How to encode data as a row+  Colonnade (E.Sized Int h) a (Cell d) ->+  -- | Collection of data+  f a ->+  Html ()+encodeTableSized mtheadAttrs tbodyAttrs trAttrs wrapContent tableAttrs colonnade xs =+  table_ tableAttrs $ do+    _ <- case E.headednessExtractForall of+      Nothing -> pure mempty+      Just extractForall -> do+        let (theadAttrs, theadTrAttrs) = extract mtheadAttrs+        thead_ theadAttrs $ tr_ theadTrAttrs $ do+          traverse_+            ( wrapContent th_+                . extract+                . ( \(E.Sized i h) -> case E.headednessExtract of+                      Just f ->+                        let (Cell attrs content) = f h+                         in E.headednessPure $ Cell (setColspanOrHide i attrs) content+                      Nothing -> E.headednessPure mempty+                      -- (E.Headed (Cell attrs content)) -> E.Headed $ Cell (setColspanOrHide i attrs) content+                      -- E.Headless -> E.Headless+                  )+                . E.oneColonnadeHead+            )+            (E.getColonnade colonnade)+       where+        extract :: forall y. h y -> y+        extract = E.runExtractForall extractForall+    encodeBodySized trAttrs tbodyAttrs colonnade xs++setColspanOrHide :: Int -> [Attribute] -> [Attribute]+setColspanOrHide i attrs+  | i < 1 = style_ "display:none;" : attrs+  | otherwise = colspan_ (Text.pack (show i)) : attrs+ foldlMapM' :: forall g b a m. (Foldable g, Monoid b, Monad m) => (a -> m b) -> g a -> m b foldlMapM' f xs = foldr f' pure xs mempty-  where+ where   f' :: a -> (b -> m b) -> b -> m b   f' x k bl = do     br <- f x     let !b = mappend bl br     k b --- | Convert a 'Cell' to 'Html' by wrapping the content with a tag--- and applying the 'Cell' attributes to that tag.+{- | Convert a 'Cell' to 'Html' by wrapping the content with a tag+and applying the 'Cell' attributes to that tag.+-} htmlFromCell :: ([Attribute] -> Html d -> Html d) -> Cell d -> Html d htmlFromCell f (Cell attr content) = f attr content --- $discussion------ In this module, some of the functions for applying a 'Colonnade' to--- some values to build a table have roughly this type signature:------ > Foldable a => Colonnade Headedness a (Cell d) -> f a -> Html d------ The 'Colonnade' content type is 'Cell', but the content--- type of the result is 'Html'. It may not be immidiately clear why--- this is done. Another strategy, which this library also--- uses, is to write--- these functions to take a 'Colonnade' whose content is 'Html':------ > Foldable a => Colonnade Headedness a (Html d) -> f a -> Html d------ When the 'Colonnade' content type is 'Html', then the header--- content is rendered as the child of a @\<th\>@ and the row--- content the child of a @\<td\>@. However, it is not possible--- to add attributes to these parent elements. To accomodate this--- situation, it is necessary to introduce 'Cell', which includes--- the possibility of attributes on the parent node.+{- $discussion +In this module, some of the functions for applying a 'Colonnade' to+some values to build a table have roughly this type signature: +> Foldable a => Colonnade Headedness a (Cell d) -> f a -> Html d++The 'Colonnade' content type is 'Cell', but the content+type of the result is 'Html'. It may not be immidiately clear why+this is done. Another strategy, which this library also+uses, is to write+these functions to take a 'Colonnade' whose content is 'Html':++> Foldable a => Colonnade Headedness a (Html d) -> f a -> Html d++When the 'Colonnade' content type is 'Html', then the header+content is rendered as the child of a @\<th\>@ and the row+content the child of a @\<td\>@. However, it is not possible+to add attributes to these parent elements. To accomodate this+situation, it is necessary to introduce 'Cell', which includes+the possibility of attributes on the parent node.+-}++sectioned ::+  (Foldable f, E.Headedness h, Foldable g, Monoid c) =>+  -- | @\<table\>@ tag attributes+  [Attribute] ->+  -- | Attributes of @\<thead\>@ and its @\<tr\>@, pass 'Nothing' to omit @\<thead\>@+  Maybe ([Attribute], [Attribute]) ->+  -- | @\<tbody\>@ tag attributes+  [Attribute] ->+  -- | @\<tr\>@ tag attributes for data rows+  (a -> [Attribute]) ->+  -- | Section divider encoding strategy+  (b -> Cell c) ->+  -- | Data encoding strategy+  Colonnade h a (Cell c) ->+  -- | Collection of data+  f (b, g a) ->+  Html ()+sectioned tableAttrs mheadAttrs bodyAttrs trAttrs dividerContent colonnade@(E.Colonnade v) collection = do+  let vlen = V.length v+  table_ tableAttrs $ do+    for_ mheadAttrs $ \(headAttrs, headTrAttrs) ->+      thead_ headAttrs . tr_ headTrAttrs $+        E.headerMonadicGeneral_ colonnade (htmlFromCell th_)+    tbody_ bodyAttrs $ for_ collection $ \(b, as) -> do+      let Cell attrs contents = dividerContent b+      _ <- tr_ [] $ do+        td_ ((colspan_ $ T.pack (show vlen)) : attrs) contents+      flip traverse_ as $ \a -> do+        tr_ (trAttrs a) $ E.rowMonadic colonnade (htmlFromCell td_) a