~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

TidyLib
tidy/src/istack.c

Version: ~ [ 1.0 ] ~

** Warning: Cannot open xref database.

1 /* istack.c -- inline stack for compatibility with Mosaic 2 3 (c) 1998-2004 (W3C) MIT, ERCIM, Keio University 4 See tidy.h for the copyright notice. 5 6 CVS Info : 7 8 $Author: arnaud02 $ 9 $Date: 2004/12/06 12:53:25 $ 10 $Revision: 1.16 $ 11 12 */ 13 14 #include "tidy-int.h" 15 #include "lexer.h" 16 #include "attrs.h" 17 #include "streamio.h" 18 #include "tmbstr.h" 19 20 /* duplicate attributes */ 21 AttVal *DupAttrs( TidyDocImpl* doc, AttVal *attrs) 22 { 23 AttVal *newattrs; 24 25 if (attrs == NULL) 26 return attrs; 27 28 newattrs = NewAttribute(); 29 *newattrs = *attrs; 30 newattrs->next = DupAttrs( doc, attrs->next ); 31 newattrs->attribute = tmbstrdup(attrs->attribute); 32 newattrs->value = tmbstrdup(attrs->value); 33 newattrs->dict = FindAttribute(doc, newattrs); 34 newattrs->asp = attrs->asp ? CloneNode(doc, attrs->asp) : NULL; 35 newattrs->php = attrs->php ? CloneNode(doc, attrs->php) : NULL; 36 return newattrs; 37 } 38 39 /* 40 push a copy of an inline node onto stack 41 but don't push if implicit or OBJECT or APPLET 42 (implicit tags are ones generated from the istack) 43 44 One issue arises with pushing inlines when 45 the tag is already pushed. For instance: 46 47 <p><em>text 48 <p><em>more text 49 50 Shouldn't be mapped to 51 52 <p><em>text</em></p> 53 <p><em><em>more text</em></em> 54 */ 55 void PushInline( TidyDocImpl* doc, Node *node) 56 { 57 Lexer* lexer = doc->lexer; 58 IStack *istack; 59 60 if (node->implicit) 61 return; 62 63 if (node->tag == NULL) 64 return; 65 66 if (!(node->tag->model & CM_INLINE)) 67 return; 68 69 if (node->tag->model & CM_OBJECT) 70 return; 71 72 if ( !nodeIsFONT(node) && IsPushed(doc, node) ) 73 return; 74 75 /* make sure there is enough space for the stack */ 76 if (lexer->istacksize + 1 > lexer->istacklength) 77 { 78 if (lexer->istacklength == 0) 79 lexer->istacklength = 6; /* this is perhaps excessive */ 80 81 lexer->istacklength = lexer->istacklength * 2; 82 lexer->istack = (IStack *)MemRealloc(lexer->istack, 83 sizeof(IStack)*(lexer->istacklength)); 84 } 85 86 istack = &(lexer->istack[lexer->istacksize]); 87 istack->tag = node->tag; 88 89 istack->element = tmbstrdup(node->element); 90 istack->attributes = DupAttrs( doc, node->attributes ); 91 ++(lexer->istacksize); 92 } 93 94 /* pop inline stack */ 95 void PopInline( TidyDocImpl* doc, Node *node ) 96 { 97 Lexer* lexer = doc->lexer; 98 AttVal *av; 99 IStack *istack; 100 101 if (node) 102 { 103 if (node->tag == NULL) 104 return; 105 106 if (!(node->tag->model & CM_INLINE)) 107 return; 108 109 if (node->tag->model & CM_OBJECT) 110 return; 111 112 /* if node is </a> then pop until we find an <a> */ 113 if ( nodeIsA(node) ) 114 { 115 while (lexer->istacksize > 0) 116 { 117 --(lexer->istacksize); 118 istack = &(lexer->istack[lexer->istacksize]); 119 120 while (istack->attributes) 121 { 122 av = istack->attributes; 123 istack->attributes = av->next; 124 FreeAttribute( doc, av ); 125 } 126 127 if ( istack->tag->id == TidyTag_A ) 128 { 129 MemFree(istack->element); 130 break; 131 } 132 133 MemFree(istack->element); 134 } 135 136 return; 137 } 138 } 139 140 if (lexer->istacksize > 0) 141 { 142 --(lexer->istacksize); 143 istack = &(lexer->istack[lexer->istacksize]); 144 145 while (istack->attributes) 146 { 147 av = istack->attributes; 148 istack->attributes = av->next; 149 FreeAttribute( doc, av ); 150 } 151 152 MemFree(istack->element); 153 154 /* #427822 - fix by Randy Waki 7 Aug 00 */ 155 if (lexer->insert >= lexer->istack + lexer->istacksize) 156 lexer->insert = NULL; 157 } 158 } 159 160 Bool IsPushed( TidyDocImpl* doc, Node *node) 161 { 162 Lexer* lexer = doc->lexer; 163 int i; 164 165 for (i = lexer->istacksize - 1; i >= 0; --i) 166 { 167 if (lexer->istack[i].tag == node->tag) 168 return yes; 169 } 170 171 return no; 172 } 173 174 /* 175 This has the effect of inserting "missing" inline 176 elements around the contents of blocklevel elements 177 such as P, TD, TH, DIV, PRE etc. This procedure is 178 called at the start of ParseBlock. when the inline 179 stack is not empty, as will be the case in: 180 181 <i><h1>italic heading</h1></i> 182 183 which is then treated as equivalent to 184 185 <h1><i>italic heading</i></h1> 186 187 This is implemented by setting the lexer into a mode 188 where it gets tokens from the inline stack rather than 189 from the input stream. 190 */ 191 int InlineDup( TidyDocImpl* doc, Node* node ) 192 { 193 Lexer* lexer = doc->lexer; 194 int n; 195 196 if ((n = lexer->istacksize - lexer->istackbase) > 0) 197 { 198 lexer->insert = &(lexer->istack[lexer->istackbase]); 199 lexer->inode = node; 200 } 201 202 return n; 203 } 204 205 /* 206 defer duplicates when entering a table or other 207 element where the inlines shouldn't be duplicated 208 */ 209 void DeferDup( TidyDocImpl* doc ) 210 { 211 doc->lexer->insert = NULL; 212 doc->lexer->inode = NULL; 213 } 214 215 Node *InsertedToken( TidyDocImpl* doc ) 216 { 217 Lexer* lexer = doc->lexer; 218 Node *node; 219 IStack *istack; 220 uint n; 221 222 /* this will only be NULL if inode != NULL */ 223 if (lexer->insert == NULL) 224 { 225 node = lexer->inode; 226 lexer->inode = NULL; 227 return node; 228 } 229 230 /* 231 232 is this is the "latest" node then update 233 the position, otherwise use current values 234 */ 235 236 if (lexer->inode == NULL) 237 { 238 lexer->lines = doc->docIn->curline; 239 lexer->columns = doc->docIn->curcol; 240 } 241 242 node = NewNode(lexer); 243 node->type = StartTag; 244 node->implicit = yes; 245 node->start = lexer->txtstart; 246 /* #431734 [JTidy bug #226261 (was 126261)] - fix by Gary Peskin 20 Dec 00 */ 247 node->end = lexer->txtend; /* was : lexer->txtstart; */ 248 istack = lexer->insert; 249 250 #if 0 && defined(_DEBUG) 251 if ( lexer->istacksize == 0 ) 252 fprintf( stderr, "0-size istack!\n" ); 253 #endif 254 255 node->element = tmbstrdup(istack->element); 256 node->tag = istack->tag; 257 node->attributes = DupAttrs( doc, istack->attributes ); 258 259 /* advance lexer to next item on the stack */ 260 n = (uint)(lexer->insert - &(lexer->istack[0])); 261 262 /* and recover state if we have reached the end */ 263 if (++n < lexer->istacksize) 264 lexer->insert = &(lexer->istack[n]); 265 else 266 lexer->insert = NULL; 267 268 return node; 269 } 270 271 272 273 274

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.