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

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

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.79 ! frystyk 6: **   @(#) $Id: HTML.c,v 1.78 1999年02月22日 22:10:11 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.78 frystyk 139:    HTTRACE(SGML_TRACE, "HTML Parser. Doesn't support this character set\n");
1.75 frystyk 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_TITLE:
 155:    HTChunk_putb(me->title, b, l);
 156:    /* Fall through */
1.71 frystyk 157:    
1.75 frystyk 158:   default:
 159:    HTextImp_addText(me->text, b, l);
1.71 frystyk 160:   }
1.42 frystyk 161:   return HT_OK;
1.1 timbl 162: }
 163: 
1.71 frystyk 164: PRIVATE int HTML_put_character (HTStructured * me, char c)
1.1 timbl 165: {
1.71 frystyk 166:   return HTML_write(me, &c, sizeof(char));
1.1 timbl 167: }
 168: 
1.64 frystyk 169: PRIVATE int HTML_put_string (HTStructured * me, const char* s)
1.1 timbl 170: {
1.71 frystyk 171:   return HTML_write(me, s, (int) strlen(s));
1.1 timbl 172: }
1.2 timbl 173: 
1.75 frystyk 174: PRIVATE void HTML_start_element (HTStructured *    me,
 175:                 int      element_number,
 176:                 const BOOL *  present,
 177:                 const char ** value)
 178: {
 179:   HTChildAnchor * address = NULL;
 180:   if (!me->started) {
 181:    HTextImp_build(me->text, HTEXT_BEGIN);
 182:    me->started = YES;
1.73 frystyk 183:   }
 184: 
1.75 frystyk 185:   /* Look at what element was started */
 186:   switch (element_number) {
1.2 timbl 187:   case HTML_A:
1.75 frystyk 188:    if (present[HTML_A_HREF] && value[HTML_A_HREF]) {
 189:      address = HTAnchor_findChildAndLink(
 190:        me->node_anchor,                    /* parent */
 191:        present[HTML_A_NAME] ? value[HTML_A_NAME] : NULL,    /* Tag */
 192:        value[HTML_A_HREF],                   /* Addresss */
 193:        present[HTML_A_REL] && value[HTML_A_REL] ? 
 194:        (HTLinkType) HTAtom_caseFor(value[HTML_A_REL]) : NULL);
1.2 timbl 195:      
1.75 frystyk 196:      if (present[HTML_A_TITLE] && value[HTML_A_TITLE]) {
 197:        HTLink * link = HTAnchor_mainLink((HTAnchor *) address);
 198:        HTParentAnchor * dest = HTAnchor_parent(HTLink_destination(link));
 199:        if (!HTAnchor_title(dest)) HTAnchor_setTitle(dest, value[HTML_A_TITLE]);
 200:      }
 201:      HTextImp_foundLink(me->text, element_number, HTML_A_HREF,
 202:                address, present, value);
1.78 frystyk 203:      HTTRACE(SGML_TRACE, "HTML Parser. Anchor `%s\'\n" _ value[HTML_A_HREF]);
1.75 frystyk 204:    }
 205:    break;
 206: 
 207:   case HTML_AREA:
 208:    if (present[HTML_AREA_HREF] && value[HTML_AREA_HREF]) {
 209:      address = HTAnchor_findChildAndLink(me->node_anchor, NULL,
 210:                        value[HTML_AREA_HREF], NULL);
 211:      HTextImp_foundLink(me->text, element_number, HTML_AREA_HREF,
 212:                address, present, value);
1.78 frystyk 213:      HTTRACE(SGML_TRACE, "HTML Parser. Image map area `%s\'\n" _ value[HTML_AREA_HREF]);
1.2 timbl 214:    }
1.75 frystyk 215:    break;
 216: 
 217:   case HTML_BASE:
 218:    if (present[HTML_BASE_HREF] && value[HTML_BASE_HREF]) {
 219:      HTAnchor_setBase(me->node_anchor, (char *) value[HTML_BASE_HREF]);
1.78 frystyk 220:      HTTRACE(SGML_TRACE, "HTML Parser. New base `%s\'\n" _ value[HTML_BASE_HREF]);
1.75 frystyk 221:    }
 222:    break;
 223: 
 224:   case HTML_BODY:
 225:    if (present[HTML_BODY_BACKGROUND] && value[HTML_BODY_BACKGROUND]) {
 226:      address = HTAnchor_findChildAndLink(me->node_anchor, NULL,
 227:                        value[HTML_BODY_BACKGROUND], NULL);
 228:      HTextImp_foundLink(me->text, element_number, HTML_BODY_BACKGROUND,
 229:                address, present, value);
1.78 frystyk 230:      HTTRACE(SGML_TRACE, "HTML Parser. Background `%s\'\n" _ value[HTML_BODY_BACKGROUND]);
1.75 frystyk 231:    }
 232:    break;
 233: 
1.77 frystyk 234:   case HTML_FORM:
 235:    if (present[HTML_FORM_ACTION] && value[HTML_FORM_ACTION]) {
 236:      address = HTAnchor_findChildAndLink(me->node_anchor, NULL,
 237:                        value[HTML_FORM_ACTION], NULL);
 238:      HTextImp_foundLink(me->text, element_number, HTML_FORM_ACTION,
 239:                address, present, value);
 240:    }
 241:    break;
 242: 
1.75 frystyk 243:   case HTML_FRAME:
 244:    if (present[HTML_FRAME_SRC] && value[HTML_FRAME_SRC]) {
 245:      address = HTAnchor_findChildAndLink(me->node_anchor, NULL,
 246:                        value[HTML_FRAME_SRC], NULL);
 247:      HTextImp_foundLink(me->text, element_number, HTML_FRAME_SRC,
 248:                address, present, value);
1.78 frystyk 249:      HTTRACE(SGML_TRACE, "HTML Parser. Frame `%s\'\n" _ value[HTML_FRAME_SRC]);
1.75 frystyk 250:    }
 251:    break;
 252:    
1.77 frystyk 253:   case HTML_INPUT:
 254:    if (present[HTML_INPUT_SRC] && value[HTML_INPUT_SRC]) {
 255:      address = HTAnchor_findChildAndLink(me->node_anchor, NULL,
 256:                        value[HTML_INPUT_SRC], NULL);
 257:      HTextImp_foundLink(me->text, element_number, HTML_INPUT_SRC,
 258:                address, present, value);
 259:    }
 260:    break;
 261: 
1.75 frystyk 262:   case HTML_IMG:
 263:    if (present[HTML_IMG_SRC] && value[HTML_IMG_SRC]) {
 264:      address = HTAnchor_findChildAndLink(me->node_anchor, NULL,
 265:                        value[HTML_IMG_SRC], NULL);
 266:      HTextImp_foundLink(me->text, element_number, HTML_IMG_SRC,
 267:                address, present, value);
 268:    }
 269:    break;
 270: 
 271:   case HTML_ISINDEX:
 272:    HTAnchor_setIndex(me->node_anchor);
 273:    break;
1.2 timbl 274:    
1.63 frystyk 275:   case HTML_LINK:
1.69 frystyk 276:    if (present[HTML_LINK_HREF] && value[HTML_LINK_HREF]) {
1.75 frystyk 277:      HTParentAnchor * dest = NULL;
 278:      address = HTAnchor_findChildAndLink(
1.73 frystyk 279:        me->node_anchor,                    /* parent */
 280:        present[HTML_A_NAME] ? value[HTML_A_NAME] : NULL,    /* Tag */
 281:        present[HTML_A_HREF] ? value[HTML_A_HREF] : NULL,    /* Addresss */
 282:        NULL);                         /* Rels */
1.75 frystyk 283:      dest = HTAnchor_parent(HTAnchor_followMainLink((HTAnchor *) address));
1.69 frystyk 284: 
 285:      /* If forward reference */
 286:      if ((present[HTML_LINK_REL] && value[HTML_LINK_REL])) {
 287:        char * strval = NULL;
 288:        char * ptr = NULL;
 289:        char * relation = NULL;
 290:        StrAllocCopy(strval, value[HTML_LINK_REL]);
 291:        ptr = strval;
 292:        while ((relation = HTNextLWSToken(&ptr)) != NULL) {
 293:          HTLink_add((HTAnchor *) me->node_anchor, (HTAnchor *) dest,
 294:                (HTLinkType) HTAtom_caseFor(relation),
 295:                METHOD_INVALID);
 296:        }
 297:        HT_FREE(strval);
 298:      }
 299: 
 300:      /* If reverse reference */
 301:      if ((present[HTML_LINK_REV] && value[HTML_LINK_REV])) {
 302:        char * strval = NULL;
 303:        char * ptr = NULL;
 304:        char * relation = NULL;
 305:        StrAllocCopy(strval, value[HTML_LINK_REV]);
 306:        ptr = strval;
 307:        while ((relation = HTNextLWSToken(&ptr)) != NULL) {
 308:          HTLink_add((HTAnchor *) dest, (HTAnchor *) me->node_anchor,
 309:                (HTLinkType) HTAtom_caseFor(relation),
 310:                METHOD_INVALID);
 311:        }
 312:        HT_FREE(strval);
 313:      }
1.63 frystyk 314: 
1.69 frystyk 315:      /* If we got any type information as well */
 316:      if (present[HTML_LINK_TYPE] && value[HTML_LINK_TYPE]) {
 317:        if (HTAnchor_format(dest) == WWW_UNKNOWN)
 318:          HTAnchor_setFormat(dest,
 319:                    (HTFormat) HTAtom_caseFor(value[HTML_LINK_TYPE]));
 320:      }
1.63 frystyk 321: 
1.75 frystyk 322:      /* Call out to the layout engine */
 323:      HTextImp_foundLink(me->text, element_number, HTML_LINK_HREF,
 324:                address, present, value);
1.70 frystyk 325:    }
1.75 frystyk 326:    break;
1.70 frystyk 327: 
 328:   case HTML_META:
 329:    if (present[HTML_META_NAME] && value[HTML_META_NAME]) {
 330:      HTAnchor_addMeta (me->node_anchor,
 331:               value[HTML_META_NAME],
 332:               (present[HTML_META_CONTENT] && value[HTML_META_CONTENT]) ?
 333:               value[HTML_META_CONTENT] : "");
1.69 frystyk 334:    }
1.75 frystyk 335:    break;
 336: 
 337:   case HTML_OBJECT:
 338:    if (present[HTML_OBJECT_CLASSID] && value[HTML_OBJECT_CLASSID]) {
 339:      address = HTAnchor_findChildAndLink(me->node_anchor, NULL,
 340:                        value[HTML_OBJECT_CLASSID], NULL);
 341:      HTextImp_foundLink(me->text, element_number, HTML_OBJECT_CLASSID,
 342:                address, present, value);
 343:    }
 344: 
 345:    if (present[HTML_OBJECT_CODEBASE] && value[HTML_OBJECT_CODEBASE]) {
 346:      address = HTAnchor_findChildAndLink(me->node_anchor, NULL,
 347:                        value[HTML_OBJECT_CODEBASE], NULL);
 348:      HTextImp_foundLink(me->text, element_number, HTML_OBJECT_CODEBASE,
 349:                address, present, value);
 350:    }
 351: 
 352:    if (present[HTML_OBJECT_DATA] && value[HTML_OBJECT_DATA]) {
 353:      address = HTAnchor_findChildAndLink(me->node_anchor, NULL,
 354:                        value[HTML_OBJECT_DATA], NULL);
 355:      HTextImp_foundLink(me->text, element_number, HTML_OBJECT_DATA,
 356:                address, present, value);
 357:    }
1.63 frystyk 358: 
1.75 frystyk 359:    if (present[HTML_OBJECT_ARCHIVE] && value[HTML_OBJECT_ARCHIVE]) {
 360:      address = HTAnchor_findChildAndLink(me->node_anchor, NULL,
 361:                        value[HTML_OBJECT_ARCHIVE], NULL);
 362:      HTextImp_foundLink(me->text, element_number, HTML_OBJECT_ARCHIVE,
 363:                address, present, value);
 364:    }
1.2 timbl 365: 
1.75 frystyk 366:    if (present[HTML_OBJECT_USEMAP] && value[HTML_OBJECT_USEMAP]) {
 367:      address = HTAnchor_findChildAndLink(me->node_anchor, NULL,
 368:                        value[HTML_OBJECT_USEMAP], NULL);
 369:      HTextImp_foundLink(me->text, element_number, HTML_OBJECT_USEMAP,
 370:                address, present, value);
1.2 timbl 371:    }
 372:    break;
 373: 
 374:   case HTML_PRE:
1.4 timbl 375:    if (me->comment_end)
1.75 frystyk 376:      HTextImp_addText(me->text, me->comment_end, strlen(me->comment_end));
1.2 timbl 377:    break;
1.11 timbl 378: 
1.75 frystyk 379:   case HTML_TITLE:
 380:     HTChunk_clear(me->title);
1.2 timbl 381:    break;
1.75 frystyk 382:   }
1.2 timbl 383: 
1.75 frystyk 384:   /* Update our parse stack */
 385:   if (SGML_findTagContents(me->dtd, element_number) != SGML_EMPTY) {
1.13 timbl 386:     if (me->sp == me->stack) {
1.78 frystyk 387:      HTTRACE(SGML_TRACE, "HTML Parser. Maximum nesting of %d exceded!\n" _ MAX_NESTING); 
1.44 frystyk 388:      me->overflow++;
1.12 timbl 389:      return;
 390:    }
1.4 timbl 391:    --(me->sp);
1.75 frystyk 392:    me->sp[0] = element_number;
1.10 timbl 393:   } 
1.75 frystyk 394: 
 395:   /* Call out to the layout engine */
 396:   HTextImp_beginElement(me->text, element_number, present, value);
1.1 timbl 397: }
1.10 timbl 398: 
1.53 frystyk 399: PRIVATE void HTML_end_element (HTStructured * me, int element_number)
1.1 timbl 400: {
1.75 frystyk 401:   if (!me->started) {
 402:    HTextImp_build(me->text, HTEXT_BEGIN);
 403:    me->started = YES;
1.1 timbl 404:   }
1.44 frystyk 405: 
1.75 frystyk 406:   /* Update our parse stack */
1.44 frystyk 407:   if (me->overflow > 0) {
 408:    me->overflow--;
 409:    return;
 410:   }
1.75 frystyk 411:   me->sp++;
1.67 frystyk 412:   if (me->sp > me->stack + MAX_NESTING - 1) {
1.78 frystyk 413:    HTTRACE(SGML_TRACE, "HTML Parser. Bottom of parse stack reached\n");
1.67 frystyk 414:    me->sp = me->stack + MAX_NESTING - 1;
 415:   }
1.44 frystyk 416: 
1.75 frystyk 417:   /* Look at what element was closed */
1.2 timbl 418:   switch(element_number) {
 419:   case HTML_TITLE:
1.56 frystyk 420:    HTAnchor_setTitle(me->node_anchor, HTChunk_data(me->title));
1.2 timbl 421:    break;
 422:    
 423:   case HTML_PRE:
1.4 timbl 424:    if (me->comment_start)
1.75 frystyk 425:      HTextImp_addText(me->text, me->comment_start, strlen(me->comment_start));
 426:    break;
 427:   }
1.44 frystyk 428: 
1.75 frystyk 429:   /* Call out to the layout engine */
 430:   HTextImp_endElement(me->text, element_number);
1.1 timbl 431: }
 432: 
