1
1
/* istack.c -- inline stack for compatibility with Mosaic
3
(c) 1998-2004 (W3C) MIT, ERCIM, Keio University
3
(c) 1998-2006 (W3C) MIT, ERCIM, Keio University
4
4
See tidy.h for the copyright notice.
9
$Date: 2004/12/06 12:53:25 $
9
$Date: 2006/12/29 16:31:08 $
18
18
#include "tmbstr.h"
20
20
/* duplicate attributes */
21
AttVal *DupAttrs( TidyDocImpl* doc, AttVal *attrs)
21
AttVal *TY_(DupAttrs)( TidyDocImpl* doc, AttVal *attrs)
28
newattrs = NewAttribute();
28
newattrs = TY_(NewAttribute)(doc);
29
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;
30
newattrs->next = TY_(DupAttrs)( doc, attrs->next );
31
newattrs->attribute = TY_(tmbstrdup)(doc->allocator, attrs->attribute);
32
newattrs->value = TY_(tmbstrdup)(doc->allocator, attrs->value);
33
newattrs->dict = TY_(FindAttribute)(doc, newattrs);
34
newattrs->asp = attrs->asp ? TY_(CloneNode)(doc, attrs->asp) : NULL;
35
newattrs->php = attrs->php ? TY_(CloneNode)(doc, attrs->php) : NULL;
39
static Bool IsNodePushable( Node *node )
41
if (node->tag == NULL)
44
if (!(node->tag->model & CM_INLINE))
47
if (node->tag->model & CM_OBJECT)
40
54
push a copy of an inline node onto stack
41
55
but don't push if implicit or OBJECT or APPLET
79
87
lexer->istacklength = 6; /* this is perhaps excessive */
81
89
lexer->istacklength = lexer->istacklength * 2;
82
lexer->istack = (IStack *)MemRealloc(lexer->istack,
90
lexer->istack = (IStack *)TidyDocRealloc(doc, lexer->istack,
83
91
sizeof(IStack)*(lexer->istacklength));
86
94
istack = &(lexer->istack[lexer->istacksize]);
87
95
istack->tag = node->tag;
89
istack->element = tmbstrdup(node->element);
90
istack->attributes = DupAttrs( doc, node->attributes );
97
istack->element = TY_(tmbstrdup)(doc->allocator, node->element);
98
istack->attributes = TY_(DupAttrs)( doc, node->attributes );
91
99
++(lexer->istacksize);
102
static void PopIStack( TidyDocImpl* doc )
104
Lexer* lexer = doc->lexer;
108
--(lexer->istacksize);
109
istack = &(lexer->istack[lexer->istacksize]);
111
while (istack->attributes)
113
av = istack->attributes;
114
istack->attributes = av->next;
115
TY_(FreeAttribute)( doc, av );
117
TidyDocFree(doc, istack->element);
120
static void PopIStackUntil( TidyDocImpl* doc, TidyTagId tid )
122
Lexer* lexer = doc->lexer;
125
while (lexer->istacksize > 0)
128
istack = &(lexer->istack[lexer->istacksize]);
129
if ( istack->tag->id == tid )
94
134
/* pop inline stack */
95
void PopInline( TidyDocImpl* doc, Node *node )
135
void TY_(PopInline)( TidyDocImpl* doc, Node *node )
97
137
Lexer* lexer = doc->lexer;
103
if (node->tag == NULL)
106
if (!(node->tag->model & CM_INLINE))
109
if (node->tag->model & CM_OBJECT)
141
if ( !IsNodePushable(node) )
112
144
/* if node is </a> then pop until we find an <a> */
113
145
if ( nodeIsA(node) )
115
while (lexer->istacksize > 0)
117
--(lexer->istacksize);
118
istack = &(lexer->istack[lexer->istacksize]);
120
while (istack->attributes)
122
av = istack->attributes;
123
istack->attributes = av->next;
124
FreeAttribute( doc, av );
127
if ( istack->tag->id == TidyTag_A )
129
MemFree(istack->element);
133
MemFree(istack->element);
147
PopIStackUntil( doc, TidyTag_A );
140
152
if (lexer->istacksize > 0)
142
--(lexer->istacksize);
143
istack = &(lexer->istack[lexer->istacksize]);
145
while (istack->attributes)
147
av = istack->attributes;
148
istack->attributes = av->next;
149
FreeAttribute( doc, av );
152
MemFree(istack->element);
154
156
/* #427822 - fix by Randy Waki 7 Aug 00 */
155
157
if (lexer->insert >= lexer->istack + lexer->istacksize)
177
Test whether the last element on the stack has the same type than "node".
179
Bool TY_(IsPushedLast)( TidyDocImpl* doc, Node *element, Node *node )
181
Lexer* lexer = doc->lexer;
183
if ( element && !IsNodePushable(element) )
186
if (lexer->istacksize > 0) {
187
if (lexer->istack[lexer->istacksize - 1].tag == node->tag) {
175
196
This has the effect of inserting "missing" inline
176
197
elements around the contents of blocklevel elements
177
198
such as P, TD, TH, DIV, PRE etc. This procedure is
206
227
defer duplicates when entering a table or other
207
228
element where the inlines shouldn't be duplicated
209
void DeferDup( TidyDocImpl* doc )
230
void TY_(DeferDup)( TidyDocImpl* doc )
211
232
doc->lexer->insert = NULL;
212
233
doc->lexer->inode = NULL;
215
Node *InsertedToken( TidyDocImpl* doc )
236
Node *TY_(InsertedToken)( TidyDocImpl* doc )
217
238
Lexer* lexer = doc->lexer;
252
272
fprintf( stderr, "0-size istack!\n" );
255
node->element = tmbstrdup(istack->element);
275
node->element = TY_(tmbstrdup)(doc->allocator, istack->element);
256
276
node->tag = istack->tag;
257
node->attributes = DupAttrs( doc, istack->attributes );
277
node->attributes = TY_(DupAttrs)( doc, istack->attributes );
259
279
/* advance lexer to next item on the stack */
260
280
n = (uint)(lexer->insert - &(lexer->istack[0]));
293
We have two CM_INLINE elements pushed ... the first is closing,
294
but, like the browser, the second should be retained ...
295
Like <b>bold <i>bold and italics</b> italics only</i>
296
This function switches the tag positions on the stack,
297
returning 'yes' if both were found in the expected order.
299
Bool TY_(SwitchInline)( TidyDocImpl* doc, Node* element, Node* node )
301
Lexer* lexer = doc->lexer;
303
&& element && element->tag
305
&& TY_(IsPushed)( doc, element )
306
&& TY_(IsPushed)( doc, node )
307
&& ((lexer->istacksize - lexer->istackbase) >= 2) )
309
/* we have a chance of succeeding ... */
311
for (i = (lexer->istacksize - lexer->istackbase - 1); i >= 0; --i)
313
if (lexer->istack[i].tag == element->tag) {
314
/* found the element tag - phew */
315
IStack *istack1 = &lexer->istack[i];
316
IStack *istack2 = NULL;
317
--i; /* back one more, and continue */
320
if (lexer->istack[i].tag == node->tag)
322
/* found the element tag - phew */
323
istack2 = &lexer->istack[i];
329
/* perform the swap */
330
IStack tmp_istack = *istack2;
332
*istack1 = tmp_istack;
342
We want to push a specific a specific element on the stack,
343
but it may not be the last element, which InlineDup()
344
would handle. Return yes, if found and inserted.
346
Bool TY_(InlineDup1)( TidyDocImpl* doc, Node* node, Node* element )
348
Lexer* lexer = doc->lexer;
351
&& (element->tag != NULL)
352
&& ((n = lexer->istacksize - lexer->istackbase) > 0) )
354
for ( i = n - 1; i >=0; --i ) {
355
if (lexer->istack[i].tag == element->tag) {
356
/* found our element tag - insert it */
357
lexer->insert = &(lexer->istack[i]);
369
* indent-tabs-mode: nil
371
* eval: (c-set-offset 'substatement-open 0)