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

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

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

Webmaster

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