home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / Libraries / DCLAP 4j / Drtf / DHTMLHandler.cpp < prev    next >
Encoding:
Text File  |  1995-12-17  |  39.6 KB  |  1,634 lines  |  [TEXT/R*ch]

  1. // DHTMLHandler.cpp
  2. // d.g.gilbert
  3.  
  4.  
  5. #include "Dvibrant.h"
  6. #include "DFile.h"
  7. #include "DRichProcess.h"
  8. #include "DRichViewNu.h"
  9. #include "DHTMLHandler.h"
  10. #include "DHTMLprocess.h"
  11. #include "rtfchars.h" 
  12.  
  13.  
  14.     
  15. class DHTMLsetup  
  16. {
  17. public:
  18.     DHTMLsetup();
  19. };
  20.  
  21. static DHTMLsetup* gHTMLsetup = NULL;
  22. #if 0
  23. static DHTMLsetup theSetup; // construct it now !
  24. #endif
  25.  
  26. DHTMLsetup::DHTMLsetup()
  27. {
  28.     DHTMLprocess::InitKeys(); 
  29.     //ReadOutputMap("gen", gGenCharMap);
  30.   //gOutMap= gGenCharMap;
  31.     ////
  32.     //DRichprocess::gGenCharMap= DRichprocess::ReadOutputMap("gen");
  33.     //DRichprocess::gSymCharMap= DRichprocess::ReadOutputMap("sym");
  34.     gHTMLsetup = this;
  35. }
  36.  
  37.  
  38.  
  39.  
  40.  
  41.  
  42. //class  DHTMLHandler
  43.  
  44.  
  45. char* DHTMLHandler::IsRich(char* buf, ulong buflen)
  46. {
  47. // HTML doesn't have a fixed magic string -- usage is variable
  48. // some diagnostic strings (all case-insensitive)
  49. // </a> </head>
  50. // <html>  <head>  <body>  <title> 
  51. // uncertain: </ <a
  52. //    href=
  53.  
  54.     char* cp, *atbuf= buf;
  55.     if (buflen==0) buflen= StrLen(buf);
  56.     ulong len = buflen;
  57.     while (len>3) {
  58.         cp= (char*) MemChr(atbuf,'<',len);
  59.         if (cp) {
  60.             if (cp[1] == '/' && (cp[2] == 'a' || cp[2] == 'A') && cp[3] == '>') 
  61.                 return buf;
  62.             else if (!StrNICmp( cp, "<html>", 6)) return buf;
  63.             else if (!StrNICmp( cp, "<head>", 6)) return buf;
  64.             else if (!StrNICmp( cp, "<title>", 7)) return buf;
  65.             else if (!StrNICmp( cp, "<p>", 3)) return buf;   // ?? weak test but need
  66.             else if (!StrNICmp( cp, "<a href=", 9)) return buf;
  67.             //if (!StrNICmp( cp, "<a ", 3)) {  
  68.             //  unsigned long    at;
  69.             //    if (Nlm_StrngPos( cp, "</a>", 3, false, &at)) return true;
  70.             //    }
  71.             cp++;
  72.             len -= (cp - atbuf);
  73.             atbuf = cp;
  74.             }
  75.         else 
  76.             return NULL;    
  77.         }
  78.     return NULL;
  79. }
  80.  
  81.             
  82.  
  83. DHTMLHandler::DHTMLHandler( DRichView* itsDoc, DFile* savefile) :
  84.     DRichHandler( itsDoc, savefile)
  85. {
  86.     fFormatName = "HTML";
  87.     fMinDataToProcess= 128; // no fixed min, need to look at data...
  88.     if (!gHTMLsetup) gHTMLsetup= new DHTMLsetup();
  89. }
  90.  
  91. DHTMLHandler::~DHTMLHandler()
  92. {
  93. }
  94.  
  95.     
  96. DRichprocess* DHTMLHandler::NewProcessor( DFile* itsFile, Nlm_MonitorPtr progress)
  97. {
  98.     fProcessor = new DHTMLprocess( itsFile, fDoc, progress);
  99.     return fProcessor;
  100. }
  101.  
  102.  
  103. Boolean DHTMLHandler::ProcessData( char* cbeg, char* cend, Boolean endOfData, 
  104.                                                 ulong& dataRemaining) 
  105. {
  106.     char  * cp;  
  107.  
  108.     fcsave= 0;    
  109.     fclen= cend - cbeg; // + 1;
  110.     cp= cend; 
  111.     if (!endOfData) {
  112.         if ((fclen==0) || ( fProcessStage == kAtStart && fclen<fMinDataToProcess)) 
  113.             return false;
  114.         // scan for last newline and stop there !!
  115. #if 1 //TEST w/out << NEED THIS for at least some
  116.         while (cp - cbeg > fLastScanto && !(*cp == '\n' || *cp == '\r')) cp--;
  117.         if (cp < cend && (*cp == '\n' || *cp == '\r')) cp++;
  118. #endif
  119.         }
  120.  
  121. #if 1 //TEST w/out << NEED THIS for at least some
  122.     if (cp - cbeg <= fLastScanto) {
  123.         fLastScanto= cend - cbeg;  
  124.         if (!endOfData) return false; // !??! don't process line w/o end
  125.         else cp= cend; 
  126.         }
  127. #endif
  128.  
  129. #if 0 // bad nulls ??
  130.     if (*cp) cp++;
  131.     fcsave= *cp; 
  132.     *cp= 0;
  133. #endif
  134.  
  135.     fclen= cp - cbeg; // + 1; 
  136.     
  137.     if (fclen && fDocFile) {
  138.         if (cbeg[fclen-1] == 0) fclen--;  //?? 
  139.         fDocFile->WriteData( cbeg, fclen);
  140.         }    
  141.         
  142.     return this->ProcessData2( cp, cbeg, cend, endOfData, dataRemaining);
  143. }
  144.  
  145.  
  146.  
  147.  
  148.  
  149. // class DHTMLprocess
  150.  
  151.  
  152.  
  153. //static char        gGenCharMap[rtfSC_MaxChar];
  154. //static char * gOutMap = gGenCharMap;
  155.  
  156. DHTMLprocess::DHTMLprocess( DFile* itsFile, DRichView* itsDoc, Nlm_MonitorPtr progress) :
  157.     DRichprocess( itsFile, itsDoc, progress),
  158.     fStop(0), fTokenLen(0), fListType(0), fListNum(0), fDLStyle(0), fQuote(0),
  159.     fCurControl(0), fCurField(0), fPicLink(0), fAnchorLink(0),
  160.     fURLstore(NULL), fNamestore(NULL), fFormURL(NULL), fGoplusStore(NULL),
  161.     fMethodstore(NULL), fValstore(NULL), fTypestore(NULL), fOptionstore(NULL),
  162.     fPushSize(0), fPushBuf(NULL), fPushBufstore(NULL),
  163.     fInHead(true), fInParam(false), fInForm(false), fInControl(false), fIsMap(false),
  164.     fTurnOn(true), fIsIndex(false), fPreformat(false)
  165.     //fOutMap= DRichprocess::gGenCharMap;
  166. }
  167.  
  168.     
  169. DHTMLprocess::~DHTMLprocess()
  170. {
  171.     MemFree(fURLstore);
  172.     MemFree(fNamestore);
  173.     MemFree(fMethodstore);
  174.     MemFree(fGoplusStore);
  175.     MemFree(fFormURL);
  176.     MemFree(fValstore);
  177.     MemFree(fTypestore);
  178.     MemFree(fOptionstore);
  179.     MemFree(fPushBufstore);
  180. }
  181.  
  182.  
  183. //static
  184. short DHTMLprocess::Hash( char    *s)
  185. {
  186.     char    c;
  187.     short    val = 0;
  188.     while ((c = *s++) != '\0') val += (int) tolower(c);
  189.     return (val);
  190. }
  191.  
  192. //static
  193. void DHTMLprocess::InitKeys()
  194. {
  195.     HTMLKey    *rp;
  196.     
  197.     for (rp = htmlKeys; rp->htmlKStr != NULL; rp++) {
  198.         rp->htmlKHash = Hash(rp->htmlKStr);
  199.         }
  200.     for (rp = htmlAmperChars; rp->htmlKStr != NULL; rp++) {
  201.         rp->htmlKHash = Hash(rp->htmlKStr);
  202.         }
  203. }
  204.  
  205.  
  206. void DHTMLprocess::Lookup( char    *s, HTMLKey* keyset)
  207. {
  208.     HTMLKey    *rp;
  209.     short    hash;
  210.     
  211. #ifdef COMP_BOR  /* ?? dgg */  
  212.     int LIBCALL (*cmp)(const char*,const char*);
  213. #else
  214. #ifdef COMP_SYMC
  215.   int (* LIBCALL cmp)(const char*, const char*);
  216. #else
  217.     int (*cmp)(const char*,const char*);
  218. #endif
  219. #endif
  220.     if (keyset == htmlAmperChars) cmp= Nlm_StringCmp;
  221.     else cmp= Nlm_StringICmp;
  222.     
  223.     fClass = tokUnknown;
  224.     if (*s == 0) return;
  225.     hash = Hash(s);
  226.     for (rp = keyset; rp->htmlKStr != NULL; rp++) {
  227.         if (hash == rp->htmlKHash && cmp(s, rp->htmlKStr) == 0) {
  228.             fClass = tokControl;
  229.             fMajor = rp->htmlKMajor;
  230.             fMinor = rp->htmlKMinor;
  231.             fStop  = rp->htmlKStop;
  232.             return;
  233.         }
  234.     }
  235. }
  236.  
  237.  
  238.  
  239.  
  240. void DHTMLprocess::Pushback(char c) // private
  241. {
  242.     if (c != EOF) {
  243.         fPushedChar = c;
  244.         }
  245. }
  246.  
  247.  
  248.  
  249. enum {
  250.     kGotNone = 0,
  251.     kGotToken,
  252.     kGotParam
  253.     };
  254.     
  255. short DHTMLprocess::GotTokenOrParam() // private
  256. {
  257.     if (fTokenLen>0) { // need to process last token ! 
  258.         fTokenBuf[fTokenLen] = '\0';
  259.         fTokenLen= 0;
  260.         if (fInParam) {
  261.             switch (fCurField) {
  262.             
  263.                 case htmlIsMap:
  264.                     fIsMap= true;
  265.                     break;
  266.                     
  267.                 case htmlAction:
  268.                 case htmlImageSrc:
  269.                 case htmlHref:
  270.                     MemFree(fURLstore);
  271.                     fURLstore= StrDup(fTokenBuf);
  272.                     break;
  273.  
  274.                 case htmlName:
  275.                     MemFree(fNamestore);
  276.                     fNamestore= StrDup(fTokenBuf);
  277.                     break;
  278.   
  279.                 case htmlMethod:
  280.                     MemFree(fMethodstore);
  281.                     fMethodstore= StrDup(fTokenBuf);
  282.                     break;
  283.                 case htmlValue:
  284.                     MemFree(fValstore);
  285.                     fValstore= StrDup(fTokenBuf);
  286.                     break;
  287.                 case htmlType:
  288.                     MemFree(fTypestore);
  289.                     fTypestore= StrDup(fTokenBuf);
  290.                     break;
  291.                 case htmlOption:
  292.                     MemFree(fOptionstore);
  293.                     fOptionstore= StrDup(fTokenBuf);
  294.                     break;
  295.  
  296.                 }
  297.             fInParam= false;
  298.             return kGotParam;
  299.             }
  300.         else {
  301.             Lookup( fTokenBuf, htmlKeys);     // sets class, major, minor 
  302.             return kGotToken;
  303.             }
  304.         }
  305.     else
  306.         return kGotNone;
  307. }
  308.  
  309.  
  310.  
  311. void DHTMLprocess::GetToken1() // private
  312. {
  313.     short    c;
  314.  
  315.     fClass = tokUnknown;   // initialize token vars  
  316.     fParam = tokNoParam;
  317.  
  318.     if (fPushedChar != EOF) {
  319.         c = fPushedChar;
  320.         fPushedChar = EOF;
  321.         }
  322.     else 
  323.         c= GetOneChar();
  324.          
  325.     switch ( c ) {
  326.     
  327.         case EOF:
  328.             fClass = tokEOF;
  329.             fMajor = tokEOF;
  330.             return;
  331.             
  332.         case tokBreakInData:
  333.             fClass= tokEOF;
  334.             fMajor= tokBreakInData;
  335.             return;
  336.                             
  337.         case '>':
  338.             {
  339.             if (!fInControl) goto cHandleText;
  340.             if (GotTokenOrParam() != kGotNone) {
  341.                 Pushback(c);
  342.                 return;
  343.                 }
  344.             fInControl= false;
  345.             fClass = tokControl;
  346.             fMajor = htmlEndControl;
  347.             fMinor = -1;
  348.             return;
  349.             }
  350.             
  351.         case '<':
  352.             if (fQuote == (char)234) { // kInFormText
  353.                 fInControl= false;
  354.                 this->handleLinkAttr( fCurControl);  
  355.                 }
  356.             fInControl= true;
  357.             fTurnOn= true;
  358.             fInParam= false;
  359.             fQuote= 0;
  360.             fCurControl= 0;
  361.             fCurField= 0;
  362.             fTokenLen= 0;
  363.             fPicLink= 0;
  364.             //fAnchorLink= 0;
  365.             fClass = tokDropchar;
  366.             return;
  367.  
  368.         default: 
  369.         
  370.             if (fInControl) {
  371.                     
  372.                 // !! need to deal with complex  options in <Control ... > syntax
  373.                 // e.g. <a href="some.string" name="some.string" etc. > text here </a>
  374.                 // e.g. < IMG SRC ="triangle.gif" ALT="Warning:"> text here...
  375.               // < A HREF="Go">< IMG SRC ="Button"> Press to start</A>
  376.                 
  377.               if ( (fQuote && c != fQuote)  
  378.                   || (fInParam && c != fQuote && c != '"' && c != '\'' && c > ' ') 
  379.                || isalnum(c) ) {
  380.                   // store in token buf until unquoted
  381.                     if (fTokenLen<kMaxTokenBuf) fTokenBuf[fTokenLen++] = c;
  382.                     if (fQuote == (char)234) { // kInFormText
  383.                         goto labelNoControl; // also stuff c into texthandler stream
  384.                         }
  385.                     else
  386.                         fClass = tokDropchar;
  387.                     return; 
  388.                   }
  389.  
  390.                 if (GotTokenOrParam() == kGotToken) {
  391.                   Pushback( c);  // ! need to handle terminator char
  392.                   return;  
  393.                     }
  394.                     
  395.                 if (fQuote && c == fQuote) {
  396.                     // must be sure we handle unquote ! after storing param
  397.                     fQuote = 0;
  398.                     fClass = tokDropchar;
  399.                     return; 
  400.                     }
  401.  
  402.                 switch ( c ) {
  403.                     case '/': fTurnOn= false; break;
  404.                     case '=': fInParam= true; break;
  405.                     case '"':  
  406.                     case '\'': 
  407.                             // ?? these may be good only if (fInParam) ???
  408.                         if (fQuote) fQuote= 0; // end of quote..
  409.                         else fQuote= c; 
  410.                         break;
  411.                     
  412.                     default:
  413.                         //if (isspace(c))  break; 
  414.                         break;
  415.                     }
  416.                     
  417.                 fClass = tokDropchar;
  418.                 return; 
  419.                  }
  420.                  
  421.              else {
  422. labelNoControl:
  423.                  switch ( c ) {
  424.  
  425.                 case '&':
  426.                     //wordat= fTokenBuf+fTokenLen;
  427.                     fTokenLen= 0;
  428.                     do { 
  429.                         c = GetOneChar(); 
  430.                         if (fTokenLen<kMaxTokenBuf) fTokenBuf[fTokenLen++] = c;
  431.                     } while (c > EOF && isalnum(c));
  432.                     fTokenBuf[fTokenLen] = '\0';
  433.                     Lookup( fTokenBuf, htmlAmperChars);     // sets class, major, minor 
  434.                     return;
  435.  
  436.                 case '\t':
  437.                     fClass = tokControl;
  438.                     fMajor = htmlSpecialChar;
  439.                     fMinor = htmlTab;
  440.                     return;
  441.                     
  442.                 case '\r': 
  443.                 case '\n': //NEWLINE:
  444.                     if (fPreformat) {
  445.                         fClass = tokControl;
  446.                         fMajor = htmlSpecialChar;
  447.                         fMinor = htmlNewline;
  448.                         }
  449.                     else if (fTextSize>0) { 
  450.                             // messy fix for that cutesy horizontal bar 
  451.                         if ( fTextSize > 15 && fText[15] == '_'
  452.                               && fText[1] == '_' && fText[fTextSize-2] == '_') {
  453.                             fTextSize= 0;
  454.                             handleSpecialChar( htmlHBar);    
  455.                             fClass = tokDropchar;
  456.                             }
  457.                         else 
  458.                             // put space in, if this isn't new parag
  459.                             goto cHandleSpace;
  460.                         }    
  461.                     else
  462.                         fClass = tokDropchar;
  463.                     return;
  464.                 
  465.                 case ' ':
  466.                 cHandleSpace:
  467.                     if (fPreformat || fLastChar != ' ') {
  468.                         fClass = tokText;
  469.                         fMajor = ' ';
  470.                         fMinor = ' '; // MapChar( c);
  471.                         }
  472.                     else
  473.                         fClass = tokDropchar;
  474.                     return;
  475.                     
  476.                 case '\0':
  477.                     fClass = tokDropchar;
  478.                     return;
  479.                     
  480.                 default:
  481.                 cHandleText:
  482.                     fClass = tokText;
  483.                     fMajor = c;
  484.                     fMinor = c; // MapChar( c);
  485.                     return;
  486.                  }
  487.              }
  488.              }
  489. }
  490.  
  491.  
  492.  
  493.  
  494.  
  495.  
  496.  
  497.  
  498.  
  499. short DHTMLprocess::GetOneChar()
  500. {
  501. #if 1
  502.     if (fPushSize && fPushBuf) {
  503.         short c= (unsigned char) *fPushBuf; // must be unsigned !!
  504.         fPushSize--;
  505.         fPushBuf++;
  506.         return c;
  507.         }
  508.     else
  509.         return DRichprocess::GetOneChar();
  510. #else
  511.     short    c;
  512.  
  513.     if (fDataBuffer) {
  514.         c= (unsigned char) *fDataBuffer; // must be unsigned !!
  515.         if (fDataSize) {    // for counted data
  516.             fDataSize--;
  517.             fDataBuffer++;
  518.             if (!fDataSize) fDataBuffer= NULL; //  so EOF next time
  519.             }
  520.         else if (c) fDataBuffer++; // for null-term data
  521.         else if (!fEndOfData) c= tokBreakInData;
  522.         else c= EOF;
  523.         }
  524.     else if (fDataFile) 
  525.         c = fgetc( fDataFile->fFile);
  526.     else {
  527.         if (!fEndOfData) c= tokBreakInData;
  528.         else c= EOF;
  529.         }
  530.     return (c);
  531. #endif
  532. }
  533.  
  534.  
  535.  
  536.  
  537.  
  538.  
  539.  
  540. void DHTMLprocess::handleTextClass()
  541. {
  542.     if (IsNewStyle()) StoreStyle(fOldStyleRec.style, FALSE);  
  543.     
  544.     if (fMinor != rtfSC_nothing)
  545.         PutStdChar(fMinor); 
  546.     else {
  547.         char    buf[128];
  548.         if (fMajor < 128)    /* in ASCII range */
  549.             sprintf (buf, "[[%c]]", fMajor);
  550.         else
  551.             sprintf (buf, "[[\\'%02x]]", fMajor);
  552.         PutLitStr (buf);
  553.         }
  554.     fLastChar= fMajor;
  555. }
  556.  
  557.  
  558. void DHTMLprocess::handleControlClass()
  559. {
  560.     switch (fMajor) {
  561.         case htmlDocAttr    : handleDocAttr(fMinor); break;
  562.         case htmlLinkAttr    : handleLinkAttr(fMinor); break;
  563.         case htmlCharAttr    : handleCharAttr(fMinor); break;
  564.         case htmlParAttr    : handleParAttr(fMinor); break;
  565.         case htmlListAttr    : handleListAttr(fMinor); break;
  566.         case htmlPictAttr    : handlePictAttr(fMinor); break;
  567.         case htmlSpecialChar: handleSpecialChar(fMinor); break;
  568.         case htmlEndControl: handleEndControl(fMinor); break;
  569.         }
  570. }
  571.  
  572.  
  573. void DHTMLprocess::handleEndControl(short attr)
  574. {
  575.     // e.g, > end of any control
  576.  
  577.     if (fCurControl == htmlForm) {
  578.         // call here AFTER DNetHTMLprocess::handleEndControl
  579.     
  580.         }
  581.     else if (fCurControl == htmlImage) {
  582.         short kind;
  583.         char * dummypict = (char*) MemNew( 1);
  584.         *dummypict= 0;
  585.         if (fAnchorLink) kind= DPictStyle::kPictNetLink;
  586.         else kind= DPictStyle::kPictNetPic;
  587.         DPictStyle* thePic= new DPictStyle( kind, dummypict, 1, true);   
  588.  
  589.         if (!fParaCount) NewParagraph();
  590.         //PutLitCharWithStyle(' ');      
  591.             
  592.         if (fPicLink) {
  593.             Nlm_RecT loc;
  594.             Nlm_LoadRect( &loc, 0, 0, 35, 22); // top is to fetch picture
  595.             thePic->AddLink( DPictStyle::kPictNetPic, fPicLink, loc);
  596.             if (fAnchorLink) {
  597.                 Nlm_LoadRect( &loc, 0, 23, 35, 35); // bottom is to fetch link info
  598.                 thePic->AddLink( DPictStyle::kPictNetLink, fAnchorLink, loc);
  599.                 }
  600.             fPicLink= 0;
  601.             }
  602.             
  603.         fStyleRec.style.ispict= TRUE;
  604.         fStyleRec.style.ismap= fIsMap;
  605.         fStyleRec.style.fPict= thePic;
  606.             // !? in html, is damn url suffix supposed indicate TYPE of data !?
  607.             // or can we assume all these are GIF pictures ?
  608.         
  609.         fStyleRec.style.pixwidth= 35;  
  610.         fStyleRec.style.pixheight= 35;  
  611.         PutLitChar(' ');  
  612.         StoreStyle(fStyleRec.style, TRUE);
  613.  
  614.         fStyleRec.style.fPict= NULL;
  615.         fStyleRec.style.ispict= FALSE;
  616.         fStyleRec.style.ismap= FALSE;
  617.         fStyleRec.style.pixwidth= 0; 
  618.         fStyleRec.style.pixheight= 0; 
  619.                     
  620.         fOldStyleRec= fStyleRec;
  621.         NewStyle(); 
  622.         //PutLitChar(' ');  
  623.         //StoreStyle(fStyleRec.style, TRUE);
  624.         }
  625.  
  626.     fCurControl= 0;
  627.     fCurField= 0;
  628.     fIsMap= false;
  629. }
  630.  
  631.  
  632.  
  633.  
  634.  
  635.  
  636. void DHTMLprocess::handleDocAttr(short attr)
  637. {
  638.     switch (attr) {
  639.     
  640.         case htmlHTML:     
  641.             if (fTurnOn) fCurControl= attr;
  642.             break;
  643.         case htmlHead:    fInHead= fTurnOn; break;
  644.         case htmlBody:  fInHead= false; break;
  645.  
  646.         case htmlTitle:      
  647.             // ! this htmlTitle can occur both in Head and Body/Anchor
  648.             if (fTurnOn) {
  649.             
  650.                 }
  651.             else {
  652.                 if (fInHead && fTextSize) {
  653.                     MemFree(fTitle);  
  654.                     fText[fTextSize]= '\0';
  655.                     fTitle= StrDup( fText); 
  656.                     }
  657.                 }
  658.             break;
  659.             
  660.         case htmlIsIndex: {
  661.             fIsIndex= true;
  662.             MemFree(fPushBufstore);
  663.             fPushBufstore= StrDup(" <A HREF=?>Click here to query</A> ");
  664.             fPushBuf= fPushBufstore;
  665.             fPushSize= StrLen(fPushBuf);
  666.             //MemFree(fURLstore);
  667.             //fURLstore= StrDup("#");
  668.             // entire doc is somehow flagged as a query document, and need
  669.             // some kind of button to send query to server from this doc !?
  670.             // go->fType= kTypeQuery;
  671.             }
  672.             break;
  673.             
  674.         case htmlBase: 
  675.             break;
  676.  
  677.         case htmlLink: 
  678.         case htmlNextID: 
  679.             break;
  680.             
  681.         //case htmlHref: // !! bug in processing tokens -- arrive here after finding Link/HREF !
  682.         }
  683. }
  684.  
  685. #if 0
  686. ///////////  html forms stuff ///////////////
  687. ///// convert to gopher ask forms ///////////
  688.  
  689. <form  action="partial-url-to-handle-data" method=get or post> 
  690.  
  691. <input name="variable_name"> // one line text input (type=text)
  692. <input type=text name="variable_name" value='default text'> // one line text input
  693.     >> Ask: variable_name:\t default text
  694.  
  695. <input type=password name="variable_name-name"> // one line password text input
  696.     >> AskP: variable_name
  697.     
  698. <input type=submit value='button title'> // button to send form
  699.     >> default ask form "okay" button
  700. <input type=reset value='button title'>  // button to clear current choices
  701.     >> no ask equivalent
  702.     
  703. <input type=checkbox name=variable_name value="box title" checked>
  704.     >> Select: box title:0 or 1
  705.     
  706. <input type=radio name=var_name value='title 1'>
  707. <input type=radio name=var_name value='title 2'>
  708.     >> Choose: var_name: \t title 1 \t title 2 ...
  709.     
  710. <textarea name=var_name cols=40 rows=2>  // text input box
  711. default text
  712. </textarea>
  713.   >> AskL: var_name \t default text
  714.   
  715. <select>
  716. <option selected> name1
  717. <option> name2
  718. </select>
  719.     >> Choose: var_name: \t name1 \t name2 ...
  720.  
  721.  
  722. </form>
  723.  
  724.     if (fCurControl==HtmlInput) {
  725.         if (!fTypeStore || StrICmp( fTypestore, "text")==0)
  726.             ;
  727.         else if (StrICmp( fTypestore, "password")==0)
  728.             ;
  729.         else if (StrICmp( fTypestore, "submit")==0)
  730.             ;
  731.         else if (StrICmp( fTypestore, "reset")==0)
  732.             ;
  733.         else if (StrICmp( fTypestore, "checkbox")==0)
  734.             ;
  735.         else if (StrICmp( fTypestore, "radio")==0)
  736.             ;
  737.         else
  738.             ;
  739.         }
  740.         
  741.         // forms tags
  742.   htmlLinkAttr,    htmlForm, "form", kSlashStop, 0,
  743.       htmlLinkAttr,    htmlInput, "input", kNoStop, 0,
  744.       htmlLinkAttr,    htmlSelect, "select", kSlashStop, 0,
  745.         htmlLinkAttr,    htmlTextarea, "textarea", kSlashStop, 0,
  746.         htmlLinkAttr,    htmlValue, "value", kNoStop, 0,
  747.         htmlLinkAttr,    htmlType, "type", kNoStop, 0,
  748.         htmlLinkAttr,    htmlOption, "option", kNoStop, 0,
  749.         htmlLinkAttr,    htmlAction, "action", kNoStop, 0,
  750.         htmlLinkAttr,    htmlMethod, "method", kNoStop, 0,
  751.  
  752.  
  753.  
  754. #endif
  755.  
  756.  
  757. void DHTMLprocess::handleLinkAttr(short attr)
  758. {
  759.     char buf[512];
  760.     
  761.     switch (attr) {
  762.     
  763.         case htmlAnchor: 
  764.             if (fTurnOn) {
  765.                 fAnchorLink= 0;
  766.                 fCurControl= attr;
  767.                 // DAMN, need to push/pop something here -- having style changes inside
  768.                 // anchor causes it to disappear now !!!
  769.                 PushStyle();
  770.                 //PutLitCharWithStyle('['); // [] for debugging
  771.                 }
  772.             else {
  773.                 fStyleRec.style.color= 0; // ?? 
  774.                 fStyleRec.style.linkid= 0;                
  775.                 //PutLitCharWithStyle(']'); // [] for debugging
  776.                 PopStyle();
  777.                 fAnchorLink= 0;
  778.                 }
  779.             break;
  780.  
  781. #if 1
  782.         case htmlForm: 
  783.             fCurControl= attr;
  784.             fCurField= attr;
  785.             fInForm= fTurnOn;
  786.             if (fInForm) {
  787.                 fFormURL= (char*) MemFree(fFormURL);
  788.                 fGoplusStore= (char*) MemFree(fGoplusStore);
  789.                 fGoplusStore= StrDup("+ASKHTML:\n");  
  790.                 PushStyle();
  791.                 }
  792.             else {
  793.                 //fStyleRec.style.color= 0; // ?? 
  794.                 //fStyleRec.style.linkid= 0;                
  795.                 //PopStyle();
  796. #if 0
  797.                 MemFree(fPushBufstore);
  798.                 fPushBufstore= StrDup("<P> Click HERE to fill out form</A><P>");
  799.                 fPushBuf= fPushBufstore;
  800.                 fPushSize= StrLen(fPushBuf);
  801. #endif
  802.                 }
  803.             break;
  804.  
  805.         case htmlInput:
  806.             if (fInControl) {
  807.               fCurControl= attr; //?? 
  808.                 fCurField= attr;
  809.                 fMethodstore= (char*) MemFree(fMethodstore);  
  810.                 fOptionstore= (char*) MemFree(fOptionstore);  
  811.                 fValstore= (char*) MemFree(fValstore);  
  812.                 }
  813.                 
  814.             else {
  815.                 char * skind = NULL, * stitle = "", * sname = "", * svalue = "", * sanswer = "";
  816.                 
  817.                 short tokenlen= MIN( fTokenLen, 80);
  818.                 fTokenBuf[tokenlen] = '\0';  // this contains non-<control> text following this control
  819.                 for (short i=0; i<tokenlen; i++) 
  820.                     if (fTokenBuf[i]<' ') {
  821.                         fTokenBuf[i]= 0; // terminate string here?
  822.                         tokenlen= 0;
  823.                         break;
  824.                         }
  825.                         
  826.                 if (fNamestore) sname= fNamestore; else sname= fTypestore;
  827.  
  828.                 if (!fTypestore || StrICmp( fTypestore, "text")==0) {
  829.                     skind= "Ask";
  830. //<input name="variable_name"> // one line text input (type=text)
  831. //<input type=text name="variable_name" value='default text'> // one line text input
  832. //    >> Ask: variable_name:\t default text
  833.                     if (tokenlen) stitle= fTokenBuf; else stitle= sname;
  834.                     if (fValstore) sanswer= fValstore; else sanswer= "";  
  835.                     }
  836.                     
  837.                 else if (StrICmp( fTypestore, "password")==0) {
  838. //<input type=password name="variable_name-name"> // one line password text input
  839. //    >> AskP: variable_name
  840.                     skind= "AskP";
  841.                     if (tokenlen) stitle= fTokenBuf; else stitle= sname;
  842.                     if (fValstore) sanswer= fValstore; else sanswer= "";  
  843.                     }
  844.                     
  845.                 else if (StrICmp( fTypestore, "submit")==0)
  846.                     ;
  847.                 else if (StrICmp( fTypestore, "reset")==0)
  848.                     ;
  849.                     
  850.                 else if (StrICmp( fTypestore, "checkbox")==0) {
  851. //<input type=checkbox name=variable_name value="box value" checked> box_title
  852. //    >> Select: box title:0 or 1
  853.                     skind= "Select";
  854.                     if (tokenlen) stitle= fTokenBuf; else stitle= sname;
  855.                     if (fValstore) svalue= fValstore; else svalue= ""; // "on" is typical value 
  856.                     //if (fChecked) sanswer= "1"; else 
  857.                     sanswer= "0"; // default value
  858.                     }
  859.                     
  860.                 else if (StrICmp( fTypestore, "radio")==0) {
  861. //<input type=radio name=var_name value='title 1'> radio title
  862. //<input type=radio name=var_name value='title 2'>
  863. //    >> Choose: var_name: \t title 1 \t title 2 ...
  864. // !! need to collect all radios with same nametag !
  865.                     skind= "Choose";
  866.                     if (tokenlen) stitle= fTokenBuf; else stitle= sname;
  867.                     if (fValstore) svalue= fValstore; else svalue= ""; // "on" is typical value 
  868.                     if (fValstore) sanswer= fValstore; else sanswer= "on\t "; // default value
  869.                     }
  870.                     
  871.                 else
  872.                     ;
  873.                     
  874.                  if (skind) {
  875.                     sprintf( buf, " %s:%s:%s:%s\t%s\n", skind, sname, svalue, stitle, sanswer); 
  876.                     StrExtendCat( &fGoplusStore, buf);
  877.                     }
  878.                 }
  879.             break;
  880.  
  881.  
  882.         case htmlSelect: 
  883.             if (fTurnOn) { // fInControl)
  884.               fCurControl= attr; //?? 
  885.                 fCurField= attr;
  886.                 //fSomething= fTurnOn;
  887.                 fOptionstore= (char*) MemFree(fOptionstore);  
  888.                 }
  889.             else {
  890.                 //<select name="myname">
  891.                 //<option selected> name1
  892.                 //<option> name2
  893.                 //</select>
  894.                 //    >> Choose: var_name: \t name1 \t name2 ...
  895.                 char * skind = NULL, * stitle = "", * sname = "", * svalue = "", * sanswer = "";
  896.                 
  897.                 short tokenlen= MIN( fTokenLen, 80);
  898.                 fTokenBuf[tokenlen] = '\0';  // this contains non-<control> text following this control
  899.                 for (short i=0; i<tokenlen; i++) 
  900.                     if (fTokenBuf[i]<' ') {
  901.                         fTokenBuf[i]= 0; // terminate string here?
  902.                         tokenlen= 0;
  903.                         break;
  904.                         }
  905.  
  906.                 if (fNamestore) sname= fNamestore; else sname= fTypestore;
  907.                 skind= "Choose";
  908.                 if (tokenlen) stitle= fTokenBuf; else stitle= sname;
  909.                 if (fCurField == htmlOption) {
  910.                 
  911.                     }
  912.                  if (skind) {
  913.                     sprintf( buf, " %s:%s:%s:%s\t%s\n", skind, sname, svalue, stitle, sanswer); 
  914.                     StrExtendCat( &fGoplusStore, buf);
  915.                     }
  916.                 }
  917.             break;
  918.  
  919.         case htmlTextarea: 
  920.             if (fTurnOn) { // fInControl)
  921.               fCurControl= attr; //?? 
  922.                 fCurField= attr;
  923.                 //fSomething= fTurnOn;
  924.                 }
  925.             else {
  926.                 //<textarea name=var_name cols=40 rows=2>  // text input box
  927.                 //default text
  928.                 //</textarea>
  929.                 //  >> AskL: var_name \t default text
  930.                 char * skind = NULL, * stitle = "", * sname = "", * svalue = "", * sanswer = "";
  931.                 
  932.                 if (fNamestore) sname= fNamestore; else sname= fTypestore;
  933.                 skind= "AskL";
  934.                 fTokenBuf[fTokenLen] = '\0';  // this contains non-<control> text following this control
  935.                 if (fTokenLen) sanswer= fTokenBuf; 
  936.                 stitle= sname; //??
  937.                  if (skind) {
  938.                     sprintf( buf, " %s:%s:%s:%s\t%s\n", skind, sname, svalue, stitle, sanswer); 
  939.                     StrExtendCat( &fGoplusStore, buf);
  940.                     }
  941.  
  942.               }
  943.             break;
  944.  
  945.  
  946.         case htmlOption: 
  947.             if (fInControl) {
  948.                 fCurField= attr;
  949.                 }
  950.             else {
  951.                 // ?!?
  952.                 short tokenlen= MIN( fTokenLen, 80);
  953.                 fTokenBuf[tokenlen] = '\0';  // this contains non-<control> text following this control
  954.                 for (short i=0; i<tokenlen; i++) 
  955.                     if (fTokenBuf[i]<' ') {
  956.                         fTokenBuf[i]= 0; // terminate string here?
  957.                         tokenlen= 0;
  958.                         break;
  959.                         }
  960.                 if (tokenlen) {
  961.                     fTokenBuf[tokenlen++]= '\t';
  962.                     fTokenBuf[tokenlen]= '\0';
  963.                     if (!fOptionstore) fOptionstore= StrDup(fTokenBuf);
  964.                     else StrExtendCat( &fOptionstore, fTokenBuf);
  965.                     }
  966.                 }
  967.             break;
  968.             
  969.         case htmlMethod:
  970.             fCurField= attr;
  971.             // this is GET or POST -- only those two?
  972.             break;
  973.             
  974.         case htmlAction:
  975.             fCurField= attr;
  976.             fURLstore= (char*) MemFree(fURLstore);  
  977.             break;
  978.             
  979.         // case htmlName: // handled
  980.         case htmlValue:
  981.             fCurField= attr;
  982.             break;
  983.             
  984.         case htmlType:
  985.              // record param
  986.             fCurField= attr;
  987.             fTypestore= (char*) MemFree(fTypestore);  
  988.             break;
  989.  
  990. #endif
  991.  
  992.  
  993.         case htmlHref: 
  994.             fCurField= attr;
  995.             // store: ="url://bob.was/here"
  996.             fURLstore= (char*) MemFree(fURLstore);  
  997.             break;
  998.  
  999.         case htmlName: 
  1000.             fCurField= attr;
  1001.             // store: ="some name"
  1002.             fNamestore= (char*) MemFree(fNamestore);  
  1003.             break;
  1004.             
  1005.         case htmlRel: 
  1006.             fCurField= attr;
  1007.             //fNamestore= (char*) MemFree(fNamestore);  
  1008.             break;
  1009.         case htmlRev: 
  1010.             fCurField= attr;
  1011.             //fNamestore= (char*) MemFree(fNamestore);  
  1012.             break;
  1013.         case htmlUrn: 
  1014.             fCurField= attr;
  1015.             //fNamestore= (char*) MemFree(fNamestore);  
  1016.             break;
  1017.         case htmlMethods: 
  1018.             fCurField= attr;
  1019.             //fNamestore= (char*) MemFree(fNamestore);  
  1020.             break;
  1021.         //case htmlTitle: // handled in other section !! 
  1022.         }
  1023. }
  1024.  
  1025.  
  1026.  
  1027. void DHTMLprocess::handlePictAttr(short attr)
  1028. {
  1029.     switch (attr) {
  1030.         case htmlImage: {
  1031.             // main tag
  1032.             fCurControl= attr;
  1033.             fCurField= attr;
  1034.             }
  1035.             break;
  1036.             
  1037.         case htmlImageSrc: 
  1038.             // this is the URL to remote picture ??
  1039.             fCurField= attr;
  1040.             // store: ="url://bob.was/here"
  1041.             fURLstore= (char*) MemFree(fURLstore);  
  1042.             break;
  1043.             
  1044.         case htmlImageAlt: 
  1045.             // text name for non-graphic clients?
  1046.         case htmlIsMap: 
  1047.         case htmlAlign: 
  1048.             fCurField= attr;
  1049.             break;
  1050.         }
  1051. }
  1052.  
  1053. #ifdef TESTDEF
  1054. #define  DEFAULTS() { DefaultParag(); DefaultStyle(); GetNlmFont(); }
  1055. #else
  1056. #define DEFAULTS()    {}
  1057. #endif
  1058.             
  1059. void DHTMLprocess::handleParAttr(short attr)
  1060. {
  1061.     switch (attr) {
  1062.     
  1063.         case htmlH1: 
  1064.             if (fTurnOn) {
  1065.                 PushStyle();
  1066.                 handleSpecialChar(htmlPage);
  1067.                 DefaultStyle();
  1068.                 fParaFmt.just= 'c';
  1069.                 fParaFmt.spaceBefore= 20; 
  1070.                 fStyleRec.style.bold= true;
  1071.                 fStyleRec.fontsize= 2 * kDefaultFontsize;
  1072.                 }
  1073.             else {
  1074.                 fParaFmt.spaceAfter= 10; 
  1075.                 PutLitCharWithStyle('\n');
  1076.                 NewParagraph();
  1077.                 fParaFmt.just= 'l';
  1078.                 fParaFmt.spaceBefore= 0; 
  1079.                 fParaFmt.spaceAfter= 0; 
  1080.                 PopStyle();
  1081.                 DEFAULTS();
  1082.                 }
  1083.             NewStyle();
  1084.             break;
  1085.             
  1086.         case htmlH2: 
  1087.              if (fTurnOn) {
  1088.                 PushStyle();
  1089.                 PutLitCharWithStyle ('\n');
  1090.                 NewParagraph();
  1091.                 DefaultStyle();
  1092.                 fParaFmt.spaceBefore= 10; 
  1093.                 fStyleRec.style.bold= true;
  1094.                 fStyleRec.fontsize= 6 + kDefaultFontsize;
  1095.                 }
  1096.             else {
  1097.                 fParaFmt.spaceAfter= 5; 
  1098.                 PutLitCharWithStyle ('\n');
  1099.                 NewParagraph();
  1100.                 fParaFmt.spaceBefore= 0; 
  1101.                 fParaFmt.spaceAfter= 0; 
  1102.                 PopStyle();
  1103.                 DEFAULTS();
  1104.                 }
  1105.             NewStyle();
  1106.             break;
  1107.                         
  1108.         case htmlH3: 
  1109.              if (fTurnOn) {
  1110.                 PushStyle();
  1111.                 PutLitCharWithStyle ('\n');
  1112.                 NewParagraph();
  1113.                 DefaultStyle();
  1114.                 fParaFmt.spaceBefore= 6; 
  1115.                 fStyleRec.style.italic= true;
  1116.                 fStyleRec.fontsize= 6 + kDefaultFontsize;
  1117.                 }
  1118.             else {
  1119.                 fParaFmt.spaceAfter= 4; 
  1120.                 PutLitCharWithStyle ('\n');
  1121.                 NewParagraph();
  1122.                 fParaFmt.spaceBefore= 0; 
  1123.                 fParaFmt.spaceAfter= 0; 
  1124.                 PopStyle();
  1125.                 DEFAULTS();
  1126.                 }
  1127.             NewStyle();
  1128.             break;
  1129.     
  1130.         case htmlH4:                          
  1131.             if (fTurnOn) {
  1132.                 PushStyle();
  1133.                 PutLitCharWithStyle('\n');
  1134.                 NewParagraph();
  1135.                 DefaultStyle();
  1136.                 fStyleRec.style.bold= true;
  1137.                 fStyleRec.fontsize= 2 + kDefaultFontsize;
  1138.                 }
  1139.             else {
  1140.                 fParaFmt.spaceAfter= 4; 
  1141.                 PutLitCharWithStyle('\n');
  1142.                 NewParagraph();
  1143.                 fParaFmt.spaceBefore= 0; 
  1144.                 fParaFmt.spaceAfter= 0; 
  1145.                 PopStyle();
  1146.                 DEFAULTS();
  1147.                 }
  1148.             NewStyle();
  1149.             break;
  1150.  
  1151.         case htmlH5: 
  1152.             if (fTurnOn) {
  1153.                 PushStyle();
  1154.                 PutLitCharWithStyle('\n');
  1155.                 NewParagraph();
  1156.                 DefaultStyle();
  1157.                 fStyleRec.fontsize= 2 + kDefaultFontsize;
  1158.                 //fStyleRec.style.italic= true;
  1159.                 }
  1160.             else {
  1161.                 fParaFmt.spaceAfter= 2; 
  1162.                 PutLitCharWithStyle('\n');
  1163.                 fParaFmt.spaceBefore= 0; 
  1164.                 fParaFmt.spaceAfter= 0; 
  1165.                 PopStyle();
  1166.                 DEFAULTS();
  1167.                 }
  1168.             NewStyle();
  1169.             break;
  1170.             
  1171.         case htmlH6: 
  1172.             if (fTurnOn) {
  1173.                 PushStyle();
  1174.                 PutLitCharWithStyle('\n');
  1175.                 NewParagraph();
  1176.                 DefaultStyle();
  1177.                 //fStyleRec.style.bold= true;
  1178.                 }
  1179.             else {
  1180.                 fParaFmt.spaceAfter= 2; 
  1181.                 PutLitCharWithStyle('\n');
  1182.                 PopStyle();
  1183.                 fParaFmt.spaceBefore= 0; 
  1184.                 fParaFmt.spaceAfter= 0; 
  1185.                 DEFAULTS();
  1186.                 }
  1187.             NewStyle();
  1188.             break;
  1189.  
  1190.  
  1191.         case htmlAddress: 
  1192.             if (fTurnOn) {
  1193.                 PushStyle();
  1194.                 PutLitCharWithStyle('\n');
  1195.                 NewParagraph();
  1196.                 DefaultStyle();
  1197.                 fParaFmt.just= 'r';
  1198.                 fStyleRec.style.italic= true;
  1199.                 }
  1200.             else {
  1201.                 PutLitCharWithStyle('\n');
  1202.                 NewParagraph();
  1203.                 fParaFmt.just= 'l';
  1204.                 PopStyle();
  1205.                 DEFAULTS();
  1206.                 }
  1207.             NewStyle();
  1208.             break;
  1209.  
  1210.         case htmlBlockquote: 
  1211.             if (fTurnOn) {
  1212.                 PushStyle();
  1213.                 PutLitCharWithStyle('\n');
  1214.                 fParaFmt.spaceBefore= 10; 
  1215.                 //fParaFmt.borderleft= TRUE;
  1216.                 NewParagraph();
  1217.                 fParaFmt.leftInset  += 30;  
  1218.                 fParaFmt.rightInset += 50;  
  1219.                 fStyleRec.style.italic= true;
  1220.                 }
  1221.             else {
  1222.                 fParaFmt.spaceAfter= 10; 
  1223.                 PutLitCharWithStyle('\n');
  1224.                 NewParagraph();
  1225.                 fParaFmt.spaceBefore= 0; 
  1226.                 fParaFmt.spaceAfter= 0; 
  1227.                 //fParaFmt.borderleft= false;
  1228.                 fParaFmt.leftInset = MAX( 0, fParaFmt.leftInset-30);  
  1229.                 fParaFmt.rightInset= MAX( 0, fParaFmt.rightInset-50);  
  1230.                 PopStyle();
  1231.                 }
  1232.             NewStyle();
  1233.             break;
  1234.  
  1235.         case htmlPreformat: 
  1236.             fPreformat= fTurnOn;
  1237.             handleCharAttr(htmlFixedwidth);
  1238.             NewStyle();
  1239.             break;
  1240.  
  1241.         case htmlLinewidth: 
  1242.             // this is attrib of htmlPreformat
  1243.             break;
  1244.  
  1245.             // lists/tables ?
  1246.          case htmlDL:
  1247.              if (fTurnOn) {
  1248.                 fParaFmt.leftInset  += kDefTabstop;  
  1249.                 fParaFmt.firstInset -= kDefTabstop;  
  1250.                  fDLStyle= htmlDL;
  1251.                  }
  1252.              else {
  1253.                 PutLitCharWithStyle('\n');
  1254.                 NewParagraph();
  1255.                 fParaFmt.leftInset  = MAX(0, fParaFmt.leftInset - kDefTabstop);  
  1256.                 fParaFmt.firstInset = MIN(0, fParaFmt.firstInset + kDefTabstop);  
  1257.                  }
  1258.                  
  1259.              // attribs of htmlDL
  1260.          case htmlCompact:
  1261.              fDLStyle= htmlCompact;
  1262.              break;
  1263.          case htmlDT:
  1264.             PutLitCharWithStyle('\n');
  1265.             NewParagraph();
  1266.             fParaFmt.leftInset  = MAX(0, fParaFmt.leftInset - kDefTabstop);  
  1267.             fParaFmt.firstInset = MIN(0, fParaFmt.firstInset + kDefTabstop);  
  1268.             break;
  1269.          case htmlDD:
  1270.              if (true) { //fDLStyle != htmlCompact) {
  1271.                  PutLitCharWithStyle('\n');
  1272.                 NewParagraph();
  1273.                 fParaFmt.leftInset  += kDefTabstop;  
  1274.                 fParaFmt.firstInset -= kDefTabstop;  
  1275.                 }
  1276.             PutStdCharWithStyle('\t');
  1277.              break;
  1278.         }
  1279. }
  1280.  
  1281.  
  1282. void DHTMLprocess::handleListAttr(short attr)
  1283. {
  1284.     switch (attr) {
  1285.     
  1286.         case htmlNumList:
  1287.         case htmlMenu:
  1288.         case htmlDir:
  1289.         case htmlBullList:
  1290.             fListType= attr;
  1291.             fListNum= 0;
  1292.              if (fTurnOn) {
  1293.                 PutLitCharWithStyle('\n');
  1294.                 NewParagraph();
  1295.                 fParaFmt.leftInset  += kDefTabstop;  
  1296.                 fParaFmt.firstInset -= kDefTabstop - 20;  
  1297.                  }
  1298.              else {
  1299.                 PutLitCharWithStyle('\n');
  1300.                 NewParagraph();
  1301.                 fParaFmt.leftInset  = MAX(0, fParaFmt.leftInset-kDefTabstop);  
  1302.                 fParaFmt.firstInset = MIN(0, fParaFmt.firstInset+kDefTabstop+20);  
  1303.                 PutLitCharWithStyle('\n');
  1304.                 NewParagraph();
  1305.                  }        
  1306.             break;
  1307.  
  1308.     
  1309.         case htmlListItem:
  1310.             PutLitCharWithStyle('\n');
  1311.             NewParagraph();
  1312.             fListNum++; // count isn't nested, nor is fListType !!
  1313.             // !!? need push/pop for list vars !!!!!!
  1314.             if (fListType == htmlNumList) {
  1315.                 char nums[30];
  1316.                 sprintf( nums, "%d\t", fListNum);
  1317.                 PutLitStr( nums);
  1318.                 }
  1319.             else {
  1320.                 PutStdCharWithStyle( gGenCharMap[rtfSC_bullet]); //'•'
  1321.                 PutStdChar('\t');
  1322.                 }
  1323.             break;
  1324.             
  1325.         }
  1326. }
  1327.  
  1328.  
  1329.  
  1330.  
  1331. void DHTMLprocess::handleCharAttr(short attr)
  1332. {
  1333.     switch (attr) {
  1334.  
  1335.     case htmlFixedwidth: //rtfFontNum:
  1336.         if (fTurnOn) {
  1337.             PushStyle();
  1338.             fStyleRec.fontname= "courier";
  1339.             fStyleRec.fontfamily= "Modern";
  1340.             fStyleRec.fontsize= kDefaultFontsize; 
  1341.             }
  1342.         else {
  1343.             PopStyle();
  1344.             } 
  1345.         NewStyle();
  1346.         //(void) GetNlmFont();  
  1347.         break;
  1348.                 
  1349.     case htmlSampleFont:
  1350.      case htmlUserFont:
  1351.         if (fTurnOn) {
  1352.             PushStyle();
  1353.             fStyleRec.fontname= "helvetica";
  1354.             fStyleRec.fontfamily= "Swiss";
  1355.             fStyleRec.fontsize= kDefaultFontsize; 
  1356.             }
  1357.         else {
  1358.             PopStyle();
  1359.             } 
  1360.         NewStyle();
  1361.         //(void) GetNlmFont();  
  1362.         break;
  1363.  
  1364.     case htmlPlain:
  1365.         DefaultStyle();
  1366.         NewStyle();
  1367.         break;
  1368.         
  1369.     case htmlVarFont: //rtfSmallCaps:
  1370.         NewStyle();
  1371.         fStyleRec.style.smallcaps= fTurnOn;
  1372.         break;
  1373.  
  1374.     case htmlEmphasis:
  1375.     case htmlBold:
  1376.         NewStyle();
  1377.         fStyleRec.style.bold= fTurnOn;
  1378.         break;
  1379.         
  1380.     case htmlDefineFont:
  1381.     case htmlCiteFont:
  1382.         // ?? also use diff font??
  1383.     case htmlItalic:
  1384.         NewStyle();
  1385.         fStyleRec.style.italic= fTurnOn;
  1386.         break;
  1387.     case htmlMoreEmphasis: //rtfUnderline:
  1388.         NewStyle();
  1389.         fStyleRec.style.bold= fTurnOn;
  1390.         if (fTurnOn) fStyleRec.style.underline = DRichStyle::kUnderline;
  1391.         else fStyleRec.style.underline= 0;
  1392.         break;
  1393.     case htmlInvisible:
  1394.         NewStyle();
  1395.         fStyleRec.style.hidden= fTurnOn;
  1396.         break;
  1397.     }
  1398. }
  1399.  
  1400.  
  1401. void DHTMLprocess::handleSpecialChar(short code)
  1402. {
  1403.     switch (code) {
  1404.         case htmlPar: 
  1405.             fParaFmt.spaceAfter += 5; 
  1406.             PutLitCharWithStyle('\n');
  1407.             NewParagraph();
  1408.             fParaFmt.spaceAfter -= 5; 
  1409.             fLastChar= ' ';
  1410.             break;
  1411.         case htmlNewline:
  1412.             PutLitCharWithStyle('\n');
  1413.             NewParagraph();
  1414.             fLastChar= ' ';
  1415.             break;
  1416.             
  1417.         case htmlHBar:
  1418.             fParaFmt.borderstyle = DParagraph::kBorderSingle; 
  1419.             fParaFmt.borderbottom = TRUE; 
  1420.             PutLitCharWithStyle('\n');
  1421.             PutLitChar(' ');
  1422.             NewParagraph();
  1423.             fParaFmt.borderstyle = DParagraph::kNoBorder; 
  1424.             fParaFmt.borderbottom = FALSE; 
  1425.             PutLitCharWithStyle('\n');
  1426.             NewParagraph();
  1427.             fLastChar= ' ';
  1428.             break;
  1429.             
  1430.         case htmlPage: 
  1431.             PutLitCharWithStyle ('\n');
  1432.             fParaFmt.newPage= TRUE;  
  1433.             NewParagraph();
  1434.             fParaFmt.newPage= FALSE; 
  1435.             fLastChar= ' ';
  1436.             break;
  1437.         case htmlTab:
  1438.             PutLitCharWithStyle('\t'); // tab isn't defined in HTML world...
  1439.             fLastChar= ' ';
  1440.             break;
  1441.  
  1442. #if 0
  1443.         case rtfSC_less:
  1444.             PutLitCharWithStyle('<');
  1445.             break;
  1446.         case rtfSC_greater:
  1447.             PutLitCharWithStyle('>');
  1448.             break;
  1449.         case rtfSC_quotedbl:
  1450.             PutLitCharWithStyle('"');
  1451.             break;
  1452.         case rtfSC_ampersand:
  1453.             PutLitCharWithStyle('&');
  1454.             break;
  1455. #endif
  1456.         default:
  1457.             PutLitCharWithStyle( gGenCharMap[code]);
  1458.             fLastChar= gGenCharMap[code];
  1459.             break;
  1460.         }
  1461. };
  1462.  
  1463.     
  1464.  
  1465.  
  1466. HTMLKey DHTMLprocess::htmlKeys[] =
  1467. {
  1468.         // document
  1469.     htmlDocAttr, htmlHTML,    "html", kSlashStop, 0,    
  1470.     htmlDocAttr, htmlTitle,    "title", kSlashStop, 0,    
  1471.     htmlDocAttr, htmlHead,    "head", kSlashStop, 0,    
  1472.     htmlDocAttr, htmlBody,    "body", kSlashStop, 0,    
  1473.     htmlDocAttr, htmlIsIndex,    "isindex", kNoStop, 0,    
  1474.     htmlDocAttr, htmlLink,    "link", kNoStop, 0,    
  1475.     htmlDocAttr, htmlNextID,    "nextid", kNoStop, 0,    
  1476.     htmlDocAttr, htmlBase,    "base", kNoStop, 0,    
  1477.       //htmlDocAttr,    htmlHref, "href=", kNoStop, 0,
  1478.     htmlDocAttr,    htmlComment,    "!", kNoStop, 0,
  1479.  
  1480.         // anchors & links
  1481.     htmlLinkAttr,    htmlAnchor,    "a", kSlashStop, 0,
  1482.       htmlLinkAttr,    htmlHref, "href", kNoStop, 0,
  1483.       htmlLinkAttr,    htmlName, "name", kNoStop, 0,
  1484.         htmlLinkAttr,    htmlRel, "rel", kNoStop, 0,
  1485.         htmlLinkAttr,    htmlRev, "rev", kNoStop, 0,
  1486.         htmlLinkAttr,    htmlUrn, "urn", kNoStop, 0,    
  1487.         htmlLinkAttr,    htmlMethods, "methods", kNoStop, 0,    
  1488.         //htmlLinkAttr, htmlTitle,    "title", kNoStop, 0,    
  1489.     
  1490.         // forms tags
  1491.   htmlLinkAttr,    htmlForm, "form", kSlashStop, 0,
  1492.       htmlLinkAttr,    htmlInput, "input", kNoStop, 0,
  1493.       htmlLinkAttr,    htmlSelect, "select", kSlashStop, 0,
  1494.         htmlLinkAttr,    htmlTextarea, "textarea", kSlashStop, 0,
  1495.         htmlLinkAttr,    htmlValue, "value", kNoStop, 0,
  1496.         htmlLinkAttr,    htmlType, "type", kNoStop, 0,
  1497.         htmlLinkAttr,    htmlOption, "option", kNoStop, 0,
  1498.         htmlLinkAttr,    htmlAction, "action", kNoStop, 0,
  1499.         htmlLinkAttr,    htmlMethod, "method", kNoStop, 0,
  1500.         
  1501.         // font styles
  1502.     htmlCharAttr,    htmlBold,        "b",        kSlashStop, 0,
  1503.     htmlCharAttr,    htmlEmphasis,        "em",    kSlashStop,     0,
  1504.     htmlCharAttr,    htmlMoreEmphasis,        "strong",    kSlashStop,     0,
  1505.     htmlCharAttr,    htmlItalic,        "i",    kSlashStop,     0,
  1506.     htmlCharAttr,    htmlFixedwidth,        "tt",    kSlashStop,     0, // courier font !?
  1507.     htmlCharAttr,    htmlFixedwidth,        "code",    kSlashStop,     0, // courier font !?
  1508.     htmlCharAttr,    htmlSampleFont,        "samp",    kSlashStop,     0, 
  1509.     htmlCharAttr,    htmlUserFont,        "kbd",    kSlashStop,     0, 
  1510.     htmlCharAttr,    htmlVarFont,        "var",    kSlashStop,     0, 
  1511.     htmlCharAttr,    htmlDefineFont,        "dfn",    kSlashStop,     0, // bold
  1512.     htmlCharAttr,    htmlCiteFont,        "cite",    kSlashStop,     0, // italic
  1513.     htmlCharAttr,    htmlPlain,        "plaintext",    kSlashStop,     0,  
  1514.  
  1515.         // paragraph styles
  1516.     htmlParAttr,    htmlH1,    "h1", kSlashStop,     0,
  1517.     htmlParAttr,    htmlH2,    "h2", kSlashStop, 0,
  1518.     htmlParAttr,    htmlH3,    "h3", kSlashStop, 0,
  1519.     htmlParAttr,    htmlH4,    "h4", kSlashStop, 0,
  1520.     htmlParAttr,    htmlH5,    "h5", kSlashStop, 0,
  1521.     htmlParAttr,    htmlH6,    "h6", kSlashStop, 0,
  1522.     htmlParAttr,    htmlAddress,    "address", kSlashStop, 0,
  1523.     htmlParAttr,    htmlBlockquote,    "blockquote", kSlashStop, 0,
  1524.  
  1525.     htmlParAttr,    htmlPreformat,    "pre", kSlashStop, 0,
  1526.       htmlParAttr,    htmlLinewidth,    "width", kNoStop, 0,
  1527.     htmlParAttr,    htmlPreformat,        "listing",        kSlashStop, 0,  
  1528.     htmlParAttr,    htmlPreformat,        "xmp",        kSlashStop, 0,  
  1529.  
  1530.         // lists/tables ?
  1531.     htmlParAttr,    htmlDL,    "dl", kSlashStop, 0,
  1532.       htmlParAttr,    htmlCompact,    "compact",  kNoStop,0,
  1533.       htmlParAttr,    htmlDT,    "dt", kNoStop, 0,
  1534.       htmlParAttr,    htmlDD,    "dd", kNoStop, 0,
  1535.  
  1536.         // lists
  1537.     htmlListAttr,    htmlBullList,    "ul",  kSlashStop, 0,
  1538.     htmlListAttr,    htmlNumList,    "ol",  kSlashStop, 0,
  1539.     htmlListAttr,    htmlMenu,    "menu",  kSlashStop, 0,
  1540.     htmlListAttr,    htmlDir,    "dir",  kSlashStop, 0,
  1541.     htmlListAttr,    htmlListItem,    "li",  kNoStop,0,
  1542.  
  1543.         // pictures
  1544.     htmlPictAttr,    htmlImage,        "img", kNoStop,    0,
  1545.       htmlPictAttr,    htmlImageSrc,        "src", kNoStop,    0,
  1546.       htmlPictAttr,    htmlImageAlt,        "alt", kNoStop,    0,
  1547.         htmlPictAttr,    htmlAlign,        "aln", kNoStop,    0,
  1548.         htmlPictAttr,    htmlAlign,        "align", kNoStop,    0,
  1549.       htmlPictAttr,    htmlIsMap,        "ismap", kNoStop,    0,
  1550.  
  1551.         // characters
  1552.     htmlSpecialChar,    htmlPar,        "p", kNoStop,    0, // parag
  1553.     htmlSpecialChar,    htmlHBar,        "hr", kNoStop,    0, // paragraph rule
  1554.     0,        -1,            NULL,    0
  1555. };
  1556.  
  1557.     
  1558.  
  1559. HTMLKey DHTMLprocess::htmlAmperChars[] =
  1560. {
  1561.     htmlSpecialChar,    rtfSC_less, "lt;", kAmperChar,        0,
  1562.     htmlSpecialChar,    rtfSC_greater, "gt;", kAmperChar,        0,
  1563.     htmlSpecialChar,    rtfSC_ampersand, "amp;", kAmperChar,        0,
  1564.     htmlSpecialChar,    rtfSC_quotedbl, "quot;", kAmperChar,        0,
  1565.  
  1566.     htmlSpecialChar,    rtfSC_AE, "AElig;", kAmperChar,        0,
  1567.     htmlSpecialChar,    rtfSC_Aacute, "Aacute;", kAmperChar,        0,
  1568.     htmlSpecialChar,    rtfSC_Acircumflex, "Acirc;", kAmperChar,        0,
  1569.     htmlSpecialChar,    rtfSC_Agrave, "Agrave;", kAmperChar,        0,
  1570.     htmlSpecialChar,    rtfSC_Aring, "Aring;", kAmperChar,        0,
  1571.     htmlSpecialChar,    rtfSC_Atilde, "Atilde;", kAmperChar,        0,
  1572.     htmlSpecialChar,    rtfSC_Adieresis, "Auml;", kAmperChar,        0,
  1573.     htmlSpecialChar,    rtfSC_Ccedilla, "Ccedil;", kAmperChar,        0,
  1574.     htmlSpecialChar,    rtfSC_Eth, "ETH;", kAmperChar,        0,
  1575.     htmlSpecialChar,    rtfSC_Eacute, "Eacute;", kAmperChar,        0,
  1576.     htmlSpecialChar,    rtfSC_Ecircumflex, "Ecirc;", kAmperChar,        0,
  1577.     htmlSpecialChar,    rtfSC_Egrave, "Egrave;", kAmperChar,        0,
  1578.     htmlSpecialChar,    rtfSC_Edieresis, "Euml;", kAmperChar,        0,
  1579.     htmlSpecialChar,    rtfSC_Iacute, "Iacute;", kAmperChar,        0,
  1580.     htmlSpecialChar,    rtfSC_Icircumflex, "Icirc;", kAmperChar,        0,
  1581.     htmlSpecialChar,    rtfSC_Igrave, "Igrave;", kAmperChar,        0,
  1582.     htmlSpecialChar,    rtfSC_Idieresis, "Iuml;", kAmperChar,        0,
  1583.     htmlSpecialChar,    rtfSC_Ntilde, "Ntilde;", kAmperChar,        0,
  1584.     htmlSpecialChar,    rtfSC_Oacute, "Oacute;", kAmperChar,        0,
  1585.     htmlSpecialChar,    rtfSC_Ocircumflex, "Ocirc;", kAmperChar,        0,
  1586.     htmlSpecialChar,    rtfSC_Ograve, "Ograve;", kAmperChar,        0,
  1587.     htmlSpecialChar,    rtfSC_Oslash, "Oslash;", kAmperChar,        0,
  1588.     htmlSpecialChar,    rtfSC_Otilde, "Otilde;", kAmperChar,        0,
  1589.     htmlSpecialChar,    rtfSC_Odieresis, "Ouml;", kAmperChar,        0,
  1590.     htmlSpecialChar,    rtfSC_Thorn, "THORN;", kAmperChar,        0,
  1591.     htmlSpecialChar,    rtfSC_Uacute, "Uacute;", kAmperChar,        0,
  1592.     htmlSpecialChar,    rtfSC_Ucircumflex, "Ucirc;", kAmperChar,        0,
  1593.     htmlSpecialChar,    rtfSC_Ugrave, "Ugrave;", kAmperChar,        0,
  1594.     htmlSpecialChar,    rtfSC_Udieresis, "Uuml;", kAmperChar,        0,
  1595.     htmlSpecialChar,    rtfSC_Yacute, "Yacute;", kAmperChar,        0,
  1596.     htmlSpecialChar,    rtfSC_aacute, "aacute;", kAmperChar,        0,
  1597.     htmlSpecialChar,    rtfSC_acircumflex, "acirc;", kAmperChar,        0,
  1598.     htmlSpecialChar,    rtfSC_ae, "aelig;", kAmperChar,        0,
  1599.     htmlSpecialChar,    rtfSC_agrave, "agrave;", kAmperChar,        0,
  1600.     htmlSpecialChar,    rtfSC_aring, "aring;", kAmperChar,        0,
  1601.     htmlSpecialChar,    rtfSC_atilde, "atilde;", kAmperChar,        0,
  1602.     htmlSpecialChar,    rtfSC_adieresis, "auml;", kAmperChar,        0,
  1603.     htmlSpecialChar,    rtfSC_ccedilla, "ccedil;", kAmperChar,        0,
  1604.     htmlSpecialChar,    rtfSC_eacute, "eacute;", kAmperChar,        0,
  1605.     htmlSpecialChar,    rtfSC_ecircumflex, "ecirc;", kAmperChar,        0,
  1606.     htmlSpecialChar,    rtfSC_egrave, "egrave;", kAmperChar,        0,
  1607.     htmlSpecialChar,    rtfSC_eth, "eth;", kAmperChar,        0,
  1608.     htmlSpecialChar,    rtfSC_edieresis, "euml;", kAmperChar,        0,
  1609.     htmlSpecialChar,    rtfSC_iacute, "iacute;", kAmperChar,        0,
  1610.     htmlSpecialChar,    rtfSC_icircumflex, "icirc;", kAmperChar,        0,
  1611.     htmlSpecialChar,    rtfSC_igrave, "igrave;", kAmperChar,        0,
  1612.     htmlSpecialChar,    rtfSC_idieresis, "iuml;", kAmperChar,        0,
  1613.     htmlSpecialChar,    rtfSC_ntilde, "ntilde;", kAmperChar,        0,
  1614.     htmlSpecialChar,    rtfSC_oacute, "oacute;", kAmperChar,        0,
  1615.     htmlSpecialChar,    rtfSC_ocircumflex, "ocirc;", kAmperChar,        0,
  1616.     htmlSpecialChar,    rtfSC_ograve, "ograve;", kAmperChar,        0,
  1617.     htmlSpecialChar,    rtfSC_oslash, "oslash;", kAmperChar,        0,
  1618.     htmlSpecialChar,    rtfSC_otilde, "otilde;", kAmperChar,        0,
  1619.     htmlSpecialChar,    rtfSC_odieresis, "ouml;", kAmperChar,        0,
  1620.     htmlSpecialChar,    rtfSC_nothing, "szlig;", kAmperChar,        0, // ! no rtf equiv.
  1621.     htmlSpecialChar,    rtfSC_thorn, "thorn;", kAmperChar,        0,
  1622.     htmlSpecialChar,    rtfSC_uacute, "uacute;", kAmperChar,        0,
  1623.     htmlSpecialChar,    rtfSC_ucircumflex, "ucirc;", kAmperChar,        0,
  1624.     htmlSpecialChar,    rtfSC_ugrave, "ugrave;", kAmperChar,        0,
  1625.     htmlSpecialChar,    rtfSC_udieresis, "uuml;", kAmperChar,        0,
  1626.     htmlSpecialChar,    rtfSC_yacute, "yacute;", kAmperChar,        0,
  1627.     htmlSpecialChar,    rtfSC_ydieresis, "yuml;", kAmperChar,        0,
  1628.     0,        -1,            NULL,    0
  1629. };
  1630.  
  1631.  
  1632.  
  1633.