{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE Strict #-}
module Granite.Render.Svg (
renderScene,
renderSceneResponsive,
attr,
svgDoc,
svgDocWith,
svgRect,
svgCircle,
svgLine,
svgPolyline,
svgPath,
svgText,
) where
import Data.Text (Text)
import Data.Text qualified as T
import Granite.Color (colorHex)
import Granite.Internal.Util (escXml, showD)
import Granite.Render.Scene (
Mark (..),
Point (..),
Rect (..),
Scene (..),
Style (..),
TextAnchor (..),
TextStyle (..),
)
attr :: Text -> Text -> Text
attr :: Text -> Text -> Text
attr Text
k Text
v = Text
" " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
k Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"=\"" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
v Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"\""
svgDoc :: Double -> Double -> Text -> Text
svgDoc :: Double -> Double -> Text -> Text
svgDoc = Bool -> Double -> Double -> Text -> Text
svgDocWith Bool
False
svgDocWith :: Bool -> Double -> Double -> Text -> Text
svgDocWith :: Bool -> Double -> Double -> Text -> Text
svgDocWith Bool
responsive Double
w Double
h Text
content =
Text
"<svg xmlns=\"http://www.w3.org/2000/svg\""
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text -> Text
attr Text
"viewBox" (Text
"0 0 " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Double -> Text
showD Double
w Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Double -> Text
showD Double
h)
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
sizing
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text -> Text
attr Text
"font-family" Text
"system-ui, -apple-system, sans-serif"
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
">\n"
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"<rect width=\"100%\" height=\"100%\" fill=\"white\"/>\n"
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
content
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"</svg>\n"
where
sizing :: Text
sizing
| Bool
responsive =
Text -> Text -> Text
attr Text
"preserveAspectRatio" Text
"xMidYMid meet"
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text -> Text
attr Text
"width" Text
"100%"
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text -> Text
attr Text
"style" Text
"height:auto"
| Bool
otherwise =
Text -> Text -> Text
attr Text
"width" (Double -> Text
showD Double
w) Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text -> Text
attr Text
"height" (Double -> Text
showD Double
h)
svgRect :: Double -> Double -> Double -> Double -> Text -> Text -> Text
svgRect :: Double -> Double -> Double -> Double -> Text -> Text -> Text
svgRect Double
x Double
y Double
w Double
h Text
fill Text
extra =
Text
"<rect"
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text -> Text
attr Text
"x" (Double -> Text
showD Double
x)
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text -> Text
attr Text
"y" (Double -> Text
showD Double
y)
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text -> Text
attr Text
"width" (Double -> Text
showD Double
w)
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text -> Text
attr Text
"height" (Double -> Text
showD Double
h)
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text -> Text
attr Text
"fill" Text
fill
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
extra
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"/>\n"
svgCircle :: Double -> Double -> Double -> Text -> Text
svgCircle :: Double -> Double -> Double -> Text -> Text
svgCircle Double
cx Double
cy Double
r Text
fill =
Text
"<circle"
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text -> Text
attr Text
"cx" (Double -> Text
showD Double
cx)
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text -> Text
attr Text
"cy" (Double -> Text
showD Double
cy)
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text -> Text
attr Text
"r" (Double -> Text
showD Double
r)
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text -> Text
attr Text
"fill" Text
fill
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"/>\n"
svgLine :: Double -> Double -> Double -> Double -> Text -> Double -> Text
svgLine :: Double -> Double -> Double -> Double -> Text -> Double -> Text
svgLine Double
x1 Double
y1 Double
x2 Double
y2 Text
stroke Double
strokeW =
Text
"<line"
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text -> Text
attr Text
"x1" (Double -> Text
showD Double
x1)
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text -> Text
attr Text
"y1" (Double -> Text
showD Double
y1)
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text -> Text
attr Text
"x2" (Double -> Text
showD Double
x2)
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text -> Text
attr Text
"y2" (Double -> Text
showD Double
y2)
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text -> Text
attr Text
"stroke" Text
stroke
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text -> Text
attr Text
"stroke-width" (Double -> Text
showD Double
strokeW)
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"/>\n"
svgPolyline :: [(Double, Double)] -> Text -> Double -> Text
svgPolyline :: [(Double, Double)] -> Text -> Double -> Text
svgPolyline [(Double, Double)]
pts Text
stroke Double
strokeW =
Text
"<polyline"
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text -> Text
attr Text
"points" (Text -> [Text] -> Text
T.intercalate Text
" " [Double -> Text
showD Double
x Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"," Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Double -> Text
showD Double
y | (Double
x, Double
y) <- [(Double, Double)]
pts])
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text -> Text
attr Text
"fill" Text
"none"
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text -> Text
attr Text
"stroke" Text
stroke
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text -> Text
attr Text
"stroke-width" (Double -> Text
showD Double
strokeW)
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text -> Text
attr Text
"stroke-linejoin" Text
"round"
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text -> Text
attr Text
"stroke-linecap" Text
"round"
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"/>\n"
svgText :: Double -> Double -> Text -> Text -> Double -> Text -> Text
svgText :: Double -> Double -> Text -> Text -> Double -> Text -> Text
svgText Double
x Double
y Text
anchor Text
fill Double
size = Double
-> Double
-> Text
-> Text
-> Double
-> Double
-> Maybe Text
-> Text
-> Text
svgTextRT Double
x Double
y Text
anchor Text
fill Double
size Double
0 Maybe Text
forall a. Maybe a
Nothing
svgTextRT ::
Double ->
Double ->
Text ->
Text ->
Double ->
Double ->
Maybe Text ->
Text ->
Text
svgTextRT :: Double
-> Double
-> Text
-> Text
-> Double
-> Double
-> Maybe Text
-> Text
-> Text
svgTextRT Double
x Double
y Text
anchor Text
fill Double
size Double
rot Maybe Text
mTitle Text
content =
Text
"<text"
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text -> Text
attr Text
"x" (Double -> Text
showD Double
x)
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text -> Text
attr Text
"y" (Double -> Text
showD Double
y)
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text -> Text
attr Text
"text-anchor" Text
anchor
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text -> Text
attr Text
"fill" Text
fill
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text -> Text
attr Text
"font-size" (Double -> Text
showD Double
size)
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
rotAttr
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
">"
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
titleEl
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
escXml Text
content
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"</text>\n"
where
rotAttr :: Text
rotAttr
| Double
rot Double -> Double -> Bool
forall a. Eq a => a -> a -> Bool
== Double
0 = Text
""
| Bool
otherwise =
Text -> Text -> Text
attr
Text
"transform"
(Text
"rotate(" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Double -> Text
showD Double
rot Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Double -> Text
showD Double
x Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Double -> Text
showD Double
y Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
")")
titleEl :: Text
titleEl = case Maybe Text
mTitle of
Maybe Text
Nothing -> Text
""
Just Text
t -> Text
"<title>" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
escXml Text
t Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"</title>"
svgPath :: Text -> Text -> Text -> Text
svgPath :: Text -> Text -> Text -> Text
svgPath Text
d Text
fill Text
extra =
Text
"<path"
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text -> Text
attr Text
"d" Text
d
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text -> Text
attr Text
"fill" Text
fill
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
extra
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"/>\n"
renderScene :: Scene -> Text
renderScene :: Scene -> Text
renderScene Scene
scene =
Double -> Double -> Text -> Text
svgDoc (Scene -> Double
sceneWidth Scene
scene) (Scene -> Double
sceneHeight Scene
scene) (Text -> Text) -> Text -> Text
forall a b. (a -> b) -> a -> b
$
[Text] -> Text
T.concat ((Mark -> Text) -> [Mark] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map Mark -> Text
renderMark (Scene -> [Mark]
sceneMarks Scene
scene))
renderSceneResponsive :: Scene -> Text
renderSceneResponsive :: Scene -> Text
renderSceneResponsive Scene
scene =
Bool -> Double -> Double -> Text -> Text
svgDocWith Bool
True (Scene -> Double
sceneWidth Scene
scene) (Scene -> Double
sceneHeight Scene
scene) (Text -> Text) -> Text -> Text
forall a b. (a -> b) -> a -> b
$
[Text] -> Text
T.concat ((Mark -> Text) -> [Mark] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map Mark -> Text
renderMark (Scene -> [Mark]
sceneMarks Scene
scene))
renderMark :: Mark -> Text
renderMark :: Mark -> Text
renderMark Mark
m = case Mark
m of
MRect (Rect Double
x Double
y Double
w Double
h) Style
sty ->
let fill :: Text
fill = Text -> (Color -> Text) -> Maybe Color -> Text
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Text
"none" Color -> Text
colorHex (Style -> Maybe Color
styleFill Style
sty)
extras :: Text
extras =
Style -> Text
strokeAttrs Style
sty
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Style -> Text
opacityAttr Style
sty
in Double -> Double -> Double -> Double -> Text -> Text -> Text
svgRect Double
x Double
y Double
w Double
h Text
fill Text
extras
MCircle (Point Double
x Double
y) Double
r Style
sty ->
let fill :: Text
fill = Text -> (Color -> Text) -> Maybe Color -> Text
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Text
"none" Color -> Text
colorHex (Style -> Maybe Color
styleFill Style
sty)
in Text
"<circle"
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text -> Text
attr Text
"cx" (Double -> Text
showD Double
x)
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text -> Text
attr Text
"cy" (Double -> Text
showD Double
y)
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text -> Text
attr Text
"r" (Double -> Text
showD Double
r)
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text -> Text
attr Text
"fill" Text
fill
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Style -> Text
strokeAttrs Style
sty
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Style -> Text
opacityAttr Style
sty
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"/>\n"
MText (Point Double
x Double
y) Text
txt TextStyle
ts ->
Double
-> Double
-> Text
-> Text
-> Double
-> Double
-> Maybe Text
-> Text
-> Text
svgTextRT
Double
x
Double
y
(TextAnchor -> Text
anchorText (TextStyle -> TextAnchor
textAnchor TextStyle
ts))
(Color -> Text
colorHex (TextStyle -> Color
textFill TextStyle
ts))
(TextStyle -> Double
textSize TextStyle
ts)
(TextStyle -> Double
textRotate TextStyle
ts)
(TextStyle -> Maybe Text
textTitle TextStyle
ts)
Text
txt
MPolyline [Point]
pts Style
sty ->
let stroke :: Text
stroke = Text -> (Color -> Text) -> Maybe Color -> Text
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Text
"#000000" Color -> Text
colorHex (Style -> Maybe Color
styleStroke Style
sty)
pairs :: [(Double, Double)]
pairs = [(Double
px, Double
py) | Point Double
px Double
py <- [Point]
pts]
in [(Double, Double)] -> Text -> Double -> Text
svgPolyline [(Double, Double)]
pairs Text
stroke (Style -> Double
styleStrokeWidth Style
sty)
MPolygon [Point]
pts Style
sty ->
let fill :: Text
fill = Text -> (Color -> Text) -> Maybe Color -> Text
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Text
"none" Color -> Text
colorHex (Style -> Maybe Color
styleFill Style
sty)
pairs :: [(Double, Double)]
pairs = [(Double
px, Double
py) | Point Double
px Double
py <- [Point]
pts]
ptsStr :: Text
ptsStr = Text -> [Text] -> Text
T.intercalate Text
" " [Double -> Text
showD Double
px Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"," Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Double -> Text
showD Double
py | (Double
px, Double
py) <- [(Double, Double)]
pairs]
in Text
"<polygon"
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text -> Text
attr Text
"points" Text
ptsStr
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text -> Text
attr Text
"fill" Text
fill
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Style -> Text
strokeAttrs Style
sty
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Style -> Text
opacityAttr Style
sty
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"/>\n"
MAxisLine (Point Double
x1 Double
y1) (Point Double
x2 Double
y2) Style
sty ->
let stroke :: Text
stroke = Text -> (Color -> Text) -> Maybe Color -> Text
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Text
"#000000" Color -> Text
colorHex (Style -> Maybe Color
styleStroke Style
sty)
in Double -> Double -> Double -> Double -> Text -> Double -> Text
svgLine Double
x1 Double
y1 Double
x2 Double
y2 Text
stroke (Style -> Double
styleStrokeWidth Style
sty)
MPath Text
d Style
sty ->
let fill :: Text
fill = Text -> (Color -> Text) -> Maybe Color -> Text
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Text
"none" Color -> Text
colorHex (Style -> Maybe Color
styleFill Style
sty)
in Text -> Text -> Text -> Text
svgPath Text
d Text
fill (Style -> Text
strokeAttrs Style
sty)
MArc (Point Double
cx Double
cy) Double
r Double
a0 Double
a1 Style
sty ->
let x0 :: Double
x0 = Double
cx Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double
r Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double -> Double
forall a. Floating a => a -> a
cos Double
a0
y0 :: Double
y0 = Double
cy Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double
r Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double -> Double
forall a. Floating a => a -> a
sin Double
a0
x1 :: Double
x1 = Double
cx Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double
r Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double -> Double
forall a. Floating a => a -> a
cos Double
a1
y1 :: Double
y1 = Double
cy Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double
r Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double -> Double
forall a. Floating a => a -> a
sin Double
a1
largeArc :: Text
largeArc = if Double
a1 Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double
a0 Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
> Double
forall a. Floating a => a
pi then Text
"1" else Text
"0"
d :: Text
d =
Text
"M "
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Double -> Text
showD Double
cx
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" "
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Double -> Text
showD Double
cy
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" L "
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Double -> Text
showD Double
x0
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" "
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Double -> Text
showD Double
y0
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" A "
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Double -> Text
showD Double
r
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" "
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Double -> Text
showD Double
r
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" 0 "
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
largeArc
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" 0 "
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Double -> Text
showD Double
x1
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" "
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Double -> Text
showD Double
y1
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" Z"
fill :: Text
fill = Text -> (Color -> Text) -> Maybe Color -> Text
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Text
"none" Color -> Text
colorHex (Style -> Maybe Color
styleFill Style
sty)
in Text -> Text -> Text -> Text
svgPath Text
d Text
fill (Style -> Text
strokeAttrs Style
sty)
MGroup [Mark]
ms ->
Text
"<g>" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> [Text] -> Text
T.concat ((Mark -> Text) -> [Mark] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map Mark -> Text
renderMark [Mark]
ms) Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"</g>\n"
anchorText :: TextAnchor -> Text
anchorText :: TextAnchor -> Text
anchorText TextAnchor
AnchorStart = Text
"start"
anchorText TextAnchor
AnchorMiddle = Text
"middle"
anchorText TextAnchor
AnchorEnd = Text
"end"
strokeAttrs :: Style -> Text
strokeAttrs :: Style -> Text
strokeAttrs Style
sty =
case Style -> Maybe Color
styleStroke Style
sty of
Maybe Color
Nothing -> Text
""
Just Color
c ->
Text -> Text -> Text
attr Text
"stroke" (Color -> Text
colorHex Color
c) Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text -> Text
attr Text
"stroke-width" (Double -> Text
showD (Style -> Double
styleStrokeWidth Style
sty))
opacityAttr :: Style -> Text
opacityAttr :: Style -> Text
opacityAttr Style
sty
| Style -> Double
styleFillOpacity Style
sty Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
< Double
1 = Text -> Text -> Text
attr Text
"fill-opacity" (Double -> Text
showD (Style -> Double
styleFillOpacity Style
sty))
| Bool
otherwise = Text
""