)`      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_ SafeLookup an entity, using  if it starts with # and  otherwise%Lookup a numeric entity, the leading '#' must have already been removed. =lookupNumericEntity "65" == Just "A" lookupNumericEntity "x41" == Just "A" lookupNumericEntity "x4E" === Just "N" lookupNumericEntity "x4e" === Just "N" lookupNumericEntity "X4e" === Just "N" lookupNumericEntity "Haskell" == Nothing lookupNumericEntity "" == Nothing lookupNumericEntity "89439085908539082" == NothingLookup a named entity, using  JlookupNamedEntity "amp" == Just "&" lookupNamedEntity "haskell" == NothingEscape an XML string. YescapeXML "hello world" == "hello world" escapeXML "hello & world" == "hello &amp; world"gA table mapping XML entity names to resolved strings. All strings are a single character long. Does not include apos- as Internet Explorer does not know about it.|A table mapping HTML entity names to resolved strings. Most resolved strings are a single character long, but some (e.g. "ngeqq"5) are two characters long. The list is taken from  Ahttp://www.w3.org/TR/html5/syntax.html#named-character-references.Safe35 vA class to generalise TagSoup parsing over many types of string-like types. Examples are given for the String type.  empty = ""  cons = (:) 4uncons [] = Nothing uncons (x:xs) = Just (x, xs)  toString = id fromChar = return strConcat = concat strNull = null  append = (++)*Convert a String from one type to another. `abcd     `abcdSafe+DA single HTML element. A whole document is represented by a list of Tag!. There is no requirement for  and  to match.An open tag with s in their original order A closing tag2A text node, guaranteed not to be the empty string A comment&Meta: A syntax error in the input file&Meta: The position of a parsed element'The column of a position, starting at 1)The row/line of a position, starting at 1An HTML attribute  id="name" generates  ("id","name") Test if a  is a  Test if a  is a  Test if a  is a Extract the string from within  , otherwise eExtract the string from within , crashes if not a  GExtract all text content from tags (similar to Verbatim found in HaXml)! Test if a  is a "Extract the string from within  , otherwise e# Test if a  is a $'Extract an attribute, crashes if not a  . Returns "" if no attribute present.%Returns True if the  is  and matches the given name&Returns True if the  is  and matches the given name' Test if a  is a fghijk !"#$%&'lfghijk !"#$%&'fghijk !"#$%&'lSafe(Match an opening tagExamplesMatching an opening <a> tag with a "btn" class:(let tag = TagOpen "a" [("class", "btn")]@tagOpen (== "a") (\attrs -> any (== ("class", "btn")) attrs) tagTrue)Match a closing tagExamplesMatching a closing </a> tag: tagClose (== "a") (TagClose "a")True"tagClose (== "a") (TagOpen "a" [])False*Match text tagsExamplesMatch all text tags:1let tags = parseTags "<p>This is a paragraph</p>";[TagOpen "p" [],TagText "This is a paragraph",TagClose "p"]"filter (tagText (const True)) tags[TagText "This is a paragraph"]+Match comment tagsExamples7Matching comment tags that include an exclamation mark:/let tags = parseTags "<!--This is a comment-->"![TagComment "This is a comment!"]*all (tagComment (\s -> '!' `elem` s)) tagsTrue,%Match an opening tag's name literallyExamples Matching <a> tags with the id "foo":%let tag = TagOpen "a" [("id", "foo")]TagOpen "a" [("id","foo")];tagOpenLit "a" (\attrs -> any (== ("id", "foo")) attrs) tagTrue-$Match a closing tag's name literallyExamplesMatch a closing <a> tag:tagCloseLit "a" (TagClose "a")TruetagCloseLit "a" (TagClose "em")False.IMatch an opening tag's name literally, and at least one of its attributesExamples Matching a <div> tag with the id "foo":BtagOpenAttrLit "div" ("id", "foo") (TagOpen "div" [("id", "foo")])True/Match a tag with given name, that contains an attribute with given name, that satisfies a predicate. If an attribute occurs multiple times, all occurrences are checked.Examples Matching an <a>, tag with an ID that starts with "comment-":6let commentTag = TagOpen "a" [("id", "comment-45678")]^tagOpenAttrNameLit "a" "id" (\idValue -> "comment-" `Data.List.isPrefixOf` idValue) commentTagTrue0Check if the 'Tag str' is  and matches the given nameExamples Matching an <a> tag:#tagOpenNameLit "a" (TagOpen "a" [])True%tagOpenNameLit "a" (TagOpen "div" [])False1Check if the 'Tag str' is  and matches the given nameExamplesMatching a closing </a> tag:"tagCloseNameLit "a" (TagClose "a")True$tagCloseNameLit "a" (TagClose "div")False22Does any attribute name/value match the predicate.3,Does any attribute name match the predicate.4-Does any attribute value match the predicate.5$Does any attribute name/value match.6Does any attribute name match.7Does any attribute value match.8TGet the tags under tags with a given name where the attributes match some predicate.()*+,-./012345678()*+,-./012345678()*+,-./012345678()*+,-./012345678Safe+ 9These options control how  parseTags works. The 9( type is usually generated by one of A, B or @(, then selected fields may be overriden. The options ; and < specify whether to generate  or ? elements respectively. Usually these options should be set to False to simplify future stages, unless you rely on position information or want to give malformed HTML messages to the end user. The options = and ># control how entities, for example &nbsp;: are handled. Both take a string, and a boolean, where True3 indicates that the entity ended with a semi-colon ;. Inside normal text =_ will be called, and the results will be inserted in the tag stream. Inside a tag attribute > will be called, and the first component of the result will be used in the attribute, and the second component will be appended after the + value (usually the second component is []3). As an example, to not decode any entities, pass: parseOptions {optEntityData=\(str,b) -> [TagText $ "&" ++ str ++ [';' | b]] ,optEntityAttrib\(str,b) -> ("&" ++ str ++ [';' | b], []);Should > values be given before some items (default=False,fast=False).<Should + values be given (default=False,fast=False)=+How to lookup an entity (Bool = has ending ';')>;How to lookup an entity in an attribute (Bool = has ending ';'?)?Require no adjacent ! values (default=True,fast=False)@A 9w structure using a custom function to lookup attributes. Any attribute that is not found will be left intact, and a  given (if < is set).9If you do not want to resolve any entities, simpliy pass  const Nothing for the lookup function.A.The default parse options value, described in 9. Equivalent to @ .BA 9; structure optimised for speed, following the fast options.m'Change the underlying string type of a 9 value. 9:;<=>?@ABm 9:;<=>?@ABm9:;<=>?@ABmSafeGN8nopqrstuvwxyz{|}~6nopqrstuvwxyz{|}~!nopqrstuvwxyz{|}~o  SafeG/+ Safe Safe SafeGCThese options control how J works.%The strange quirk of only minimizing <br>. tags is due to Internet Explorer treating  <br></br> as <br><br>.E=Escape a piece of text (default = escape the four characters &"<>)F2Minimise <b></b> -> <b/> (default = minimise only <br> tags)GAShould a tag be output with no escaping (default = true only for script)HReplace the four characters &"<> with their HTML entities ( lifted to ).I/The default render options value, described in C.J\Show a list of tags, as they might have been parsed, using the default settings given in C. ZrenderTags [TagOpen "hello" [],TagText "my&",TagClose "world"] == "<hello>my&amp;</world>"K3Show a list of tags using settings supplied by the CA parameter, eg. to avoid escaping any characters one could do: HrenderTagsOptions renderOptions{optEscape = id} [TagText "my&"] == "my&" CDEFGHIJK CDEFGHIJKCDEFGHIJK SafeLCParse a string to a list of tags, using an HTML 5 compliant parser. YparseTags "<hello>my&amp;</world>" == [TagOpen "hello" [],TagText "my&",TagClose "world"]MAParse a string to a list of tags, using settings supplied by the 92 parameter, eg. to output position information: parseTagsOptions parseOptions{optTagPosition = True} "<hello>my&amp;</world>" == [TagPosition 1 1,TagOpen "hello" [],TagPosition 1 8,TagText "my&",TagPosition 1 15,TagClose "world"]LM 9:;<=>?@ABLMLMSafe35GNCDefine a class to allow String's or Tag str's to be used as matchesOConvert a value into a .PWTurns all tag names and attributes to lower case and converts DOCTYPE to upper case.QPerforms an inexact match, the first item should be the thing to match. If the second item is a blank string, that is considered to match anything. For example: (TagText "test" ~== TagText "" ) == True (TagText "test" ~== TagText "test") == True (TagText "test" ~== TagText "soup") == FalseFor - missing attributes on the right are allowed.R Negation of QS_This function takes a list, and returns all suffixes whose first item matches the predicate.TThis function is similar to SE, but splits the list so no element appears in any two partitions. NOPQRST3 !"#$%&'9:;<=>?@ABCDEFGHIJKLMNOPQRST3LM9:;<=>?AB@JKHCDEFGIP!#%&'$" STNOQRNOPQRSTNone U A tree of  values.VA 'TagOpen'/'TagClose' pair with the  values in between.W Any leaf nodeXdConvert a list of tags into a tree. This version is not lazy at all, that is saved for version 2.YBuild a U from a string.ZBuild a U from a string, specifying the 9.[ Flatten a U back to a list of .\ Render a U.] Render a U with some C.^(This operation is based on the Uniplate universeu function. Given a list of trees, it returns those trees, and all the children trees at any level. For example: universeTree [TagBranch "a" [("href","url")] [TagBranch "b" [] [TagLeaf (TagText "text")]]] == [TagBranch "a" [("href","url")] [TagBranch "b" [] [TagLeaf (TagText "text")]]] ,TagBranch "b" [] [TagLeaf (TagText "text")]]BThis operation is particularly useful for queries. To collect all "a" tags in a tree, simply do: 0[x | x@(TagBranch "a" _ _) <- universeTree tree]_(This operation is based on the Uniplate  transform function. Given a list of trees, it applies the function to every tree in a bottom-up manner. This operation is useful for manipulating a tree - for example to make all tag names upper case: upperCase = transformTree f where f (TagBranch name atts inner) = [TagBranch (map toUpper name) atts inner] f x = [x] UVWXYZ[\]^_9:;<=>?CDEFGUVWXYZ[\]^_UVWXYZ9:;<=>?[\]CDEFG_^ UVWXYZ[\]^_ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIIJKLMNOPQ R R S T U V W X Y Z [\]^_`abcdefghijklmnopqrstuuvwxyz{|}~~!       8 [AJcTLfuFLg815eqFBOjUwhText.StringLikeText.HTML.TagSoup.EntityText.HTML.TagSoupText.HTML.TagSoup.MatchText.HTML.TagSoup.TreeText.HTML.TagSoup.TypeText.HTML.TagSoup.Options Text.HTML.TagSoup.ImplementationText.HTML.TagSoup.SpecificationText.HTML.TagSoup.ManualText.HTML.TagSoup.GeneratedText.HTML.TagSoup.RenderText.HTML.TagSoup.Parserbase Data.String fromString lookupEntitylookupNumericEntitylookupNamedEntity escapeXML xmlEntities htmlEntities StringLikeemptyconsunconstoStringfromChar strConcatstrNullappend castStringTagTagOpenTagCloseTagText TagComment TagWarning TagPositionColumnRow Attribute isTagOpen isTagClose isTagText maybeTagText fromTagText innerText isTagWarningmaybeTagWarning isTagPosition fromAttrib isTagOpenNameisTagCloseName isTagCommenttagOpentagClosetagText tagComment tagOpenLit tagCloseLittagOpenAttrLittagOpenAttrNameLittagOpenNameLittagCloseNameLitanyAttr anyAttrName anyAttrValue anyAttrLitanyAttrNameLitanyAttrValueLit getTagContent ParseOptionsoptTagPosition optTagWarning optEntityDataoptEntityAttriboptTagTextMergeparseOptionsEntities parseOptionsparseOptionsFast RenderOptions optEscape optMinimize optRawTag escapeHTML renderOptions renderTagsrenderTagsOptions parseTagsparseTagsOptionsTagReptoTagRepcanonicalizeTags~==~/=sections partitionsTagTree TagBranchTagLeaftagTree parseTreeparseTreeOptions flattenTree renderTreerenderTreeOptions universeTree transformTree$fStringLikeText$fStringLikeText0$fStringLikeByteString$fStringLikeByteString0$fStringLike[]GHC.BaseNothingPosition nullPositionpositionString positionChar tagPosition $fFunctorTagfmapParseOptionsOutable&SstlhdeofnextposOutCharTagShutAttNameAttValTagEnd TagEndCloseComment CommentEnd EntityName EntityNum EntityHex EntityEndWarnPoserrSeenerrWantexpandampCharampOutstateoutput entityChrisEofisCharisTag isTagShut isAttNameisAttValisTagEnd isTagEndClose isComment isCommentEnd isEntityNameisEntityNumHex isEntityNum isEntityHex isEntityEndisWarnfromChrfromWarn getEntityEnd tagTextMerge $fOutableOut $fOutableCharParserTypeTag TypeNormalTypeXmlTypeDecl TypeScriptwhiteparsedat charReferenceisScriptneilXmlTagOpenneilXmlTagClose neilTagEndneilScriptBody closeTagOpentagName beforeAttNameattName afterAttNamebeforeAttValueattValueDQuotedattValueSQuotedattValueUnquotedcharRefAttValueafterAttValueQuotedselfClosingStartTag bogusComment bogusComment1markupDeclOpen commentStartcommentStartDashcommentcommentEndDash commentEndcommentEndBangcommentEndSpace cdataSectioncharRef charRefNum charRefNum2 charRefNum3 charRefAlpha charRefAlpha2 alphaCharhexChar $fTagRep[] $fTagRepTag flattenTreeFB$fFunctorTagTree