{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE MultiWayIf #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ScopedTypeVariables #-}

-- | Defines the top-level HTML types and parser functions.
module Zenacy.HTML.Internal.HTML
  ( HTMLOptions(..)
  , HTMLResult(..)
  , HTMLError(..)
  , HTMLNode(..)
  , HTMLAttr(..)
  , HTMLNamespace(..)
  , HTMLAttrNamespace(..)
  , htmlParse
  , htmlParseEasy
  , htmlFragment
  , htmlDefaultDocument
  , htmlDefaultDoctype
  , htmlDefaultFragment
  , htmlDefaultElement
  , htmlDefaultTemplate
  , htmlDefaultText
  , htmlDefaultComment
  , htmlAttr
  , htmlElem
  , htmlText
  ) where

import Zenacy.HTML.Internal.BS
import Zenacy.HTML.Internal.Core
import Zenacy.HTML.Internal.DOM
import Zenacy.HTML.Internal.Parser
import Zenacy.HTML.Internal.Types
import Data.Default
  ( Default(..)
  )
import Data.Either
  ( either
  )
import Data.Foldable
  ( toList
  )
import Data.Maybe
  ( fromJust
  )
import Data.Text
  ( Text
  )
import qualified Data.Text as T
  ( empty
  )
import qualified Data.Text.Encoding as T
  ( encodeUtf8
  , decodeUtf8
  )

-- | Defines options for the HTML parser.
data HTMLOptions = HTMLOptions
  { HTMLOptions -> Bool
htmlOptionLogErrors      :: !Bool
    -- ^ Indicates that errors should be logged.
  , HTMLOptions -> Bool
htmlOptionIgnoreEntities :: !Bool
    -- ^ Indicates that entities should not be decoded.
  } deriving (HTMLOptions -> HTMLOptions -> Bool
(HTMLOptions -> HTMLOptions -> Bool)
-> (HTMLOptions -> HTMLOptions -> Bool) -> Eq HTMLOptions
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: HTMLOptions -> HTMLOptions -> Bool
$c/= :: HTMLOptions -> HTMLOptions -> Bool
== :: HTMLOptions -> HTMLOptions -> Bool
$c== :: HTMLOptions -> HTMLOptions -> Bool
Eq, Eq HTMLOptions
Eq HTMLOptions
-> (HTMLOptions -> HTMLOptions -> Ordering)
-> (HTMLOptions -> HTMLOptions -> Bool)
-> (HTMLOptions -> HTMLOptions -> Bool)
-> (HTMLOptions -> HTMLOptions -> Bool)
-> (HTMLOptions -> HTMLOptions -> Bool)
-> (HTMLOptions -> HTMLOptions -> HTMLOptions)
-> (HTMLOptions -> HTMLOptions -> HTMLOptions)
-> Ord HTMLOptions
HTMLOptions -> HTMLOptions -> Bool
HTMLOptions -> HTMLOptions -> Ordering
HTMLOptions -> HTMLOptions -> HTMLOptions
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: HTMLOptions -> HTMLOptions -> HTMLOptions
$cmin :: HTMLOptions -> HTMLOptions -> HTMLOptions
max :: HTMLOptions -> HTMLOptions -> HTMLOptions
$cmax :: HTMLOptions -> HTMLOptions -> HTMLOptions
>= :: HTMLOptions -> HTMLOptions -> Bool
$c>= :: HTMLOptions -> HTMLOptions -> Bool
> :: HTMLOptions -> HTMLOptions -> Bool
$c> :: HTMLOptions -> HTMLOptions -> Bool
<= :: HTMLOptions -> HTMLOptions -> Bool
$c<= :: HTMLOptions -> HTMLOptions -> Bool
< :: HTMLOptions -> HTMLOptions -> Bool
$c< :: HTMLOptions -> HTMLOptions -> Bool
compare :: HTMLOptions -> HTMLOptions -> Ordering
$ccompare :: HTMLOptions -> HTMLOptions -> Ordering
$cp1Ord :: Eq HTMLOptions
Ord, Int -> HTMLOptions -> ShowS
[HTMLOptions] -> ShowS
HTMLOptions -> String
(Int -> HTMLOptions -> ShowS)
-> (HTMLOptions -> String)
-> ([HTMLOptions] -> ShowS)
-> Show HTMLOptions
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [HTMLOptions] -> ShowS
$cshowList :: [HTMLOptions] -> ShowS
show :: HTMLOptions -> String
$cshow :: HTMLOptions -> String
showsPrec :: Int -> HTMLOptions -> ShowS
$cshowsPrec :: Int -> HTMLOptions -> ShowS
Show)

-- | Defines an HTML parser result.
data HTMLResult = HTMLResult
  { HTMLResult -> HTMLNode
htmlResultDocument :: !HTMLNode
    -- ^ The parsed document structure.
  , HTMLResult -> [HTMLError]
htmlResultErrors   :: ![HTMLError]
    -- ^ The errors logged while parsing if error logging was enabled.
  } deriving (HTMLResult -> HTMLResult -> Bool
(HTMLResult -> HTMLResult -> Bool)
-> (HTMLResult -> HTMLResult -> Bool) -> Eq HTMLResult
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: HTMLResult -> HTMLResult -> Bool
$c/= :: HTMLResult -> HTMLResult -> Bool
== :: HTMLResult -> HTMLResult -> Bool
$c== :: HTMLResult -> HTMLResult -> Bool
Eq, Eq HTMLResult
Eq HTMLResult
-> (HTMLResult -> HTMLResult -> Ordering)
-> (HTMLResult -> HTMLResult -> Bool)
-> (HTMLResult -> HTMLResult -> Bool)
-> (HTMLResult -> HTMLResult -> Bool)
-> (HTMLResult -> HTMLResult -> Bool)
-> (HTMLResult -> HTMLResult -> HTMLResult)
-> (HTMLResult -> HTMLResult -> HTMLResult)
-> Ord HTMLResult
HTMLResult -> HTMLResult -> Bool
HTMLResult -> HTMLResult -> Ordering
HTMLResult -> HTMLResult -> HTMLResult
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: HTMLResult -> HTMLResult -> HTMLResult
$cmin :: HTMLResult -> HTMLResult -> HTMLResult
max :: HTMLResult -> HTMLResult -> HTMLResult
$cmax :: HTMLResult -> HTMLResult -> HTMLResult
>= :: HTMLResult -> HTMLResult -> Bool
$c>= :: HTMLResult -> HTMLResult -> Bool
> :: HTMLResult -> HTMLResult -> Bool
$c> :: HTMLResult -> HTMLResult -> Bool
<= :: HTMLResult -> HTMLResult -> Bool
$c<= :: HTMLResult -> HTMLResult -> Bool
< :: HTMLResult -> HTMLResult -> Bool
$c< :: HTMLResult -> HTMLResult -> Bool
compare :: HTMLResult -> HTMLResult -> Ordering
$ccompare :: HTMLResult -> HTMLResult -> Ordering
$cp1Ord :: Eq HTMLResult
Ord, Int -> HTMLResult -> ShowS
[HTMLResult] -> ShowS
HTMLResult -> String
(Int -> HTMLResult -> ShowS)
-> (HTMLResult -> String)
-> ([HTMLResult] -> ShowS)
-> Show HTMLResult
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [HTMLResult] -> ShowS
$cshowList :: [HTMLResult] -> ShowS
show :: HTMLResult -> String
$cshow :: HTMLResult -> String
showsPrec :: Int -> HTMLResult -> ShowS
$cshowsPrec :: Int -> HTMLResult -> ShowS
Show)

-- | An HTML error type.
data HTMLError = HTMLError
  { HTMLError -> Text
htmlErrorText  :: !Text
    -- ^ The error message.
  } deriving (Int -> HTMLError -> ShowS
[HTMLError] -> ShowS
HTMLError -> String
(Int -> HTMLError -> ShowS)
-> (HTMLError -> String)
-> ([HTMLError] -> ShowS)
-> Show HTMLError
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [HTMLError] -> ShowS
$cshowList :: [HTMLError] -> ShowS
show :: HTMLError -> String
$cshow :: HTMLError -> String
showsPrec :: Int -> HTMLError -> ShowS
$cshowsPrec :: Int -> HTMLError -> ShowS
Show, HTMLError -> HTMLError -> Bool
(HTMLError -> HTMLError -> Bool)
-> (HTMLError -> HTMLError -> Bool) -> Eq HTMLError
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: HTMLError -> HTMLError -> Bool
$c/= :: HTMLError -> HTMLError -> Bool
== :: HTMLError -> HTMLError -> Bool
$c== :: HTMLError -> HTMLError -> Bool
Eq, Eq HTMLError
Eq HTMLError
-> (HTMLError -> HTMLError -> Ordering)
-> (HTMLError -> HTMLError -> Bool)
-> (HTMLError -> HTMLError -> Bool)
-> (HTMLError -> HTMLError -> Bool)
-> (HTMLError -> HTMLError -> Bool)
-> (HTMLError -> HTMLError -> HTMLError)
-> (HTMLError -> HTMLError -> HTMLError)
-> Ord HTMLError
HTMLError -> HTMLError -> Bool
HTMLError -> HTMLError -> Ordering
HTMLError -> HTMLError -> HTMLError
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: HTMLError -> HTMLError -> HTMLError
$cmin :: HTMLError -> HTMLError -> HTMLError
max :: HTMLError -> HTMLError -> HTMLError
$cmax :: HTMLError -> HTMLError -> HTMLError
>= :: HTMLError -> HTMLError -> Bool
$c>= :: HTMLError -> HTMLError -> Bool
> :: HTMLError -> HTMLError -> Bool
$c> :: HTMLError -> HTMLError -> Bool
<= :: HTMLError -> HTMLError -> Bool
$c<= :: HTMLError -> HTMLError -> Bool
< :: HTMLError -> HTMLError -> Bool
$c< :: HTMLError -> HTMLError -> Bool
compare :: HTMLError -> HTMLError -> Ordering
$ccompare :: HTMLError -> HTMLError -> Ordering
$cp1Ord :: Eq HTMLError
Ord)

-- | Defines the model type for an HTML document.
data HTMLNode
  = HTMLDocument
    { HTMLNode -> Text
htmlDocumentName       :: !Text           -- ^ The document name.
    , HTMLNode -> [HTMLNode]
htmlDocumentChildren   :: ![HTMLNode]     -- ^ The document children.
    }
  | HTMLDoctype
    { HTMLNode -> Text
htmlDoctypeName        :: !Text           -- ^ The DOCTYPE name.
    , HTMLNode -> Maybe Text
htmlDoctypePublicID    :: !(Maybe Text)   -- ^ The public ID.
    , HTMLNode -> Maybe Text
htmlDoctypeSystemID    :: !(Maybe Text)   -- ^ The system ID.
    }
  | HTMLFragment
    { HTMLNode -> Text
htmlFragmentName       :: !Text           -- ^ The fragment name.
    , HTMLNode -> [HTMLNode]
htmlFragmentChildren   :: ![HTMLNode]     -- ^ The fragment children.
    }
  | HTMLElement
    { HTMLNode -> Text
htmlElementName        :: !Text           -- ^ The element name.
    , HTMLNode -> HTMLNamespace
htmlElementNamespace   :: !HTMLNamespace  -- ^ The element namespace.
    , HTMLNode -> [HTMLAttr]
htmlElementAttributes  :: ![HTMLAttr]     -- ^ The element attributes.
    , HTMLNode -> [HTMLNode]
htmlElementChildren    :: ![HTMLNode]     -- ^ The element children.
    }
  | HTMLTemplate
    { HTMLNode -> HTMLNamespace
htmlTemplateNamespace  :: !HTMLNamespace  -- ^ The template namespace.
    , HTMLNode -> [HTMLAttr]
htmlTemplateAttributes :: ![HTMLAttr]     -- ^ The template attributes.
    , HTMLNode -> HTMLNode
htmlTemplateContents   :: !HTMLNode       -- ^ The template contents.
    }
  | HTMLText
    { HTMLNode -> Text
htmlTextData           :: !Text           -- ^ The text value.
    }
  | HTMLComment
    { HTMLNode -> Text
htmlCommentData        :: !Text           -- ^ The comment text.
    }
    deriving (HTMLNode -> HTMLNode -> Bool
(HTMLNode -> HTMLNode -> Bool)
-> (HTMLNode -> HTMLNode -> Bool) -> Eq HTMLNode
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: HTMLNode -> HTMLNode -> Bool
$c/= :: HTMLNode -> HTMLNode -> Bool
== :: HTMLNode -> HTMLNode -> Bool
$c== :: HTMLNode -> HTMLNode -> Bool
Eq, Eq HTMLNode
Eq HTMLNode
-> (HTMLNode -> HTMLNode -> Ordering)
-> (HTMLNode -> HTMLNode -> Bool)
-> (HTMLNode -> HTMLNode -> Bool)
-> (HTMLNode -> HTMLNode -> Bool)
-> (HTMLNode -> HTMLNode -> Bool)
-> (HTMLNode -> HTMLNode -> HTMLNode)
-> (HTMLNode -> HTMLNode -> HTMLNode)
-> Ord HTMLNode
HTMLNode -> HTMLNode -> Bool
HTMLNode -> HTMLNode -> Ordering
HTMLNode -> HTMLNode -> HTMLNode
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: HTMLNode -> HTMLNode -> HTMLNode
$cmin :: HTMLNode -> HTMLNode -> HTMLNode
max :: HTMLNode -> HTMLNode -> HTMLNode
$cmax :: HTMLNode -> HTMLNode -> HTMLNode
>= :: HTMLNode -> HTMLNode -> Bool
$c>= :: HTMLNode -> HTMLNode -> Bool
> :: HTMLNode -> HTMLNode -> Bool
$c> :: HTMLNode -> HTMLNode -> Bool
<= :: HTMLNode -> HTMLNode -> Bool
$c<= :: HTMLNode -> HTMLNode -> Bool
< :: HTMLNode -> HTMLNode -> Bool
$c< :: HTMLNode -> HTMLNode -> Bool
compare :: HTMLNode -> HTMLNode -> Ordering
$ccompare :: HTMLNode -> HTMLNode -> Ordering
$cp1Ord :: Eq HTMLNode
Ord, Int -> HTMLNode -> ShowS
[HTMLNode] -> ShowS
HTMLNode -> String
(Int -> HTMLNode -> ShowS)
-> (HTMLNode -> String) -> ([HTMLNode] -> ShowS) -> Show HTMLNode
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [HTMLNode] -> ShowS
$cshowList :: [HTMLNode] -> ShowS
show :: HTMLNode -> String
$cshow :: HTMLNode -> String
showsPrec :: Int -> HTMLNode -> ShowS
$cshowsPrec :: Int -> HTMLNode -> ShowS
Show)

-- | An HTML element attribute type.
data HTMLAttr = HTMLAttr
  { HTMLAttr -> Text
htmlAttrName      :: Text
  , HTMLAttr -> Text
htmlAttrVal       :: Text
  , HTMLAttr -> HTMLAttrNamespace
htmlAttrNamespace :: HTMLAttrNamespace
  } deriving (HTMLAttr -> HTMLAttr -> Bool
(HTMLAttr -> HTMLAttr -> Bool)
-> (HTMLAttr -> HTMLAttr -> Bool) -> Eq HTMLAttr
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: HTMLAttr -> HTMLAttr -> Bool
$c/= :: HTMLAttr -> HTMLAttr -> Bool
== :: HTMLAttr -> HTMLAttr -> Bool
$c== :: HTMLAttr -> HTMLAttr -> Bool
Eq, Eq HTMLAttr
Eq HTMLAttr
-> (HTMLAttr -> HTMLAttr -> Ordering)
-> (HTMLAttr -> HTMLAttr -> Bool)
-> (HTMLAttr -> HTMLAttr -> Bool)
-> (HTMLAttr -> HTMLAttr -> Bool)
-> (HTMLAttr -> HTMLAttr -> Bool)
-> (HTMLAttr -> HTMLAttr -> HTMLAttr)
-> (HTMLAttr -> HTMLAttr -> HTMLAttr)
-> Ord HTMLAttr
HTMLAttr -> HTMLAttr -> Bool
HTMLAttr -> HTMLAttr -> Ordering
HTMLAttr -> HTMLAttr -> HTMLAttr
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: HTMLAttr -> HTMLAttr -> HTMLAttr
$cmin :: HTMLAttr -> HTMLAttr -> HTMLAttr
max :: HTMLAttr -> HTMLAttr -> HTMLAttr
$cmax :: HTMLAttr -> HTMLAttr -> HTMLAttr
>= :: HTMLAttr -> HTMLAttr -> Bool
$c>= :: HTMLAttr -> HTMLAttr -> Bool
> :: HTMLAttr -> HTMLAttr -> Bool
$c> :: HTMLAttr -> HTMLAttr -> Bool
<= :: HTMLAttr -> HTMLAttr -> Bool
$c<= :: HTMLAttr -> HTMLAttr -> Bool
< :: HTMLAttr -> HTMLAttr -> Bool
$c< :: HTMLAttr -> HTMLAttr -> Bool
compare :: HTMLAttr -> HTMLAttr -> Ordering
$ccompare :: HTMLAttr -> HTMLAttr -> Ordering
$cp1Ord :: Eq HTMLAttr
Ord, Int -> HTMLAttr -> ShowS
[HTMLAttr] -> ShowS
HTMLAttr -> String
(Int -> HTMLAttr -> ShowS)
-> (HTMLAttr -> String) -> ([HTMLAttr] -> ShowS) -> Show HTMLAttr
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [HTMLAttr] -> ShowS
$cshowList :: [HTMLAttr] -> ShowS
show :: HTMLAttr -> String
$cshow :: HTMLAttr -> String
showsPrec :: Int -> HTMLAttr -> ShowS
$cshowsPrec :: Int -> HTMLAttr -> ShowS
Show)

-- | Defines default options.
instance Default HTMLOptions where
  def :: HTMLOptions
def = HTMLOptions :: Bool -> Bool -> HTMLOptions
HTMLOptions
    { htmlOptionLogErrors :: Bool
htmlOptionLogErrors      = Bool
False
    , htmlOptionIgnoreEntities :: Bool
htmlOptionIgnoreEntities = Bool
False
    }

-- | Defines a default result.
instance Default HTMLResult where
  def :: HTMLResult
def = HTMLResult :: HTMLNode -> [HTMLError] -> HTMLResult
HTMLResult
    { htmlResultDocument :: HTMLNode
htmlResultDocument = HTMLNode
htmlDefaultDocument
    , htmlResultErrors :: [HTMLError]
htmlResultErrors   = []
    }

-- | Defines a default error.
instance Default HTMLError where
  def :: HTMLError
def = HTMLError :: Text -> HTMLError
HTMLError
    { htmlErrorText :: Text
htmlErrorText = Text
T.empty
    }

-- | Defines a default attribute.
instance Default HTMLAttr where
  def :: HTMLAttr
def = HTMLAttr :: Text -> Text -> HTMLAttrNamespace -> HTMLAttr
HTMLAttr
    { htmlAttrName :: Text
htmlAttrName      = Text
T.empty
    , htmlAttrVal :: Text
htmlAttrVal       = Text
T.empty
    , htmlAttrNamespace :: HTMLAttrNamespace
htmlAttrNamespace = HTMLAttrNamespace
HTMLAttrNamespaceNone
    }

-- | Parses an HTML document.
htmlParse :: HTMLOptions -> Text -> Either HTMLError HTMLResult
htmlParse :: HTMLOptions -> Text -> Either HTMLError HTMLResult
htmlParse HTMLOptions {Bool
htmlOptionIgnoreEntities :: Bool
htmlOptionLogErrors :: Bool
htmlOptionIgnoreEntities :: HTMLOptions -> Bool
htmlOptionLogErrors :: HTMLOptions -> Bool
..} Text
x =
  case Either BS ParserResult
d of
    Right ParserResult {[BS]
DOM
parserResultErrors :: ParserResult -> [BS]
parserResultDOM :: ParserResult -> DOM
parserResultErrors :: [BS]
parserResultDOM :: DOM
..} ->
      HTMLResult -> Either HTMLError HTMLResult
forall a b. b -> Either a b
Right HTMLResult
forall a. Default a => a
def
        { htmlResultDocument :: HTMLNode
htmlResultDocument = DOM -> HTMLNode
domToHTML DOM
parserResultDOM
        , htmlResultErrors :: [HTMLError]
htmlResultErrors   = (BS -> HTMLError) -> [BS] -> [HTMLError]
forall a b. (a -> b) -> [a] -> [b]
map BS -> HTMLError
f [BS]
parserResultErrors
        }
    Left BS
e ->
      HTMLError -> Either HTMLError HTMLResult
forall a b. a -> Either a b
Left (BS -> HTMLError
f BS
e)
  where
    d :: Either BS ParserResult
d = ParserOptions -> Either BS ParserResult
parseDocument ParserOptions
forall a. Default a => a
def
      { parserOptionInput :: BS
parserOptionInput          = Text -> BS
T.encodeUtf8 Text
x
      , parserOptionLogErrors :: Bool
parserOptionLogErrors      = Bool
htmlOptionLogErrors
      , parserOptionIgnoreEntities :: Bool
parserOptionIgnoreEntities = Bool
htmlOptionIgnoreEntities
      }
    f :: BS -> HTMLError
f BS
x = HTMLError
forall a. Default a => a
def { htmlErrorText :: Text
htmlErrorText = BS -> Text
T.decodeUtf8 BS
x }

-- | Parses an HTML document the easy way.
htmlParseEasy :: Text -> HTMLNode
htmlParseEasy :: Text -> HTMLNode
htmlParseEasy =
  (HTMLError -> HTMLNode)
-> (HTMLResult -> HTMLNode)
-> Either HTMLError HTMLResult
-> HTMLNode
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (HTMLNode -> HTMLError -> HTMLNode
forall a b. a -> b -> a
const HTMLNode
htmlDefaultDocument) HTMLResult -> HTMLNode
htmlResultDocument (Either HTMLError HTMLResult -> HTMLNode)
-> (Text -> Either HTMLError HTMLResult) -> Text -> HTMLNode
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HTMLOptions -> Text -> Either HTMLError HTMLResult
htmlParse HTMLOptions
forall a. Default a => a
def

-- | Parses an HTML fragment.
htmlFragment :: HTMLOptions -> Text -> Either HTMLError HTMLResult
htmlFragment :: HTMLOptions -> Text -> Either HTMLError HTMLResult
htmlFragment HTMLOptions {Bool
htmlOptionIgnoreEntities :: Bool
htmlOptionLogErrors :: Bool
htmlOptionIgnoreEntities :: HTMLOptions -> Bool
htmlOptionLogErrors :: HTMLOptions -> Bool
..} Text
x = HTMLError -> Either HTMLError HTMLResult
forall a b. a -> Either a b
Left HTMLError
forall a. Default a => a
def
  { htmlErrorText :: Text
htmlErrorText = Text
"fragment support not currently implemented" }

-- | Defines a default document.
htmlDefaultDocument :: HTMLNode
htmlDefaultDocument :: HTMLNode
htmlDefaultDocument = HTMLDocument :: Text -> [HTMLNode] -> HTMLNode
HTMLDocument
  { htmlDocumentName :: Text
htmlDocumentName     = Text
T.empty
  , htmlDocumentChildren :: [HTMLNode]
htmlDocumentChildren = []
  }

-- | Defines a default document type.
htmlDefaultDoctype :: HTMLNode
htmlDefaultDoctype :: HTMLNode
htmlDefaultDoctype = HTMLDoctype :: Text -> Maybe Text -> Maybe Text -> HTMLNode
HTMLDoctype
  { htmlDoctypeName :: Text
htmlDoctypeName     = Text
T.empty
  , htmlDoctypePublicID :: Maybe Text
htmlDoctypePublicID = Maybe Text
forall a. Maybe a
Nothing
  , htmlDoctypeSystemID :: Maybe Text
htmlDoctypeSystemID = Maybe Text
forall a. Maybe a
Nothing
  }

-- | Defines a default document fragment.
htmlDefaultFragment :: HTMLNode
htmlDefaultFragment :: HTMLNode
htmlDefaultFragment = HTMLFragment :: Text -> [HTMLNode] -> HTMLNode
HTMLFragment
  { htmlFragmentName :: Text
htmlFragmentName     = Text
T.empty
  , htmlFragmentChildren :: [HTMLNode]
htmlFragmentChildren = []
  }

-- | Defines a default element.
htmlDefaultElement :: HTMLNode
htmlDefaultElement :: HTMLNode
htmlDefaultElement = HTMLElement :: Text -> HTMLNamespace -> [HTMLAttr] -> [HTMLNode] -> HTMLNode
HTMLElement
  { htmlElementName :: Text
htmlElementName       = Text
T.empty
  , htmlElementNamespace :: HTMLNamespace
htmlElementNamespace  = HTMLNamespace
HTMLNamespaceHTML
  , htmlElementAttributes :: [HTMLAttr]
htmlElementAttributes = []
  , htmlElementChildren :: [HTMLNode]
htmlElementChildren   = []
  }

-- | Defines a default template.
htmlDefaultTemplate :: HTMLNode
htmlDefaultTemplate :: HTMLNode
htmlDefaultTemplate = HTMLTemplate :: HTMLNamespace -> [HTMLAttr] -> HTMLNode -> HTMLNode
HTMLTemplate
  { htmlTemplateNamespace :: HTMLNamespace
htmlTemplateNamespace  = HTMLNamespace
HTMLNamespaceHTML
  , htmlTemplateAttributes :: [HTMLAttr]
htmlTemplateAttributes = []
  , htmlTemplateContents :: HTMLNode
htmlTemplateContents   = HTMLNode
htmlDefaultFragment
  }

-- | Defines a default text.
htmlDefaultText :: HTMLNode
htmlDefaultText :: HTMLNode
htmlDefaultText = HTMLText :: Text -> HTMLNode
HTMLText
  { htmlTextData :: Text
htmlTextData = Text
T.empty
  }

-- | Defines a default comment.
htmlDefaultComment :: HTMLNode
htmlDefaultComment :: HTMLNode
htmlDefaultComment = HTMLComment :: Text -> HTMLNode
HTMLComment
  { htmlCommentData :: Text
htmlCommentData = Text
T.empty
  }

-- | Makes an attribute.
htmlAttr :: Text -> Text -> HTMLAttr
htmlAttr :: Text -> Text -> HTMLAttr
htmlAttr Text
n Text
v = Text -> Text -> HTMLAttrNamespace -> HTMLAttr
HTMLAttr Text
n Text
v HTMLAttrNamespace
HTMLAttrNamespaceNone

-- | Makes an element.
htmlElem :: Text -> [HTMLAttr] -> [HTMLNode] -> HTMLNode
htmlElem :: Text -> [HTMLAttr] -> [HTMLNode] -> HTMLNode
htmlElem Text
n [HTMLAttr]
a [HTMLNode]
c = Text -> HTMLNamespace -> [HTMLAttr] -> [HTMLNode] -> HTMLNode
HTMLElement Text
n HTMLNamespace
HTMLNamespaceHTML [HTMLAttr]
a [HTMLNode]
c

-- | Makes a text node.
htmlText :: Text -> HTMLNode
htmlText :: Text -> HTMLNode
htmlText = Text -> HTMLNode
HTMLText

-- | Converts a DOM document to an HTML document.
domToHTML :: DOM -> HTMLNode
domToHTML :: DOM -> HTMLNode
domToHTML DOM
d = DOM -> DOMNode -> HTMLNode
nodeToHTML DOM
d (DOMNode -> HTMLNode) -> DOMNode -> HTMLNode
forall a b. (a -> b) -> a -> b
$ DOM -> DOMNode
domDocument DOM
d

-- | Converts a DOM node to an HTML node.
nodeToHTML :: DOM -> DOMNode -> HTMLNode
nodeToHTML :: DOM -> DOMNode -> HTMLNode
nodeToHTML DOM
d = DOMNode -> HTMLNode
go where
  go :: DOMNode -> HTMLNode
go DOMDocument {Int
BS
Seq Int
DOMQuirks
domDocumentQuirksMode :: DOMNode -> DOMQuirks
domDocumentChildren :: DOMNode -> Seq Int
domDocumentName :: DOMNode -> BS
domDocumentParent :: DOMNode -> Int
domDocumentID :: DOMNode -> Int
domDocumentQuirksMode :: DOMQuirks
domDocumentChildren :: Seq Int
domDocumentName :: BS
domDocumentParent :: Int
domDocumentID :: Int
..} = HTMLDocument :: Text -> [HTMLNode] -> HTMLNode
HTMLDocument
    { htmlDocumentName :: Text
htmlDocumentName     = BS -> Text
t BS
domDocumentName
    , htmlDocumentChildren :: [HTMLNode]
htmlDocumentChildren = Seq Int -> [HTMLNode]
f Seq Int
domDocumentChildren
    }
  go DOMDoctype {Int
Maybe BS
BS
domDoctypeSystemID :: DOMNode -> Maybe BS
domDoctypePublicID :: DOMNode -> Maybe BS
domDoctypeName :: DOMNode -> BS
domDoctypeParent :: DOMNode -> Int
domDoctypeID :: DOMNode -> Int
domDoctypeSystemID :: Maybe BS
domDoctypePublicID :: Maybe BS
domDoctypeName :: BS
domDoctypeParent :: Int
domDoctypeID :: Int
..} = HTMLDoctype :: Text -> Maybe Text -> Maybe Text -> HTMLNode
HTMLDoctype
    { htmlDoctypeName :: Text
htmlDoctypeName     = BS -> Text
t BS
domDoctypeName
    , htmlDoctypePublicID :: Maybe Text
htmlDoctypePublicID = BS -> Text
t (BS -> Text) -> Maybe BS -> Maybe Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe BS
domDoctypePublicID
    , htmlDoctypeSystemID :: Maybe Text
htmlDoctypeSystemID = BS -> Text
t (BS -> Text) -> Maybe BS -> Maybe Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe BS
domDoctypeSystemID
    }
  go DOMFragment {Int
BS
Seq Int
domFragmentChildren :: DOMNode -> Seq Int
domFragmentName :: DOMNode -> BS
domFragmentParent :: DOMNode -> Int
domFragmentID :: DOMNode -> Int
domFragmentChildren :: Seq Int
domFragmentName :: BS
domFragmentParent :: Int
domFragmentID :: Int
..} = HTMLFragment :: Text -> [HTMLNode] -> HTMLNode
HTMLFragment
    { htmlFragmentName :: Text
htmlFragmentName     = BS -> Text
t BS
domFragmentName
    , htmlFragmentChildren :: [HTMLNode]
htmlFragmentChildren = Seq Int -> [HTMLNode]
f Seq Int
domFragmentChildren
    }
  go DOMElement {Int
BS
Seq Int
Seq DOMAttr
HTMLNamespace
domElementChildren :: DOMNode -> Seq Int
domElementAttributes :: DOMNode -> Seq DOMAttr
domElementNamespace :: DOMNode -> HTMLNamespace
domElementName :: DOMNode -> BS
domElementParent :: DOMNode -> Int
domElementID :: DOMNode -> Int
domElementChildren :: Seq Int
domElementAttributes :: Seq DOMAttr
domElementNamespace :: HTMLNamespace
domElementName :: BS
domElementParent :: Int
domElementID :: Int
..} = HTMLElement :: Text -> HTMLNamespace -> [HTMLAttr] -> [HTMLNode] -> HTMLNode
HTMLElement
    { htmlElementName :: Text
htmlElementName       = BS -> Text
t BS
domElementName
    , htmlElementNamespace :: HTMLNamespace
htmlElementNamespace  = HTMLNamespace
domElementNamespace
    , htmlElementAttributes :: [HTMLAttr]
htmlElementAttributes = Seq DOMAttr -> [HTMLAttr]
h Seq DOMAttr
domElementAttributes
    , htmlElementChildren :: [HTMLNode]
htmlElementChildren   = Seq Int -> [HTMLNode]
f Seq Int
domElementChildren
    }
  go DOMTemplate {Int
Seq DOMAttr
HTMLNamespace
domTemplateContents :: DOMNode -> Int
domTemplateAttributes :: DOMNode -> Seq DOMAttr
domTemplateNamespace :: DOMNode -> HTMLNamespace
domTemplateParent :: DOMNode -> Int
domTemplateID :: DOMNode -> Int
domTemplateContents :: Int
domTemplateAttributes :: Seq DOMAttr
domTemplateNamespace :: HTMLNamespace
domTemplateParent :: Int
domTemplateID :: Int
..} = HTMLTemplate :: HTMLNamespace -> [HTMLAttr] -> HTMLNode -> HTMLNode
HTMLTemplate
    { htmlTemplateNamespace :: HTMLNamespace
htmlTemplateNamespace  = HTMLNamespace
domTemplateNamespace
    , htmlTemplateAttributes :: [HTMLAttr]
htmlTemplateAttributes = Seq DOMAttr -> [HTMLAttr]
h Seq DOMAttr
domTemplateAttributes
    , htmlTemplateContents :: HTMLNode
htmlTemplateContents   = Int -> HTMLNode
g Int
domTemplateContents
    }
  go DOMText {Int
BS
domTextData :: DOMNode -> BS
domTextParent :: DOMNode -> Int
domTextID :: DOMNode -> Int
domTextData :: BS
domTextParent :: Int
domTextID :: Int
..} = HTMLText :: Text -> HTMLNode
HTMLText
    { htmlTextData :: Text
htmlTextData = BS -> Text
t BS
domTextData
    }
  go DOMComment {Int
BS
domCommentData :: DOMNode -> BS
domCommentParent :: DOMNode -> Int
domCommentID :: DOMNode -> Int
domCommentData :: BS
domCommentParent :: Int
domCommentID :: Int
..} = HTMLComment :: Text -> HTMLNode
HTMLComment
    { htmlCommentData :: Text
htmlCommentData = BS -> Text
t BS
domCommentData
    }
  f :: Seq Int -> [HTMLNode]
f = (DOMNode -> HTMLNode) -> [DOMNode] -> [HTMLNode]
forall a b. (a -> b) -> [a] -> [b]
map DOMNode -> HTMLNode
go ([DOMNode] -> [HTMLNode])
-> (Seq Int -> [DOMNode]) -> Seq Int -> [HTMLNode]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DOM -> [Int] -> [DOMNode]
domMapID DOM
d ([Int] -> [DOMNode]) -> (Seq Int -> [Int]) -> Seq Int -> [DOMNode]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Seq Int -> [Int]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList
  g :: Int -> HTMLNode
g = DOMNode -> HTMLNode
go (DOMNode -> HTMLNode) -> (Int -> DOMNode) -> Int -> HTMLNode
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe DOMNode -> DOMNode
forall a. HasCallStack => Maybe a -> a
fromJust (Maybe DOMNode -> DOMNode)
-> (Int -> Maybe DOMNode) -> Int -> DOMNode
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DOM -> Int -> Maybe DOMNode
domGetNode DOM
d
  h :: Seq DOMAttr -> [HTMLAttr]
h = (DOMAttr -> HTMLAttr) -> [DOMAttr] -> [HTMLAttr]
forall a b. (a -> b) -> [a] -> [b]
map DOMAttr -> HTMLAttr
attr ([DOMAttr] -> [HTMLAttr])
-> (Seq DOMAttr -> [DOMAttr]) -> Seq DOMAttr -> [HTMLAttr]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Seq DOMAttr -> [DOMAttr]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList
  t :: BS -> Text
t = BS -> Text
T.decodeUtf8
  attr :: DOMAttr -> HTMLAttr
attr (DOMAttr BS
n BS
v HTMLAttrNamespace
s) = Text -> Text -> HTMLAttrNamespace -> HTMLAttr
HTMLAttr (BS -> Text
t BS
n) (BS -> Text
t BS
v) HTMLAttrNamespace
s