[BACK] Return to HTML.c CVS log [TXT] [DIR] Up to [Public] / libwww / Library / src

Annotation of libwww/Library/src/HTML.c, revision 1.76

1.39 frystyk 1: /*                                   HTML.c
1.75 frystyk 2: **   SIMPLE HTML PARSER WITHOUT ANY PRESENTATION CODE
1.39 frystyk 3: **
1.43 frystyk 4: **   (c) COPYRIGHT MIT 1995.
1.39 frystyk 5: **   Please first read the full copyright statement in the file COPYRIGH.
1.76 ! frystyk 6: **   @(#) $Id: HTML.c,v 1.75 1999年01月06日 15:38:47 frystyk Exp $
1.1 timbl 7: **
1.2 timbl 8: **   This generates of a hypertext object. It converts from the
1.75 frystyk 9: **   structured stream interface foo HTML events into the style-
 10: **   oriented interface of the HText interface.
1.1 timbl 11: **
1.35 duns 12: ** HISTORY:
 13: **   8 Jul 94 FM  Insulate free() from _free structure element.
1.1 timbl 14: */
1.16 timbl 15: 
1.41 frystyk 16: /* Library include files */
1.72 frystyk 17: #include "wwwsys.h"
1.63 frystyk 18: #include "WWWUtil.h"
 19: #include "WWWCore.h"
 20: #include "WWWHTML.h"
1.73 frystyk 21: #include "HTML.h"
1.75 frystyk 22: #include "HTextImp.h"
1.73 frystyk 23: 
1.75 frystyk 24: #define PUTC(t,c)   (*(t)->target->isa->put_character)((t)->target, (c))
 25: #define PUTS(t,s)   (*(t)->target->isa->put_string)((t)->target, (s))
 26: #define PUTB(s,b,l)  (*(t)->target->isa->put_block)((t)->target, (b), (l))
 27: #define FLUSH_TARGET(t)    (*(t)->target->isa->flush)((t)->target)
 28: #define FREE_TARGET(t) (*(t)->target->isa->_free)((t)->target)
 29: #define ABORT_TARGET(t)    (*(t)->target->isa->abort)((t)->target, e)
1.1 timbl 30: 
1.75 frystyk 31: #define MAX_NESTING 40
1.1 timbl 32: 
1.75 frystyk 33: struct _HTStream {
 34:   const HTStreamClass *   isa;
 35:   /* .... */
 36: };
1.2 timbl 37: 
 38: struct _HTStructured {
1.60 frystyk 39:   const HTStructuredClass * isa;
1.54 frystyk 40:   HTRequest *            request;
1.2 timbl 41:   HTParentAnchor *      node_anchor;
1.75 frystyk 42:   HTextImp *             text;
 43:   HTStream *         target;
 44:   HTChunk *         title;
 45:   BOOL            in_word;
 46:   SGML_dtd *         dtd;
1.2 timbl 47:   char *           comment_start; /* for literate programming */
 48:   char *           comment_end;
1.75 frystyk 49:   BOOL            started;
1.1 timbl 50: 
1.75 frystyk 51:   int                overflow;
 52:   int *           sp;
 53:   int                stack[MAX_NESTING];
1.2 timbl 54: };
1.1 timbl 55: 
1.75 frystyk 56: /*
 57: **   Entity values -- for ISO Latin 1 local representation
1.2 timbl 58: **   This MUST match exactly the table referred to in the DTD!
 59: */
