Annotation of libwww/Library/src/HTMLGen.c, revision 2.2
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,
2.2 ! timbl 75: int, element_number,
! 76: CONST BOOL*, present,
! 77: CONST char **, value)
2.1 timbl 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:
2.2 ! timbl 154: PRIVATE void PlainToHTML_end_document ARGS1(HTStructured *, this)
2.1 timbl 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: **
2.2 ! timbl 195: ** This object just converts a plain text stream into HTML
! 196: ** It is officially a structured strem but only the stream bits exist.
! 197: ** This is just the easiest way of typecasting all the routines.
2.1 timbl 198: */
2.2 ! timbl 199: PRIVATE CONST HTStructuredClass PlainToHTMLConversion =
2.1 timbl 200: {
201: "plaintexttoHTML",
202: HTMLGen_free,
203: PlainToHTML_end_document,
204: HTMLGen_put_character,
205: HTMLGen_put_string,
206: HTMLGen_write,
2.2 ! timbl 207: NULL, /* Structured stuff */
! 208: NULL,
! 209: NULL
2.1 timbl 210: };
211:
212:
213: /* HTConverter from plain text to HTML Stream
214: ** ------------------------------------------
215: */
216:
217: PUBLIC HTStream* HTPlainToHTML ARGS3(
218: HTPresentation *, pres,
219: HTParentAnchor *, anchor,
220: HTStream *, sink)
221: {
222: HTStream* this = (HTStream*)malloc(sizeof(*this));
223: if (this == NULL) outofmem(__FILE__, "PlainToHTML");
2.2 ! timbl 224: this->isa = (HTStreamClass*) &PlainToHTMLConversion;
2.1 timbl 225:
226: this->target = sink;
227: this->targetClass = *this->target->isa;
228: /* Copy pointers to routines for speed*/
229:
230: PUTS("<BODY>\n<PRE>\n");
231: return this;
232: }
233:
234:
Webmaster