Annotation of libwww/Library/src/HTMLGen.c, revision 2.4
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:
2.3 timbl 25: #define PUTC(c) (*me->targetClass.put_character)(me->target, c)
26: #define PUTS(s) (*me->targetClass.put_string)(me->target, s)
2.4 ! timbl 27: #define PUTB(s,l) (*me->targetClass.put_block)(me->target, s, l)
2.1 timbl 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: */
2.3 timbl 49: PRIVATE void HTMLGen_put_character ARGS2(HTStructured *, me, char, c)
2.1 timbl 50: {
51: PUTC(c);
52: }
53:
54:
55:
56: /* String handling
57: ** ---------------
58: */
2.3 timbl 59: PRIVATE void HTMLGen_put_string ARGS2(HTStructured *, me, CONST char*, s)
2.1 timbl 60: {
61: PUTS(s);
62: }
63:
2.3 timbl 64: PRIVATE void HTMLGen_write ARGS3(HTStructured *, me, CONST char*, s, int, l)
2.1 timbl 65: {
66: PUTB(s,l);
67: }
68:
69:
70: /* Start Element
71: ** -------------
72: */
73: PRIVATE void HTMLGen_start_element ARGS4(
2.3 timbl 74: HTStructured *, me,
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: */
2.3 timbl 110: PRIVATE void HTMLGen_end_element ARGS2(HTStructured *, me,
2.1 timbl 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:
2.3 timbl 124: PRIVATE void HTMLGen_put_entity ARGS2(HTStructured *, me, int, entity_number)
2.1 timbl 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: */
2.3 timbl 139: PRIVATE void HTMLGen_free ARGS1(HTStructured *, me)
2.1 timbl 140: {
2.3 timbl 141: (*me->targetClass.free)(me->target); /* ripple through */
142: free(me);
2.1 timbl 143: }
144:
145:
146:
2.3 timbl 147: PRIVATE void HTMLGen_end_document ARGS1(HTStructured *, me)
2.1 timbl 148: {
149: PUTC('\n'); /* Make sure ends with newline for sed etc etc */
2.3 timbl 150: (*me->targetClass.end_document)(me->target);
2.1 timbl 151: }
152:
153:
2.3 timbl 154: PRIVATE void PlainToHTML_end_document ARGS1(HTStructured *, me)
2.1 timbl 155: {
156: PUTS("</PRE></BODY>\n");/* Make sure ends with newline for sed etc etc */
2.3 timbl 157: (*me->targetClass.end_document)(me->target);
2.1 timbl 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: {
2.3 timbl 182: HTStructured* me = (HTStructured*)malloc(sizeof(*me));
183: if (me == NULL) outofmem(__FILE__, "HTMLGenerator");
184: me->isa = &HTMLGeneration;
2.1 timbl 185:
2.3 timbl 186: me->target = output;
187: me->targetClass = *me->target->isa; /* Copy pointers to routines for speed*/
2.1 timbl 188:
2.3 timbl 189: return me;
2.1 timbl 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: {
2.3 timbl 222: HTStream* me = (HTStream*)malloc(sizeof(*me));
223: if (me == NULL) outofmem(__FILE__, "PlainToHTML");
224: me->isa = (HTStreamClass*) &PlainToHTMLConversion;
2.1 timbl 225:
2.3 timbl 226: me->target = sink;
227: me->targetClass = *me->target->isa;
2.1 timbl 228: /* Copy pointers to routines for speed*/
229:
230: PUTS("<BODY>\n<PRE>\n");
2.3 timbl 231: return me;
2.1 timbl 232: }
233:
234:
Webmaster