1.75 frystyk 60: #define ENTITY_SIZE  67
 61: static char * ISO_Latin1[ENTITY_SIZE] = {
1.2 timbl 62:    "306円", /* capital AE diphthong (ligature) */ 
 63:    "301円", /* capital A, acute accent */ 
 64:    "302円", /* capital A, circumflex accent */ 
 65:    "300円", /* capital A, grave accent */ 
 66:    "305円", /* capital A, ring */ 
 67:    "303円", /* capital A, tilde */ 
 68:    "304円", /* capital A, dieresis or umlaut mark */ 
 69:    "307円", /* capital C, cedilla */ 
 70:    "320円", /* capital Eth, Icelandic */ 
 71:    "311円", /* capital E, acute accent */ 
 72:    "312円", /* capital E, circumflex accent */ 
 73:    "310円", /* capital E, grave accent */ 
 74:    "313円", /* capital E, dieresis or umlaut mark */ 
 75:    "315円", /* capital I, acute accent */ 
 76:    "316円", /* capital I, circumflex accent */ 
 77:    "314円", /* capital I, grave accent */ 
 78:    "317円", /* capital I, dieresis or umlaut mark */ 
 79:    "321円", /* capital N, tilde */ 
 80:    "323円", /* capital O, acute accent */ 
 81:    "324円", /* capital O, circumflex accent */ 
 82:    "322円", /* capital O, grave accent */ 
 83:    "330円", /* capital O, slash */ 
 84:    "325円", /* capital O, tilde */ 
 85:    "326円", /* capital O, dieresis or umlaut mark */ 
 86:    "336円", /* capital THORN, Icelandic */ 
 87:    "332円", /* capital U, acute accent */ 
 88:    "333円", /* capital U, circumflex accent */ 
 89:    "331円", /* capital U, grave accent */ 
 90:    "334円", /* capital U, dieresis or umlaut mark */ 
 91:    "335円", /* capital Y, acute accent */ 
 92:    "341円", /* small a, acute accent */ 
 93:    "342円", /* small a, circumflex accent */ 
 94:    "346円", /* small ae diphthong (ligature) */ 
 95:    "340円", /* small a, grave accent */ 
 96:    "046円", /* ampersand */ 
 97:    "345円", /* small a, ring */ 
 98:    "343円", /* small a, tilde */ 
 99:    "344円", /* small a, dieresis or umlaut mark */ 
 100:    "347円", /* small c, cedilla */ 
 101:    "351円", /* small e, acute accent */ 
 102:    "352円", /* small e, circumflex accent */ 
 103:    "350円", /* small e, grave accent */ 
 104:    "360円", /* small eth, Icelandic */ 
 105:    "353円", /* small e, dieresis or umlaut mark */ 
 106:    "076円", /* greater than */ 
 107:    "355円", /* small i, acute accent */ 
 108:    "356円", /* small i, circumflex accent */ 
 109:    "354円", /* small i, grave accent */ 
 110:    "357円", /* small i, dieresis or umlaut mark */ 
 111:    "074円", /* less than */ 
1.62 frystyk 112:    "040円", /* non-breaking space */
1.2 timbl 113:    "361円", /* small n, tilde */ 
 114:    "363円", /* small o, acute accent */ 
 115:    "364円", /* small o, circumflex accent */ 
 116:    "362円", /* small o, grave accent */ 
 117:    "370円", /* small o, slash */ 
 118:    "365円", /* small o, tilde */ 
 119:    "366円", /* small o, dieresis or umlaut mark */ 
1.36 frystyk 120:     "042円", /* double quote sign - June 94 */
1.2 timbl 121:    "337円", /* small sharp s, German (sz ligature) */ 
 122:    "376円", /* small thorn, Icelandic */ 
 123:    "372円", /* small u, acute accent */ 
 124:    "373円", /* small u, circumflex accent */ 
 125:    "371円", /* small u, grave accent */ 
 126:    "374円", /* small u, dieresis or umlaut mark */ 
 127:    "375円", /* small y, acute accent */ 
 128:    "377円", /* small y, dieresis or umlaut mark */ 
1.1 timbl 129: };
 130: 
1.75 frystyk 131: PRIVATE char ** CurrentEntityValues = ISO_Latin1;
1.2 timbl 132: 
1.75 frystyk 133: PUBLIC BOOL HTMLUseCharacterSet (HTMLCharacterSet i)
1.1 timbl 134: {
1.75 frystyk 135:   if (i == HTML_ISO_LATIN1) {
 136:    CurrentEntityValues = ISO_Latin1;
 137:    return YES;
1.1 timbl 138:   } else {
1.75 frystyk 139:    if (SGML_TRACE) HTTrace("HTML Parser. Doesn't support this character set\n");
 140:    return NO;
1.1 timbl 141:   }
 142: }
 143: 
