//CRTF_HTMLConverter:: void R2H_CreateHTMLElements(string strRTFSource) { //Go thru RTF main string string strCurrentText=string.Empty; for (int iStrPos=0;iStrPos<strRTFSource.Length;iStrPos++) { string strChTest=strRTFSource[iStrPos].ToString(); if (strChTest==@"\") { //New tag if (strCurrentText.Length>0) { CHTMLElement pElement = new CHTMLElement(); pElement.m_enNodeType=THTMLNodeType.c_nodText; pElement.m_strNodeText = strCurrentText; m_arrHTMLElements.Add(pElement); strCurrentText=string.Empty; } string strTag=R2H_GetRTFTag(strRTFSource, iStrPos); R2H_InterpretTag(strTag); iStrPos+=strTag.Length; //string strNextTag=R2H_GetRTFTag(strRTFSource, iStrPos+1); if (((iStrPos+1)<strRTFSource.Length) && (strRTFSource[iStrPos+1]==' ')) iStrPos++; //Ignore Blank after Tag } else { //Normal character strCurrentText+=strChTest; } } //loop thru string //Add last text if (strCurrentText.Length>0) { CHTMLElement pElement = new CHTMLElement(); pElement.m_enNodeType=THTMLNodeType.c_nodText; pElement.m_strNodeText = strCurrentText; m_arrHTMLElements.Add(pElement); //strCurrentText=string.Empty; } }
//CRTF_HTMLConverter:: void R2H_InterpretTag(string strRTFTag) { string strTestTag=string.Empty; CHTMLElement pElement=null; #region Однозначные операторы switch(strRTFTag) { case "rtf1": return; case "b": pElement=createAttrib(THTMLNodeType.c_nodHTMLBegin, "b"); break; case "b0": pElement=createAttrib(THTMLNodeType.c_nodHTMLBegin, "b"); break; case "i": pElement=createAttrib(THTMLNodeType.c_nodHTMLBegin, "i"); break; case "i0": pElement=createAttrib(THTMLNodeType.c_nodHTMLEnd, "i"); break; case "ul": pElement=createAttrib(THTMLNodeType.c_nodHTMLBegin, "u"); break; case "ulnone": pElement=createAttrib(THTMLNodeType.c_nodHTMLEnd, "u"); break; case "title": pElement=createAttrib(THTMLNodeType.c_nodComment, "title"); break; case "author": pElement=createAttrib(THTMLNodeType.c_nodComment, "author"); break; case "subject": pElement=createAttrib(THTMLNodeType.c_nodComment, "subject"); break; case "company": pElement=createAttrib(THTMLNodeType.c_nodComment, "company"); break; case "manager": pElement=createAttrib(THTMLNodeType.c_nodComment, "manager"); break; case "operator": pElement=createAttrib(THTMLNodeType.c_nodComment, "operator"); break; case "category": pElement=createAttrib(THTMLNodeType.c_nodComment, "category"); break; case "comment": pElement=createAttrib(THTMLNodeType.c_nodComment, "comment"); break; case "keywords": pElement=createAttrib(THTMLNodeType.c_nodComment, "keywords"); break; case "creatim": pElement=createAttrib(THTMLNodeType.c_nodComment, "createtime"); break; case "time": pElement=createAttrib(THTMLNodeType.c_nodComment, "time"); break; case "protect": pElement=createAttrib(THTMLNodeType.c_nodHTMLBegin, "protected"); break; case "protect0": pElement=createAttrib(THTMLNodeType.c_nodHTMLEnd, "protected"); break; case "v": //unvisible pElement=createAttrib(THTMLNodeType.c_nodHTMLBegin, "pre"); break; case "v0": pElement=createAttrib(THTMLNodeType.c_nodHTMLEnd, "pre"); break; case "par": strTestTag="par"; string strSpecialChar=strRTFTag.Remove(0, strTestTag.Length); int lLastUnclosedPStart=-1; //Look if we first must close paragraph for (int iLastElements=m_arrHTMLElements.Count-1;iLastElements>=0;iLastElements--) { CHTMLElement pElementTest = (CHTMLElement)m_arrHTMLElements[iLastElements]; if (pElementTest.m_strNodeText=="p") { if (pElementTest.m_enNodeType==THTMLNodeType.c_nodHTMLEnd) break; //everything is OK if ((pElementTest.m_enNodeType==THTMLNodeType.c_nodHTMLBegin)) { lLastUnclosedPStart=iLastElements; break; //everything is OK } } } if (lLastUnclosedPStart>=0) { //Look if there is no text between last <p> and this <p-end> (e.g. <p></p>) //HTML does then not display a linefeed, therefore make it to <p> </p> bool bLastParaEmpty=true; for (int iLastPara=lLastUnclosedPStart;iLastPara<m_arrHTMLElements.Count;iLastPara++) { CHTMLElement pElementTest = (CHTMLElement)m_arrHTMLElements[iLastPara]; if (pElementTest.m_enNodeType==THTMLNodeType.c_nodText) { if ((pElementTest.m_strNodeText!="")&& (pElementTest.m_strNodeText!="\r")&& (pElementTest.m_strNodeText!="\n")&& (pElementTest.m_strNodeText!="\r\n")&& (pElementTest.m_strNodeText!="b")) { bLastParaEmpty = false; } } } if (bLastParaEmpty) { //Insert modified blank (see above) CHTMLElement pElementBlank = new CHTMLElement(); pElementBlank.m_enNodeType=THTMLNodeType.c_nodText; pElementBlank.m_strNodeText = " "; m_arrHTMLElements.Add(pElementBlank); } //Insert Closing </p> CHTMLElement pElementClose = new CHTMLElement(); pElementClose.m_enNodeType=THTMLNodeType.c_nodHTMLEnd; pElementClose.m_strNodeText = "p"; m_arrHTMLElements.Add(pElementClose); } pElement=new CHTMLElement(); //Add paragraph tag (<p> pElement.m_enNodeType=THTMLNodeType.c_nodHTMLBegin; pElement.m_strNodeText = "p"; return; } #endregion if (pElement!=null) return; pElement=new CHTMLElement(); bool wordOk=true; #region Special character (umlaut) strTestTag="'"; if (LeftFromString(ref strRTFTag,strTestTag) && wordOk) { string strSpecialChar=strRTFTag.Remove(0, strTestTag.Length); if (strSpecialChar.Length==2) //RTF (must be 2-digit hex code) { strSpecialChar=strSpecialChar.Substring(0,2); pElement.m_enNodeType=THTMLNodeType.c_nodText; string strHex=Converters.fromHex(strSpecialChar); pElement.m_strNodeText = strHex; //"&#x"+strSpecialChar+";"; } wordOk=false; } #endregion #region Paragraph Alignment strTestTag="q"; if (LeftFromString(ref strRTFTag,strTestTag) && wordOk) { //Get RTF alignment string strAlignHTML=string.Empty; pElement.m_enNodeType=THTMLNodeType.c_nodHTMLBegin; pElement.m_strNodeText= "font"; string strAlignRTF = strRTFTag.Remove(0, strTestTag.Length); Debug.Assert(strAlignRTF.Length==1); //Invalid RTF //Convert RTF options to HTML options switch(strAlignRTF) { case "l": strAlignHTML="left"; break; case "r": strAlignHTML="right"; break; case "c": strAlignHTML="center"; break; default: break; //unsupported } //Find last paragraph int lLastParaStart=-1; for (int iLastElements=m_arrHTMLElements.Count-1;iLastElements>=0;iLastElements--) { CHTMLElement pElementTest = (CHTMLElement)m_arrHTMLElements[iLastElements]; if ((pElementTest.m_enNodeType==THTMLNodeType.c_nodHTMLBegin) && (pElementTest.m_strNodeText=="p")) { lLastParaStart=iLastElements; break; //everything is OK } } if ((lLastParaStart>=0) && (strAlignHTML!="")) { CHTMLElement pElementPara = (CHTMLElement)m_arrHTMLElements[lLastParaStart]; //pElementPara.m_mapParams.SetAt("align", "\""+strAlignHTML+"\""); //SetAt("align", "\""+strAlignHTML+"\"") string val="\""+strAlignHTML+"\""; int key=pElementPara.m_mapParams.IndexOfKey("align"); if (key!=-1) pElementPara.m_mapParams.Add("align",val); else pElementPara.m_mapParams[key]=val; } wordOk=false; } #endregion #region font color strTestTag="cf"; if (LeftFromString(ref strRTFTag,strTestTag) && wordOk) { pElement.m_enNodeType=THTMLNodeType.c_nodHTMLBegin; pElement.m_strNodeText= "font"; string strActColor = strRTFTag.Remove(0, strTestTag.Length); Debug.Assert(strActColor.Length>0); //Invalid RTF int lActColor=int.Parse(strActColor); Debug.Assert(lActColor<m_arrColors.Count); //Color not in Colortable ! if (lActColor<m_arrColors.Count) { Color clr=(Color)m_arrColors[lActColor]; //int r=0,g=0,b=0; //r=GetRValue(ref); //g=GetGValue(ref); //b=GetBValue(ref); //strHTMLColor.Format("#%02x%02x%02x",r,g,b); m_strActFontColor = System.Drawing.ColorTranslator.ToHtml(clr);; } wordOk=false; } #endregion #region font size strTestTag="fs"; if (LeftFromString(ref strRTFTag,strTestTag) && wordOk) { pElement.m_enNodeType=THTMLNodeType.c_nodHTMLBegin; pElement.m_strNodeText= "font"; m_strActFontSize = strRTFTag.Remove(0, strTestTag.Length); Debug.Assert(m_strActFontSize.Length>0); //Invalid RTF //m_strActFontSize=LongToString(StringToLong(m_strActFontSize)/2); //RTF stores the doubled font size m_strActFontSize=Convert.ToString(int.Parse(m_strActFontSize)/2); //RTF stores the doubled font size wordOk=false; } #endregion #region font name strTestTag="f"; //f+number //(strRTFTag.Mid(1).SpanIncluding("01234567890")==strRTFTag.Mid(1))) int seek=strRTFTag.Substring(0,2).IndexOfAny(new char[]{'0','1','2','3','4','5','6','7','8','9','0'},1); if (LeftFromString(ref strRTFTag,strTestTag) && wordOk && (seek!=-1)) { string strActFontDsgn = strRTFTag; pElement.m_enNodeType=THTMLNodeType.c_nodHTMLBegin; pElement.m_strNodeText= "font"; Debug.Assert(strActFontDsgn.Length>0); //Invalid RTF //string strActFontName; //bool bFound=false; int bFound=m_mapFontNames.IndexOf(m_strActFontName); //Debug.Assert(bFound==-1); //Font not found in font table, don't change font if (bFound!=-1) m_mapFontNames[bFound]=m_strActFontName; else m_mapFontNames.Add(m_strActFontName); wordOk=false; } #endregion #region New font tag ? if ( !wordOk && (pElement.m_enNodeType==THTMLNodeType.c_nodHTMLBegin) && (pElement.m_strNodeText=="font")) { bool bMustClose=false; //Look if we first must close paragraph for (int iLastElements=m_arrHTMLElements.Count-1;iLastElements>=0;iLastElements--) { CHTMLElement pElementTest = (CHTMLElement)m_arrHTMLElements[iLastElements]; if ((pElementTest.m_enNodeType==THTMLNodeType.c_nodHTMLEnd) && (pElementTest.m_strNodeText=="font")) break; //everything is OK if ((pElementTest.m_enNodeType==THTMLNodeType.c_nodHTMLBegin) && (pElementTest.m_strNodeText=="font")) { bMustClose=true; break; //everything is OK } } if (bMustClose) { //Insert Closing </p> CHTMLElement pElementClose = new CHTMLElement(); pElementClose.m_enNodeType=THTMLNodeType.c_nodHTMLEnd; pElementClose.m_strNodeText = "font"; m_arrHTMLElements.Add(pElementClose); } //Set font tag options //pElement.m_mapParams.SetAt("color", "\""+m_strActFontColor+"\""); string key="color", val="\""+m_strActFontColor+"\"";; int index=pElement.m_mapParams.IndexOfKey(key); if (index==-1) pElement.m_mapParams.Add(key,val); else pElement.m_mapParams[key]=val; //pElement.m_mapParams.SetAt("style", "\"font-size: "+m_strActFontSize+"pt; font-family:"+m_strActFontName+";\""); key="style"; val="\"font-size: "+m_strActFontSize+"pt; font-family:"+m_strActFontName+";\""; index =pElement.m_mapParams.IndexOfKey(key); if (index==-1) pElement.m_mapParams.Add(key,val); else pElement.m_mapParams[key]=val; } #endregion #region old Interpret #region Char attributes /* //Char attributes if (strRTFTag=="b") { pElement.m_enNodeType= THTMLNodeType.c_nodHTMLBegin; pElement.m_strNodeText = "b"; } else if (strRTFTag=="b0") { pElement.m_enNodeType=THTMLNodeType.c_nodHTMLEnd; pElement.m_strNodeText = "b"; } else if (strRTFTag=="i") { pElement.m_enNodeType=THTMLNodeType.c_nodHTMLBegin; pElement.m_strNodeText = "i"; } else if (strRTFTag=="i0") { pElement.m_enNodeType=THTMLNodeType.c_nodHTMLEnd; pElement.m_strNodeText = "i"; } else if (strRTFTag=="ul") { pElement.m_enNodeType=THTMLNodeType.c_nodHTMLBegin; pElement.m_strNodeText = "u"; } else if (strRTFTag=="ulnone") { pElement.m_enNodeType=THTMLNodeType.c_nodHTMLEnd; pElement.m_strNodeText = "u"; } */ #endregion #region Special character (umlaut) /* //Special character (umlaut) strTestTag="'"; if ((pElement.m_enNodeType==THTMLNodeType.c_nodInvalid) && (strRTFTag.Length>=strTestTag.Length) && (strRTFTag.Substring(0,strTestTag.Length)==strTestTag)) { string strSpecialChar=strRTFTag.Remove(0, strTestTag.Length); if (strSpecialChar.Length==2) //RTF (must be 2-digit hex code) { strSpecialChar=strSpecialChar.Substring(0,2); pElement.m_enNodeType=THTMLNodeType.c_nodText; string strHex=Converters.fromHex(strSpecialChar); pElement.m_strNodeText = strHex; //"&#x"+strSpecialChar+";"; } } //Paragraph Tag if ((pElement.m_enNodeType==THTMLNodeType.c_nodInvalid) && (strRTFTag=="par")) { int lLastUnclosedPStart=-1; //Look if we first must close paragraph for (int iLastElements=m_arrHTMLElements.Count-1;iLastElements>=0;iLastElements--) { CHTMLElement pElementTest = (CHTMLElement)m_arrHTMLElements[iLastElements]; if (pElementTest.m_strNodeText=="p") { if (pElementTest.m_enNodeType==THTMLNodeType.c_nodHTMLEnd) break; //everything is OK if ((pElementTest.m_enNodeType==THTMLNodeType.c_nodHTMLBegin)) { lLastUnclosedPStart=iLastElements; break; //everything is OK } } } if (lLastUnclosedPStart>=0) { //Look if there is no text between last <p> and this <p-end> (e.g. <p></p>) //HTML does then not display a linefeed, therefore make it to <p> </p> bool bLastParaEmpty=true; for (int iLastPara=lLastUnclosedPStart;iLastPara<m_arrHTMLElements.Count;iLastPara++) { CHTMLElement pElementTest = (CHTMLElement)m_arrHTMLElements[iLastPara]; if (pElementTest.m_enNodeType==THTMLNodeType.c_nodText) { if ((pElementTest.m_strNodeText!="")&& (pElementTest.m_strNodeText!="\r")&& (pElementTest.m_strNodeText!="\n")&& (pElementTest.m_strNodeText!="\r\n")&& (pElementTest.m_strNodeText!="b")) { bLastParaEmpty = false; } } } if (bLastParaEmpty) { //Insert modified blank (see above) CHTMLElement pElementBlank = new CHTMLElement(); pElementBlank.m_enNodeType=THTMLNodeType.c_nodText; pElementBlank.m_strNodeText = " "; m_arrHTMLElements.Add(pElementBlank); } //Insert Closing </p> CHTMLElement pElementClose = new CHTMLElement(); pElementClose.m_enNodeType=THTMLNodeType.c_nodHTMLEnd; pElementClose.m_strNodeText = "p"; m_arrHTMLElements.Add(pElementClose); } //Add paragraph tag (<p> pElement.m_enNodeType=THTMLNodeType.c_nodHTMLBegin; pElement.m_strNodeText = "p"; } else { ; //Unknown RTF tag, just ignore } */ #endregion #region Old Paragraph Alignment /* strTestTag="q"; if ((pElement.m_enNodeType==THTMLNodeType.c_nodInvalid) && (strRTFTag.Length>=strTestTag.Length) && (strRTFTag.Substring(0,strTestTag.Length)==strTestTag)) { //Get RTF alignment string strAlignRTF, strAlignHTML=string.Empty; pElement.m_enNodeType=THTMLNodeType.c_nodHTMLBegin; pElement.m_strNodeText= "font"; strAlignRTF = strRTFTag.Remove(0, strTestTag.Length); Debug.Assert(strAlignRTF.Length==1); //Invalid RTF //Convert RTF options to HTML options if (strAlignRTF=="l") { strAlignHTML="left"; } else if (strAlignRTF=="r") { strAlignHTML="right"; } else if (strAlignRTF=="c") { strAlignHTML="center"; } else { ; //unsupported } //Find last paragraph int lLastParaStart=-1; for (int iLastElements=m_arrHTMLElements.Count-1;iLastElements>=0;iLastElements--) { CHTMLElement pElementTest = (CHTMLElement)m_arrHTMLElements[iLastElements]; if ((pElementTest.m_enNodeType==THTMLNodeType.c_nodHTMLBegin) && (pElementTest.m_strNodeText=="p")) { lLastParaStart=iLastElements; break; //everything is OK } } if ((lLastParaStart>=0) && (strAlignHTML!="")) { CHTMLElement pElementPara = (CHTMLElement)m_arrHTMLElements[lLastParaStart]; //pElementPara.m_mapParams.SetAt("align", "\""+strAlignHTML+"\""); //SetAt("align", "\""+strAlignHTML+"\"") string val="\""+strAlignHTML+"\""; int key=pElementPara.m_mapParams.IndexOfKey("align"); if (key!=-1) pElementPara.m_mapParams.Add("align",val); else pElementPara.m_mapParams[key]=val; } } */ #endregion #region Old font color /* //font color strTestTag="cf"; if ((pElement.m_enNodeType==THTMLNodeType.c_nodInvalid) && (strRTFTag.Length>=strTestTag.Length) && (strRTFTag.Substring(0,strTestTag.Length)==strTestTag)) { pElement.m_enNodeType=THTMLNodeType.c_nodHTMLBegin; pElement.m_strNodeText= "font"; string strActColor = strRTFTag.Remove(0, strTestTag.Length); Debug.Assert(strActColor.Length>0); //Invalid RTF int lActColor=int.Parse(strActColor); Debug.Assert(lActColor<m_arrColors.Count); //Color not in Colortable ! if (lActColor<m_arrColors.Count) { Color clr=(Color)m_arrColors[lActColor]; //int r=0,g=0,b=0; //r=GetRValue(ref); //g=GetGValue(ref); //b=GetBValue(ref); //strHTMLColor.Format("#%02x%02x%02x",r,g,b); m_strActFontColor = System.Drawing.ColorTranslator.ToHtml(clr);; } } */ #endregion #region Old font size /* //font size strTestTag="fs"; if ((pElement.m_enNodeType==THTMLNodeType.c_nodInvalid) && (strRTFTag.Length>=strTestTag.Length) && (strRTFTag.Substring(0,strTestTag.Length)==strTestTag)) { pElement.m_enNodeType=THTMLNodeType.c_nodHTMLBegin; pElement.m_strNodeText= "font"; m_strActFontSize = strRTFTag.Remove(0, strTestTag.Length); Debug.Assert(m_strActFontSize.Length>0); //Invalid RTF //m_strActFontSize=LongToString(StringToLong(m_strActFontSize)/2); //RTF stores the doubled font size m_strActFontSize=Convert.ToString(int.Parse(m_strActFontSize)/2); //RTF stores the doubled font size } */ #endregion #region Old font name /* //font name strTestTag="f"; //f+number //(strRTFTag.Mid(1).SpanIncluding("01234567890")==strRTFTag.Mid(1))) int seek=strRTFTag.IndexOfAny(new char[]{'0','1','2','3','4','5','6','7','8','9','0'},1); if ((pElement.m_enNodeType==THTMLNodeType.c_nodInvalid) && (strRTFTag.Length>=strTestTag.Length) && (strRTFTag.Substring(0,strTestTag.Length)==strTestTag) && (seek!=-1)) { string strActFontDsgn = strRTFTag; pElement.m_enNodeType=THTMLNodeType.c_nodHTMLBegin; pElement.m_strNodeText= "font"; Debug.Assert(strActFontDsgn.Length>0); //Invalid RTF //string strActFontName; //bool bFound=false; int bFound=m_mapFontNames.IndexOf(m_strActFontName); Debug.Assert(bFound==-1); //Font not found in font table, don't change font if (bFound!=-1) m_mapFontNames[bFound]=m_strActFontName; else m_mapFontNames.Add(m_strActFontName); } */ #endregion #region Old New font tag ? /* //New font tag ? if ((pElement.m_enNodeType==THTMLNodeType.c_nodHTMLBegin) && (pElement.m_strNodeText=="font")) { bool bMustClose=false; //Look if we first must close paragraph for (int iLastElements=m_arrHTMLElements.Count-1;iLastElements>=0;iLastElements--) { CHTMLElement pElementTest = (CHTMLElement)m_arrHTMLElements[iLastElements]; if ((pElementTest.m_enNodeType==THTMLNodeType.c_nodHTMLEnd) && (pElementTest.m_strNodeText=="font")) break; //everything is OK if ((pElementTest.m_enNodeType==THTMLNodeType.c_nodHTMLBegin) && (pElementTest.m_strNodeText=="font")) { bMustClose=true; break; //everything is OK } } if (bMustClose) { //Insert Closing </p> CHTMLElement pElementClose = new CHTMLElement(); pElementClose.m_enNodeType=THTMLNodeType.c_nodHTMLEnd; pElementClose.m_strNodeText = "font"; m_arrHTMLElements.Add(pElementClose); } //Set font tag options //pElement.m_mapParams.SetAt("color", "\""+m_strActFontColor+"\""); string key="color", val="\""+m_strActFontColor+"\"";; int index=pElement.m_mapParams.IndexOfKey(key); if (index==-1) pElement.m_mapParams.Add(key,val); else pElement.m_mapParams[key]=val; //pElement.m_mapParams.SetAt("style", "\"font-size: "+m_strActFontSize+"pt; font-family:"+m_strActFontName+";\""); key="style"; val="\"font-size: "+m_strActFontSize+"pt; font-family:"+m_strActFontName+";\""; index =pElement.m_mapParams.IndexOfKey(key); if (index==-1) pElement.m_mapParams.Add(key,val); else pElement.m_mapParams[key]=val; } */ #endregion #endregion if (pElement.m_enNodeType!=THTMLNodeType.c_nodInvalid) m_arrHTMLElements.Add(pElement); }
CHTMLElement createAttrib(THTMLNodeType type,string text) { CHTMLElement ret = new CHTMLElement(); ret.m_enNodeType=type; ret.m_strNodeText=text; return ret; }