1.53 frystyk 433: PRIVATE void HTML_put_entity (HTStructured * me, int entity_number)
1.1 timbl 434: {
1.75 frystyk 435:   if (!me->started) {
 436:    HTextImp_build(me->text, HTEXT_BEGIN);
 437:    me->started = YES;
 438:   }
 439:   if (entity_number>=0 && entity_number<ENTITY_SIZE)
 440:    HTML_put_string(me, *(CurrentEntityValues+entity_number));
1.1 timbl 441: }
1.2 timbl 442: 
1.53 frystyk 443: PUBLIC int HTML_flush (HTStructured * me)
1.42 frystyk 444: {
1.75 frystyk 445:   if (!me->started) {
 446:    HTextImp_build(me->text, HTEXT_BEGIN);
 447:    me->started = YES;
 448:   }
 449:   if (me->comment_end) HTML_put_string(me, me->comment_end);
 450:   return me->target ? FLUSH_TARGET(me) : HT_OK;
 451: }
 452: 
 453: PRIVATE int HTML_unparsedBeginElement (HTStructured * me, const char * b, int l)
 454: {
 455:   if (!me->started) {
 456:    HTextImp_build(me->text, HTEXT_BEGIN);
 457:    me->started = YES;
 458:   }
 459:   HTextImp_unparsedBeginElement(me->text, b, l);
 460:   return HT_OK;
1.42 frystyk 461: }
1.2 timbl 462: 
1.75 frystyk 463: PRIVATE int HTML_unparsedEndElement (HTStructured * me, const char * b, int l)
1.1 timbl 464: {
1.75 frystyk 465:   if (!me->started) {
 466:    HTextImp_build(me->text, HTEXT_BEGIN);
 467:    me->started = YES;
 468:   }
 469:   HTextImp_unparsedEndElement(me->text, b, l);
 470:   return HT_OK;
 471: }
