1 {-# LANGUAGE OverloadedLists #-}
2 {-# OPTIONS_GHC -Wno-orphans #-}
4 module Worksheets.Utils.HTML (
5 module Worksheets.Utils.HTML,
6 module Text.Blaze.Html5,
7 module Text.Blaze.Renderer.Utf8,
10 import Data.Char qualified as Char
11 import Data.List qualified as List
12 import Data.Map.Strict qualified as Map
13 import Data.Text qualified as Text
14 import Data.Text.Short qualified as ShortText
16 import Text.Blaze.Html5
17 import Text.Blaze.Html5.Attributes qualified as HA
18 import Text.Blaze.Renderer.Utf8
19 import Worksheets.Utils.Paper
20 import Worksheets.Utils.Prelude
22 classes :: [String] -> Attribute
23 classes cls = HA.class_ $ cls & List.filter (not . null) <&> toValue & List.intersperse " " & mconcat
25 className :: Show a => a -> String
27 x & show & List.map \c ->
32 type CSSBlock = Map String String
34 styles :: CSSBlock -> Attribute
37 [ toValue k <> ":" <> toValue v <> ";"
38 | (k, v) <- kvs & Map.toList
43 type CSS = Map [String] CSSBlock
44 styleCSS :: CSS -> Markup
48 $ [ mconcat [n <> " {" | n <- ns]
51 [ k <> ":" <> v <> ";"
52 | (k, v) <- kvs & Map.toList
55 <> mconcat [" }" | _n <- ns]
57 | (ns, kvs) <- m & Map.toList
66 instance ToMarkup ShortText where
67 toMarkup = ShortText.toText >>> toMarkup
68 preEscapedToMarkup = ShortText.toText >>> preEscapedToMarkup
71 = LengthFractionalRatio Natural
72 | LengthMillimeters Double
74 instance ToCSS String where
76 instance ToCSS Text where
78 instance ToCSS Double where
79 toCSS = show >>> toCSS
80 instance ToCSS a => ToCSS (Maybe a) where
81 toCSS = maybe "" toCSS
82 instance ToCSS Length where
84 LengthFractionalRatio x -> show x <> "fr"
85 LengthMillimeters x -> show x <> "mm"
86 cm :: Double -> Length
87 cm = LengthMillimeters . (* 10)
88 mm :: Double -> Length
89 mm = LengthMillimeters
90 fr :: Natural -> Length
91 fr = LengthFractionalRatio
94 PageOrientationLandscape -> 29.7 & cm
95 PageOrientationPortrait -> 21.0 & cm
97 PageOrientationLandscape -> 21.0 & cm
98 PageOrientationPortrait -> 29.7 & cm
102 PageSizeA4Plus -> "A4plus"
104 cssPageOrientation = \case
105 PageOrientationPortrait -> "portrait"
106 PageOrientationLandscape -> "landscape"
108 cssPrintPage :: PageOrientation -> PageSize -> CSS
109 cssPrintPage pageOrient pageSize =
114 [ cssPageSize pageSize
115 , cssPageOrientation pageOrient
122 cssBlockObjectFitCover :: CSSBlock
123 cssBlockObjectFitCover = ["object-fit" := "cover"]