Because computer programmers like myself are lazy, and if we have to do something twice, that's once to much, I wrote a program to do this for me. Right now it consists of Two RichTextBoxes and a WebBrowser thrown onto a windows from. Paste RTF code (like the code from VS) into rtfTextBox, and press the convert button and presto, you're done. The Html is outputed in another RichTextBox, and copied to the Clipboard, while the Webrowser gives you a preview. No CSS are needed.
In the near future I'd love to turn this into a VS add in so I can just select some code, right click, and select Convert.
You'll fine the source code posted below, which was generated using itself of course. :)
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace RTF2HTMLConverter {
    public partial class Form1 : Form {
        const string BackwardsSlash = "&bws;";
        const string OpenCurlyBracket = "&ocb;";
        const string CloseCurlyBracker = "&ccb;";
        const string DoubleQuote = """;
        const string GreaterThan = ">";
        const string LessThan = "<";
        const string Ampersand = "&amp";
        bool _inColorSpan;
        public Form1() {
            InitializeComponent();
        }
        private void button1_Click(object sender, EventArgs e) {
            string[] rtf = rtfTextBox.Rtf.Replace("&", Ampersand).Replace("\\\\", BackwardsSlash).Replace("\\}", CloseCurlyBracker).Replace("\\{", OpenCurlyBracket).Replace("\"", DoubleQuote).Replace(">", GreaterThan).Replace("<", LessThan).Split('\n');
            string rtfLine;
            _inColorSpan = false;
            Dictionary<string, string> colors = new Dictionary<string, string>();
            StringBuilder output = new StringBuilder();
            output.Append("<pre class=\"code\"><span style=\"font-size:85%;\">");
            for (int i = 1; i < rtf.Length; i++) {
                rtfLine = rtf[i];
                if(i == 1){
                    GetColors(rtfLine, colors);
                }else
                    output.Append(GetOutputLine(rtfLine, colors));
                }
            }
            output.Append("</span></pre>\n");
            htmlTextBox.Text = output.ToString().Replace(BackwardsSlash, "\\").Replace(CloseCurlyBracker, "}").Replace(OpenCurlyBracket,"{");
            webBrowser1.DocumentText = htmlTextBox.Text;
            Clipboard.SetText(htmlTextBox.Text);
        }
        private string GetOutputLine(string rtfLine, Dictionary<string, string> colors) {
            string outputLine = string.Empty;
            string[] rtfLineSegments = rtfLine.Split('\\');
            string firstWord;
            string currentColor = string.Empty;
            foreach (string segment in rtfLineSegments) {
                if(segment == string.Empty){
                    continue;
                }
                firstWord = GetFirstWord(segment);
                if (firstWord.IndexOf(' ') == 0) {//Trailing Spaces, just add it
                    outputLine += segment;
                } else if (colors.Keys.Contains(firstWord.Trim())) {//Change the Color
                    if (segment == firstWord) { // No Other Text, just change the color
                        currentColor = firstWord;
                        outputLine += GetColorSpan(colors[segment]);
                    } else if(segment.Substring(firstWord.Length).Trim() != string.Empty) { // Change color and Add the rest of the segment if there is something to update
                        if (currentColor != string.Empty && currentColor == firstWord.Trim()) { // Color hasn't changed, skip adding new color span
                            outputLine += segment.Substring(firstWord.Length);
                        } else {
                            currentColor = firstWord.Trim();
                            outputLine += GetColorSpan(colors[currentColor]) + segment.Substring(firstWord.Length);
                        }
                    }else//all Blank Spaces, don't worry about the color
                        outputLine += segment.Substring(firstWord.Length);
                    }
                } else if (!segment.Contains(' ') && rtfLineSegments.Length > 2) { // Control word, skip it
                    continue;
                } else if (!segment.Contains(' ') && rtfLineSegments[0] == segment && rtfLineSegments.Length == 2) {// There is no Color for this segment, so use everything
                    outputLine += segment;
                }else
                    //First word is control word, skip it and add the rest
                    outputLine += segment.Substring(firstWord.Length);
                }
            }
            return outputLine += "\n";
        }
        private static string GetFirstWord(string segment) {
            string firstWord;
            if (!segment.Contains(' ')) {
                firstWord = segment;
            } else {
                firstWord = segment.Substring(0, segment.IndexOf(' ') + 1);
            }
            return firstWord;
        }
        private static void GetColors(string rtfLine, Dictionary<string, string> colors) {
            string[] colorValues = rtfLine.Substring(1, rtfLine.Length - 2).Split(';');
            string rtfColor;
            string htmlColor;
            for (int k = 1; k < colorValues.Length; k++) {
                rtfColor = colorValues[k];
                if (rtfColor == "}") {
                    continue;
                }
                if (rtfColor.Contains("\\red")) {
                    string[] hexColors = rtfColor.Split('\\');
                    htmlColor = "#" + GetHexValue(hexColors[1], "red") + GetHexValue(hexColors[2], "green") + GetHexValue(hexColors[3], "blue");
                    htmlColor = ConvertColor(htmlColor);
                    htmlColor = "color: " + htmlColor;
                } else {
                    throw new Exception("Unrecognized Color " + rtfColor);
                }
                colors.Add("cf" + k.ToString(), htmlColor);
            }
        }
        private static string ConvertColor(string htmlColor) {// Convert the Colors from a Dark Scheme, to a White Scheme
            switch (htmlColor) {
                case "#ff8000":
                    htmlColor = "blue"; // Reserved Words
                    break;
                case "#fefffe":
                    htmlColor = "#010001"; // Regular Text
                    break;
                case "#808080":
                    htmlColor = "green"; // Comments
                    break;
                case "#ffffff":
                    htmlColor = "black"; //;
                    break;
                case "#ffff00":
                    htmlColor = "#2b91af"; //class Names
                    break;
                case "#2892b0":
                    htmlColor = "red"; // Integers
                    break;
                case "#00ff00":
                    htmlColor = "#a31515"; // Strings
                    break;
            }
            return htmlColor;
        }
        private static string GetHexValue(string hexColor, string colorName){
            return System.Convert.ToString(int.Parse(hexColor.Substring(colorName.Length, hexColor.Length - colorName.Length)), 16).PadLeft(2, '0');
        }
        private string GetColorSpan(string color){
            if (_inColorSpan) {
                return string.Format("</span><span style=\"{0}\">", color);
            } else {
                _inColorSpan = true;
                return string.Format("<span style=\"{0}\">", color);
            }
        }
    }
}
 
 
 
 Posts
Posts
 
 

No comments:
Post a Comment