1.75 frystyk 144: PRIVATE int HTML_write (HTStructured * me, const char * b, int l)
1.1 timbl 145: {
1.75 frystyk 146:   if (!me->started) {
 147:    HTextImp_build(me->text, HTEXT_BEGIN);
 148:    me->started = YES;
1.1 timbl 149:   }
 150: 
1.75 frystyk 151:   /* Look at what we got */
 152:   switch (me->sp[0]) {
1.2 timbl 153: 
1.75 frystyk 154:   case HTML_COMMENT:
 155:    break;                 /* Do Nothing */
 156:        
 157:   case HTML_TITLE:
 158:    HTChunk_putb(me->title, b, l);
 159:    /* Fall through */
1.71 frystyk 160:    
1.75 frystyk 161:   default:
 162:    HTextImp_addText(me->text, b, l);
1.71 frystyk 163:   }
1.42 frystyk 164:   return HT_OK;
1.1 timbl 165: }
 166: 
1.71 frystyk 167: PRIVATE int HTML_put_character (HTStructured * me, char c)
1.1 timbl 168: {
1.71 frystyk 169:   return HTML_write(me, &c, sizeof(char));
1.1 timbl 170: }
 171: 
1.64 frystyk 172: PRIVATE int HTML_put_string (HTStructured * me, const char* s)
1.1 timbl 173: {
1.71 frystyk 174:   return HTML_write(me, s, (int) strlen(s));
1.1 timbl 175: }
1.2 timbl 176: 
1.75 frystyk 177: PRIVATE void HTML_start_element (HTStructured *    me,
 178:                 int      element_number,
 179:                 const BOOL *  present,
 180:                 const char ** value)
 181: {
 182:   HTChildAnchor * address = NULL;
 183:   if (!me->started) {
 184:    HTextImp_build(me->text, HTEXT_BEGIN);
 185:    me->started = YES;
1.73 frystyk 186:   }
 187: 
1.75 frystyk 188:   /* Look at what element was started */
 189:   switch (element_number) {
1.2 timbl 190:   case HTML_A:
1.75 frystyk 191:    if (present[HTML_A_HREF] && value[HTML_A_HREF]) {
 192:      address = HTAnchor_findChildAndLink(
 193:        me->node_anchor,                    /* parent */
 194:        present[HTML_A_NAME] ? value[HTML_A_NAME] : NULL,    /* Tag */
 195:        value[HTML_A_HREF],                   /* Addresss */
 196:        present[HTML_A_REL] && value[HTML_A_REL] ? 
 197:        (HTLinkType) HTAtom_caseFor(value[HTML_A_REL]) : NULL);
1.2 timbl 198:      
1.75 frystyk 199:      if (present[HTML_A_TITLE] && value[HTML_A_TITLE]) {
 200:        HTLink * link = HTAnchor_mainLink((HTAnchor *) address);
 201:        HTParentAnchor * dest = HTAnchor_parent(HTLink_destination(link));
 202:        if (!HTAnchor_title(dest)) HTAnchor_setTitle(dest, value[HTML_A_TITLE]);
 203:      }
 204:      HTextImp_foundLink(me->text, element_number, HTML_A_HREF,
 205:                address, present, value);
 206:      if (SGML_TRACE)
 207:        HTTrace("HTML Parser. Anchor `%s\'\n", value[HTML_A_HREF]);
 208:    }
 209:    break;
 210: 
 211:   case HTML_AREA:
 212:    if (present[HTML_AREA_HREF] && value[HTML_AREA_HREF]) {
 213:      address = HTAnchor_findChildAndLink(me->node_anchor, NULL,
 214:                        value[HTML_AREA_HREF], NULL);
 215:      HTextImp_foundLink(me->text, element_number, HTML_AREA_HREF,
 216:                address, present, value);
 217:      if (SGML_TRACE)
 218:        HTTrace("HTML Parser. Image map area `%s\'\n", value[HTML_AREA_HREF]);
1.2 timbl 219:    }
1.75 frystyk 220:    break;
 221: 
 222:   case HTML_BASE:
 223:    if (present[HTML_BASE_HREF] && value[HTML_BASE_HREF]) {
 224:      HTAnchor_setBase(me->node_anchor, (char *) value[HTML_BASE_HREF]);
 225:      if (SGML_TRACE)
 226:        HTTrace("HTML Parser. New base `%s\'\n", value[HTML_BASE_HREF]);
 227:    }
 228:    break;
 229: 
 230:   case HTML_BODY:
 231:    if (present[HTML_BODY_BACKGROUND] && value[HTML_BODY_BACKGROUND]) {
 232:      address = HTAnchor_findChildAndLink(me->node_anchor, NULL,
 233:                        value[HTML_BODY_BACKGROUND], NULL);
 234:      HTextImp_foundLink(me->text, element_number, HTML_BODY_BACKGROUND,
 235:                address, present, value);
 236:      if (SGML_TRACE)
 237:        HTTrace("HTML Parser. Background `%s\'\n", value[HTML_BODY_BACKGROUND]);
 238:    }
 239:    break;
 240: 
 241:   case HTML_FRAME:
 242:    if (present[HTML_FRAME_SRC] && value[HTML_FRAME_SRC]) {
 243:      address = HTAnchor_findChildAndLink(me->node_anchor, NULL,
 244:                        value[HTML_FRAME_SRC], NULL);
 245:      HTextImp_foundLink(me->text, element_number, HTML_FRAME_SRC,
 246:                address, present, value);
 247:      if (SGML_TRACE)
 248:        HTTrace("HTML Parser. Frame `%s\'\n", value[HTML_FRAME_SRC]);
 249:    }
 250:    break;
 251:    
 252:   case HTML_IMG:
 253:    if (present[HTML_IMG_SRC] && value[HTML_IMG_SRC]) {
 254:      address = HTAnchor_findChildAndLink(me->node_anchor, NULL,
 255:                        value[HTML_IMG_SRC], NULL);
 256:      HTextImp_foundLink(me->text, element_number, HTML_IMG_SRC,
 257:                address, present, value);
 258:    }
 259:    break;
 260: 
 261:   case HTML_ISINDEX:
 262:    HTAnchor_setIndex(me->node_anchor);
 263:    break;
1.2 timbl 264:    
1.63 frystyk 265:   case HTML_LINK:
1.69 frystyk 266:    if (present[HTML_LINK_HREF] && value[HTML_LINK_HREF]) {
1.75 frystyk 267:      HTParentAnchor * dest = NULL;
 268:      address = HTAnchor_findChildAndLink(
1.73 frystyk 269:        me->node_anchor,                    /* parent */
 270:        present[HTML_A_NAME] ? value[HTML_A_NAME] : NULL,    /* Tag */
 271:        present[HTML_A_HREF] ? value[HTML_A_HREF] : NULL,    /* Addresss */
 272:        NULL);                         /* Rels */
1.75 frystyk 273:      dest = HTAnchor_parent(HTAnchor_followMainLink((HTAnchor *) address));
1.69 frystyk 274: 
 275:      /* If forward reference */
 276:      if ((present[HTML_LINK_REL] && value[HTML_LINK_REL])) {
 277:        char * strval = NULL;
 278:        char * ptr = NULL;
 279:        char * relation = NULL;
 280:        StrAllocCopy(strval, value[HTML_LINK_REL]);
 281:        ptr = strval;
 282:        while ((relation = HTNextLWSToken(&ptr)) != NULL) {
 283:          HTLink_add((HTAnchor *) me->node_anchor, (HTAnchor *) dest,
 284:                (HTLinkType) HTAtom_caseFor(relation),
 285:                METHOD_INVALID);
 286:        }
 287:        HT_FREE(strval);
 288:      }
 289: 
 290:      /* If reverse reference */
 291:      if ((present[HTML_LINK_REV] && value[HTML_LINK_REV])) {
 292:        char * strval = NULL;
 293:        char * ptr = NULL;
 294:        char * relation = NULL;
 295:        StrAllocCopy(strval, value[HTML_LINK_REV]);
 296:        ptr = strval;
 297:        while ((relation = HTNextLWSToken(&ptr)) != NULL) {
 298:          HTLink_add((HTAnchor *) dest, (HTAnchor *) me->node_anchor,
 299:                (HTLinkType) HTAtom_caseFor(relation),
 300:                METHOD_INVALID);
 301:        }
 302:        HT_FREE(strval);
 303:      }
1.63 frystyk 304: 
1.69 frystyk 305:      /* If we got any type information as well */
 306:      if (present[HTML_LINK_TYPE] && value[HTML_LINK_TYPE]) {
 307:        if (HTAnchor_format(dest) == WWW_UNKNOWN)
 308:          HTAnchor_setFormat(dest,
 309:                    (HTFormat) HTAtom_caseFor(value[HTML_LINK_TYPE]));
 310:      }
1.63 frystyk 311: 
1.75 frystyk 312:      /* Call out to the layout engine */
 313:      HTextImp_foundLink(me->text, element_number, HTML_LINK_HREF,
 314:                address, present, value);
1.70 frystyk 315:    }
1.75 frystyk 316:    break;
1.70 frystyk 317: 
 318:   case HTML_META:
 319:    if (present[HTML_META_NAME] && value[HTML_META_NAME]) {
 320:      HTAnchor_addMeta (me->node_anchor,
 321:               value[HTML_META_NAME],
 322:               (present[HTML_META_CONTENT] && value[HTML_META_CONTENT]) ?
 323:               value[HTML_META_CONTENT] : "");
1.69 frystyk 324:    }
1.75 frystyk 325:    break;
 326: 
 327:   case HTML_OBJECT:
 328:    if (present[HTML_OBJECT_CLASSID] && value[HTML_OBJECT_CLASSID]) {
 329:      address = HTAnchor_findChildAndLink(me->node_anchor, NULL,
 330:                        value[HTML_OBJECT_CLASSID], NULL);
 331:      HTextImp_foundLink(me->text, element_number, HTML_OBJECT_CLASSID,
 332:                address, present, value);
 333:    }
 334: 
 335:    if (present[HTML_OBJECT_CODEBASE] && value[HTML_OBJECT_CODEBASE]) {
 336:      address = HTAnchor_findChildAndLink(me->node_anchor, NULL,
 337:                        value[HTML_OBJECT_CODEBASE], NULL);
 338:      HTextImp_foundLink(me->text, element_number, HTML_OBJECT_CODEBASE,
 339:                address, present, value);
 340:    }
 341: 
 342:    if (present[HTML_OBJECT_DATA] && value[HTML_OBJECT_DATA]) {
 343:      address = HTAnchor_findChildAndLink(me->node_anchor, NULL,
 344:                        value[HTML_OBJECT_DATA], NULL);
 345:      HTextImp_foundLink(me->text, element_number, HTML_OBJECT_DATA,
 346:                address, present, value);
 347:    }
1.63 frystyk 348: 
1.75 frystyk 349:    if (present[HTML_OBJECT_ARCHIVE] && value[HTML_OBJECT_ARCHIVE]) {
 350:      address = HTAnchor_findChildAndLink(me->node_anchor, NULL,
 351:                        value[HTML_OBJECT_ARCHIVE], NULL);
 352:      HTextImp_foundLink(me->text, element_number, HTML_OBJECT_ARCHIVE,
 353:                address, present, value);
 354:    }
1.2 timbl 355: 
1.75 frystyk 356:    if (present[HTML_OBJECT_USEMAP] && value[HTML_OBJECT_USEMAP]) {
 357:      address = HTAnchor_findChildAndLink(me->node_anchor, NULL,
 358:                        value[HTML_OBJECT_USEMAP], NULL);
 359:      HTextImp_foundLink(me->text, element_number, HTML_OBJECT_USEMAP,
 360:                address, present, value);
1.2 timbl 361:    }
 362:    break;
 363: 
 364:   case HTML_PRE:
1.4 timbl 365:    if (me->comment_end)
1.75 frystyk 366:      HTextImp_addText(me->text, me->comment_end, strlen(me->comment_end));
1.2 timbl 367:    break;
1.11 timbl 368: 
1.75 frystyk 369:   case HTML_TITLE:
 370:     HTChunk_clear(me->title);
1.2 timbl 371:    break;
1.75 frystyk 372:   }
1.2 timbl 373: 
1.75 frystyk 374:   /* Update our parse stack */
 375:   if (SGML_findTagContents(me->dtd, element_number) != SGML_EMPTY) {
1.13 timbl 376:     if (me->sp == me->stack) {
1.44 frystyk 377:      if (SGML_TRACE)
1.75 frystyk 378:        HTTrace("HTML Parser. Maximum nesting of %d exceded!\n", MAX_NESTING); 
1.44 frystyk 379:      me->overflow++;
1.12 timbl 380:      return;
 381:    }
1.4 timbl 382:    --(me->sp);
1.75 frystyk 383:    me->sp[0] = element_number;
1.10 timbl 384:   } 
1.75 frystyk 385: 
 386:   /* Call out to the layout engine */
 387:   HTextImp_beginElement(me->text, element_number, present, value);
1.1 timbl 388: }
1.10 timbl 389: 
1.53 frystyk 390: PRIVATE void HTML_end_element (HTStructured * me, int element_number)
1.1 timbl 391: {
1.75 frystyk 392:   if (!me->started) {
 393:    HTextImp_build(me->text, HTEXT_BEGIN);
 394:    me->started = YES;
1.1 timbl 395:   }
1.44 frystyk 396: 
1.75 frystyk 397:   /* Update our parse stack */
1.44 frystyk 398:   if (me->overflow > 0) {
 399:    me->overflow--;
 400:    return;
 401:   }
1.75 frystyk 402:   me->sp++;
1.67 frystyk 403:   if (me->sp > me->stack + MAX_NESTING - 1) {
1.75 frystyk 404:    if (SGML_TRACE) HTTrace("HTML Parser. Bottom of parse stack reached\n");
1.67 frystyk 405:    me->sp = me->stack + MAX_NESTING - 1;
 406:   }
1.44 frystyk 407: 
1.75 frystyk 408:   /* Look at what element was closed */
1.2 timbl 409:   switch(element_number) {
 410:   case HTML_TITLE:
1.56 frystyk 411:    HTAnchor_setTitle(me->node_anchor, HTChunk_data(me->title));
1.2 timbl 412:    break;
 413:    
 414:   case HTML_PRE:
1.4 timbl 415:    if (me->comment_start)
1.75 frystyk 416:      HTextImp_addText(me->text, me->comment_start, strlen(me->comment_start));
 417:    break;
 418:   }
1.44 frystyk 419: 
1.75 frystyk 420:   /* Call out to the layout engine */
 421:   HTextImp_endElement(me->text, element_number);
1.1 timbl 422: }
 423: 
