    -- | Clear to write, read and edit DSL for writing HTML
    --
    -- See "Lucid.Html5" for a complete list of Html5 combinators. That
    -- module is re-exported from this module for your convenience.
    --
    -- See "Lucid.Base" for lower level functions like
    -- `makeElement`, `makeAttribute`, 'termRaw', etc.
    --
    -- To convert html to the lucid DSL, use the (experimental) program
    -- <https://github.com/dbaynard/lucid-from-html lucid-from-html>
    -- which may eventually be integrated into lucid itself.

    module Lucid
      (-- * Intro
       -- $intro
       renderText
      ,renderBS
      ,renderTextT
      ,renderBST
      ,renderToFile
       -- * Running
       -- $running
      ,execHtmlT
      ,evalHtmlT
      ,runHtmlT
       -- * Types
      ,Html
      ,HtmlT
      ,Attribute
       -- * Classes
       -- $overloaded
      ,Term(..)
      ,ToHtml(..)
      ,With(..)
      -- * Re-exports
      ,module Lucid.Html5)
     where

    import Lucid.Base
    import Lucid.Html5

    -- $intro
    --
    -- HTML terms in Lucid are written with a postfix ‘@_@’ to indicate data
    -- rather than code. Some examples:
    --
    -- 'p_', 'class_', 'table_', 'style_'
    --
    -- Note: If you're testing in the REPL you need to add a type annotation to
    -- indicate that you want HTML. In normal code your top-level
    -- declaration signatures handle that.
    --
    -- For GHCi:
    --
    -- @
    -- :set -XOverloadedStrings -XExtendedDefaultRules@
    -- import Lucid
    -- @
    --
    -- In a module: @{-\# LANGUAGE OverloadedStrings, ExtendedDefaultRules \#-}@
    --
    -- Plain text is written like this, and is automatically escaped:
    --
    -- >>> "123 < 456" :: Html ()
    -- 123 &lt; 456
    --
    -- Except some elements, like 'script_':
    --
    -- >>> script_ "alert('Hello!' > 12)" :: Html ()
    -- <script>alert('Hello!' > 12)</script>
    --
    -- Elements nest by function application:
    --
    -- >>> table_ (tr_ (td_ (p_ "Hello, World!"))) :: Html ()
    -- <table><tr><td><p>Hello, World!</p></td></tr></table>
    --
    -- Elements are juxtaposed via monoidal append (remember to import "Data.Monoid"):
    --
    -- >>> p_ "hello" <> p_ "sup" :: Html ()
    -- <p>hello</p><p>sup</p>
    --
    -- Or monadic sequencing:
    --
    -- >>> div_ (do p_ "hello"; p_ "sup") :: Html ()
    -- <div><p>hello</p><p>sup</p></div>
    --
    -- Attributes are set by providing an argument list:
    --
    -- >>> p_ [class_ "brand"] "Lucid Inc" :: Html ()
    -- <p class="brand">Lucid Inc</p>
    --
    -- >>> p_ [data_ "zot" "foo",checked_] "Go!" :: Html ()
    -- <p data-zot="foo" checked>go</p>
    --
    -- Attribute and element terms are not conflicting:
    --
    -- >>> style_ [style_ "inception"] "Go deeper." :: Html ()
    -- <style style="inception">Go deeper.</style>
    --
    -- Here is a fuller example of Lucid:
    --
    -- @
    -- table_ [rows_ "2"]
    --        (tr_ (do td_ [class_ "top",colspan_ "2",style_ "color:red"]
    --                     (p_ "Hello, attributes!")
    --                 td_ "yay!"))
    -- @
    --
    -- Elements (and some attributes) are variadic and overloaded, see the
    -- 'Term' class for more explanation about that.
    --
    -- For proper rendering you can easily run some HTML immediately with:
    --
    -- >>> renderText (p_ "Hello!")
    -- > "<p>Hello!</p>"
    --
    -- >>> renderBS (p_ [style_ "color:red"] "Hello!")
    -- "<p style=\"color:red\">Hello!</p>"
    --
    -- For ease of use in GHCi, there is a 'Show' instance, as
    -- demonstrated above.

    -- $overloaded
    --
    -- To support convenient use of HTML terms, HTML terms are
    -- overloaded. Here are the following types possible for an element
    -- term accepting attributes and/or children:
    --
    -- @
    -- p_ :: Term arg result => arg -> result
    -- p_ :: Monad m => [Attribute] -> HtmlT m () -> HtmlT m ()
    -- p_ :: Monad m => HtmlT m () -> HtmlT m ()
    -- @
    --
    -- The first is the generic form. The latter two are the possible
    -- types for an element.
    --
    -- Elements that accept no content are always concrete:
    --
    -- @
    -- input_ :: Monad m => [Attribute] -> HtmlT m ()
    -- @
    --
    -- And some elements share the same name as attributes, so you can
    -- also overload them as attributes:
    --
    -- @
    -- style_ :: TermRaw arg result => arg -> result
    -- style_ :: Monad m => [Attribute] -> Text -> HtmlT m ()
    -- style_ :: Monad m => Text -> HtmlT m ()
    -- style_ :: Text -> Attribute
    -- @

    -- $running
    --
    -- If the above rendering functions aren't suited for your purpose,
    -- you can run the monad directly and use the more low-level blaze
    -- `Builder`, which has a plethora of output modes in
    -- "Blaze.ByteString.Builder".