tidy-ext 0.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. data/.gitignore +4 -0
  2. data/LICENSE +50 -0
  3. data/README +12 -0
  4. data/Rakefile +60 -0
  5. data/VERSION +1 -0
  6. data/ext/tidy/access.c +3310 -0
  7. data/ext/tidy/access.h +279 -0
  8. data/ext/tidy/alloc.c +107 -0
  9. data/ext/tidy/attrask.c +209 -0
  10. data/ext/tidy/attrdict.c +2398 -0
  11. data/ext/tidy/attrdict.h +122 -0
  12. data/ext/tidy/attrget.c +213 -0
  13. data/ext/tidy/attrs.c +1911 -0
  14. data/ext/tidy/attrs.h +374 -0
  15. data/ext/tidy/buffio.c +232 -0
  16. data/ext/tidy/buffio.h +118 -0
  17. data/ext/tidy/charsets.c +1032 -0
  18. data/ext/tidy/charsets.h +14 -0
  19. data/ext/tidy/clean.c +2674 -0
  20. data/ext/tidy/clean.h +87 -0
  21. data/ext/tidy/config.c +1746 -0
  22. data/ext/tidy/config.h +153 -0
  23. data/ext/tidy/entities.c +419 -0
  24. data/ext/tidy/entities.h +24 -0
  25. data/ext/tidy/extconf.rb +5 -0
  26. data/ext/tidy/fileio.c +106 -0
  27. data/ext/tidy/fileio.h +46 -0
  28. data/ext/tidy/forward.h +69 -0
  29. data/ext/tidy/iconvtc.c +105 -0
  30. data/ext/tidy/iconvtc.h +15 -0
  31. data/ext/tidy/istack.c +373 -0
  32. data/ext/tidy/lexer.c +3825 -0
  33. data/ext/tidy/lexer.h +617 -0
  34. data/ext/tidy/localize.c +1882 -0
  35. data/ext/tidy/mappedio.c +329 -0
  36. data/ext/tidy/mappedio.h +16 -0
  37. data/ext/tidy/message.h +207 -0
  38. data/ext/tidy/parser.c +4408 -0
  39. data/ext/tidy/parser.h +76 -0
  40. data/ext/tidy/platform.h +636 -0
  41. data/ext/tidy/pprint.c +2276 -0
  42. data/ext/tidy/pprint.h +93 -0
  43. data/ext/tidy/ruby-tidy.c +195 -0
  44. data/ext/tidy/streamio.c +1407 -0
  45. data/ext/tidy/streamio.h +222 -0
  46. data/ext/tidy/tagask.c +286 -0
  47. data/ext/tidy/tags.c +955 -0
  48. data/ext/tidy/tags.h +235 -0
  49. data/ext/tidy/tidy-int.h +129 -0
  50. data/ext/tidy/tidy.h +1097 -0
  51. data/ext/tidy/tidyenum.h +622 -0
  52. data/ext/tidy/tidylib.c +1751 -0
  53. data/ext/tidy/tmbstr.c +306 -0
  54. data/ext/tidy/tmbstr.h +92 -0
  55. data/ext/tidy/utf8.c +539 -0
  56. data/ext/tidy/utf8.h +52 -0
  57. data/ext/tidy/version.h +14 -0
  58. data/ext/tidy/win32tc.c +795 -0
  59. data/ext/tidy/win32tc.h +19 -0
  60. data/spec/spec_helper.rb +5 -0
  61. data/spec/tidy/compat_spec.rb +44 -0
  62. data/spec/tidy/remote_uri_spec.rb +14 -0
  63. data/spec/tidy/test1.html +5 -0
  64. data/spec/tidy/tidy_spec.rb +34 -0
  65. metadata +125 -0
