From 77846542f5f6de5bffee3dacdd04b4a91f6d2a63 Mon Sep 17 00:00:00 2001 From: Teo Fonrouge Date: Tue, 25 May 2010 00:09:08 +0000 Subject: [PATCH] 2010-05-24 19:08 UTC-0500 Teo Fonrouge (teo/at/windtelsoft/dot/com) * contrib/hbtip/thtml.prg --- harbour/ChangeLog | 3 ++ harbour/contrib/hbtip/thtml.prg | 82 +++++++++------------------------ 2 files changed, 25 insertions(+), 60 deletions(-) diff --git a/harbour/ChangeLog b/harbour/ChangeLog index d102dcf700..fbfc51b6b9 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -2,6 +2,9 @@ * $Id$ */ +2010-05-24 19:08 UTC-0500 Teo Fonrouge (teo/at/windtelsoft/dot/com) + * contrib/hbtip/thtml.prg + /* Use this format for entry headers: YYYY-MM-DD HH:MM UTC[-|+]hhmm Your Full Name (your_email address) 2010-12-31 13:59 UTC+0100 Foo Bar (foo.bar foobar.org) diff --git a/harbour/contrib/hbtip/thtml.prg b/harbour/contrib/hbtip/thtml.prg index ed986c980b..481c68c3d2 100644 --- a/harbour/contrib/hbtip/thtml.prg +++ b/harbour/contrib/hbtip/thtml.prg @@ -57,8 +57,6 @@ // A Html document can have more than 16 nesting levels. // The current implementation of FOR EACH is not suitable for the HTML classes -#define FOR_EACH_NESTING_LIMIT_IS_ONLY_16_AND_FAR_TOO_SMALL - // Directives for a light weight html parser #xtrans P_PARSER( ) => {,0,Len(),0} #define P_STR 1 // the string to parse @@ -1018,7 +1016,7 @@ METHOD prevNode() CLASS THtmlNode // creates HTML code for this node METHOD toString( nIndent ) CLASS THtmlNode - LOCAL cIndent, cHtml := "", oNode, i, imax + LOCAL cIndent, cHtml := "", oNode IF ::htmlTagName == "_text_" // a leaf has no child nodes @@ -1036,7 +1034,7 @@ METHOD toString( nIndent ) CLASS THtmlNode IF ! ::isInline() .OR. ::htmlTagName == "!--" cHtml += cIndent ELSEIF ::keepFormatting() - cHtml += Chr( 13 ) + Chr( 10 ) + cHtml += hb_osNewLine() ENDIF cHtml += "<" + ::htmlTagName + ::attrToString() @@ -1047,23 +1045,12 @@ METHOD toString( nIndent ) CLASS THtmlNode IF ISARRAY( ::htmlContent ) -#ifdef FOR_EACH_NESTING_LIMIT_IS_ONLY_16_AND_FAR_TOO_SMALL - imax := Len( ::htmlContent ) - FOR i := 1 TO imax - oNode := ::htmlContent[ i ] - IF ! oNode:isInline() .OR. oNode:htmlTagName == "!--" - cHtml += Chr( 13 ) + Chr( 10 ) - ENDIF - cHtml += oNode:toString( nIndent + 1 ) - NEXT -#else FOR EACH oNode IN ::htmlContent IF ! oNode:isInline() .OR. oNode:htmlTagName == "!--" - cHtml += Xhr( 13 ) + Chr( 10 ) + cHtml += hb_osNewLine() ENDIF cHtml += oNode:toString( nIndent + 1 ) NEXT -#endif ELSEIF ISCHARACTER( ::htmlContent ) cHtml += ::htmlContent @@ -1073,12 +1060,12 @@ METHOD toString( nIndent ) CLASS THtmlNode IF ::isInline() .OR. ::keepFormatting() .OR. ::isType( CM_HEADING ) .OR. ::isType( CM_HEAD ) RETURN cHtml += iif( ::htmlEndTagName == "/", " />", "<" + ::htmlEndTagName + ">" ) ENDIF - IF !( Right( cHtml, 1 ) == Chr( 10 ) ) - cHtml += Chr( 13 ) + Chr( 10 ) + IF !( Right( cHtml, Len( hb_osNewLine() ) ) == hb_osNewLine() ) + cHtml += hb_osNewLine() ENDIF RETURN cHtml += cIndent + iif( ::htmlEndTagName == "/", " />", "<" + ::htmlEndTagName + ">" ) ELSEIF ::htmlTagName $ "!--,br" - RETURN cHtml += Chr( 13 ) + Chr( 10 ) + cIndent + RETURN cHtml += hb_osNewLine() + cIndent ENDIF RETURN cHtml @@ -1139,25 +1126,6 @@ METHOD collect( oEndNode ) CLASS THtmlNode RETURN stack[ S_DATA ] -#ifdef FOR_EACH_NESTING_LIMIT_IS_ONLY_16_AND_FAR_TOO_SMALL - -STATIC FUNCTION __CollectTags( oTHtmlNode, stack, oEndNode ) - LOCAL i, imax - S_PUSH( stack, oTHtmlNode ) - - IF oTHtmlNode:isNode() .AND. ! oTHtmlNode == oEndNode - imax := Len( oTHtmlNode:htmlContent ) - FOR i := 1 TO imax - __CollectTags( oTHtmlNode:htmlContent[ i ], stack, oEndNode ) - NEXT - ENDIF - - RETURN stack - -#else - -// $HZ BUG: Unrecoverable error 9000: FOR EACH excessive nesting! - STATIC FUNCTION __CollectTags( oTHtmlNode, stack, oEndNode ) LOCAL oSubNode @@ -1170,12 +1138,11 @@ STATIC FUNCTION __CollectTags( oTHtmlNode, stack, oEndNode ) ENDIF RETURN stack -#endif // Retrieves the textual content of a node METHOD getText( cEOL ) CLASS THtmlNode LOCAL cText := "" - LOCAL oNode, i, imax + LOCAL oNode IF cEOL == NIL cEOL := hb_osNewLine() @@ -1185,21 +1152,6 @@ METHOD getText( cEOL ) CLASS THtmlNode RETURN RTrim( ::htmlContent ) + cEOL ENDIF -#ifdef FOR_EACH_NESTING_LIMIT_IS_ONLY_16_AND_FAR_TOO_SMALL - - imax := Len( ::htmlContent ) - FOR i := 1 TO imax - oNode := ::htmlContent[ i ] - cText += oNode:getText( cEOL ) - IF Lower( ::htmlTagName ) $ "td,th" .AND. AScan( ::parent:htmlContent, {| o | o == Self } ) < Len( ::parent:htmlContent ) - // leave table rows in one line, cells separated by Tab - cText := SubStr( cText, 1, Len( cText ) - Len( cEol ) ) - cText += Chr( 9 ) - ENDIF - NEXT - -#else - FOR EACH oNode IN ::htmlContent cText += oNode:getText( cEOL ) IF Lower( ::htmlTagName ) $ "td,th" .AND. AScan( ::parent:htmlContent, {| o | o == Self } ) < Len( ::parent:htmlContent ) @@ -1209,8 +1161,6 @@ METHOD getText( cEOL ) CLASS THtmlNode ENDIF NEXT -#endif - RETURN cText // Returns the value of an HTML attribute @@ -1305,7 +1255,7 @@ STATIC FUNCTION __ParseAttr( parser ) parser:p_pos-- EXIT - CASE '"' + CASE Chr( 34 ) CASE "'" lIsQuoted := .T. parser:p_end := parser:p_pos @@ -1557,15 +1507,27 @@ METHOD pushNode( cTagName ) CLASS THtmlNode // called by "-" operator // returns the parent of this node and raises error if cName is an invalid closing tag METHOD popNode( cName ) CLASS THtmlNode - cName := LTrim( cName ) + LOCAL endTag + cName := Lower( LTrim( cName ) ) IF Left( cName, 1 ) == "/" cName := SubStr( cName, 2 ) ENDIF - IF !( Lower( cName ) == Lower( ::htmlTagName ) ) + IF !( cName == Lower( ::htmlTagName ) ) RETURN ::error( "Invalid closing HTML tag for: <" + ::htmlTagName + ">", ::className(), "-", EG_ARG, { cName } ) ENDIF + + /* tfonrouge: 2010-05-25 + this allows to properly close the tags "tr,th,td" by simply using: + node - ["tr","th","td"] + */ + IF AScan( {"tr","th","td"}, cName ) > 0 + endTag := "" + IF !Right( ::toString(), 3 + Len( cName ) ) == endTag + ::addNode( THtmlNode():new( Self, "/"+cName, , ) ) + ENDIF + ENDIF RETURN Self:parent