/* HTML Generator
** ==============
**
** This version of the HTML object sends HTML markup to the output stream.
**
** Bugs: Line wrapping is not done at all.
** All data handled as PCDATA.
** Should convert old XMP, LISTING and PLAINTEXT to PRE.
**
** It is not obvious to me right now whether the HEAD should be generated
** from the incomming data or the anchor. Currently it's from the former
** which is cleanest.
*/
#include "../config.h"
/* Implements:
*/
#include "HTMLGen.h"
#include
#include "HTMLDTD.h"
#include "HTStream.h"
#include "SGML.h"
#include "HTFormat.h"
#define PUTC(c) (*me->targetClass.put_character)(me->target, c)
#define PUTS(s) (*me->targetClass.put_string)(me->target, s)
#define PUTB(s,l) (*me->targetClass.put_block)(me->target, s, l)
/* HTML Object
** -----------
*/
struct _HTStream {
WWW_CONST HTStreamClass * isa;
HTStream * target;
HTStreamClass targetClass; /* COPY for speed */
};
struct _HTStructured {
WWW_CONST HTStructuredClass * isa;
HTStream * target;
HTStreamClass targetClass; /* COPY for speed */
};
/* Character handling
** ------------------
*/
PRIVATE void HTMLGen_put_character ARGS2(HTStructured *, me, char, c)
{
PUTC(c);
}
/* String handling
** ---------------
*/
PRIVATE void HTMLGen_put_string ARGS2(HTStructured *, me, WWW_CONST char*, s)
{
PUTS(s);
}
PRIVATE void HTMLGen_write ARGS3(HTStructured *, me, WWW_CONST char*, s, int, l)
{
PUTB(s,l);
}
/* Start Element
** -------------
*/
PRIVATE void HTMLGen_start_element ARGS4(
HTStructured *, me,
int, element_number,
WWW_CONST BOOL*, present,
WWW_CONST char **, value)
{
int i;
HTTag * tag = &HTML_dtd.tags[element_number];
PUTC('<');
PUTS(tag->name);
if (present) for (i=0; i< tag->number_of_attributes; i++) {
if (present[i]) {
PUTC(' ');
PUTS(tag->attributes[i].name);
if (value[i]) {
PUTS("=\"");
PUTS(value[i]);
PUTC('"');
}
}
}
PUTC('>');
}
/* End Element
** -----------
**
*/
/* When we end an element, the style must be returned to that
** in effect before that element. Note that anchors (etc?)
** don't have an associated style, so that we must scan down the
** stack for an element with a defined style. (In fact, the styles
** should be linked to the whole stack not just the top one.)
** TBL 921119
*/
PRIVATE void HTMLGen_end_element ARGS2(HTStructured *, me,
int , element_number)
{
PUTS("");
PUTS(HTML_dtd.tags[element_number].name);
PUTC('>');
}
/* Expanding entities
** ------------------
**
*/
PRIVATE void HTMLGen_put_entity ARGS2(HTStructured *, me, int, entity_number)
{
PUTC('&');
PUTS(HTML_dtd.entity_names[entity_number]);
PUTC(';');
}
/* Free an HTML object
** -------------------
**
** Note that the SGML parsing context is freed, but the created object is not,
** as it takes on an existence of its own unless explicitly freed.
*/
PRIVATE void HTMLGen_free ARGS1(HTStructured *, me)
{
(*me->targetClass.free)(me->target); /* ripple through */
free(me);
}
PRIVATE void HTMLGen_end_document ARGS1(HTStructured *, me)
{
PUTC('\n'); /* Make sure ends with newline for sed etc etc */
(*me->targetClass.end_document)(me->target);
}
PRIVATE void HTMLGen_handle_interrupt ARGS1(HTStructured *, me)
{
(*me->targetClass.handle_interrupt)(me->target);
}
PRIVATE void PlainToHTML_end_document ARGS1(HTStructured *, me)
{
PUTS("
\n\n");
return me;
}