@@ -0,0 +1,1751 @@
1
+ /* tidylib.c -- internal library definitions
2
+
3
+ (c) 1998-2008 (W3C) MIT, ERCIM, Keio University
4
+ See tidy.h for the copyright notice.
5
+
6
+ CVS Info :
7
+
8
+ $Author: arnaud02 $
9
+ $Date: 2008/06/18 20:18:54 $
10
+ $Revision: 1.75 $
11
+
12
+ Defines HTML Tidy API implemented by tidy library.
13
+
14
+ Very rough initial cut for discussion purposes.
15
+
16
+ Public interface is const-correct and doesn't explicitly depend
17
+ on any globals. Thus, thread-safety may be introduced w/out
18
+ changing the interface.
19
+
20
+ Looking ahead to a C++ wrapper, C functions always pass
21
+ this-equivalent as 1st arg.
22
+
23
+ Created 2001-05-20 by Charles Reitzel
24
+
25
+ */
26
+
27
+ #include <errno.h>
28
+
29
+ #include "tidy-int.h"
30
+ #include "parser.h"
31
+ #include "clean.h"
32
+ #include "config.h"
33
+ #include "message.h"
34
+ #include "pprint.h"
35
+ #include "entities.h"
36
+ #include "tmbstr.h"
37
+ #include "utf8.h"
38
+ #include "mappedio.h"
39
+
40
+ #ifdef TIDY_WIN32_MLANG_SUPPORT
41
+ #include "win32tc.h"
42
+ #endif
43
+
44
+ /* Create/Destroy a Tidy "document" object */
45
+ static TidyDocImpl* tidyDocCreate( TidyAllocator *allocator );
46
+ static void tidyDocRelease( TidyDocImpl* impl );
47
+
48
+ static int tidyDocStatus( TidyDocImpl* impl );
49
+
50
+ /* Parse Markup */
51
+ static int tidyDocParseFile( TidyDocImpl* impl, ctmbstr htmlfil );
52
+ static int tidyDocParseStdin( TidyDocImpl* impl );
53
+ static int tidyDocParseString( TidyDocImpl* impl, ctmbstr content );
54
+ static int tidyDocParseBuffer( TidyDocImpl* impl, TidyBuffer* inbuf );
55
+ static int tidyDocParseSource( TidyDocImpl* impl, TidyInputSource* docIn );
56
+
57
+
58
+ /* Execute post-parse diagnostics and cleanup.
59
+ ** Note, the order is important. You will get different
60
+ ** results from the diagnostics depending on if they are run
61
+ ** pre-or-post repair.
62
+ */
63
+ static int tidyDocRunDiagnostics( TidyDocImpl* doc );
64
+ static int tidyDocCleanAndRepair( TidyDocImpl* doc );
65
+
66
+
67
+ /* Save cleaned up file to file/buffer/sink */
68
+ static int tidyDocSaveFile( TidyDocImpl* impl, ctmbstr htmlfil );
69
+ static int tidyDocSaveStdout( TidyDocImpl* impl );
70
+ static int tidyDocSaveString( TidyDocImpl* impl, tmbstr buffer, uint* buflen );
71
+ static int tidyDocSaveBuffer( TidyDocImpl* impl, TidyBuffer* outbuf );
72
+ static int tidyDocSaveSink( TidyDocImpl* impl, TidyOutputSink* docOut );
73
+ static int tidyDocSaveStream( TidyDocImpl* impl, StreamOut* out );
74
+
75
+ #ifdef NEVER
76
+ TidyDocImpl* tidyDocToImpl( TidyDoc tdoc )
77
+ {
78
+ return (TidyDocImpl*) tdoc;
79
+ }
80
+ TidyDoc tidyImplToDoc( TidyDocImpl* impl )
81
+ {
82
+ return (TidyDoc) impl;
83
+ }
84
+
85
+ Node* tidyNodeToImpl( TidyNode tnod )
86
+ {
87
+ return (Node*) tnod;
88
+ }
89
+ TidyNode tidyImplToNode( Node* node )
90
+ {
91
+ return (TidyNode) node;
92
+ }
93
+
94
+ AttVal* tidyAttrToImpl( TidyAttr tattr )
95
+ {
96
+ return (AttVal*) tattr;
97
+ }
98
+ TidyAttr tidyImplToAttr( AttVal* attval )
99
+ {
100
+ return (TidyAttr) attval;
101
+ }
102
+
103
+ const TidyOptionImpl* tidyOptionToImpl( TidyOption topt )
104
+ {
105
+ return (const TidyOptionImpl*) topt;
106
+ }
107
+ TidyOption tidyImplToOption( const TidyOptionImpl* option )
108
+ {
109
+ return (TidyOption) option;
110
+ }
111
+ #endif
112
+
113
+ /* Tidy public interface
114
+ **
115
+ ** Most functions return an integer:
116
+ **
117
+ ** 0 -> SUCCESS
118
+ ** >0 -> WARNING
119
+ ** <0 -> ERROR
120
+ **
121
+ */
122
+
123
+ TidyDoc TIDY_CALL tidyCreate(void)
124
+ {
125
+ TidyDocImpl* impl = tidyDocCreate( &TY_(g_default_allocator) );
126
+ return tidyImplToDoc( impl );
127
+ }
128
+
129
+ TidyDoc TIDY_CALL tidyCreateWithAllocator( TidyAllocator *allocator )
130
+ {
131
+ TidyDocImpl* impl = tidyDocCreate( allocator );
132
+ return tidyImplToDoc( impl );
133
+ }
134
+
135
+ void TIDY_CALL tidyRelease( TidyDoc tdoc )
136
+ {
137
+ TidyDocImpl* impl = tidyDocToImpl( tdoc );
138
+ tidyDocRelease( impl );
139
+ }
140
+
141
+ TidyDocImpl* tidyDocCreate( TidyAllocator *allocator )
142
+ {
143
+ TidyDocImpl* doc = (TidyDocImpl*)TidyAlloc( allocator, sizeof(TidyDocImpl) );
144
+ TidyClearMemory( doc, sizeof(*doc) );
145
+ doc->allocator = allocator;
146
+
147
+ TY_(InitMap)();
148
+ TY_(InitTags)( doc );
149
+ TY_(InitAttrs)( doc );
150
+ TY_(InitConfig)( doc );
151
+ TY_(InitPrintBuf)( doc );
152
+
153
+ /* By default, wire tidy messages to standard error.
154
+ ** Document input will be set by parsing routines.
155
+ ** Document output will be set by pretty print routines.
156
+ ** Config input will be set by config parsing routines.
157
+ ** But we need to start off with a way to report errors.
158
+ */
159
+ doc->errout = TY_(StdErrOutput)();
160
+ return doc;
161
+ }
162
+
163
+ void tidyDocRelease( TidyDocImpl* doc )
164
+ {
165
+ /* doc in/out opened and closed by parse/print routines */
166
+ if ( doc )
167
+ {
168
+ assert( doc->docIn == NULL );
169
+ assert( doc->docOut == NULL );
170
+
171
+ TY_(ReleaseStreamOut)( doc, doc->errout );
172
+ doc->errout = NULL;
173
+
174
+ TY_(FreePrintBuf)( doc );
175
+ TY_(FreeLexer)( doc );
176
+ TY_(FreeNode)(doc, &doc->root);
177
+ TidyClearMemory(&doc->root, sizeof(Node));
178
+
179
+ if (doc->givenDoctype)
180
+ TidyDocFree(doc, doc->givenDoctype);
181
+
182
+ TY_(FreeConfig)( doc );
183
+ TY_(FreeAttrTable)( doc );
184
+ TY_(FreeTags)( doc );
185
+ TidyDocFree( doc, doc );
186
+ }
187
+ }
188
+
189
+ /* Let application store a chunk of data w/ each Tidy tdocance.
190
+ ** Useful for callbacks.
191
+ */
192
+ void TIDY_CALL tidySetAppData( TidyDoc tdoc, void* appData )
193
+ {
194
+ TidyDocImpl* impl = tidyDocToImpl( tdoc );
195
+ if ( impl )
196
+ impl->appData = appData;
197
+ }
198
+ void* TIDY_CALL tidyGetAppData( TidyDoc tdoc )
199
+ {
200
+ TidyDocImpl* impl = tidyDocToImpl( tdoc );
201
+ if ( impl )
202
+ return impl->appData;
203
+ return NULL;
204
+ }
205
+
206
+ ctmbstr TIDY_CALL tidyReleaseDate(void)
207
+ {
208
+ return TY_(ReleaseDate)();
209
+ }
210
+
211
+
212
+ /* Get/set configuration options
213
+ */
214
+ Bool TIDY_CALL tidySetOptionCallback( TidyDoc tdoc, TidyOptCallback pOptCallback )
215
+ {
216
+ TidyDocImpl* impl = tidyDocToImpl( tdoc );
217
+ if ( impl )
218
+ {
219
+ impl->pOptCallback = pOptCallback;
220
+ return yes;
221
+ }
222
+ return no;
223
+ }
224
+
225
+
226
+ int TIDY_CALL tidyLoadConfig( TidyDoc tdoc, ctmbstr cfgfil )
227
+ {
228
+ TidyDocImpl* impl = tidyDocToImpl( tdoc );
229
+ if ( impl )
230
+ return TY_(ParseConfigFile)( impl, cfgfil );
231
+ return -EINVAL;
232
+ }
233
+
234
+ int TIDY_CALL tidyLoadConfigEnc( TidyDoc tdoc, ctmbstr cfgfil, ctmbstr charenc )
235
+ {
236
+ TidyDocImpl* impl = tidyDocToImpl( tdoc );
237
+ if ( impl )
238
+ return TY_(ParseConfigFileEnc)( impl, cfgfil, charenc );
239
+ return -EINVAL;
240
+ }
241
+
242
+ int TIDY_CALL tidySetCharEncoding( TidyDoc tdoc, ctmbstr encnam )
243
+ {
244
+ TidyDocImpl* impl = tidyDocToImpl( tdoc );
245
+ if ( impl )
246
+ {
247
+ int enc = TY_(CharEncodingId)( impl, encnam );
248
+ if ( enc >= 0 && TY_(AdjustCharEncoding)(impl, enc) )
249
+ return 0;
250
+
251
+ TY_(ReportBadArgument)( impl, "char-encoding" );
252
+ }
253
+ return -EINVAL;
254
+ }
255
+
256
+ int TIDY_CALL tidySetInCharEncoding( TidyDoc tdoc, ctmbstr encnam )
257
+ {
258
+ TidyDocImpl* impl = tidyDocToImpl( tdoc );
259
+ if ( impl )
260
+ {
261
+ int enc = TY_(CharEncodingId)( impl, encnam );
262
+ if ( enc >= 0 && TY_(SetOptionInt)( impl, TidyInCharEncoding, enc ) )
263
+ return 0;
264
+
265
+ TY_(ReportBadArgument)( impl, "in-char-encoding" );
266
+ }
267
+ return -EINVAL;
268
+ }
269
+
270
+ int TIDY_CALL tidySetOutCharEncoding( TidyDoc tdoc, ctmbstr encnam )
271
+ {
272
+ TidyDocImpl* impl = tidyDocToImpl( tdoc );
273
+ if ( impl )
274
+ {
275
+ int enc = TY_(CharEncodingId)( impl, encnam );
276
+ if ( enc >= 0 && TY_(SetOptionInt)( impl, TidyOutCharEncoding, enc ) )
277
+ return 0;
278
+
279
+ TY_(ReportBadArgument)( impl, "out-char-encoding" );
280
+ }
281
+ return -EINVAL;
282
+ }
283
+
284
+ TidyOptionId TIDY_CALL tidyOptGetIdForName( ctmbstr optnam )
285
+ {
286
+ const TidyOptionImpl* option = TY_(lookupOption)( optnam );
287
+ if ( option )
288
+ return option->id;
289
+ return N_TIDY_OPTIONS; /* Error */
290
+ }
291
+
292
+ TidyIterator TIDY_CALL tidyGetOptionList( TidyDoc tdoc )
293
+ {
294
+ TidyDocImpl* impl = tidyDocToImpl( tdoc );
295
+ if ( impl )
296
+ return TY_(getOptionList)( impl );
297
+ return (TidyIterator) -1;
298
+ }
299
+
300
+ TidyOption TIDY_CALL tidyGetNextOption( TidyDoc tdoc, TidyIterator* pos )
301
+ {
302
+ TidyDocImpl* impl = tidyDocToImpl( tdoc );
303
+ const TidyOptionImpl* option = NULL;
304
+ if ( impl )
305
+ option = TY_(getNextOption)( impl, pos );
306
+ else if ( pos )
307
+ *pos = 0;
308
+ return tidyImplToOption( option );
309
+ }
310
+
311
+
312
+ TidyOption TIDY_CALL tidyGetOption( TidyDoc ARG_UNUSED(tdoc), TidyOptionId optId )
313
+ {
314
+ const TidyOptionImpl* option = TY_(getOption)( optId );
315
+ return tidyImplToOption( option );
316
+ }
317
+ TidyOption TIDY_CALL tidyGetOptionByName( TidyDoc ARG_UNUSED(doc), ctmbstr optnam )
318
+ {
319
+ const TidyOptionImpl* option = TY_(lookupOption)( optnam );
320
+ return tidyImplToOption( option );
321
+ }
322
+
323
+ TidyOptionId TIDY_CALL tidyOptGetId( TidyOption topt )
324
+ {
325
+ const TidyOptionImpl* option = tidyOptionToImpl( topt );
326
+ if ( option )
327
+ return option->id;
328
+ return N_TIDY_OPTIONS;
329
+ }
330
+ ctmbstr TIDY_CALL tidyOptGetName( TidyOption topt )
331
+ {
332
+ const TidyOptionImpl* option = tidyOptionToImpl( topt );
333
+ if ( option )
334
+ return option->name;
335
+ return NULL;
336
+ }
337
+ TidyOptionType TIDY_CALL tidyOptGetType( TidyOption topt )
338
+ {
339
+ const TidyOptionImpl* option = tidyOptionToImpl( topt );
340
+ if ( option )
341
+ return option->type;
342
+ return (TidyOptionType) -1;
343
+ }
344
+ TidyConfigCategory TIDY_CALL tidyOptGetCategory( TidyOption topt )
345
+ {
346
+ const TidyOptionImpl* option = tidyOptionToImpl( topt );
347
+ if ( option )
348
+ return option->category;
349
+ return (TidyConfigCategory) -1;
350
+ }
351
+ ctmbstr TIDY_CALL tidyOptGetDefault( TidyOption topt )
352
+ {
353
+ const TidyOptionImpl* option = tidyOptionToImpl( topt );
354
+ if ( option && option->type == TidyString )
355
+ return (ctmbstr) option->dflt;
356
+ return NULL;
357
+ }
358
+ ulong TIDY_CALL tidyOptGetDefaultInt( TidyOption topt )
359
+ {
360
+ const TidyOptionImpl* option = tidyOptionToImpl( topt );
361
+ if ( option && option->type != TidyString )
362
+ return option->dflt;
363
+ return ~0U;
364
+ }
365
+ Bool TIDY_CALL tidyOptGetDefaultBool( TidyOption topt )
366
+ {
367
+ const TidyOptionImpl* option = tidyOptionToImpl( topt );
368
+ if ( option && option->type != TidyString )
369
+ return ( option->dflt ? yes : no );
370
+ return no;
371
+ }
372
+ Bool TIDY_CALL tidyOptIsReadOnly( TidyOption topt )
373
+ {
374
+ const TidyOptionImpl* option = tidyOptionToImpl( topt );
375
+ if ( option )
376
+ return ( option->parser == NULL );
377
+ return yes;
378
+ }
379
+
380
+
381
+ TidyIterator TIDY_CALL tidyOptGetPickList( TidyOption topt )
382
+ {
383
+ const TidyOptionImpl* option = tidyOptionToImpl( topt );
384
+ if ( option )
385
+ return TY_(getOptionPickList)( option );
386
+ return (TidyIterator) -1;
387
+ }
388
+ ctmbstr TIDY_CALL tidyOptGetNextPick( TidyOption topt, TidyIterator* pos )
389
+ {
390
+ const TidyOptionImpl* option = tidyOptionToImpl( topt );
391
+ if ( option )
392
+ return TY_(getNextOptionPick)( option, pos );
393
+ return NULL;
394
+ }
395
+
396
+
397
+ ctmbstr TIDY_CALL tidyOptGetValue( TidyDoc tdoc, TidyOptionId optId )
398
+ {
399
+ TidyDocImpl* impl = tidyDocToImpl( tdoc );
400
+ ctmbstr optval = NULL;
401
+ if ( impl )
402
+ optval = cfgStr( impl, optId );
403
+ return optval;
404
+ }
405
+ Bool TIDY_CALL tidyOptSetValue( TidyDoc tdoc, TidyOptionId optId, ctmbstr val )
406
+ {
407
+ TidyDocImpl* impl = tidyDocToImpl( tdoc );
408
+ if ( impl )
409
+ return TY_(ParseConfigValue)( impl, optId, val );
410
+ return no;
411
+ }
412
+ Bool TIDY_CALL tidyOptParseValue( TidyDoc tdoc, ctmbstr optnam, ctmbstr val )
413
+ {
414
+ TidyDocImpl* impl = tidyDocToImpl( tdoc );
415
+ if ( impl )
416
+ return TY_(ParseConfigOption)( impl, optnam, val );
417
+ return no;
418
+ }
419
+
420
+ ulong TIDY_CALL tidyOptGetInt( TidyDoc tdoc, TidyOptionId optId )
421
+ {
422
+ TidyDocImpl* impl = tidyDocToImpl( tdoc );
423
+ ulong opti = 0;
424
+ if ( impl )
425
+ opti = cfg( impl, optId );
426
+ return opti;
427
+ }
428
+
429
+ Bool TIDY_CALL tidyOptSetInt( TidyDoc tdoc, TidyOptionId optId, ulong val )
430
+ {
431
+ TidyDocImpl* impl = tidyDocToImpl( tdoc );
432
+ if ( impl )
433
+ return TY_(SetOptionInt)( impl, optId, val );
434
+ return no;
435
+ }
436
+
437
+ Bool TIDY_CALL tidyOptGetBool( TidyDoc tdoc, TidyOptionId optId )
438
+ {
439
+ TidyDocImpl* impl = tidyDocToImpl( tdoc );
440
+ Bool optb = no;
441
+ if ( impl )
442
+ {
443
+ const TidyOptionImpl* option = TY_(getOption)( optId );
444
+ if ( option )
445
+ {
446
+ optb = cfgBool( impl, optId );
447
+ }
448
+ }
449
+ return optb;
450
+ }
451
+
452
+ Bool TIDY_CALL tidyOptSetBool( TidyDoc tdoc, TidyOptionId optId, Bool val )
453
+ {
454
+ TidyDocImpl* impl = tidyDocToImpl( tdoc );
455
+ if ( impl )
456
+ return TY_(SetOptionBool)( impl, optId, val );
457
+ return no;
458
+ }
459
+
460
+ ctmbstr TIDY_CALL tidyOptGetEncName( TidyDoc tdoc, TidyOptionId optId )
461
+ {
462
+ uint enc = tidyOptGetInt( tdoc, optId );
463
+ return TY_(CharEncodingOptName)( enc );
464
+ }
465
+
466
+ ctmbstr TIDY_CALL tidyOptGetCurrPick( TidyDoc tdoc, TidyOptionId optId )
467
+ {
468
+ const TidyOptionImpl* option = TY_(getOption)( optId );
469
+ if ( option && option->pickList )
470
+ {
471
+ uint ix, pick = tidyOptGetInt( tdoc, optId );
472
+ const ctmbstr* pL = option->pickList;
473
+ for ( ix=0; *pL && ix < pick; ++ix )
474
+ ++pL;
475
+ if ( *pL )
476
+ return *pL;
477
+ }
478
+ return NULL;
479
+ }
480
+
481
+
482
+ TidyIterator TIDY_CALL tidyOptGetDeclTagList( TidyDoc tdoc )
483
+ {
484
+ TidyDocImpl* impl = tidyDocToImpl( tdoc );
485
+ TidyIterator declIter = 0;
486
+ if ( impl )
487
+ declIter = TY_(GetDeclaredTagList)( impl );
488
+ return declIter;
489
+ }
490
+
491
+ ctmbstr TIDY_CALL tidyOptGetNextDeclTag( TidyDoc tdoc, TidyOptionId optId,
492
+ TidyIterator* iter )
493
+ {
494
+ TidyDocImpl* impl = tidyDocToImpl( tdoc );
495
+ ctmbstr tagnam = NULL;
496
+ if ( impl )
497
+ {
498
+ UserTagType tagtyp = tagtype_null;
499
+ if ( optId == TidyInlineTags )
500
+ tagtyp = tagtype_inline;
501
+ else if ( optId == TidyBlockTags )
502
+ tagtyp = tagtype_block;
503
+ else if ( optId == TidyEmptyTags )
504
+ tagtyp = tagtype_empty;
505
+ else if ( optId == TidyPreTags )
506
+ tagtyp = tagtype_pre;
507
+ if ( tagtyp != tagtype_null )
508
+ tagnam = TY_(GetNextDeclaredTag)( impl, tagtyp, iter );
509
+ }
510
+ return tagnam;
511
+ }
512
+
513
+ ctmbstr TIDY_CALL tidyOptGetDoc( TidyDoc ARG_UNUSED(tdoc), TidyOption opt )
514
+ {
515
+ const TidyOptionId optId = tidyOptGetId( opt );
516
+ const TidyOptionDoc* docDesc = TY_(OptGetDocDesc)( optId );
517
+ return docDesc ? docDesc->doc : NULL;
518
+ }
519
+
520
+ TidyIterator TIDY_CALL tidyOptGetDocLinksList( TidyDoc ARG_UNUSED(tdoc), TidyOption opt )
521
+ {
522
+ const TidyOptionId optId = tidyOptGetId( opt );
523
+ const TidyOptionDoc* docDesc = TY_(OptGetDocDesc)( optId );
524
+ if (docDesc && docDesc->links)
525
+ return (TidyIterator)docDesc->links;
526
+ return (TidyIterator)NULL;
527
+ }
528
+
529
+ TidyOption TIDY_CALL tidyOptGetNextDocLinks( TidyDoc tdoc, TidyIterator* pos )
530
+ {
531
+ const TidyOptionId* curr = (const TidyOptionId *)*pos;
532
+ TidyOption opt;
533
+
534
+ if (*curr == TidyUnknownOption)
535
+ {
536
+ *pos = (TidyIterator)NULL;
537
+ return (TidyOption)0;
538
+ }
539
+ opt = tidyGetOption(tdoc, *curr);
540
+ curr++;
541
+ *pos = (*curr == TidyUnknownOption ) ?
542
+ (TidyIterator)NULL:(TidyIterator)curr;
543
+ return opt;
544
+ }
545
+
546
+ int TIDY_CALL tidyOptSaveFile( TidyDoc tdoc, ctmbstr cfgfil )
547
+ {
548
+ TidyDocImpl* impl = tidyDocToImpl( tdoc );
549
+ if ( impl )
550
+ return TY_(SaveConfigFile)( impl, cfgfil );
551
+ return -EINVAL;
552
+ }
553
+
554
+ int TIDY_CALL tidyOptSaveSink( TidyDoc tdoc, TidyOutputSink* sink )
555
+ {
556
+ TidyDocImpl* impl = tidyDocToImpl( tdoc );
557
+ if ( impl )
558
+ return TY_(SaveConfigSink)( impl, sink );
559
+ return -EINVAL;
560
+ }
561
+
562
+ Bool TIDY_CALL tidyOptSnapshot( TidyDoc tdoc )
563
+ {
564
+ TidyDocImpl* impl = tidyDocToImpl( tdoc );
565
+ if ( impl )
566
+ {
567
+ TY_(TakeConfigSnapshot)( impl );
568
+ return yes;
569
+ }
570
+ return no;
571
+ }
572
+ Bool TIDY_CALL tidyOptResetToSnapshot( TidyDoc tdoc )
573
+ {
574
+ TidyDocImpl* impl = tidyDocToImpl( tdoc );
575
+ if ( impl )
576
+ {
577
+ TY_(ResetConfigToSnapshot)( impl );
578
+ return yes;
579
+ }
580
+ return no;
581
+ }
582
+ Bool TIDY_CALL tidyOptResetAllToDefault( TidyDoc tdoc )
583
+ {
584
+ TidyDocImpl* impl = tidyDocToImpl( tdoc );
585
+ if ( impl )
586
+ {
587
+ TY_(ResetConfigToDefault)( impl );
588
+ return yes;
589
+ }
590
+ return no;
591
+ }
592
+
593
+ Bool TIDY_CALL tidyOptResetToDefault( TidyDoc tdoc, TidyOptionId optId )
594
+ {
595
+ TidyDocImpl* impl = tidyDocToImpl( tdoc );
596
+ if ( impl )
597
+ return TY_(ResetOptionToDefault)( impl, optId );
598
+ return no;
599
+ }
600
+
601
+ Bool TIDY_CALL tidyOptDiffThanDefault( TidyDoc tdoc )
602
+ {
603
+ TidyDocImpl* impl = tidyDocToImpl( tdoc );
604
+ if ( impl )
605
+ return TY_(ConfigDiffThanDefault)( impl );
606
+ return no;
607
+ }
608
+ Bool TIDY_CALL tidyOptDiffThanSnapshot( TidyDoc tdoc )
609
+ {
610
+ TidyDocImpl* impl = tidyDocToImpl( tdoc );
611
+ if ( impl )
612
+ return TY_(ConfigDiffThanSnapshot)( impl );
613
+ return no;
614
+ }
615
+
616
+ Bool TIDY_CALL tidyOptCopyConfig( TidyDoc to, TidyDoc from )
617
+ {
618
+ TidyDocImpl* docTo = tidyDocToImpl( to );
619
+ TidyDocImpl* docFrom = tidyDocToImpl( from );
620
+ if ( docTo && docFrom )
621
+ {
622
+ TY_(CopyConfig)( docTo, docFrom );
623
+ return yes;
624
+ }
625
+ return no;
626
+ }
627
+
628
+
629
+ /* I/O and Message handling interface
630
+ **
631
+ ** By default, Tidy will define, create and use
632
+ ** tdocances of input and output handlers for
633
+ ** standard C buffered I/O (i.e. FILE* stdin,
634
+ ** FILE* stdout and FILE* stderr for content
635
+ ** input, content output and diagnostic output,
636
+ ** respectively. A FILE* cfgFile input handler
637
+ ** will be used for config files. Command line
638
+ ** options will just be set directly.
639
+ */
640
+
641
+ /* Use TidyReportFilter to filter messages by diagnostic level:
642
+ ** info, warning, etc. Just set diagnostic output
643
+ ** handler to redirect all diagnostics output. Return true
644
+ ** to proceed with output, false to cancel.
645
+ */
646
+ Bool TIDY_CALL tidySetReportFilter( TidyDoc tdoc, TidyReportFilter filt )
647
+ {
648
+ TidyDocImpl* impl = tidyDocToImpl( tdoc );
649
+ if ( impl )
650
+ {
651
+ impl->mssgFilt = filt;
652
+ return yes;
653
+ }
654
+ return no;
655
+ }
656
+
657
+ #if 0 /* Not yet */
658
+ int tidySetContentOutputSink( TidyDoc tdoc, TidyOutputSink* outp )
659
+ {
660
+ TidyDocImpl* impl = tidyDocToImpl( tdoc );
661
+ if ( impl )
662
+ {
663
+ impl->docOut = outp;
664
+ return 0;
665
+ }
666
+ return -EINVAL;
667
+ }
668
+ int tidySetDiagnosticOutputSink( TidyDoc tdoc, TidyOutputSink* outp )
669
+ {
670
+ TidyDocImpl* impl = tidyDocToImpl( tdoc );
671
+ if ( impl )
672
+ {
673
+ impl->msgOut = outp;
674
+ return 0;
675
+ }
676
+ return -EINVAL;
677
+ }
678
+
679
+
680
+ /* Library helpers
681
+ */
682
+ cmbstr tidyLookupMessage( TidyDoc tdoc, int errorNo )
683
+ {
684
+ TidyDocImpl* impl = tidyDocToImpl( tdoc );
685
+ cmbstr mssg = NULL;
686
+ if ( impl )
687
+ mssg = tidyMessage_Lookup( impl->messages, errorNo );
688
+ return mssg;
689
+ }
690
+ #endif
691
+
692
+
693
+ FILE* TIDY_CALL tidySetErrorFile( TidyDoc tdoc, ctmbstr errfilnam )
694
+ {
695
+ TidyDocImpl* impl = tidyDocToImpl( tdoc );
696
+ if ( impl )
697
+ {
698
+ FILE* errout = fopen( errfilnam, "wb" );
699
+ if ( errout )
700
+ {
701
+ uint outenc = cfg( impl, TidyOutCharEncoding );
702
+ uint nl = cfg( impl, TidyNewline );
703
+ TY_(ReleaseStreamOut)( impl, impl->errout );
704
+ impl->errout = TY_(FileOutput)( impl, errout, outenc, nl );
705
+ return errout;
706
+ }
707
+ else /* Emit message to current error sink */
708
+ TY_(FileError)( impl, errfilnam, TidyError );
709
+ }
710
+ return NULL;
711
+ }
712
+
713
+ int TIDY_CALL tidySetErrorBuffer( TidyDoc tdoc, TidyBuffer* errbuf )
714
+ {
715
+ TidyDocImpl* impl = tidyDocToImpl( tdoc );
716
+ if ( impl )
717
+ {
718
+ uint outenc = cfg( impl, TidyOutCharEncoding );
719
+ uint nl = cfg( impl, TidyNewline );
720
+ TY_(ReleaseStreamOut)( impl, impl->errout );
721
+ impl->errout = TY_(BufferOutput)( impl, errbuf, outenc, nl );
722
+ return ( impl->errout ? 0 : -ENOMEM );
723
+ }
724
+ return -EINVAL;
725
+ }
726
+
727
+ int TIDY_CALL tidySetErrorSink( TidyDoc tdoc, TidyOutputSink* sink )
728
+ {
729
+ TidyDocImpl* impl = tidyDocToImpl( tdoc );
730
+ if ( impl )
731
+ {
732
+ uint outenc = cfg( impl, TidyOutCharEncoding );
733
+ uint nl = cfg( impl, TidyNewline );
734
+ TY_(ReleaseStreamOut)( impl, impl->errout );
735
+ impl->errout = TY_(UserOutput)( impl, sink, outenc, nl );
736
+ return ( impl->errout ? 0 : -ENOMEM );
737
+ }
738
+ return -EINVAL;
739
+ }
740
+
741
+
742
+ /* Document info */
743
+ int TIDY_CALL tidyStatus( TidyDoc tdoc )
744
+ {
745
+ TidyDocImpl* impl = tidyDocToImpl( tdoc );
746
+ int tidyStat = -EINVAL;
747
+ if ( impl )
748
+ tidyStat = tidyDocStatus( impl );
749
+ return tidyStat;
750
+ }
751
+ int TIDY_CALL tidyDetectedHtmlVersion( TidyDoc ARG_UNUSED(tdoc) )
752
+ {
753
+ /* TidyDocImpl* impl = tidyDocToImpl( tdoc ); */
754
+ return 0;
755
+ }
756
+ Bool TIDY_CALL tidyDetectedXhtml( TidyDoc ARG_UNUSED(tdoc) )
757
+ {
758
+ /* TidyDocImpl* impl = tidyDocToImpl( tdoc ); */
759
+ return no;
760
+ }
761
+ Bool TIDY_CALL tidyDetectedGenericXml( TidyDoc ARG_UNUSED(tdoc) )
762
+ {
763
+ /* TidyDocImpl* impl = tidyDocToImpl( tdoc ); */
764
+ return no;
765
+ }
766
+
767
+ uint TIDY_CALL tidyErrorCount( TidyDoc tdoc )
768
+ {
769
+ TidyDocImpl* impl = tidyDocToImpl( tdoc );
770
+ uint count = 0xFFFFFFFF;
771
+ if ( impl )
772
+ count = impl->errors;
773
+ return count;
774
+ }
775
+ uint TIDY_CALL tidyWarningCount( TidyDoc tdoc )
776
+ {
777
+ TidyDocImpl* impl = tidyDocToImpl( tdoc );
778
+ uint count = 0xFFFFFFFF;
779
+ if ( impl )
780
+ count = impl->warnings;
781
+ return count;
782
+ }
783
+ uint TIDY_CALL tidyAccessWarningCount( TidyDoc tdoc )
784
+ {
785
+ TidyDocImpl* impl = tidyDocToImpl( tdoc );
786
+ uint count = 0xFFFFFFFF;
787
+ if ( impl )
788
+ count = impl->accessErrors;
789
+ return count;
790
+ }
791
+ uint TIDY_CALL tidyConfigErrorCount( TidyDoc tdoc )
792
+ {
793
+ TidyDocImpl* impl = tidyDocToImpl( tdoc );
794
+ uint count = 0xFFFFFFFF;
795
+ if ( impl )
796
+ count = impl->optionErrors;
797
+ return count;
798
+ }
799
+
800
+
801
+ /* Error reporting functions
802
+ */
803
+ void TIDY_CALL tidyErrorSummary( TidyDoc tdoc )
804
+ {
805
+ TidyDocImpl* impl = tidyDocToImpl( tdoc );
806
+ if ( impl )
807
+ TY_(ErrorSummary)( impl );
808
+ }
809
+ void TIDY_CALL tidyGeneralInfo( TidyDoc tdoc )
810
+ {
811
+ TidyDocImpl* impl = tidyDocToImpl( tdoc );
812
+ if ( impl )
813
+ TY_(GeneralInfo)( impl );
814
+ }
815
+
816
+
817
+ /* I/O Functions
818
+ **
819
+ ** Initial version supports only whole-file operations.
820
+ ** Do not expose Tidy StreamIn or Out data structures - yet.
821
+ */
822
+
823
+ /* Parse/load Functions
824
+ **
825
+ ** HTML/XHTML version determined from input.
826
+ */
827
+ int TIDY_CALL tidyParseFile( TidyDoc tdoc, ctmbstr filnam )
828
+ {
829
+ TidyDocImpl* doc = tidyDocToImpl( tdoc );
830
+ return tidyDocParseFile( doc, filnam );
831
+ }
832
+ int TIDY_CALL tidyParseStdin( TidyDoc tdoc )
833
+ {
834
+ TidyDocImpl* doc = tidyDocToImpl( tdoc );
835
+ return tidyDocParseStdin( doc );
836
+ }
837
+ int TIDY_CALL tidyParseString( TidyDoc tdoc, ctmbstr content )
838
+ {
839
+ TidyDocImpl* doc = tidyDocToImpl( tdoc );
840
+ return tidyDocParseString( doc, content );
841
+ }
842
+ int TIDY_CALL tidyParseBuffer( TidyDoc tdoc, TidyBuffer* inbuf )
843
+ {
844
+ TidyDocImpl* doc = tidyDocToImpl( tdoc );
845
+ return tidyDocParseBuffer( doc, inbuf );
846
+ }
847
+ int TIDY_CALL tidyParseSource( TidyDoc tdoc, TidyInputSource* source )
848
+ {
849
+ TidyDocImpl* doc = tidyDocToImpl( tdoc );
850
+ return tidyDocParseSource( doc, source );
851
+ }
852
+
853
+
854
+ int tidyDocParseFile( TidyDocImpl* doc, ctmbstr filnam )
855
+ {
856
+ #ifdef _WIN32
857
+ return TY_(DocParseFileWithMappedFile)( doc, filnam );
858
+ #else
859
+ int status = -ENOENT;
860
+ FILE* fin = fopen( filnam, "rb" );
861
+
862
+ #if PRESERVE_FILE_TIMES
863
+ struct stat sbuf = {0};
864
+ /* get last modified time */
865
+ TidyClearMemory( &doc->filetimes, sizeof(doc->filetimes) );
866
+ if ( fin && cfgBool(doc,TidyKeepFileTimes) &&
867
+ fstat(fileno(fin), &sbuf) != -1 )
868
+ {
869
+ doc->filetimes.actime = sbuf.st_atime;
870
+ doc->filetimes.modtime = sbuf.st_mtime;
871
+ }
872
+ #endif
873
+
874
+ if ( fin )
875
+ {
876
+ StreamIn* in = TY_(FileInput)( doc, fin, cfg( doc, TidyInCharEncoding ));
877
+ if ( !in )
878
+ {
879
+ fclose( fin );
880
+ return status;
881
+ }
882
+ status = TY_(DocParseStream)( doc, in );
883
+ TY_(freeFileSource)(&in->source, yes);
884
+ TY_(freeStreamIn)(in);
885
+ }
886
+ else /* Error message! */
887
+ TY_(FileError)( doc, filnam, TidyError );
888
+ return status;
889
+ #endif
890
+ }
891
+
892
+ int tidyDocParseStdin( TidyDocImpl* doc )
893
+ {
894
+ StreamIn* in = TY_(FileInput)( doc, stdin, cfg( doc, TidyInCharEncoding ));
895
+ int status = TY_(DocParseStream)( doc, in );
896
+ TY_(freeStreamIn)(in);
897
+ return status;
898
+ }
899
+
900
+ int tidyDocParseBuffer( TidyDocImpl* doc, TidyBuffer* inbuf )
901
+ {
902
+ int status = -EINVAL;
903
+ if ( inbuf )
904
+ {
905
+ StreamIn* in = TY_(BufferInput)( doc, inbuf, cfg( doc, TidyInCharEncoding ));
906
+ status = TY_(DocParseStream)( doc, in );
907
+ TY_(freeStreamIn)(in);
908
+ }
909
+ return status;
910
+ }
911
+
912
+ int tidyDocParseString( TidyDocImpl* doc, ctmbstr content )
913
+ {
914
+ int status = -EINVAL;
915
+ TidyBuffer inbuf;
916
+ StreamIn* in = NULL;
917
+
918
+ if ( content )
919
+ {
920
+ tidyBufInitWithAllocator( &inbuf, doc->allocator );
921
+ tidyBufAttach( &inbuf, (byte*)content, TY_(tmbstrlen)(content)+1 );
922
+ in = TY_(BufferInput)( doc, &inbuf, cfg( doc, TidyInCharEncoding ));
923
+ status = TY_(DocParseStream)( doc, in );
924
+ tidyBufDetach( &inbuf );
925
+ TY_(freeStreamIn)(in);
926
+ }
927
+ return status;
928
+ }
929
+
930
+ int tidyDocParseSource( TidyDocImpl* doc, TidyInputSource* source )
931
+ {
932
+ StreamIn* in = TY_(UserInput)( doc, source, cfg( doc, TidyInCharEncoding ));
933
+ int status = TY_(DocParseStream)( doc, in );
934
+ TY_(freeStreamIn)(in);
935
+ return status;
936
+ }
937
+
938
+
939
+ /* Print/save Functions
940
+ **
941
+ */
942
+ int TIDY_CALL tidySaveFile( TidyDoc tdoc, ctmbstr filnam )
943
+ {
944
+ TidyDocImpl* doc = tidyDocToImpl( tdoc );
945
+ return tidyDocSaveFile( doc, filnam );
946
+ }
947
+ int TIDY_CALL tidySaveStdout( TidyDoc tdoc )
948
+ {
949
+ TidyDocImpl* doc = tidyDocToImpl( tdoc );
950
+ return tidyDocSaveStdout( doc );
951
+ }
952
+ int TIDY_CALL tidySaveString( TidyDoc tdoc, tmbstr buffer, uint* buflen )
953
+ {
954
+ TidyDocImpl* doc = tidyDocToImpl( tdoc );
955
+ return tidyDocSaveString( doc, buffer, buflen );
956
+ }
957
+ int TIDY_CALL tidySaveBuffer( TidyDoc tdoc, TidyBuffer* outbuf )
958
+ {
959
+ TidyDocImpl* doc = tidyDocToImpl( tdoc );
960
+ return tidyDocSaveBuffer( doc, outbuf );
961
+ }
962
+ int TIDY_CALL tidySaveSink( TidyDoc tdoc, TidyOutputSink* sink )
963
+ {
964
+ TidyDocImpl* doc = tidyDocToImpl( tdoc );
965
+ return tidyDocSaveSink( doc, sink );
966
+ }
967
+
968
+ int tidyDocSaveFile( TidyDocImpl* doc, ctmbstr filnam )
969
+ {
970
+ int status = -ENOENT;
971
+ FILE* fout = NULL;
972
+
973
+ /* Don't zap input file if no output */
974
+ if ( doc->errors > 0 &&
975
+ cfgBool(doc, TidyWriteBack) && !cfgBool(doc, TidyForceOutput) )
976
+ status = tidyDocStatus( doc );
977
+ else
978
+ fout = fopen( filnam, "wb" );
979
+
980
+ if ( fout )
981
+ {
982
+ uint outenc = cfg( doc, TidyOutCharEncoding );
983
+ uint nl = cfg( doc, TidyNewline );
984
+ StreamOut* out = TY_(FileOutput)( doc, fout, outenc, nl );
985
+
986
+ status = tidyDocSaveStream( doc, out );
987
+
988
+ fclose( fout );
989
+ TidyDocFree( doc, out );
990
+
991
+ #if PRESERVE_FILE_TIMES
992
+ if ( doc->filetimes.actime )
993
+ {
994
+ /* set file last accessed/modified times to original values */
995
+ utime( filnam, &doc->filetimes );
996
+ TidyClearMemory( &doc->filetimes, sizeof(doc->filetimes) );
997
+ }
998
+ #endif /* PRESERVFILETIMES */
999
+ }
1000
+ if ( status < 0 ) /* Error message! */
1001
+ TY_(FileError)( doc, filnam, TidyError );
1002
+ return status;
1003
+ }
1004
+
1005
+
1006
+
1007
+ /* Note, _setmode() does NOT work on Win2K Pro w/ VC++ 6.0 SP3.
1008
+ ** The code has been left in in case it works w/ other compilers
1009
+ ** or operating systems. If stdout is in Text mode, be aware that
1010
+ ** it will garble UTF16 documents. In text mode, when it encounters
1011
+ ** a single byte of value 10 (0xA), it will insert a single byte
1012
+ ** value 13 (0xD) just before it. This has the effect of garbling
1013
+ ** the entire document.
1014
+ */
1015
+
1016
+ #if !defined(NO_SETMODE_SUPPORT)
1017
+
1018
+ #if defined(_WIN32) || defined(OS2_OS)
1019
+ #include <fcntl.h>
1020
+ #include <io.h>
1021
+ #endif
1022
+
1023
+ #endif
1024
+
1025
+ int tidyDocSaveStdout( TidyDocImpl* doc )
1026
+ {
1027
+ #if !defined(NO_SETMODE_SUPPORT)
1028
+
1029
+ #if defined(_WIN32) || defined(OS2_OS)
1030
+ int oldstdoutmode = -1, oldstderrmode = -1;
1031
+ #endif
1032
+
1033
+ #endif
1034
+ int status = 0;
1035
+ uint outenc = cfg( doc, TidyOutCharEncoding );
1036
+ uint nl = cfg( doc, TidyNewline );
1037
+ StreamOut* out = TY_(FileOutput)( doc, stdout, outenc, nl );
1038
+
1039
+ #if !defined(NO_SETMODE_SUPPORT)
1040
+
1041
+ #if defined(_WIN32) || defined(OS2_OS)
1042
+ oldstdoutmode = setmode( fileno(stdout), _O_BINARY );
1043
+ oldstderrmode = setmode( fileno(stderr), _O_BINARY );
1044
+ #endif
1045
+
1046
+ #endif
1047
+
1048
+ if ( 0 == status )
1049
+ status = tidyDocSaveStream( doc, out );
1050
+
1051
+ fflush(stdout);
1052
+ fflush(stderr);
1053
+
1054
+ #if !defined(NO_SETMODE_SUPPORT)
1055
+
1056
+ #if defined(_WIN32) || defined(OS2_OS)
1057
+ if ( oldstdoutmode != -1 )
1058
+ oldstdoutmode = setmode( fileno(stdout), oldstdoutmode );
1059
+ if ( oldstderrmode != -1 )
1060
+ oldstderrmode = setmode( fileno(stderr), oldstderrmode );
1061
+ #endif
1062
+
1063
+ #endif
1064
+
1065
+ TidyDocFree( doc, out );
1066
+ return status;
1067
+ }
1068
+
1069
+ int tidyDocSaveString( TidyDocImpl* doc, tmbstr buffer, uint* buflen )
1070
+ {
1071
+ uint outenc = cfg( doc, TidyOutCharEncoding );
1072
+ uint nl = cfg( doc, TidyNewline );
1073
+ TidyBuffer outbuf;
1074
+ StreamOut* out;
1075
+ int status;
1076
+
1077
+ tidyBufInitWithAllocator( &outbuf, doc->allocator );
1078
+ out = TY_(BufferOutput)( doc, &outbuf, outenc, nl );
1079
+ status = tidyDocSaveStream( doc, out );
1080
+
1081
+ if ( outbuf.size > *buflen )
1082
+ status = -ENOMEM;
1083
+ else
1084
+ memcpy( buffer, outbuf.bp, outbuf.size );
1085
+
1086
+ *buflen = outbuf.size;
1087
+ tidyBufFree( &outbuf );
1088
+ TidyDocFree( doc, out );
1089
+ return status;
1090
+ }
1091
+
1092
+ int tidyDocSaveBuffer( TidyDocImpl* doc, TidyBuffer* outbuf )
1093
+ {
1094
+ int status = -EINVAL;
1095
+ if ( outbuf )
1096
+ {
1097
+ uint outenc = cfg( doc, TidyOutCharEncoding );
1098
+ uint nl = cfg( doc, TidyNewline );
1099
+ StreamOut* out = TY_(BufferOutput)( doc, outbuf, outenc, nl );
1100
+
1101
+ status = tidyDocSaveStream( doc, out );
1102
+ TidyDocFree( doc, out );
1103
+ }
1104
+ return status;
1105
+ }
1106
+
1107
+ int tidyDocSaveSink( TidyDocImpl* doc, TidyOutputSink* sink )
1108
+ {
1109
+ uint outenc = cfg( doc, TidyOutCharEncoding );
1110
+ uint nl = cfg( doc, TidyNewline );
1111
+ StreamOut* out = TY_(UserOutput)( doc, sink, outenc, nl );
1112
+ int status = tidyDocSaveStream( doc, out );
1113
+ TidyDocFree( doc, out );
1114
+ return status;
1115
+ }
1116
+
1117
+ int tidyDocStatus( TidyDocImpl* doc )
1118
+ {
1119
+ if ( doc->errors > 0 )
1120
+ return 2;
1121
+ if ( doc->warnings > 0 || doc->accessErrors > 0 )
1122
+ return 1;
1123
+ return 0;
1124
+ }
1125
+
1126
+
1127
+
1128
+ int TIDY_CALL tidyCleanAndRepair( TidyDoc tdoc )
1129
+ {
1130
+ TidyDocImpl* impl = tidyDocToImpl( tdoc );
1131
+ if ( impl )
1132
+ return tidyDocCleanAndRepair( impl );
1133
+ return -EINVAL;
1134
+ }
1135
+
1136
+ int TIDY_CALL tidyRunDiagnostics( TidyDoc tdoc )
1137
+ {
1138
+ TidyDocImpl* impl = tidyDocToImpl( tdoc );
1139
+ if ( impl )
1140
+ return tidyDocRunDiagnostics( impl );
1141
+ return -EINVAL;
1142
+ }
1143
+
1144
+
1145
+ /* Workhorse functions.
1146
+ **
1147
+ ** Parse requires input source, all input config items
1148
+ ** and diagnostic sink to have all been set before calling.
1149
+ **
1150
+ ** Emit likewise requires that document sink and all
1151
+ ** pretty printing options have been set.
1152
+ */
1153
+ static ctmbstr integrity = "\nPanic - tree has lost its integrity\n";
1154
+
1155
+ int TY_(DocParseStream)( TidyDocImpl* doc, StreamIn* in )
1156
+ {
1157
+ Bool xmlIn = cfgBool( doc, TidyXmlTags );
1158
+ int bomEnc;
1159
+
1160
+ assert( doc != NULL && in != NULL );
1161
+ assert( doc->docIn == NULL );
1162
+ doc->docIn = in;
1163
+
1164
+ TY_(TakeConfigSnapshot)( doc ); /* Save config state */
1165
+ TY_(FreeLexer)( doc );
1166
+ TY_(FreeAnchors)( doc );
1167
+
1168
+ TY_(FreeNode)(doc, &doc->root);
1169
+ TidyClearMemory(&doc->root, sizeof(Node));
1170
+
1171
+ if (doc->givenDoctype)
1172
+ TidyDocFree(doc, doc->givenDoctype);
1173
+
1174
+ doc->givenDoctype = NULL;
1175
+
1176
+ doc->lexer = TY_(NewLexer)( doc );
1177
+ /* doc->lexer->root = &doc->root; */
1178
+ doc->root.line = doc->lexer->lines;
1179
+ doc->root.column = doc->lexer->columns;
1180
+ doc->inputHadBOM = no;
1181
+
1182
+ bomEnc = TY_(ReadBOMEncoding)(in);
1183
+
1184
+ if (bomEnc != -1)
1185
+ {
1186
+ in->encoding = bomEnc;
1187
+ TY_(SetOptionInt)(doc, TidyInCharEncoding, bomEnc);
1188
+ }
1189
+
1190
+ #ifdef TIDY_WIN32_MLANG_SUPPORT
1191
+ if (in->encoding > WIN32MLANG)
1192
+ TY_(Win32MLangInitInputTranscoder)(in, in->encoding);
1193
+ #endif /* TIDY_WIN32_MLANG_SUPPORT */
1194
+
1195
+ /* Tidy doesn't alter the doctype for generic XML docs */
1196
+ if ( xmlIn )
1197
+ {
1198
+ TY_(ParseXMLDocument)( doc );
1199
+ if ( !TY_(CheckNodeIntegrity)( &doc->root ) )
1200
+ TidyPanic( doc->allocator, integrity );
1201
+ }
1202
+ else
1203
+ {
1204
+ doc->warnings = 0;
1205
+ TY_(ParseDocument)( doc );
1206
+ if ( !TY_(CheckNodeIntegrity)( &doc->root ) )
1207
+ TidyPanic( doc->allocator, integrity );
1208
+ }
1209
+
1210
+ #ifdef TIDY_WIN32_MLANG_SUPPORT
1211
+ TY_(Win32MLangUninitInputTranscoder)(in);
1212
+ #endif /* TIDY_WIN32_MLANG_SUPPORT */
1213
+
1214
+ doc->docIn = NULL;
1215
+ return tidyDocStatus( doc );
1216
+ }
1217
+
1218
+ int tidyDocRunDiagnostics( TidyDocImpl* doc )
1219
+ {
1220
+ Bool quiet = cfgBool( doc, TidyQuiet );
1221
+ Bool force = cfgBool( doc, TidyForceOutput );
1222
+
1223
+ if ( !quiet )
1224
+ {
1225
+
1226
+ TY_(ReportMarkupVersion)( doc );
1227
+ TY_(ReportNumWarnings)( doc );
1228
+ }
1229
+
1230
+ if ( doc->errors > 0 && !force )
1231
+ TY_(NeedsAuthorIntervention)( doc );
1232
+
1233
+ return tidyDocStatus( doc );
1234
+ }
1235
+
1236
+ int tidyDocCleanAndRepair( TidyDocImpl* doc )
1237
+ {
1238
+ Bool word2K = cfgBool( doc, TidyWord2000 );
1239
+ Bool logical = cfgBool( doc, TidyLogicalEmphasis );
1240
+ Bool clean = cfgBool( doc, TidyMakeClean );
1241
+ Bool dropFont = cfgBool( doc, TidyDropFontTags );
1242
+ Bool htmlOut = cfgBool( doc, TidyHtmlOut );
1243
+ Bool xmlOut = cfgBool( doc, TidyXmlOut );
1244
+ Bool xhtmlOut = cfgBool( doc, TidyXhtmlOut );
1245
+ Bool xmlDecl = cfgBool( doc, TidyXmlDecl );
1246
+ Bool tidyMark = cfgBool( doc, TidyMark );
1247
+ Bool tidyXmlTags = cfgBool( doc, TidyXmlTags );
1248
+ Bool wantNameAttr = cfgBool( doc, TidyAnchorAsName );
1249
+ Node* node;
1250
+
1251
+ if (tidyXmlTags)
1252
+ return tidyDocStatus( doc );
1253
+
1254
+ /* simplifies <b><b> ... </b> ...</b> etc. */
1255
+ TY_(NestedEmphasis)( doc, &doc->root );
1256
+
1257
+ /* cleans up <dir>indented text</dir> etc. */
1258
+ TY_(List2BQ)( doc, &doc->root );
1259
+ TY_(BQ2Div)( doc, &doc->root );
1260
+
1261
+ /* replaces i by em and b by strong */
1262
+ if ( logical )
1263
+ TY_(EmFromI)( doc, &doc->root );
1264
+
1265
+ if ( word2K && TY_(IsWord2000)(doc) )
1266
+ {
1267
+ /* prune Word2000's <![if ...]> ... <![endif]> */
1268
+ TY_(DropSections)( doc, &doc->root );
1269
+
1270
+ /* drop style & class attributes and empty p, span elements */
1271
+ TY_(CleanWord2000)( doc, &doc->root );
1272
+ TY_(DropEmptyElements)(doc, &doc->root);
1273
+ }
1274
+
1275
+ /* replaces presentational markup by style rules */
1276
+ if ( clean || dropFont )
1277
+ TY_(CleanDocument)( doc );
1278
+
1279
+ /* Move terminating <br /> tags from out of paragraphs */
1280
+ /*! Do we want to do this for all block-level elements? */
1281
+
1282
+ /* This is disabled due to http://tidy.sf.net/bug/681116 */
1283
+ #if 0
1284
+ FixBrakes( doc, TY_(FindBody)( doc ));
1285
+ #endif
1286
+
1287
+ /* Reconcile http-equiv meta element with output encoding */
1288
+ if (cfg( doc, TidyOutCharEncoding) != RAW
1289
+ #ifndef NO_NATIVE_ISO2022_SUPPORT
1290
+ && cfg( doc, TidyOutCharEncoding) != ISO2022
1291
+ #endif
1292
+ )
1293
+ TY_(VerifyHTTPEquiv)( doc, TY_(FindHEAD)( doc ));
1294
+
1295
+ if ( !TY_(CheckNodeIntegrity)( &doc->root ) )
1296
+ TidyPanic( doc->allocator, integrity );
1297
+
1298
+ /* remember given doctype for reporting */
1299
+ node = TY_(FindDocType)(doc);
1300
+ if (node)
1301
+ {
1302
+ AttVal* fpi = TY_(GetAttrByName)(node, "PUBLIC");
1303
+ if (AttrHasValue(fpi))
1304
+ {
1305
+ if (doc->givenDoctype)
1306
+ TidyDocFree(doc, doc->givenDoctype);
1307
+ doc->givenDoctype = TY_(tmbstrdup)(doc->allocator,fpi->value);
1308
+ }
1309
+ }
1310
+
1311
+ if ( doc->root.content )
1312
+ {
1313
+ /* If we had XHTML input but want HTML output */
1314
+ if ( htmlOut && doc->lexer->isvoyager )
1315
+ {
1316
+ Node* node = TY_(FindDocType)(doc);
1317
+ /* Remove reference, but do not free */
1318
+ if (node)
1319
+ TY_(RemoveNode)(node);
1320
+ }
1321
+
1322
+ if (xhtmlOut && !htmlOut)
1323
+ {
1324
+ TY_(SetXHTMLDocType)(doc);
1325
+ TY_(FixAnchors)(doc, &doc->root, wantNameAttr, yes);
1326
+ TY_(FixXhtmlNamespace)(doc, yes);
1327
+ TY_(FixLanguageInformation)(doc, &doc->root, yes, yes);
1328
+ }
1329
+ else
1330
+ {
1331
+ TY_(FixDocType)(doc);
1332
+ TY_(FixAnchors)(doc, &doc->root, wantNameAttr, yes);
1333
+ TY_(FixXhtmlNamespace)(doc, no);
1334
+ TY_(FixLanguageInformation)(doc, &doc->root, no, yes);
1335
+ }
1336
+
1337
+ if (tidyMark )
1338
+ TY_(AddGenerator)(doc);
1339
+ }
1340
+
1341
+ /* ensure presence of initial <?xml version="1.0"?> */
1342
+ if ( xmlOut && xmlDecl )
1343
+ TY_(FixXmlDecl)( doc );
1344
+
1345
+ return tidyDocStatus( doc );
1346
+ }
1347
+
1348
+ static
1349
+ Bool showBodyOnly( TidyDocImpl* doc, TidyTriState bodyOnly )
1350
+ {
1351
+ Node* node;
1352
+
1353
+ switch( bodyOnly )
1354
+ {
1355
+ case TidyNoState:
1356
+ return no;
1357
+ case TidyYesState:
1358
+ return yes;
1359
+ default:
1360
+ node = TY_(FindBody)( doc );
1361
+ if (node && node->implicit )
1362
+ return yes;
1363
+ }
1364
+ return no;
1365
+ }
1366
+
1367
+
1368
+ int tidyDocSaveStream( TidyDocImpl* doc, StreamOut* out )
1369
+ {
1370
+ Bool showMarkup = cfgBool( doc, TidyShowMarkup );
1371
+ Bool forceOutput = cfgBool( doc, TidyForceOutput );
1372
+ #if SUPPORT_UTF16_ENCODINGS
1373
+ Bool outputBOM = ( cfgAutoBool(doc, TidyOutputBOM) == TidyYesState );
1374
+ Bool smartBOM = ( cfgAutoBool(doc, TidyOutputBOM) == TidyAutoState );
1375
+ #endif
1376
+ Bool xmlOut = cfgBool( doc, TidyXmlOut );
1377
+ Bool xhtmlOut = cfgBool( doc, TidyXhtmlOut );
1378
+ TidyTriState bodyOnly = cfgAutoBool( doc, TidyBodyOnly );
1379
+
1380
+ Bool dropComments = cfgBool(doc, TidyHideComments);
1381
+ Bool makeClean = cfgBool(doc, TidyMakeClean);
1382
+ Bool asciiChars = cfgBool(doc, TidyAsciiChars);
1383
+ Bool makeBare = cfgBool(doc, TidyMakeBare);
1384
+ Bool escapeCDATA = cfgBool(doc, TidyEscapeCdata);
1385
+ TidyAttrSortStrategy sortAttrStrat = cfg(doc, TidySortAttributes);
1386
+
1387
+ if (escapeCDATA)
1388
+ TY_(ConvertCDATANodes)(doc, &doc->root);
1389
+
1390
+ if (dropComments)
1391
+ TY_(DropComments)(doc, &doc->root);
1392
+
1393
+ if (makeClean)
1394
+ {
1395
+ /* noop */
1396
+ TY_(DropFontElements)(doc, &doc->root, NULL);
1397
+ TY_(WbrToSpace)(doc, &doc->root);
1398
+ }
1399
+
1400
+ if ((makeClean && asciiChars) || makeBare)
1401
+ TY_(DowngradeTypography)(doc, &doc->root);
1402
+
1403
+ if (makeBare)
1404
+ /* Note: no longer replaces &nbsp; in */
1405
+ /* attribute values / non-text tokens */
1406
+ TY_(NormalizeSpaces)(doc->lexer, &doc->root);
1407
+ else
1408
+ TY_(ReplacePreformattedSpaces)(doc, &doc->root);
1409
+
1410
+ if ( sortAttrStrat != TidySortAttrNone )
1411
+ TY_(SortAttributes)(&doc->root, sortAttrStrat);
1412
+
1413
+ if ( showMarkup && (doc->errors == 0 || forceOutput) )
1414
+ {
1415
+ #if SUPPORT_UTF16_ENCODINGS
1416
+ /* Output a Byte Order Mark if required */
1417
+ if ( outputBOM || (doc->inputHadBOM && smartBOM) )
1418
+ TY_(outBOM)( out );
1419
+ #endif
1420
+
1421
+ /* No longer necessary. No DOCTYPE == HTML 3.2,
1422
+ ** which gives you only the basic character entities,
1423
+ ** which are safe in any browser.
1424
+ ** if ( !TY_(FindDocType)(doc) )
1425
+ ** TY_(SetOptionBool)( doc, TidyNumEntities, yes );
1426
+ */
1427
+
1428
+ doc->docOut = out;
1429
+ if ( xmlOut && !xhtmlOut )
1430
+ TY_(PPrintXMLTree)( doc, NORMAL, 0, &doc->root );
1431
+ else if ( showBodyOnly( doc, bodyOnly ) )
1432
+ TY_(PrintBody)( doc );
1433
+ else
1434
+ TY_(PPrintTree)( doc, NORMAL, 0, &doc->root );
1435
+
1436
+ TY_(PFlushLine)( doc, 0 );
1437
+ doc->docOut = NULL;
1438
+ }
1439
+
1440
+ TY_(ResetConfigToSnapshot)( doc );
1441
+ return tidyDocStatus( doc );
1442
+ }
1443
+
1444
+ /* Tree traversal functions
1445
+ **
1446
+ ** The big issue here is the degree to which we should mimic
1447
+ ** a DOM and/or SAX nodes.
1448
+ **
1449
+ ** Is it 100% possible (and, if so, how difficult is it) to
1450
+ ** emit SAX events from this API? If SAX events are possible,
1451
+ ** is that 100% of data needed to build a DOM?
1452
+ */
1453
+
1454
+ TidyNode TIDY_CALL tidyGetRoot( TidyDoc tdoc )
1455
+ {
1456
+ TidyDocImpl* impl = tidyDocToImpl( tdoc );
1457
+ Node* node = NULL;
1458
+ if ( impl )
1459
+ node = &impl->root;
1460
+ return tidyImplToNode( node );
1461
+ }
1462
+
1463
+ TidyNode TIDY_CALL tidyGetHtml( TidyDoc tdoc )
1464
+ {
1465
+ TidyDocImpl* impl = tidyDocToImpl( tdoc );
1466
+ Node* node = NULL;
1467
+ if ( impl )
1468
+ node = TY_(FindHTML)( impl );
1469
+ return tidyImplToNode( node );
1470
+ }
1471
+
1472
+ TidyNode TIDY_CALL tidyGetHead( TidyDoc tdoc )
1473
+ {
1474
+ TidyDocImpl* impl = tidyDocToImpl( tdoc );
1475
+ Node* node = NULL;
1476
+ if ( impl )
1477
+ node = TY_(FindHEAD)( impl );
1478
+ return tidyImplToNode( node );
1479
+ }
1480
+
1481
+ TidyNode TIDY_CALL tidyGetBody( TidyDoc tdoc )
1482
+ {
1483
+ TidyDocImpl* impl = tidyDocToImpl( tdoc );
1484
+ Node* node = NULL;
1485
+ if ( impl )
1486
+ node = TY_(FindBody)( impl );
1487
+ return tidyImplToNode( node );
1488
+ }
1489
+
1490
+ /* parent / child */
1491
+ TidyNode TIDY_CALL tidyGetParent( TidyNode tnod )
1492
+ {
1493
+ Node* nimp = tidyNodeToImpl( tnod );
1494
+ return tidyImplToNode( nimp->parent );
1495
+ }
1496
+ TidyNode TIDY_CALL tidyGetChild( TidyNode tnod )
1497
+ {
1498
+ Node* nimp = tidyNodeToImpl( tnod );
1499
+ return tidyImplToNode( nimp->content );
1500
+ }
1501
+
1502
+ /* siblings */
1503
+ TidyNode TIDY_CALL tidyGetNext( TidyNode tnod )
1504
+ {
1505
+ Node* nimp = tidyNodeToImpl( tnod );
1506
+ return tidyImplToNode( nimp->next );
1507
+ }
1508
+ TidyNode TIDY_CALL tidyGetPrev( TidyNode tnod )
1509
+ {
1510
+ Node* nimp = tidyNodeToImpl( tnod );
1511
+ return tidyImplToNode( nimp->prev );
1512
+ }
1513
+
1514
+ /* Node info */
1515
+ TidyNodeType TIDY_CALL tidyNodeGetType( TidyNode tnod )
1516
+ {
1517
+ Node* nimp = tidyNodeToImpl( tnod );
1518
+ TidyNodeType ntyp = TidyNode_Root;
1519
+ if ( nimp )
1520
+ ntyp = (TidyNodeType) nimp->type;
1521
+ return ntyp;
1522
+ }
1523
+
1524
+ uint TIDY_CALL tidyNodeLine( TidyNode tnod )
1525
+ {
1526
+ Node* nimp = tidyNodeToImpl( tnod );
1527
+ uint line = 0;
1528
+ if ( nimp )
1529
+ line = nimp->line;
1530
+ return line;
1531
+ }
1532
+ uint TIDY_CALL tidyNodeColumn( TidyNode tnod )
1533
+ {
1534
+ Node* nimp = tidyNodeToImpl( tnod );
1535
+ uint col = 0;
1536
+ if ( nimp )
1537
+ col = nimp->column;
1538
+ return col;
1539
+ }
1540
+
1541
+ ctmbstr TIDY_CALL tidyNodeGetName( TidyNode tnod )
1542
+ {
1543
+ Node* nimp = tidyNodeToImpl( tnod );
1544
+ ctmbstr nnam = NULL;
1545
+ if ( nimp )
1546
+ nnam = nimp->element;
1547
+ return nnam;
1548
+ }
1549
+
1550
+
1551
+ Bool TIDY_CALL tidyNodeHasText( TidyDoc tdoc, TidyNode tnod )
1552
+ {
1553
+ TidyDocImpl* doc = tidyDocToImpl( tdoc );
1554
+ if ( doc )
1555
+ return TY_(nodeHasText)( doc, tidyNodeToImpl(tnod) );
1556
+ return no;
1557
+ }
1558
+
1559
+
1560
+ Bool TIDY_CALL tidyNodeGetText( TidyDoc tdoc, TidyNode tnod, TidyBuffer* outbuf )
1561
+ {
1562
+ TidyDocImpl* doc = tidyDocToImpl( tdoc );
1563
+ Node* nimp = tidyNodeToImpl( tnod );
1564
+ if ( doc && nimp && outbuf )
1565
+ {
1566
+ uint outenc = cfg( doc, TidyOutCharEncoding );
1567
+ uint nl = cfg( doc, TidyNewline );
1568
+ StreamOut* out = TY_(BufferOutput)( doc, outbuf, outenc, nl );
1569
+ Bool xmlOut = cfgBool( doc, TidyXmlOut );
1570
+ Bool xhtmlOut = cfgBool( doc, TidyXhtmlOut );
1571
+
1572
+ doc->docOut = out;
1573
+ if ( xmlOut && !xhtmlOut )
1574
+ TY_(PPrintXMLTree)( doc, NORMAL, 0, nimp );
1575
+ else
1576
+ TY_(PPrintTree)( doc, NORMAL, 0, nimp );
1577
+
1578
+ TY_(PFlushLine)( doc, 0 );
1579
+ doc->docOut = NULL;
1580
+
1581
+ TidyDocFree( doc, out );
1582
+ return yes;
1583
+ }
1584
+ return no;
1585
+ }
1586
+
1587
+ Bool TIDY_CALL tidyNodeGetValue( TidyDoc tdoc, TidyNode tnod, TidyBuffer* buf )
1588
+ {
1589
+ TidyDocImpl *doc = tidyDocToImpl( tdoc );
1590
+ Node *node = tidyNodeToImpl( tnod );
1591
+ if ( doc == NULL || node == NULL || buf == NULL )
1592
+ return no;
1593
+
1594
+ switch( node->type ) {
1595
+ case TextNode:
1596
+ case CDATATag:
1597
+ case CommentTag:
1598
+ case ProcInsTag:
1599
+ case SectionTag:
1600
+ case AspTag:
1601
+ case JsteTag:
1602
+ case PhpTag:
1603
+ {
1604
+ tidyBufClear( buf );
1605
+ tidyBufAppend( buf, doc->lexer->lexbuf + node->start,
1606
+ node->end - node->start );
1607
+ break;
1608
+ }
1609
+ default:
1610
+ /* The node doesn't have a value */
1611
+ return no;
1612
+ }
1613
+
1614
+ return yes;
1615
+ }
1616
+
1617
+ Bool TIDY_CALL tidyNodeIsProp( TidyDoc ARG_UNUSED(tdoc), TidyNode tnod )
1618
+ {
1619
+ Node* nimp = tidyNodeToImpl( tnod );
1620
+ Bool isProprietary = yes;
1621
+ if ( nimp )
1622
+ {
1623
+ switch ( nimp->type )
1624
+ {
1625
+ case RootNode:
1626
+ case DocTypeTag:
1627
+ case CommentTag:
1628
+ case XmlDecl:
1629
+ case ProcInsTag:
1630
+ case TextNode:
1631
+ case CDATATag:
1632
+ isProprietary = no;
1633
+ break;
1634
+
1635
+ case SectionTag:
1636
+ case AspTag:
1637
+ case JsteTag:
1638
+ case PhpTag:
1639
+ isProprietary = yes;
1640
+ break;
1641
+
1642
+ case StartTag:
1643
+ case EndTag:
1644
+ case StartEndTag:
1645
+ isProprietary = ( nimp->tag
1646
+ ? (nimp->tag->versions&VERS_PROPRIETARY)!=0
1647
+ : yes );
1648
+ break;
1649
+ }
1650
+ }
1651
+ return isProprietary;
1652
+ }
1653
+
1654
+ TidyTagId TIDY_CALL tidyNodeGetId(TidyNode tnod)
1655
+ {
1656
+ Node* nimp = tidyNodeToImpl(tnod);
1657
+
1658
+ TidyTagId tagId = TidyTag_UNKNOWN;
1659
+ if (nimp && nimp->tag)
1660
+ tagId = nimp->tag->id;
1661
+
1662
+ return tagId;
1663
+ }
1664
+
1665
+
1666
+ /* Null for non-element nodes and all pure HTML
1667
+ cmbstr tidyNodeNsLocal( TidyNode tnod )
1668
+ {
1669
+ }
1670
+ cmbstr tidyNodeNsPrefix( TidyNode tnod )
1671
+ {
1672
+ }
1673
+ cmbstr tidyNodeNsUri( TidyNode tnod )
1674
+ {
1675
+ }
1676
+ */
1677
+
1678
+ /* Iterate over attribute values */
1679
+ TidyAttr TIDY_CALL tidyAttrFirst( TidyNode tnod )
1680
+ {
1681
+ Node* nimp = tidyNodeToImpl( tnod );
1682
+ AttVal* attval = NULL;
1683
+ if ( nimp )
1684
+ attval = nimp->attributes;
1685
+ return tidyImplToAttr( attval );
1686
+ }
1687
+ TidyAttr TIDY_CALL tidyAttrNext( TidyAttr tattr )
1688
+ {
1689
+ AttVal* attval = tidyAttrToImpl( tattr );
1690
+ AttVal* nxtval = NULL;
1691
+ if ( attval )
1692
+ nxtval = attval->next;
1693
+ return tidyImplToAttr( nxtval );
1694
+ }
1695
+
1696
+ ctmbstr TIDY_CALL tidyAttrName( TidyAttr tattr )
1697
+ {
1698
+ AttVal* attval = tidyAttrToImpl( tattr );
1699
+ ctmbstr anam = NULL;
1700
+ if ( attval )
1701
+ anam = attval->attribute;
1702
+ return anam;
1703
+ }
1704
+ ctmbstr TIDY_CALL tidyAttrValue( TidyAttr tattr )
1705
+ {
1706
+ AttVal* attval = tidyAttrToImpl( tattr );
1707
+ ctmbstr aval = NULL;
1708
+ if ( attval )
1709
+ aval = attval->value;
1710
+ return aval;
1711
+ }
1712
+
1713
+ /* Null for pure HTML
1714
+ ctmbstr tidyAttrNsLocal( TidyAttr tattr )
1715
+ {
1716
+ }
1717
+ ctmbstr tidyAttrNsPrefix( TidyAttr tattr )
1718
+ {
1719
+ }
1720
+ ctmbstr tidyAttrNsUri( TidyAttr tattr )
1721
+ {
1722
+ }
1723
+ */
1724
+
1725
+ TidyAttrId TIDY_CALL tidyAttrGetId( TidyAttr tattr )
1726
+ {
1727
+ AttVal* attval = tidyAttrToImpl( tattr );
1728
+ TidyAttrId attrId = TidyAttr_UNKNOWN;
1729
+ if ( attval && attval->dict )
1730
+ attrId = attval->dict->id;
1731
+ return attrId;
1732
+ }
1733
+ Bool TIDY_CALL tidyAttrIsProp( TidyAttr tattr )
1734
+ {
1735
+ AttVal* attval = tidyAttrToImpl( tattr );
1736
+ Bool isProprietary = yes;
1737
+ if ( attval )
1738
+ isProprietary = ( attval->dict
1739
+ ? (attval->dict->versions & VERS_PROPRIETARY) != 0
1740
+ : yes );
1741
+ return isProprietary;
1742
+ }
1743
+
1744
+ /*
1745
+ * local variables:
1746
+ * mode: c
1747
+ * indent-tabs-mode: nil
1748
+ * c-basic-offset: 4
1749
+ * eval: (c-set-offset 'substatement-open 0)
1750
+ * end:
1751
+ */