1.4 timbl 472: 
1.75 frystyk 473: PRIVATE int HTML_unparsedEntity (HTStructured * me, const char * b, int l)
 474: {
 475:   if (!me->started) {
 476:    HTextImp_build(me->text, HTEXT_BEGIN);
 477:    me->started = YES;
1.2 timbl 478:   }
1.75 frystyk 479:   HTextImp_unparsedEntity(me->text, b, l);
 480:   return HT_OK;
 481: }
 482: 
 483: PUBLIC int HTML_free (HTStructured * me)
 484: {
 485:   if (!me->started) HTextImp_build(me->text, HTEXT_BEGIN);
 486:   if (me->comment_end) HTML_put_string(me, me->comment_end);
 487:   HTextImp_build(me->text, HTEXT_END);
1.76 frystyk 488:   HTextImp_delete(me->text);
1.56 frystyk 489:   HTChunk_delete(me->title);
1.75 frystyk 490:   if (me->target) FREE_TARGET(me);
1.58 frystyk 491:   HT_FREE(me);
1.42 frystyk 492:   return HT_OK;
1.1 timbl 493: }
 494: 
1.53 frystyk 495: PRIVATE int HTML_abort (HTStructured * me, HTList * e)
1.14 timbl 496: {
1.75 frystyk 497:   if (!me->started) HTextImp_build(me->text, HTEXT_BEGIN);
 498:   HTextImp_build(me->text, HTEXT_ABORT);
1.76 frystyk 499:   HTextImp_delete(me->text);
1.56 frystyk 500:   HTChunk_delete(me->title);
1.75 frystyk 501:   if (me->target) ABORT_TARGET(me);
1.58 frystyk 502:   HT_FREE(me);
1.42 frystyk 503:   return HT_ERROR;
1.1 timbl 504: }
 505: 
