+ tAttrPair[] aAttributes
+Class cHTMLParser is a cObject
+ Function isHTMLSpace String sInp Returns Boolean
+ Function_Return ((Trim(sInp))="")
+ Function tokenizeTags String sText Returns String[]
+ Move "" to sCurrentToken
+ Move (AddressOf(sText)) to pText
+ Move (Length(sText)) to iMax
+ For iPos from 0 to (iMax-1)
+ Move (Character(DeRefC(pText,iPos))) to sChar
+ If ((sType = "space") and (sChar = '"') ) Begin
+ Move "double-quote" to sType
+ Else If ((sType = "space") and (sChar = "'") ) Begin
+ Move "single-quote" to sType
+ Else If ((sType = "space") and (sChar = "=") ) Begin
+ If (sCurrentToken<>"") Move sCurrentToken to Tokens[(SizeOfArray(Tokens))]
+ Move "=" to Tokens[(SizeOfArray(Tokens))]
+ Move "" to sCurrentToken
+ Else If ((sType = "space") and (not(isHTMLSpace(Self,sChar))) ) Begin
+ If (sCurrentToken<>"") Move sCurrentToken to Tokens[(SizeOfArray(Tokens))]
+ Move sChar to sCurrentToken
+ Else If ((sType = "text") and (isHTMLSpace(Self,sChar)) ) Begin
+ If (sCurrentToken<>"") Move sCurrentToken to Tokens[(SizeOfArray(Tokens))]
+ Move "" to sCurrentToken
+ Else If ((sType = "text") and (sChar = "=") ) Begin
+ If (sCurrentToken<>"") Move sCurrentToken to Tokens[(SizeOfArray(Tokens))]
+ Move "=" to Tokens[(SizeOfArray(Tokens))]
+ Move "" to sCurrentToken
+ Else If ((sType="single-quote") and (sChar="'")) Begin
+ If (sCurrentToken<>"") Move sCurrentToken to Tokens[(SizeOfArray(Tokens))]
+ Move "" to sCurrentToken
+ Else If ((sType="double-quote") and (sChar='"')) Begin
+ If (sCurrentToken<>"") Move sCurrentToken to Tokens[(SizeOfArray(Tokens))]
+ Move "" to sCurrentToken
+ Else Append sCurrentToken sChar
+ If (sCurrentToken<>"") Move sCurrentToken to Tokens[(SizeOfArray(Tokens))]
+ Function ParseHTMLTag String sText Returns tTagData
+ //strip angle brackets......
+ Move (Length(sText)) to iMax
+ Move (Mid(sText,(iMax-2),2)) to sText
+ Move (False) to tagData.isAloneTag
+ If ((right(sText,1))="/") Begin
+ Move (True) to tagData.isAloneTag
+ Move (Length(sText)) to iMax
+ Move (Left(sText,(iMax-1))) to sText
+ Move (tokenizeTags(Self,sText)) to Tokens
+ Move (SizeOfArray(Tokens)) to iMax
+ Move "" to Tokens[iMax+1] //stop any overflow when looking ahead.
+ Move Tokens[0] to tagData.sValue
+ If (Tokens[iPos] <> "") Begin
+ Move Tokens[iPos] to tagData.aAttributes[iAttrNo].sAttr
+ If (Tokens[iPos + 1] = "=") Begin
+ Move Tokens[iPos+2] to tagData.aAttributes[iAttrNo].sValue
+ Move True to tagData.aAttributes[iAttrNo].isAssigned
+ Else Move False to tagData.aAttributes[iAttrNo].isAssigned
+ Move (iAttrNo+1) to iAttrNo
+ Function_Return tagData
+ Function ParseHTML String sText Returns tParsedHTML[]
+ Move "" to sCurrentToken
+ Move (AddressOf(sText)) to pText
+ Move (Length(sText)) to iMax
+ For iPos from 0 to (iMax-1)
+ Move (Character(DeRefC(pText,iPos))) to sChar
+ If ((sChar = "<") and (sType="text")) Begin
+ Move (Trim(sCurrentToken)) to sCurrentToken
+ If (sCurrentToken <>"") Begin
+ Move (SizeOfArray(aParsed)) to iTokenPos
+ Move sCurrentToken to aParsed[iTokenPos].sValue
+ Move sType to aParsed[iTokenPos].sType
+ Move "" to sCurrentToken
+ Append sCurrentToken sChar
+ Else If ((sChar = ">") and (sType="tag")) Begin
+ Append sCurrentToken sChar
+ Move (SizeOfArray(aParsed)) to iTokenPos
+ Move sCurrentToken to aParsed[iTokenPos].sValue
+ Move sType to aParsed[iTokenPos].sType
+ Move "" to sCurrentToken
+ Append sCurrentToken sChar
+ Move (Trim(sCurrentToken)) to sCurrentToken
+ If (sCurrentToken<>"") Begin
+ Move (SizeOfArray(aParsed)) to iTokenPos
+ Move sCurrentToken to aParsed[iTokenPos].sValue
+ Move sType to aParsed[ iTokenPos ].sType
+ Move (SizeOfArray(aParsed)) to iMax
+ For iPos from 0 to (iMax-1)
+ If (aParsed[iPos].sType = "tag") Get ParseHTMLTag aParsed[iPos].sValue to aParsed[iPos].tagData
+ Function_Return aParsed
+ Function SplitHTML String sInp Returns tParsedHTML[]
+ Function_Return (ParseHTML(Self,sInp))
+ Function QuoteIfNeeded String sText Returns String
+ Move (False) to isQuotable
+ Move (AddressOf(sText)) to pText
+ Move (Length(sText)) to iMax
+ For iPos from 0 to (iMax-1)
+ Move (Character(DeRefC(pText,iPos))) to sChar
+ Move (Lowercase(sChar)) to sChar
+ If ((pos(sChar,"abcdefghijlkmnopqrstuvwxyz01234567890"))=0) Move (True) to isQuotable
+ If (sChar = '"') Move "'" to sQuoteCode
+ If (isQuotable) Move (sQuoteCode+sText+sQuoteCode) to sText
+ Function TagToHtml tTagData tag Returns String
+ Move (SizeOfArray(tag.aAttributes)) to iMax
+ For iPos from 0 to (iMax-1)
+ Append sRet " " tag.aAttributes[iPos].sAttr
+ If (tag.aAttributes[iPos].isAssigned) Begin
+ Append sRet "=" (QuoteIfNeeded(Self,tag.aAttributes[iPos].sValue))
+ If (tag.isAloneTag) Append sRet "/>"
+ Function toHTML tParsedHTML[] Parsed Returns String
+ tParsedHTML HtmlFragment
+ Move (SizeOfArray(Parsed)) to iMax
+ For iPos from 0 to (iMax-1)
+ Move parsed[iPos] to HtmlFragment
+ If (HtmlFragment.sType = "tag") Append sRet (TagToHtml(Self,HtmlFragment.tagdata))
+ If (HtmlFragment.sType = "text") Append sRet HtmlFragment.sValue
+ Function toFlatHTML tParsedHTML[] Parsed Returns String
+ tParsedHTML HtmlFragment
+ Move (SizeOfArray(Parsed)) to iMax
+ For iPos from 0 to (iMax-1)
+ Move parsed[iPos] to HtmlFragment
+ If (HtmlFragment.sType = "tag") Append sRet (TagToHtml(Self,HtmlFragment.tagdata))
+ If (HtmlFragment.sType = "text") Append sRet HtmlFragment.sValue