1.53 frystyk 424: PRIVATE void HTML_put_entity (HTStructured * me, int entity_number)
1.1 timbl 425: {
1.75 frystyk 426:   if (!me->started) {
 427:    HTextImp_build(me->text, HTEXT_BEGIN);
 428:    me->started = YES;
 429:   }
 430:   if (entity_number>=0 && entity_number<ENTITY_SIZE)
 431:    HTML_put_string(me, *(CurrentEntityValues+entity_number));
1.1 timbl 432: }
1.2 timbl 433: 
1.53 frystyk 434: PUBLIC int HTML_flush (HTStructured * me)
1.42 frystyk 435: {
1.75 frystyk 436:   if (!me->started) {
 437:    HTextImp_build(me->text, HTEXT_BEGIN);
 438:    me->started = YES;
 439:   }
 440:   if (me->comment_end) HTML_put_string(me, me->comment_end);
 441:   return me->target ? FLUSH_TARGET(me) : HT_OK;
 442: }
 443: 
 444: PRIVATE int HTML_unparsedBeginElement (HTStructured * me, const char * b, int l)
 445: {
 446:   if (!me->started) {
 447:    HTextImp_build(me->text, HTEXT_BEGIN);
 448:    me->started = YES;
 449:   }
 450:   HTextImp_unparsedBeginElement(me->text, b, l);
 451:   return HT_OK;
1.42 frystyk 452: }
1.2 timbl 453: 
1.75 frystyk 454: PRIVATE int HTML_unparsedEndElement (HTStructured * me, const char * b, int l)
1.1 timbl 455: {
1.75 frystyk 456:   if (!me->started) {
 457:    HTextImp_build(me->text, HTEXT_BEGIN);
 458:    me->started = YES;
 459:   }
 460:   HTextImp_unparsedEndElement(me->text, b, l);
 461:   return HT_OK;
 462: }