1.2 timbl 506: /*   Structured Object Class
 507: **   -----------------------
 508: */
1.60 frystyk 509: PRIVATE const HTStructuredClass HTMLPresentation = /* As opposed to print etc */
1.2 timbl 510: {       
1.75 frystyk 511:   "text/html",
 512:   HTML_flush,
 513:   HTML_free,
 514:   HTML_abort,
 515:   HTML_put_character,
 516:   HTML_put_string,
 517:   HTML_write,
 518:   HTML_start_element,
 519:   HTML_end_element,
 520:   HTML_put_entity,
 521:   HTML_unparsedBeginElement,
 522:   HTML_unparsedEndElement,
 523:   HTML_unparsedEntity
 524: };
1.4 timbl 525: 
1.75 frystyk 526: /*   Structured Text object
 527: **   ----------------------
1.2 timbl 528: **
1.16 timbl 529: **   The structured stream can generate either presentation,
1.4 timbl 530: **   or plain text, or HTML.
1.1 timbl 531: */
1.75 frystyk 532: PRIVATE HTStructured * HTML_new (HTRequest *  request,
 533:                 void *     param,
 534:                 HTFormat    input_format,
 535:                 HTFormat    output_format,
 536:                 HTStream *   output_stream)
 537: {
 538:   HTStructured * me = NULL;
 539:   if (request) {
 540:    if ((me = (HTStructured *) HT_CALLOC(1, sizeof(HTStructured))) == NULL)
 541:      HT_OUTOFMEM("HTML_new");
 542:    me->isa = &HTMLPresentation;
 543:    me->dtd = HTML_dtd();
 544:    me->request = request;
 545:    me->node_anchor = HTRequest_anchor(request);
 546:    me->title = HTChunk_new(128);
 547:    me->comment_start = NULL;
 548:    me->comment_end = NULL;
 549:    me->target = output_stream;
 550:    me->sp = me->stack + MAX_NESTING - 1;
 551: 
 552:    /* Create the text object */
 553:    me->text = HTextImp_new(me->request, me->node_anchor, me->target);
 554:   }
 555:   return me;
1.1 timbl 556: }
 557: 
