/// <summary> /// /Add constructor logic here /// </summary> /// <param name="enMode"></param> public clsRtf2Html(TMode enMode) { Debug.Assert(enMode==TMode.c_modRTF2HTML); //vice versa unsupported at the moment m_enMode = enMode; m_RTFTree = new CRTFNode(); SetTitle = "RTF2HTML Generated Document"; m_arrColors=new ArrayList(); //Color[] m_arrHTMLElements=new ArrayList(); //CHTMLElement[] m_mapFontNames=new ArrayList(); //CMapStringToString[] m_RTFTree=new CRTFNode(); m_strName=string.Empty; m_strCode=string.Empty; m_strThisCode=string.Empty; m_strPlain=string.Empty; m_strLang=string.Empty; ResetMetaData(); }
public string ConvertRTF2HTML(ref string source) { #if DEBUG System.IO.StreamWriter sw=new System.IO.StreamWriter(@"c:\temp\_123Rtf.rtf"); sw.Write(source); sw.Flush(); sw.Close(); #endif //Initializing m_strHTML = string.Empty; m_strRTF=source; //Check_Valid_RTF m_strRTF=m_strRTF.TrimEnd('\n'); //m_strRTF.TrimRight("\n"); m_strRTF=m_strRTF.TrimEnd('\r'); //m_strRTF.TrimRight("\r"); m_strRTF=m_strRTF.Replace(@"_\v &_\v0"," "); //старое наследие RTF - это пробел между словами в гиперссылке //m_strRTF=m_strRTF.Replace("&_"," "); //старое наследие RTF //string strEndChar=m_strRTF.Substring(m_strRTF.Length-1,1); if (!(m_strRTF.Length>=7 && m_strRTF.Substring(0,6)=="{\\rtf1") && m_strRTF.LastIndexOf("}")==-1) { //Invalid RTF file. Must start with "{RTF1" and end with "}" Debug.Assert(false,"Not right RTF","header or footer this message RTF not valid !"); return m_strHTML; } //Clear internal members ResetMetaData(); //Build up RTF Tree. Each tree in a node coresponds to a {} section in the RTF file (code) //and has a designator (name), like \RTF or \FONTTBL. We start with the whole RTF file //(Section \RTF1) m_RTFTree = new CRTFNode(); CRTFNode NodeRoot = R2H_BuildTree(m_strRTF,ref m_RTFTree); string strRTFCode = NodeRoot.m_strThisCode; //Fill internal meta data members R2H_SetMetaData(ref NodeRoot); //HTML Header m_strHTML+=R2H_GetHTMLHeader(); //Create html main body R2H_CreateHTMLElements(strRTFCode); //Get HTML main body as string string strHTMLText=R2H_GetHTMLElements(); //strHTMLText); m_strHTML+=" "+strHTMLText+"\r\n"; //HTML Footer m_strHTML+=R2H_GetHTMLFooter(); /* #if DEBUG if (m_strHTML!=string.Empty) { Form frm=new Form(); TreeView tv=new TreeView(); frm.Controls.Add(tv); tv.Visible=true; tv.Dock=DockStyle.Fill; tv.Nodes.Add(NodeRoot); tv.ExpandAll(); frm.Show(); } #endif */ return m_strHTML; }
//CRTF_HTMLConverter::CRTFNode CRTF_HTMLConverter:: CRTFNode R2H_BuildTree(string strSource, ref CRTFNode pNodeParent) { //Initializing string strName=string.Empty; CRTFNode nodeThis=new CRTFNode(); //Extract Node's Name if ((strSource.Length>2) && (strSource.Substring(0,2)==@"{\")) { for (int iStrPos=2;iStrPos<strSource.Length;iStrPos++) { string strChTest=strSource[iStrPos].ToString(); int seek=strChTest.IndexOfAny(new char[]{' ','{','}','\\','\r'}); // if (seek==-1) //strChTest.SpanIncluding(" {}\\\r")!="") break; else strName+=strChTest; } } else { //Invalid RTF Node. RTF Nodes must start with a { and then contain a \NAME identifier Debug.Assert(false); return nodeThis; } //Extract pure text - отрезаем начало и конец string strNodeText=strSource.Substring(1,strSource.Length-2); //strNodeText=strNodeText.Remove(0,1); //strNodeText.Delete(0,1); //strNodeTextstrNodeText.Remove(strNodeText.Length-1, 1); //strNodeText.Delete(strNodeText.Length)-1, 1); //Add node into tree CRTFNode nodeA=new CRTFNode(); nodeA.m_strCode = strSource; nodeA.m_strName = strName; if (pNodeParent!=null) nodeThis = (CRTFNode)pNodeParent.Nodes[pNodeParent.Nodes.Add(nodeA)]; else nodeThis = (CRTFNode)nodeA.Nodes[m_RTFTree.Nodes.Add(nodeA)]; //Looking for children string strNodeNew=string.Empty,strThisCode=string.Empty ; int lLevel=0; //# Of opened { for (int iStrPos=0;iStrPos<strNodeText.Length;iStrPos++) { string strChTest=strNodeText[iStrPos].ToString(); if (strChTest=="{") { //New element if (lLevel==0) strNodeNew=string.Empty; //else - Nested Element, will be added during recurse lLevel++; } if (lLevel>0) strNodeNew+=strChTest; else strThisCode+=strChTest; if (strChTest=="}") { Debug.Assert(lLevel>0); //Invalid RTF, more closing } than opening ґ{ lLevel--; if (lLevel==0) { //Recurse (new Sub-Node (child) ready R2H_BuildTree(strNodeNew,ref nodeThis); //R2H_BuildTree(strNodeNew,&nodeThis); } else {;} //Nested Element, will be added during recurse } } //loop thru string Debug.Assert(lLevel==0); //Invalid RTF, more opening { than closing } //Get the plain text (without \) string strPlain=string.Empty; for (int iStrPos=0;iStrPos<strNodeText.Length;iStrPos++) { string strChTest=strNodeText[iStrPos].ToString(); if (strChTest==@"\") { string strTag=R2H_GetRTFTag(strNodeText, iStrPos); iStrPos+=strTag.Length; if (((iStrPos+1)<strNodeText.Length)&&(strNodeText[iStrPos+1]==' ')) iStrPos++; //Ignore Blank after Tag else strPlain+=strChTest; } } //loop thru string nodeThis.m_strPlain=strPlain; nodeThis.m_strThisCode = strThisCode; return nodeThis; }
//CRTF_HTMLConverter:: void R2H_SetMetaData(ref CRTFNode NodeRoot) { //Initializing string strRTFSource = NodeRoot.m_strThisCode; //Go thru RTF main string's global data for (int iStrPos=0;iStrPos<strRTFSource.Length;iStrPos++) { string strChTest=strRTFSource[iStrPos].ToString(); if (strChTest==@"\") { string strTag=R2H_GetRTFTag(strRTFSource, iStrPos); string strTestTag; strTestTag="ansicpg"; if ((strTag.Length>=strTestTag.Length) && (strTag.Substring(0,strTestTag.Length)==strTestTag)) { //добавляем строку кодовой страницы m_strCharset = strTag.Remove(0, strTestTag.Length); } iStrPos+=strTag.Length; if (((iStrPos+1)<strRTFSource.Length) && (strRTFSource[iStrPos+1]==' ')) iStrPos++; //Ignore Blank after Tag } else { //Normal character } } //loop thru string //Go thru 1st-level-nodes for(int iRTFNodes=0;iRTFNodes<NodeRoot.Nodes.Count;iRTFNodes++) { //Color table if (((CRTFNode)NodeRoot.Nodes[iRTFNodes]).m_strName=="colortbl") { string strColorTbl=((CRTFNode)NodeRoot.Nodes[iRTFNodes]).m_strThisCode; strColorTbl=strColorTbl.Remove(0,((CRTFNode)NodeRoot.Nodes[iRTFNodes]).m_strName.Length+1); //+1=leading \ (backslash) //Palette entries are separated with semicolon ; ArrayList arrStrColors=new ArrayList(); //CStringArray arrStrColors; arrStrColors.Add(strColorTbl); //StringToArray(strColorTbl, arrStrColors); for (int iColor=0;iColor<arrStrColors.Count;iColor++) { //RGB values within palette entry are \redXXX\greenXXX\blueXXX int r=0,g=0,b=0; string strColorEntry=((string)arrStrColors[iColor]).Trim(); if (strColorEntry.Length>0) { //Loop thru base colors (r,g,b) and set them //CStringArray arrStrRGBs; ArrayList arrStrRGBs=new ArrayList(); R2H_GetRTFTags(strColorEntry, ref arrStrRGBs); Debug.Assert(arrStrRGBs.Count==3); //RTF must contain exactly 3 entries for red/green/blue for (int iBaseColor=0;iBaseColor<arrStrRGBs.Count;iBaseColor++) { string strBaseColor=(string)arrStrRGBs[iBaseColor]; string strTestBaseColor="red"; if ((strBaseColor.Length>=strTestBaseColor.Length) && (strBaseColor.Substring(0,strTestBaseColor.Length)==strTestBaseColor)) { strBaseColor=strBaseColor.Remove(0, strTestBaseColor.Length); r=int.Parse(strBaseColor); } strTestBaseColor="green"; if ((strBaseColor.Length>=strTestBaseColor.Length) && (strBaseColor.Substring(0,strTestBaseColor.Length)==strTestBaseColor)) { strBaseColor=strBaseColor.Remove(0, strTestBaseColor.Length); g=int.Parse(strBaseColor); } strTestBaseColor="blue"; if ((strBaseColor.Length>=strTestBaseColor.Length) && (strBaseColor.Substring(0,strTestBaseColor.Length)==strTestBaseColor)) { strBaseColor=strBaseColor.Remove(0, strTestBaseColor.Length); b=int.Parse(strBaseColor); } } } Color COLORREF =Color.FromArgb(r,g,b); m_arrColors.Add(COLORREF); } continue; } //Font Table if (((CRTFNode)NodeRoot.Nodes[iRTFNodes]).m_strThisCode=="fonttbl") //m_strName { for(int iFontNodes=0;iFontNodes<NodeRoot.Nodes[iRTFNodes].Nodes.Count;iFontNodes++) { string strFontName=((CRTFNode)NodeRoot.Nodes[iRTFNodes].Nodes[iFontNodes]).m_strName; string strFont=((CRTFNode)NodeRoot.Nodes[iRTFNodes].Nodes[iFontNodes]).m_strPlain; Debug.Assert((strFontName.Length>=2) && (strFontName.Substring(1)=="f")); //No valid RTF Debug.Assert(strFont.Length>0); strFont=strFont.Trim(); strFont.Replace(';',' '); //m_mapFontNames.SetAt(strFontName, strFont); int ps =m_mapFontNames.IndexOf(strFontName); if (ps!=-1) m_mapFontNames[ps]= strFont; } //for-each-font continue; } //if font-table } //for each 1st-level-node }