Annotation of libwww/Library/src/HTMLGen.c, revision 2.1
2.1 ! timbl 1: /* HTML Generator
! 2: ** ==============
! 3: **
! 4: ** This version of the HTML object sends HTML markup to the output stream.
! 5: **
! 6: ** Bugs: Line wrapping is not done at all.
! 7: ** All data handled as PCDATA.
! 8: ** Should convert old XMP, LISTING and PLAINTEXT to PRE.
! 9: **
! 10: ** It is not obvious to me right now whether the HEAD should be generated
! 11: ** from the incomming data or the anchor. Currently itis from the former
! 12: ** which is cleanest.
! 13: */
! 14:
! 15: /* Implements:
! 16: */
! 17: #include "HTMLGen.h"
! 18:
! 19: #include <stdio.h>
! 20: #include "HTMLDTD.h"
! 21: #include "HTStream.h"
! 22: #include "SGML.h"
! 23: #include "HTFormat.h"
! 24:
! 25: #define PUTC(c) (*this->targetClass.put_character)(this->target, c)
! 26: #define PUTS(s) (*this->targetClass.put_string)(this->target, s)
! 27: #define PUTB(s,l) (*this->targetClass.write)(this->target, s, l)
! 28:
! 29: /* HTML Object
! 30: ** -----------
! 31: */
! 32:
! 33: struct _HTStream {
! 34: CONST HTStreamClass * isa;
! 35: HTStream * target;
! 36: HTStreamClass targetClass; /* COPY for speed */
! 37: };
! 38:
! 39: struct _HTStructured {
! 40: CONST HTStructuredClass * isa;
! 41: HTStream * target;
! 42: HTStreamClass targetClass; /* COPY for speed */
! 43: };
! 44:
! 45:
! 46: /* Character handling
! 47: ** ------------------
! 48: */
! 49: PRIVATE void HTMLGen_put_character ARGS2(HTStructured *, this, char, c)
! 50: {
! 51: PUTC(c);
! 52: }
! 53:
! 54:
! 55:
! 56: /* String handling
! 57: ** ---------------
! 58: */
! 59: PRIVATE void HTMLGen_put_string ARGS2(HTStructured *, this, CONST char*, s)
! 60: {
! 61: PUTS(s);
! 62: }
! 63:
! 64: PRIVATE void HTMLGen_write ARGS3(HTStructured *, this, CONST char*, s, int, l)
! 65: {
! 66: PUTB(s,l);
! 67: }
! 68:
! 69:
! 70: /* Start Element
! 71: ** -------------
! 72: */
! 73: PRIVATE void HTMLGen_start_element ARGS4(
! 74: HTStructured *, this,
! 75: int, element_number,
! 76: BOOL*, present,
! 77: char **, value)
! 78: {
! 79: int i;
! 80:
! 81: HTTag * tag = &HTML_dtd.tags[element_number];
! 82: PUTC('<');
! 83: PUTS(tag->name);
! 84: if (present) for (i=0; i< tag->number_of_attributes; i++) {
! 85: if (present[i]) {
! 86: PUTC(' ');
! 87: PUTS(tag->attributes[i].name);
! 88: if (value[i]) {
! 89: PUTS("=\"");
! 90: PUTS(value[i]);
! 91: PUTC('"');
! 92: }
! 93: }
! 94: }
! 95: PUTC('>');
! 96: }
! 97:
! 98:
! 99: /* End Element
! 100: ** -----------
! 101: **
! 102: */
! 103: /* When we end an element, the style must be returned to that
! 104: ** in effect before that element. Note that anchors (etc?)
! 105: ** don't have an associated style, so that we must scan down the
! 106: ** stack for an element with a defined style. (In fact, the styles
! 107: ** should be linked to the whole stack not just the top one.)
! 108: ** TBL 921119
! 109: */
! 110: PRIVATE void HTMLGen_end_element ARGS2(HTStructured *, this,
! 111: int , element_number)
! 112: {
! 113: PUTS("</");
! 114: PUTS(HTML_dtd.tags[element_number].name);
! 115: PUTC('>');
! 116: }
! 117:
! 118:
! 119: /* Expanding entities
! 120: ** ------------------
! 121: **
! 122: */
! 123:
! 124: PRIVATE void HTMLGen_put_entity ARGS2(HTStructured *, this, int, entity_number)
! 125: {
! 126: PUTC('&');
! 127: PUTS(HTML_dtd.entity_names[entity_number]);
! 128: PUTC(';');
! 129: }
! 130:
! 131:
! 132:
! 133: /* Free an HTML object
! 134: ** -------------------
! 135: **
! 136: ** Note that the SGML parsing context is freed, but the created object is not,
! 137: ** as it takes on an existence of its own unless explicitly freed.
! 138: */
! 139: PRIVATE void HTMLGen_free ARGS1(HTStructured *, this)
! 140: {
! 141: (*this->targetClass.free)(this->target); /* ripple through */
! 142: free(this);
! 143: }
! 144:
! 145:
! 146:
! 147: PRIVATE void HTMLGen_end_document ARGS1(HTStructured *, this)
! 148: {
! 149: PUTC('\n'); /* Make sure ends with newline for sed etc etc */
! 150: (*this->targetClass.end_document)(this->target);
! 151: }
! 152:
! 153:
! 154: PRIVATE void PlainToHTML_end_document ARGS1(HTStream *, this)
! 155: {
! 156: PUTS("</PRE></BODY>\n");/* Make sure ends with newline for sed etc etc */
! 157: (*this->targetClass.end_document)(this->target);
! 158: }
! 159:
! 160:
! 161:
! 162: /* Structured Object Class
! 163: ** -----------------------
! 164: */
! 165: PUBLIC CONST HTStructuredClass HTMLGeneration = /* As opposed to print etc */
! 166: {
! 167: "text/html",
! 168: HTMLGen_free,
! 169: HTMLGen_end_document,
! 170: HTMLGen_put_character, HTMLGen_put_string, HTMLGen_write,
! 171: HTMLGen_start_element, HTMLGen_end_element,
! 172: HTMLGen_put_entity
! 173: };
! 174:
! 175:
! 176: /* Subclass-specific Methods
! 177: ** -------------------------
! 178: */
! 179:
! 180: PUBLIC HTStructured * HTMLGenerator ARGS1(HTStream *, output)
! 181: {
! 182: HTStructured* this = (HTStructured*)malloc(sizeof(*this));
! 183: if (this == NULL) outofmem(__FILE__, "HTMLGenerator");
! 184: this->isa = &HTMLGeneration;
! 185:
! 186: this->target = output;
! 187: this->targetClass = *this->target->isa; /* Copy pointers to routines for speed*/
! 188:
! 189: return this;
! 190: }
! 191:
! 192: /* Stream Object Class
! 193: ** -------------------
! 194: **
! 195: ** Ok so this object just converts a plain text stream into HTML
! 196: */
! 197: PUBLIC CONST HTStreamClass PlainToHTMLConversion = /* As opposed to print etc */
! 198: {
! 199: "plaintexttoHTML",
! 200: HTMLGen_free,
! 201: PlainToHTML_end_document,
! 202: HTMLGen_put_character,
! 203: HTMLGen_put_string,
! 204: HTMLGen_write,
! 205: };
! 206:
! 207:
! 208: /* HTConverter from plain text to HTML Stream
! 209: ** ------------------------------------------
! 210: */
! 211:
! 212: PUBLIC HTStream* HTPlainToHTML ARGS3(
! 213: HTPresentation *, pres,
! 214: HTParentAnchor *, anchor,
! 215: HTStream *, sink)
! 216: {
! 217: HTStream* this = (HTStream*)malloc(sizeof(*this));
! 218: if (this == NULL) outofmem(__FILE__, "PlainToHTML");
! 219: this->isa = &PlainToHTMLConversion;
! 220:
! 221: this->target = sink;
! 222: this->targetClass = *this->target->isa;
! 223: /* Copy pointers to routines for speed*/
! 224:
! 225: PUTS("<BODY>\n<PRE>\n");
! 226: return this;
! 227: }
! 228:
! 229:
Webmaster