HTML.CPP
/*++ 
 
Copyright (c) 1997  Microsoft Corporation 
 
Module Name:    html.cpp 
 
Abstract: 
 
   This module contains simple HTML authoring functions. 
 
 
--*/ 
 
#define WIN32_LEAN_AND_MEAN 
#include <windows.h> 
#include <httpext.h> 
 
#include <stdio.h> 
#include <stdarg.h> 
 
#include "html.h" 
 
 
void 
WriteString(  
    IN EXTENSION_CONTROL_BLOCK * pECB,  
    IN LPCSTR lpsz 
) 
{ 
    DWORD dwBytesWritten; 
 
    dwBytesWritten = lstrlen( lpsz ); 
    pECB->WriteClient( pECB->ConnID, (PVOID) lpsz, &dwBytesWritten, 0 ); 
} 
 
 
void  
HtmlCreatePage(  
    IN EXTENSION_CONTROL_BLOCK * pECB,  
    IN LPCSTR lpszTitle 
) 
{ 
    WriteString( pECB, "<HTML>\r\n\r\n" ); 
 
    if ( lpszTitle ) { 
        WriteString( pECB, "<HEAD><TITLE>" ); 
        HtmlWriteText( pECB, lpszTitle ); 
        WriteString( pECB, "</TITLE></HEAD>\r\n\r\n" ); 
    } 
    WriteString( pECB, "<BODY>\r\n\r\n" ); 
} 
 
 
void  
HtmlEndPage(  
    IN EXTENSION_CONTROL_BLOCK * pECB 
) 
{ 
    WriteString( pECB, "</BODY>\r\n\r\n" ); 
    WriteString( pECB, "</HTML>\r\n" ); 
} 
 
 
void  
HtmlHeading(  
    IN EXTENSION_CONTROL_BLOCK * pECB,  
    IN int nHeading, 
    IN LPCSTR lpszText 
) 
{ 
    HtmlBeginHeading( pECB, nHeading ); 
    HtmlWriteText( pECB, lpszText ); 
    HtmlEndHeading( pECB, nHeading ); 
} 
 
 
void  
HtmlBeginHeading(  
    IN EXTENSION_CONTROL_BLOCK * pECB,  
    IN int nHeading 
) 
{ 
    char szCode[16]; 
 
    wsprintf( szCode, "<H%i>", nHeading ); 
    WriteString( pECB, szCode ); 
} 
 
 
void  
HtmlEndHeading(  
    IN EXTENSION_CONTROL_BLOCK * pECB,  
    IN int nHeading 
) 
{ 
    char szCode[16]; 
 
    wsprintf( szCode, "</H%i>", nHeading ); 
    WriteString( pECB, szCode ); 
} 
 
 
void  
HtmlWriteTextLine(  
    IN EXTENSION_CONTROL_BLOCK * pECB,  
    IN LPCSTR lpsz 
) 
{ 
    HtmlWriteText( pECB, lpsz ); 
    WriteString( pECB, "\r\n" ); 
} 
 
 
void  
HtmlWriteText(  
    IN EXTENSION_CONTROL_BLOCK * pECB,  
    IN LPCSTR lpsz 
) 
{ 
    char szBuf[1028]; 
    int nLen; 
    int i; 
 
    //  
    // Build up enough data to make call to WriteString 
    // worthwhile; convert special chars too. 
    //  
    nLen = 0; 
    for ( i = 0; lpsz[i]; i++ ) { 
        if ( lpsz[i] == '<' ) 
            lstrcpy( &szBuf[nLen], "<" ); 
        else if ( lpsz[i] == '>' ) 
            lstrcpy( &szBuf[nLen], ">" ); 
        else if ( lpsz[i] == '&' ) 
            lstrcpy( &szBuf[nLen], "&" ); 
        else if ( lpsz[i] == '\"' ) 
            lstrcpy( &szBuf[nLen], """ ); 
        else { 
            szBuf[nLen] = lpsz[i]; 
            szBuf[nLen + 1] = 0; 
        } 
 
        nLen += lstrlen( &szBuf[nLen] ); 
 
        if ( nLen >= 1024 ) { 
            WriteString( pECB, szBuf ); 
            nLen = 0; 
        } 
    } 
 
    if ( nLen ) 
        WriteString( pECB, szBuf ); 
} 
 
 
void  
HtmlEndParagraph(  
    IN EXTENSION_CONTROL_BLOCK * pECB  
) 
{ 
    WriteString( pECB, "<P>\r\n" ); 
} 
 
 
// 
// HtmlHyperLink adds a hyptertext link.  lpszDoc is the destination 
// document, and lpszText is the display text. 
//  
// HtmlHyperLinkAndBookmark adds a hyperlink with a bookmark link. 
// HtmlBookmarkLink adds only a bookmark link. 
//  
 
void  
HtmlHyperLink(  
    IN EXTENSION_CONTROL_BLOCK * pECB,  
    IN LPCSTR lpszDoc,  
    IN LPCSTR lpszText 
) 
{ 
    WriteString( pECB, "<A HREF=\"" ); 
    HtmlWriteText( pECB, lpszDoc ); 
    WriteString( pECB, "\">" ); 
    HtmlWriteText( pECB, lpszText ); 
    WriteString( pECB, "</A>\r\n" ); 
} 
 
void  
HtmlHyperLinkAndBookmark(  
    IN EXTENSION_CONTROL_BLOCK * pECB, 
    IN LPCSTR lpszDoc,  
    IN LPCSTR lpszBookmark, 
    IN LPCSTR lpszText 
) 
{ 
    WriteString( pECB, "<A HREF=\"" ); 
    if ( lpszDoc ) 
        HtmlWriteText( pECB, lpszDoc ); 
    WriteString( pECB, "#" ); 
    HtmlWriteText( pECB, lpszBookmark ); 
    WriteString( pECB, "\">" ); 
    HtmlWriteText( pECB, lpszText ); 
    WriteString( pECB, "</A>\r\n" ); 
} 
 
 
void  
HtmlBookmarkLink(  
    IN EXTENSION_CONTROL_BLOCK * pECB,  
    IN LPCSTR lpszBookmark, 
    IN LPCSTR lpszText 
) 
{ 
    HtmlHyperLinkAndBookmark( pECB, NULL, lpszBookmark, lpszText ); 
} 
 
 
// 
// The following support list formatting. 
//  
 
void  
HtmlBeginUnnumberedList(  
    IN EXTENSION_CONTROL_BLOCK * pECB  
) 
{ 
    WriteString( pECB, "<UL>\r\n" ); 
} 
 
 
void  
HtmlBeginListItem(  
    IN EXTENSION_CONTROL_BLOCK * pECB  
) 
{ 
    WriteString( pECB, "<LI>" ); 
} 
 
 
void  
HtmlEndUnnumberedList(  
    IN EXTENSION_CONTROL_BLOCK * pECB  
) 
{ 
    WriteString( pECB, "</UL>" ); 
} 
 
 
void  
HtmlBeginNumberedList(  
    IN EXTENSION_CONTROL_BLOCK * pECB  
) 
{ 
    WriteString( pECB, "<OL>" ); 
} 
 
 
void  
HtmlEndNumberedList(  
    IN EXTENSION_CONTROL_BLOCK * pECB  
) 
{ 
    WriteString( pECB, "</OL>" ); 
} 
 
 
void  
HtmlBeginDefinitionList(  
    IN EXTENSION_CONTROL_BLOCK * pECB  
) 
{ 
    WriteString( pECB, "<DL>" ); 
} 
 
 
void  
HtmlEndDefinitionList(  
    IN EXTENSION_CONTROL_BLOCK * pECB  
) 
{ 
    WriteString( pECB, "</DL>" ); 
} 
 
 
void  
HtmlDefinition(  
    IN EXTENSION_CONTROL_BLOCK * pECB,  
    IN LPCSTR lpszTerm, 
    IN LPSTR lpszDef 
) 
{ 
    int nStart, nEnd, nLen; 
    char tcHolder; 
 
    WriteString( pECB, "<DT> " ); 
    HtmlWriteText( pECB, lpszTerm ); 
    WriteString( pECB, "\r\n" ); 
    WriteString( pECB, "<DD> " ); 
 
    nStart = 0; 
    nLen = lstrlen( lpszDef ); 
    do { 
        nEnd = nStart + 70; 
        if ( nEnd >= nLen ) { 
            HtmlWriteText( pECB, &lpszDef[nStart] ); 
            WriteString( pECB, "\r\n" ); 
            break; 
        } 
        while ( nEnd > nStart ) 
            if ( lpszDef[nEnd] == ' ' ) 
                break; 
 
        if ( nEnd == nStart ) 
            // too long! 
            nEnd = nStart + 70; 
 
        // write defintion segment 
        tcHolder = lpszDef[nEnd]; 
        lpszDef[nEnd] = 0; 
        HtmlWriteText( pECB, &lpszDef[nStart] ); 
        WriteString( pECB, "\r\n" ); 
        lpszDef[nEnd] = tcHolder; 
        nStart = nEnd; 
 
        // skip excess whitespace 
        while ( lpszDef[nStart] == ' ' ) 
            nStart++; 
 
        // pretty formatting 
        if ( nStart < nLen ) 
            WriteString( pECB, "     " ); 
    } while ( nStart < nLen ); 
} 
 
 
// For complex defintions 
void  
HtmlBeginDefinitionTerm(  
    IN EXTENSION_CONTROL_BLOCK * pECB  
) 
{ 
    WriteString( pECB, "<DT>" ); 
} 
 
 
void  
HtmlBeginDefinition(  
    IN EXTENSION_CONTROL_BLOCK * pECB  
) 
{ 
    WriteString( pECB, "<DD>" ); 
} 
 
 
// 
// Text formatting 
//  
 
void  
HtmlBeginPreformattedText(  
    IN EXTENSION_CONTROL_BLOCK * pECB  
) 
{ 
    WriteString( pECB, "<PRE>" ); 
} 
 
 
void  
HtmlEndPreformattedText(  
    IN EXTENSION_CONTROL_BLOCK * pECB  
) 
{ 
    WriteString( pECB, "</PRE>" ); 
} 
 
 
void  
HtmlBeginBlockQuote(  
    IN EXTENSION_CONTROL_BLOCK * pECB  
) 
{ 
    WriteString( pECB, "<BLOCKQUOTE>" ); 
} 
 
 
void  
HtmlEndBlockQuote(  
    IN EXTENSION_CONTROL_BLOCK * pECB  
) 
{ 
    WriteString( pECB, "</BLOCKQUOTE>" ); 
} 
 
 
void  
HtmlBeginAddress(  
    IN EXTENSION_CONTROL_BLOCK * pECB  
) 
{ 
    WriteString( pECB, "<ADDRESS>" ); 
} 
 
 
void  
HtmlEndAddress(  
    IN EXTENSION_CONTROL_BLOCK * pECB  
) 
{ 
    WriteString( pECB, "</ADDRESS>" ); 
} 
 
 
void  
HtmlBeginDefine(  
    IN EXTENSION_CONTROL_BLOCK * pECB  
) 
{ 
    WriteString( pECB, "<DFN>" ); 
} 
 
 
void  
HtmlEndDefine(  
    IN EXTENSION_CONTROL_BLOCK * pECB  
) 
{ 
    WriteString( pECB, "</DFN>" ); 
} 
 
 
void  
HtmlBeginEmphasis(  
    IN EXTENSION_CONTROL_BLOCK * pECB  
) 
{ 
    WriteString( pECB, "<EM>" ); 
} 
 
 
void  
HtmlEndEmphasis(  
    IN EXTENSION_CONTROL_BLOCK * pECB  
) 
{ 
    WriteString( pECB, "</EM>" ); 
} 
 
 
void  
HtmlBeginCitation(  
    IN EXTENSION_CONTROL_BLOCK * pECB  
) 
{ 
    WriteString( pECB, "<CITE>" ); 
} 
 
 
void  
HtmlEndCitation(  
    IN EXTENSION_CONTROL_BLOCK * pECB  
) 
{ 
    WriteString( pECB, "</CITE>" ); 
} 
 
 
void  
HtmlBeginCode(  
    IN EXTENSION_CONTROL_BLOCK * pECB  
) 
{ 
    WriteString( pECB, "<CODE>" ); 
} 
 
 
void  
HtmlEndCode(  
    IN EXTENSION_CONTROL_BLOCK * pECB  
) 
{ 
    WriteString( pECB, "</CODE>" ); 
} 
 
 
void  
HtmlBeginKeyboard(  
    IN EXTENSION_CONTROL_BLOCK * pECB  
) 
{ 
    WriteString( pECB, "<KBD>" ); 
} 
 
 
void  
HtmlEndKeyboard(  
    IN EXTENSION_CONTROL_BLOCK * pECB  
) 
{ 
    WriteString( pECB, "</KBD>" ); 
} 
 
 
void  
HtmlBeginStatus(  
    IN EXTENSION_CONTROL_BLOCK * pECB  
) 
{ 
    WriteString( pECB, "<SAMP>" ); 
} 
 
 
void  
HtmlEndStatus(  
    IN EXTENSION_CONTROL_BLOCK * pECB  
) 
{ 
    WriteString( pECB, "</SAMP>" ); 
} 
 
 
void  
HtmlBeginStrong(  
    IN EXTENSION_CONTROL_BLOCK * pECB  
) 
{ 
    WriteString( pECB, "<STRONG>" ); 
} 
 
 
void  
HtmlEndStrong(  
    IN EXTENSION_CONTROL_BLOCK * pECB  
) 
{ 
    WriteString( pECB, "</STRONG>" ); 
} 
 
 
void  
HtmlBeginVariable(  
    IN EXTENSION_CONTROL_BLOCK * pECB  
) 
{ 
    WriteString( pECB, "<VAR>" ); 
} 
 
 
void  
HtmlEndVariable(  
    IN EXTENSION_CONTROL_BLOCK * pECB  
) 
{ 
    WriteString( pECB, "</VAR>" ); 
} 
 
 
void  
HtmlBold(  
    IN EXTENSION_CONTROL_BLOCK * pECB,  
    IN LPCSTR lpszText 
) 
{ 
    HtmlBeginBold( pECB ); 
    HtmlWriteText( pECB, lpszText ); 
    HtmlEndBold( pECB ); 
} 
 
 
void  
HtmlBeginBold(  
    IN EXTENSION_CONTROL_BLOCK * pECB  
) 
{ 
    WriteString( pECB, "<B>" ); 
} 
 
 
void  
HtmlEndBold(  
    IN EXTENSION_CONTROL_BLOCK * pECB  
) 
{ 
    WriteString( pECB, "</B>" ); 
} 
 
 
void  
HtmlItalic(  
    IN EXTENSION_CONTROL_BLOCK * pECB,  
    IN LPCSTR lpszText 
) 
{ 
    HtmlBeginItalic( pECB ); 
    HtmlWriteText( pECB, lpszText ); 
    HtmlEndItalic( pECB ); 
} 
 
 
void  
HtmlBeginItalic(  
    IN EXTENSION_CONTROL_BLOCK * pECB  
) 
{ 
    WriteString( pECB, "<I>" ); 
} 
 
 
void  
HtmlEndItalic(  
    IN EXTENSION_CONTROL_BLOCK * pECB  
) 
{ 
    WriteString( pECB, "</I>" ); 
} 
 
 
void  
HtmlFixed(  
    IN EXTENSION_CONTROL_BLOCK * pECB,  
    IN LPCSTR lpszText 
) 
{ 
    HtmlBeginFixed( pECB ); 
    HtmlWriteText( pECB, lpszText ); 
    HtmlEndFixed( pECB ); 
} 
 
 
void  
HtmlBeginFixed(  
    IN EXTENSION_CONTROL_BLOCK * pECB  
) 
{ 
    WriteString( pECB, "<TT>" ); 
} 
 
 
void  
HtmlEndFixed(  
    IN EXTENSION_CONTROL_BLOCK * pECB  
) 
{ 
    WriteString( pECB, "</TT>" ); 
} 
 
 
void  
HtmlLineBreak(  
    IN EXTENSION_CONTROL_BLOCK * pECB  
) 
{ 
    WriteString( pECB, "<BR>\r\n" ); 
} 
 
 
void  
HtmlHorizontalRule(  
    IN EXTENSION_CONTROL_BLOCK * pECB  
) 
{ 
    WriteString( pECB, "\r\n<HR>\r\n" ); 
} 
 
 
void  
HtmlImage(  
    IN EXTENSION_CONTROL_BLOCK * pECB,  
    IN LPCSTR lpszPicFile, 
    IN LPCSTR lpszAltText 
) 
{ 
    WriteString( pECB, "<IMG SRC = \"" ); 
    HtmlWriteText( pECB, lpszPicFile ); 
    WriteString( pECB, "\"" ); 
    if ( lpszAltText ) { 
        WriteString( pECB, " ALT = \"" ); 
        HtmlWriteText( pECB, lpszAltText ); 
        WriteString( pECB, "\"" ); 
    } 
    WriteString( pECB, ">\r\n" ); 
} 
 
 
void  
HtmlPrintf(  
    IN EXTENSION_CONTROL_BLOCK * pECB,  
    IN LPCSTR lpszFormat, 
    ... 
) 
{ 
    char szBuf[8192]; 
 
    va_list list; 
 
    va_start( list, lpszFormat ); 
 
    vsprintf( szBuf, lpszFormat, list ); 
    WriteString( pECB, szBuf ); 
 
    va_end( list ); 
}