1.4 timbl 463: 
1.75 frystyk 464: PRIVATE int HTML_unparsedEntity (HTStructured * me, const char * b, int l)
 465: {
 466:   if (!me->started) {
 467:    HTextImp_build(me->text, HTEXT_BEGIN);
 468:    me->started = YES;
1.2 timbl 469:   }
1.75 frystyk 470:   HTextImp_unparsedEntity(me->text, b, l);
 471:   return HT_OK;
 472: }
 473: 
 474: PUBLIC int HTML_free (HTStructured * me)
 475: {
 476:   if (!me->started) HTextImp_build(me->text, HTEXT_BEGIN);
 477:   if (me->comment_end) HTML_put_string(me, me->comment_end);
 478:   HTextImp_build(me->text, HTEXT_END);
1.76 ! frystyk 479:   HTextImp_delete(me->text);
1.56 frystyk 480:   HTChunk_delete(me->title);
1.75 frystyk 481:   if (me->target) FREE_TARGET(me);
1.58 frystyk 482:   HT_FREE(me);
1.42 frystyk 483:   return HT_OK;
1.1 timbl 484: }
 485: 
1.53 frystyk 486: PRIVATE int HTML_abort (HTStructured * me, HTList * e)
1.14 timbl 487: {
1.75 frystyk 488:   if (!me->started) HTextImp_build(me->text, HTEXT_BEGIN);
 489:   HTextImp_build(me->text, HTEXT_ABORT);
1.76 ! frystyk 490:   HTextImp_delete(me->text);
1.56 frystyk 491:   HTChunk_delete(me->title);
1.75 frystyk 492:   if (me->target) ABORT_TARGET(me);
1.58 frystyk 493:   HT_FREE(me);
1.42 frystyk 494:   return HT_ERROR;
1.1 timbl 495: }
 496: 
