packages feed

xhtml-3000.3.0.0: Text/XHtml/Debug.hs

{-# OPTIONS_HADDOCK hide #-}

{-# language OverloadedStrings #-}

-- | This module contains functions for displaying
--   HTML as a pretty tree.
module Text.XHtml.Debug ( HtmlTree(..), treeHtml, treeColors, debugHtml ) where

import Text.XHtml.Internals
import Text.XHtml.Extras
import Text.XHtml.Table
import Text.XHtml.Strict.Elements
import Text.XHtml.Strict.Attributes
import qualified Data.Text.Lazy as LText

import Data.List (uncons)

--
-- * Tree Displaying Combinators
--

-- | The basic idea is you render your structure in the form
-- of this tree, and then use treeHtml to turn it into a Html
-- object with the structure explicit.
data HtmlTree
      = HtmlLeaf Html
      | HtmlNode Html [HtmlTree] Html

treeHtml :: [LText.Text] -> HtmlTree -> Html
treeHtml colors h =
    table !
      [ border 0,
        cellpadding 0,
        cellspacing 2
      ]
      << treeHtml' colors h
  where
    manycolors = scanr (:) []

    treeHtmls :: [[LText.Text]] -> [HtmlTree] -> HtmlTable
    treeHtmls c ts = aboves (zipWith treeHtml' c ts)

    treeHtml' :: [LText.Text] -> HtmlTree -> HtmlTable
    treeHtml' _ (HtmlLeaf leaf) = cell
                                        (td ! [width "100%"]
                                          << bold
                                              << leaf)
    treeHtml' (c:cs@(c2:_)) (HtmlNode hopen ts hclose)
        | null ts && isNoHtml hclose = cell hd
        | null ts = hd </> bar `beside` (td ! [bgcolor' c2] << spaceHtml) </> tl
        | otherwise = hd </> (bar `beside` treeHtmls morecolors ts) </> tl
      where
        -- This stops a column of colors being the same
        -- color as the immediately outside nesting bar.
        morecolors = filter (maybe True ((/= c) . fst) . uncons) (manycolors cs)
        bar = td ! [bgcolor' c,width "10"] << spaceHtml
        hd = td ! [bgcolor' c] << hopen
        tl = td ! [bgcolor' c] << hclose
    treeHtml' _ _ = error "The imposible happens"

instance HTML HtmlTree where
      toHtml = treeHtml treeColors

-- type "length treeColors" to see how many colors are here.
treeColors :: [LText.Text]
treeColors = ["#88ccff","#ffffaa","#ffaaff","#ccffff"] ++ treeColors


--
-- * Html Debugging Combinators
--

-- | This uses the above tree rendering function, and displays the
-- Html as a tree structure, allowing debugging of what is
-- actually getting produced.
debugHtml :: (HTML a) => a -> Html
debugHtml obj = table ! [border 0] <<
                  ( th ! [bgcolor' "#008888"]
                     << underline'
                       << ("Debugging Output" :: String)
               </>  td << toHtml (debug' (toHtml obj))
              )
  where

      debug' :: Html -> [HtmlTree]
      debug' (Html markups) = map debug (markups [])

      debug :: HtmlElement -> HtmlTree
      debug (HtmlString str) = HtmlLeaf (spaceHtml +++
                                              linesToHtml (lines (builderToString str)))
      debug (HtmlTag {
              markupTag = tag',
              markupContent = content',
              markupAttrs  = mkAttrs
              }) =
              if isNoHtml content'
                then HtmlNode hd [] noHtml
                else HtmlNode hd (map debug (getHtmlElements content')) tl
        where
              attrs = mkAttrs []
              args = if null attrs
                     then ""
                     else "  " <> unwords (map show attrs)
              hd = xsmallFont << ("<" <> builderToString tag' <> args <> ">")
              tl = xsmallFont << ("</" <> builderToString tag' <> ">")

bgcolor' :: LText.Text -> HtmlAttr
bgcolor' c = thestyle ("background-color:" <> c)

underline' :: Html -> Html
underline' = thespan ! [thestyle "text-decoration:underline"]

xsmallFont :: Html -> Html
xsmallFont  = thespan ! [thestyle "font-size:x-small"]