1.2 timbl 558: /*   HTConverter for HTML to plain text
 559: **   ----------------------------------
1.1 timbl 560: **
1.2 timbl 561: **   This will convert from HTML to presentation or plain text.
1.1 timbl 562: */
1.75 frystyk 563: PUBLIC HTStream * HTMLToPlain (HTRequest *   request,
 564:                void *      param,
 565:                HTFormat     input_format,
 566:                HTFormat     output_format,
 567:                HTStream *    output_stream)
1.1 timbl 568: {
1.75 frystyk 569:   return SGML_new(HTML_dtd(), HTML_new(
1.16 timbl 570:    request, NULL, input_format, output_format, output_stream));
1.1 timbl 571: }
 572: 
 573: 
1.2 timbl 574: /*   HTConverter for HTML to C code
 575: **   ------------------------------
 576: **
1.36 frystyk 577: **   C code is like plain text but all non-preformatted code
1.2 timbl 578: **   is commented out.
 579: **   This will convert from HTML to presentation or plain text.
 580: */
1.75 frystyk 581: PUBLIC HTStream * HTMLToC (HTRequest * request,
 582:              void *    param,
 583:              HTFormat   input_format,
 584:              HTFormat   output_format,
 585:              HTStream *  output_stream)
 586: {
 587:   if (output_stream) {
 588:    HTStructured * html = NULL;
 589:    (*output_stream->isa->put_string)(output_stream, "/* "); /* Before title */
 590:    html = HTML_new(request, NULL, input_format, output_format, output_stream);
 591:    html->comment_start = "\n/* ";
 592:    html->dtd = HTML_dtd();
 593:    html->comment_end = " */\n";  /* Must start in col 1 for cpp */
 594:    return SGML_new(HTML_dtd(), html);
 595:   } else
 596:    return HTErrorStream();
1.1 timbl 597: }
 598: 
 599: 
1.2 timbl 600: /*   Presenter for HTML
 601: **   ------------------
 602: **
 603: **   This will convert from HTML to presentation or plain text.
 604: **
 605: **   Override this if you have a windows version
1.1 timbl 606: */
1.75 frystyk 607: PUBLIC HTStream * HTMLPresent (HTRequest *   request,
 608:                void *      param,
 609:                HTFormat     input_format,
 610:                HTFormat     output_format,
 611:                HTStream *    output_stream)
1.1 timbl 612: {
1.75 frystyk 613:   return SGML_new(HTML_dtd(), HTML_new(
1.16 timbl 614:    request, NULL, input_format, output_format, output_stream));
1.1 timbl 615: }
1.29 frystyk 616: 

Webmaster

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