1.2 timbl 497: /*   Structured Object Class
 498: **   -----------------------
 499: */
1.60 frystyk 500: PRIVATE const HTStructuredClass HTMLPresentation = /* As opposed to print etc */
1.2 timbl 501: {       
1.75 frystyk 502:   "text/html",
 503:   HTML_flush,
 504:   HTML_free,
 505:   HTML_abort,
 506:   HTML_put_character,
 507:   HTML_put_string,
 508:   HTML_write,
 509:   HTML_start_element,
 510:   HTML_end_element,
 511:   HTML_put_entity,
 512:   HTML_unparsedBeginElement,
 513:   HTML_unparsedEndElement,
 514:   HTML_unparsedEntity
 515: };
1.4 timbl 516: 
1.75 frystyk 517: /*   Structured Text object
 518: **   ----------------------
1.2 timbl 519: **
1.16 timbl 520: **   The structured stream can generate either presentation,
1.4 timbl 521: **   or plain text, or HTML.
1.1 timbl 522: */
1.75 frystyk 523: PRIVATE HTStructured * HTML_new (HTRequest *  request,
 524:                 void *     param,
 525:                 HTFormat    input_format,
 526:                 HTFormat    output_format,
 527:                 HTStream *   output_stream)
 528: {
 529:   HTStructured * me = NULL;
 530:   if (request) {
 531:    if ((me = (HTStructured *) HT_CALLOC(1, sizeof(HTStructured))) == NULL)
 532:      HT_OUTOFMEM("HTML_new");
 533:    me->isa = &HTMLPresentation;
 534:    me->dtd = HTML_dtd();
 535:    me->request = request;
 536:    me->node_anchor = HTRequest_anchor(request);
 537:    me->title = HTChunk_new(128);
 538:    me->comment_start = NULL;
 539:    me->comment_end = NULL;
 540:    me->target = output_stream;
 541:    me->sp = me->stack + MAX_NESTING - 1;
 542: 
 543:    /* Create the text object */
 544:    me->text = HTextImp_new(me->request, me->node_anchor, me->target);
 545:   }
 546:   return me;
1.1 timbl 547: }
 548: 
