Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

385 lines
9.9 KiB

/*
Enhanced NCSA Mosaic from Spyglass
"Guitar"
Copyright 1994 Spyglass, Inc.
All Rights Reserved
Author(s):
Eric W. Sink [email protected]
*/
#include "all.h"
#define ELE_TEXT 1
#define ELE_IMAGE 2
#define ELE_VERTICALTAB 3
#define ELE_HR 4
#define ELE_NEWLINE 5
#define ELE_BEGINLIST 6
#define ELE_ENDLIST 7
#define ELE_LISTITEM 8
#define LINE_LENGTH 72
struct _plain
{
struct CharStream *pcs;
int nLines;
int x;
};
static int nIndentLevel = 0;
static BOOL bDoIndent = TRUE;
static BOOL bDoBullet = FALSE;
static void x_doindent(struct _plain *pp)
{
int j, k;
if (!bDoIndent)
return;
k = nIndentLevel / 2;
#ifdef DEBUG
printf("Here in x_doindent k = %d, nIndentLevel = %d, x = %d.\n", k, nIndentLevel, pp->x);
#endif
for (j = 0; j < k; j++)
{
if (bDoBullet && j == k-1)
{
CS_AddChar(pp->pcs, ' ');
CS_AddChar(pp->pcs, ' ');
if (j < 1)
CS_AddChar(pp->pcs, '*');
else if (j == 1)
CS_AddChar(pp->pcs, 'o');
else
CS_AddChar(pp->pcs, '+');
bDoBullet = FALSE;
}
CS_AddChar(pp->pcs, '\t');
}
if (k > 0)
bDoIndent = FALSE;
}
static void x_newline(struct _plain *pp)
{
#if defined(WIN32) || defined(MAC)
CS_AddChar(pp->pcs, 13); /* CR */
#endif
#if defined(WIN32) || defined(UNIX)
CS_AddChar(pp->pcs, 10); /* LF */
#endif
pp->nLines++;
pp->x = 0;
bDoIndent = TRUE;
}
static void x_add_string(struct _plain *pp, char *s, int len)
{
char *p;
char *q;
int mylen;
mylen = len;
q = s;
while (mylen > 0)
{
if ((pp->x + mylen) <= LINE_LENGTH)
{
x_doindent(pp);
CS_AddString(pp->pcs, q, mylen);
pp->x += mylen;
mylen = 0;
}
else
{
p = q + (LINE_LENGTH - pp->x);
while ((p > q) && (*p != ' '))
{
p--;
}
if (p > q)
{
x_doindent(pp);
CS_AddString(pp->pcs, q, p - q + 1);
mylen -= (p - q + 1);
q += (p - q + 1);
pp->x += (p - q + 1);
x_newline(pp);
}
else
{
if (pp->x)
{
x_newline(pp);
}
else
{
x_doindent(pp);
CS_AddString(pp->pcs, q, LINE_LENGTH);
mylen -= LINE_LENGTH;
q += LINE_LENGTH;
pp->x += LINE_LENGTH;
x_newline(pp);
}
}
}
}
}
static void x_AddElement(struct _plain *pPlain, struct _www *pdoc, struct _element *pel)
{
int j;
switch (pel->type)
{
case ELE_TAB:
CS_AddChar(pPlain->pcs, '\t');
break;
case ELE_TEXT:
if (pdoc->pStyles->sty[pel->iStyle]->freeFormat)
{
x_add_string(pPlain, &pdoc->pool.chars[pel->textOffset], pel->textLen);
}
else
{
x_doindent(pPlain);
CS_AddString(pPlain->pcs, &pdoc->pool.chars[pel->textOffset], pel->textLen);
}
break;
case ELE_IMAGE:
#if 0 /* not sure we really want to do this yet */
CS_AddChar(plain.pcs, '<');
if (pel->textLen)
{
x_add_string(pPlain, &pdoc->pool[pel->textOffset], pel->textLen);
}
else
{
x_add_string(pPlain, "IMAGE", 5);
}
CS_AddChar(plain.pcs, '>');
#endif
break;
case ELE_VERTICALTAB:
for (j = 0; j < pel->iBlankLines; j++)
{
x_newline(pPlain);
}
bDoIndent = TRUE;
break;
case ELE_HR:
x_newline(pPlain);
for (j = 0; j < LINE_LENGTH; j++)
{
CS_AddChar(pPlain->pcs, '-');
}
x_newline(pPlain);
break;
case ELE_NEWLINE:
if (pPlain->x || !pdoc->pStyles->sty[pel->iStyle]->freeFormat)
x_newline(pPlain);
bDoIndent = TRUE;
break;
case ELE_BEGINLIST:
#ifdef DEBUG
printf("Here in ELE_BEGINLIST, %d.\n", pel->IndentLevel);
#endif
nIndentLevel = pel->IndentLevel;
break;
case ELE_ENDLIST:
#ifdef DEBUG
printf("Here in ELE_ENDLIST, %d.\n", pel->IndentLevel);
#endif
nIndentLevel = pel->IndentLevel;
break;
case ELE_LISTITEM:
#ifdef DEBUG
printf("Here in ELE_LISTITEM, %d.\n", pel->IndentLevel);
#endif
nIndentLevel = pel->IndentLevel;
break;
case ELE_OPENLISTITEM:
#ifdef DEBUG
printf("Here in ELE_OPENLISTITEM, %d.\n", pel->IndentLevel);
#endif
nIndentLevel = pel->IndentLevel;
break;
case ELE_CLOSELISTITEM:
#ifdef DEBUG
printf("Here in ELE_CLOSELISTITEM, %d.\n", pel->IndentLevel);
#endif
nIndentLevel = pel->IndentLevel;
break;
case ELE_OUTDENT:
#ifdef DEBUG
printf("Here in ELE_OUTDENT, %d.\n", pel->IndentLevel);
#endif
nIndentLevel = pel->IndentLevel;
break;
case ELE_INDENT:
#ifdef DEBUG
printf("Here in ELE_INDENT, %d.\n", pel->IndentLevel);
#endif
nIndentLevel = pel->IndentLevel;
break;
case ELE_BULLET:
#ifdef DEBUG
printf("Here in ELE_BULLET, %d.\n", pel->IndentLevel);
#endif
bDoBullet = TRUE;
nIndentLevel = pel->IndentLevel;
break;
default:
break;
}
}
/* Convert the document to plain text, e.g. for a "Save As" command */
struct CharStream *W3Doc_GetPlainText(struct Mwin *tw)
{
struct _plain plain;
int i;
int nElementsFormatted;
struct _www *pdoc;
pdoc = tw->w3doc;
memset(&plain, 0, sizeof(plain));
plain.pcs = CS_Create();
if (plain.pcs)
{
WAIT_Push(tw, waitNoInteract, GTR_GetString(SID_INF_FORMATTING_PLAIN_TEXT));
nElementsFormatted = 0;
WAIT_SetRange(tw, 0, 100, pdoc->elementCount);
for (i = 0; i >= 0; i = pdoc->aElements[i].next)
{
nElementsFormatted++;
x_AddElement(&plain, pdoc, &pdoc->aElements[i]);
WAIT_SetTherm(tw, nElementsFormatted);
}
WAIT_Pop(tw);
}
return plain.pcs;
}
/* Convert the selected area into plain text */
struct CharStream *W3Doc_GetSelectedText(struct Mwin *tw)
{
struct _plain plain;
int i;
struct _www *pdoc;
pdoc = tw->w3doc;
memset(&plain, 0, sizeof(plain));
plain.pcs = CS_Create();
if (pdoc->selStart.elementIndex == -1)
return NULL;
if (plain.pcs)
{
#ifndef UNIX
WAIT_Push(tw, waitNoInteract, GTR_GetString(SID_INF_CONVERTING_SELECTION_TO_PLAIN_TEXT));
#endif
/* We need to specially handle the first element in case not all of it is
selected. */
if (pdoc->aElements[pdoc->selStart.elementIndex].type == ELE_TEXT)
{
i = pdoc->selStart.elementIndex;
if (i != pdoc->selEnd.elementIndex)
{
if (pdoc->pStyles->sty[pdoc->aElements[i].iStyle]->freeFormat)
{
x_add_string(&plain, &pdoc->pool.chars[pdoc->aElements[i].textOffset + pdoc->selStart.offset],
pdoc->aElements[i].textLen - pdoc->selStart.offset);
}
else
{
x_doindent(&plain);
CS_AddString(plain.pcs, &pdoc->pool.chars[pdoc->aElements[i].textOffset + pdoc->selStart.offset],
pdoc->aElements[i].textLen - pdoc->selStart.offset);
}
i = pdoc->aElements[i].next;
}
else
{
/* The selection begins and ends on this element */
i = pdoc->selStart.elementIndex;
if (pdoc->pStyles->sty[pdoc->aElements[i].iStyle]->freeFormat)
{
x_add_string(&plain, &pdoc->pool.chars[pdoc->aElements[i].textOffset + pdoc->selStart.offset],
pdoc->selEnd.offset - pdoc->selStart.offset);
}
else
{
x_doindent(&plain);
CS_AddString(plain.pcs, &pdoc->pool.chars[pdoc->aElements[i].textOffset + pdoc->selStart.offset],
pdoc->selEnd.offset - pdoc->selStart.offset);
}
i = -1; /* We're done */
}
}
else
{
i = pdoc->selStart.elementIndex;
}
while (i >= 0 && i != pdoc->selEnd.elementIndex)
{
x_AddElement(&plain, pdoc, &pdoc->aElements[i]);
i = pdoc->aElements[i].next;
}
/* Now we need to specially handle the last element, again in case not all of
it is selected. */
if (i >= 0)
{
if (pdoc->aElements[i].type == ELE_TEXT)
{
if (pdoc->pStyles->sty[pdoc->aElements[i].iStyle]->freeFormat)
{
x_add_string(&plain, &pdoc->pool.chars[pdoc->aElements[i].textOffset], pdoc->selEnd.offset);
}
else
{
x_doindent(&plain);
CS_AddString(plain.pcs, &pdoc->pool.chars[pdoc->aElements[i].textOffset],pdoc->selEnd.offset);
}
}
else
{
x_AddElement(&plain, pdoc, &pdoc->aElements[i]);
}
}
#ifndef UNIX
WAIT_Pop(tw);
#endif
}
return plain.pcs;
}