Wednesday, January 2, 2008

Creating .NET source code formatter using ASP.NET AJAX

For blogging I use online formatter for .NET source code, which is available on manoli.net
The source code for the library is available for free download. And the license is allowing to use this library in commercial and not commercial applications. I thought it will be great if I use this library on my own website. So I did :).
I enhanced the colorer, by adding to the page AJAX functionality using code for previous article.
I just changed a little my Command class, this is the only method I added there:

        public object Format(object data)
        {
            string output = "";
            object[] input = data as object[];
            if (input != null)
            {
                string code = input[0] as string;
                string lang = input[1] as string;
                bool lineNumbers = (bool)input[2];
                bool altBackground = (bool)input[3];
                bool embedStylesheet = (bool)input[4];
                if (
                    !String.IsNullOrEmpty(code) &&
                    !String.IsNullOrEmpty(lang)
                    )
                {
                    SourceFormat format;
                    switch (lang)
                    {
                        case "C#":
                            format = new CSharpFormat();
                            break;
                        case "JS":
                            format = new JavaScriptFormat();
                            break;
                        case "VB":
                            format = new VisualBasicFormat();
                            break;
                        case "html/xml/aspx":
                            format = new HtmlFormat();
                            break;
                        case "T-SQL":
                            format = new TsqlFormat();
                            break;
                        case "MSH":
                            format = new MshFormat();
                            break;
                        default:
                            format = new CSharpFormat();
                            break;
                    }
                    format.LineNumbers = lineNumbers;
                    format.Alternate = altBackground;
                    format.EmbedStyleSheet = embedStylesheet;
                    output = format.FormatCode(code);
                }
            }
            return output;
        }


Also I changed the initialisation code for main.js file:

var mainScreen =
{
    result : null,
    lang : null,
    lineNumbers : null,
    altBackground : null,
    embedStylesheet : null,
    resultDiv : null,
    resultPreview : null,
    resultHtml : null,
    code : null
}

mainScreen.Init = function() {
    /// <summary>
    /// Initializes mainScreen variables
    /// </summary>
    
    this.lang = document.getElementsByName("lang");
    this.lang[0].checked = true;
    this.lineNumbers = $get("lineNumbers");
    this.altBackground = $get("altBackground");
    this.embedStylesheet = $get("embedStylesheet");
    this.resultDiv = $get("resultDiv");
    this.resultPreview = $get("resultPreview");
    this.resultHtml = $get("resultHtml");
    this.code = $get("code");
};


And html markup for the page looks like:

<%@ Page StylesheetTheme="Default" Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>

<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="cc1" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>.NET Source Code Colorer</title>
</head>
<body>
    <form id="form1" runat="server">
    <asp:ScriptManager 
        EnablePageMethods="true" 
        ID="MainSM" 
        runat="server" 
        ScriptMode="Release"
        LoadScriptsBeforeUI="true">
        <Scripts>
            <asp:ScriptReference Path="~/Scripts/Main.js" />
        </Scripts>
    </asp:ScriptManager>
    <script type="text/javascript">
        var mHandlers = {};
        mHandlers.FormatResult = function(obj) {
            mainScreen.resultHtml.value = obj;
            mainScreen.resultPreview.innerHTML = obj;
            if(obj!="") {
                mainScreen.resultDiv.style.display = "";
            } else {
                mainScreen.resultDiv.style.display = "none";
            }
        };
        mHandlers.Format = function() {
            var par = new Array();
            par[0] = mainScreen.code.value;
            var langValue = "";
            var i = 0;
            for(i = 0; i<mainScreen.lang.length; i++) {
                if(mainScreen.lang[i].checked) {
                    langValue += mainScreen.lang[i].value;
                }
            }
            par[1] = langValue;
            par[2] = mainScreen.lineNumbers.checked;
            par[3] = mainScreen.altBackground.checked;
            par[4] = mainScreen.embedStylesheet.checked;
            mainScreen.ExecuteCommand(
                "Format", 
                "mHandlers.FormatResult", 
                par);
        };
    </script>
    <div>
    <table border="0" cellpadding="0" cellspacing="0" width="100%">
        <tr>
            <td align="left" valign="top">
                Paste script to generate html<br />
                <div style="width: 100%;">
                    <div style="width: 70%; float: left;">
                        <textarea 
                            id="code" 
                            style="width: 95%; height: 200px;"></textarea>
                    </div>
                    <div style="width: 25%; float: right;">
                    <input name="lang" type="radio" 
                        value="C#" />&nbsp;C#<br />
                    <input name="lang" type="radio" 
                        value="VB" />&nbsp;VB<br /> 
                    <input name="lang" type="radio" 
                        value="html/xml/aspx" />&nbsp;html/xml/aspx<br />
                    <input name="lang" type="radio" 
                        value="JS" />&nbsp;JS<br />
                    <input name="lang" type="radio" 
                        value="T-SQL" />&nbsp;T-SQL<br />
                    <input name="lang" type="radio" 
                        value="MSH" />&nbsp;MSH<br /><br />
                    <input id="lineNumbers" 
                        type="checkbox" />&nbsp;Line numbers<br />
                    <input id="altBackground" 
                        type="checkbox" />&nbsp;Alternate lines<br />
                    <input id="embedStylesheet" 
                        type="checkbox" />&nbsp;Embed stylesheet<br />
                    </div>
                </div>
                <br />
            </td>
        </tr>
        <tr>
            <td align="left" valign="top">
                <input 
                    type="button" 
                    value="Format" 
                    onclick="mHandlers.Format();" />
            </td>
        </tr>
        <tr>
            <td align="left" valign="top">
                <div id="resultDiv" style="display: none;">
                    <hr style="height: 1px; color: Black;" />
                    <cc1:TabContainer 
                        ID="tcColorer" 
                        runat="server" 
                        ActiveTabIndex="0" 
                        Width="520px">
                        <cc1:TabPanel 
                            runat="server" 
                            HeaderText="Preview" 
                            ID="tp1">
                            <ContentTemplate>
                                <div 
                                    id="resultPreview" 
                                    style="
                                            height: 200px; 
                                            width: 500px; 
                                            overflow: auto;">
                                </div>
                            </ContentTemplate>
                        </cc1:TabPanel>
                        <cc1:TabPanel 
                            ID="tp2" 
                            runat="server" 
                            HeaderText="Html">
                            <ContentTemplate>
                                <textarea 
                                    id="resultHtml" 
                                    style="
                                            height: 200px; 
                                            width:500px; 
                                            overflow:scroll; "></textarea>
                            </ContentTemplate>
                        </cc1:TabPanel>
                    </cc1:TabContainer>
                </div>
            </td>
        </tr>
        <tr>
            <td align="left" valign="top">
                <br /><br />
                Credits to 
                <a href="http://manoli.net/">
                Jean-Claude Manoli
                </a> 
                for this excellent 
                <a href="http://manoli.net/csharpformat/CSharpFormat.zip">
                CSharpFormat
                </a> 
                library
            </td>
        </tr>
    </table>
    </div>
    </form>
</body>
</html>


Use it online! Or download source code.

2 comments:

Anonymous said...

Good post.

Anonymous said...

I cannot run the applicatio in localhost.
I get this JS error:


---------------------------
Error
---------------------------
A Runtime Error has occurred.
Do you wish to Debug?

Line: 102
Error: 'mainScreen.code.value' is null or not an object
---------------------------
Yes No
---------------------------


Can you help me?

thanks a lot!

Nicola