Search code examples
htmlhaskellsvgblaze-html

How to render blaze-svg markup within blaze-html


I want to include a svg diagram generated with blaze-svg directly in html generated with blaze-html. Both are based on blaze-markup, so I expected it to be easy.

diagram1 :: Svg
diagram1 = ... 

try1 :: Html
try1 = html $
  body $ do
    h1 "My first diagram"
    toHtml diagram1

try2 :: Html
try2 :: html $
  body $ do
    h1 "My first diagram"
    toHtml $ renderSvg diagram1

Both try1 and try2 passes the compiler but neither shows the diagram. What is the right way? Is it a problem with including the svg tag directly?


Solution

  • try2 first generates a string representation of the SVG with renderSvg, escapes it (toHtml) and includes the result into the HTML output. Using it, you should see the source of the SVG instead of the resulting image.

    try1 should actually work. toHtml is defined as the identity on the Svg type, so you could also just use diagram1 directly.

    Here is a complete example that generates a HTML document with embedded SVG:

    {-# LANGUAGE OverloadedStrings #-}
    module Main where
    
    import Prelude hiding (head)
    import Text.Blaze.Svg11 hiding (title)
    import Text.Blaze.Svg11.Attributes hiding (title)
    import Text.Blaze.Html5
    import Text.Blaze.Html.Renderer.Pretty
    
    diagram1 :: Svg
    diagram1 = svg ! width "100" ! height "100" $
      circle ! cx "50" ! cy "50" ! r "40" ! stroke "green"
             ! strokeWidth "4" ! fill "yellow"
    
    try2 :: Html
    try2 = docTypeHtml $ do
      head $ title "Works"
      body $ do
        h1 "My first diagram"
        diagram1
    
    main :: IO ()
    main = putStr $ renderHtml try2