1.2 timbl 549: /*   HTConverter for HTML to plain text
 550: **   ----------------------------------
1.1 timbl 551: **
1.2 timbl 552: **   This will convert from HTML to presentation or plain text.
1.1 timbl 553: */
1.75 frystyk 554: PUBLIC HTStream * HTMLToPlain (HTRequest *   request,
 555:                void *      param,
 556:                HTFormat     input_format,
 557:                HTFormat     output_format,
 558:                HTStream *    output_stream)
1.1 timbl 559: {
1.75 frystyk 560:   return SGML_new(HTML_dtd(), HTML_new(
1.16 timbl 561:    request, NULL, input_format, output_format, output_stream));
1.1 timbl 562: }
 563: 
 564: 
1.2 timbl 565: /*   HTConverter for HTML to C code
 566: **   ------------------------------
 567: **
1.36 frystyk 568: **   C code is like plain text but all non-preformatted code
1.2 timbl 569: **   is commented out.
 570: **   This will convert from HTML to presentation or plain text.
 571: */
1.75 frystyk 572: PUBLIC HTStream * HTMLToC (HTRequest * request,
 573:              void *    param,
 574:              HTFormat   input_format,
 575:              HTFormat   output_format,
 576:              HTStream *  output_stream)
 577: {
 578:   if (output_stream) {
 579:    HTStructured * html = NULL;
 580:    (*output_stream->isa->put_string)(output_stream, "/* "); /* Before title */
 581:    html = HTML_new(request, NULL, input_format, output_format, output_stream);
 582:    html->comment_start = "\n/* ";
 583:    html->dtd = HTML_dtd();
 584:    html->comment_end = " */\n";  /* Must start in col 1 for cpp */
 585:    return SGML_new(HTML_dtd(), html);
 586:   } else
 587:    return HTErrorStream();
1.1 timbl 588: }
 589: 
 590: 
1.2 timbl 591: /*   Presenter for HTML
 592: **   ------------------
 593: **
 594: **   This will convert from HTML to presentation or plain text.
 595: **
 596: **   Override this if you have a windows version
1.1 timbl 597: */
1.75 frystyk 598: PUBLIC HTStream * HTMLPresent (HTRequest *   request,
 599:                void *      param,
 600:                HTFormat     input_format,
 601:                HTFormat     output_format,
 602:                HTStream *    output_stream)
1.1 timbl 603: {
1.75 frystyk 604:   return SGML_new(HTML_dtd(), HTML_new(
1.16 timbl 605:    request, NULL, input_format, output_format, output_stream));
1.1 timbl 606: }
1.29 frystyk 607: 

Webmaster

AltStyle によって変換されたページ (->オリジナル) /