Got more questions? Find advice on: SQL | XML | Regular Expressions | Windows
in Search
Welcome to AspAdvice Sign in | Join | Help

Paul D. Murphy

Better Lemonade Mousetraps

Syntax Highlighter Server Control

This blog post is an asp.net server control that wraps the syntax highlighter javascripts files found here: http://www.dreamprojections.com/syntaxhighlighter/Default.aspx
I made some more notes on it here where i started to post it (couldn't 10,000 character limit *ouch*) http://support.webhosting.net/forum/showthread.php?t=26

-------

/// <license>

/// /**

/// * Code Syntax Highlighter.

/// * Version 1.3.0

/// * Copyright (C) 2004 Alex Gorbatchev.

/// * http://www.dreamprojections.com/syntaxhighlighter/

/// *

/// *

/// * ASP.NET SyntaxHighlighter Server Control

/// * Version 0.2

/// * Copyright (c) 2006 Paul D. Murphy

///

/// TODO: Change this to a different url

///

/// * http://blogs.aspadvice.com/pmurphy/

/// *

/// * This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General

/// * Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option)

/// * any later version.

/// *

/// * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied

/// * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more

/// * details.

/// *

/// * You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to

/// * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

/// */

/// </license>

///

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Text;

using System.Web;

using System.Web.UI;

using System.Web.UI.HtmlControls;

using System.Web.UI.WebControls;

namespace Nimbus3.Sandbox

{

/// <summary>Provides syntax hightlighting for C#, VB.net, Delphi, JavaScript, PHP, Python, SQL and XML source code.</summary>

/// <history>

///

/// 0.2 --- Initial Iteration 2006.01.03

///

/// * Developed basic runtime operations.

/// * No features.

/// * Not xhtml complaint.

/// * Non performant

///

/// 0.3 --- Clean up the mess 2006.01.04

///

/// * Moved some strings into constants

/// * Pushed the script directory path into a property

/// * Added proper commenting (sorta)

/// * Added field containment to mitigate bag access

///

///

/// TODO: Move most of the stuff into controlstate.

/// BUG: It eats content at design time...

/// </history>

[DefaultProperty("Text")]

[ToolboxData("<{0}:SyntaxHighlighter runat=server></{0}:SyntaxHighlighter>")]

public class SyntaxHighlighter : Control

{

/// client side class attribute value tags

private const String _cvSeperator = ":";

private const String _cvCollapse = _cvSeperator + "collapse";

private const String _cvNoGutter = _cvSeperator + "nogutter";

private const String _cvNoControls = _cvSeperator + "nocontrols";

private const String _cvFirstLine = _cvSeperator + "firstline[{0}]";

///

/// view state keys

private const String _vskLanguage = "Language";

private const String _vskNoGutter = "NoGutter";

private const String _vskNoControls = "NoControls";

private const String _vskCollapse = "Collapse";

private const String _vskFirstLine = "FirstLine";

private const String _vskRows = "Rows";

private const String _vskColumns = "Columns";

private const String _vskName = "Name";

private const String _vskScriptPath = "ScriptPath";

///

/// fields

private String _controlBody = String.Empty;

private String _name;

private String _scriptPath;

private Boolean? _noGutter;

private Boolean? _noControls;

private Boolean? _collapse;

private Int32? _firstLine;

private Int32? _rows;

private Int32? _columns;

private CodeLanguage? _language;

public SyntaxHighlighter()

: base()

{ }

/// All these properties look alike. i smell abstraction

public CodeLanguage Language

{

get

{

if (_language == null)

{

_language = new CodeLanguage?(CodeLanguage.Unknown);

ViewStateHelper.Get(ViewState, _vskLanguage, ref _language);

}

return _language.Value;

}

set

{

_language = value;

ViewState[_vskLanguage] = value;

}

}

public Boolean NoGutter

{

get

{

if (_noGutter == null)

{

_noGutter = new Boolean?(false);

ViewStateHelper.Get(ViewState, _vskNoGutter, ref _noGutter);

}

return _noGutter.Value;

}

set

{

_noGutter = value;

ViewState[_vskNoGutter] = value;

}

}

public Boolean NoControls

{

get

{

if (_noControls == null)

{

_noControls = new Boolean?(false);

ViewStateHelper.Get(ViewState, _vskNoControls, ref _noControls);

}

return _noControls.Value;

}

set

{

_noControls = value;

ViewState[_vskNoControls] = value;

}

}

public Boolean Collapse

{

get

{

if (_collapse == null)

{

_collapse = new Boolean?(false);

ViewStateHelper.Get(ViewState, _vskCollapse, ref _collapse);

}

return _collapse.Value;

}

set

{

_collapse = value;

ViewState[_vskCollapse] = value;

}

}

public Int32 FirstLine

{

get

{

if (_firstLine == null)

{

_firstLine = new Int32?(1);

ViewStateHelper.Get(ViewState, _vskFirstLine, ref _firstLine);

}

return _firstLine.Value;

}

set

{

_firstLine = value;

ViewState[_vskFirstLine] = value;

}

}

public Int32 Rows

{

get

{

if (_rows == null)

{

_rows = new Int32?(20);

ViewStateHelper.Get(ViewState, _vskRows, ref _rows);

}

return _rows.Value;

}

set

{

_rows = value;

ViewState[_vskRows] = value;

}

}

public Int32 Columns

{

get

{

if (_columns == null)

{

_columns = new Int32?(60);

ViewStateHelper.Get(ViewState, _vskColumns, ref _columns);

}

return _columns.Value;

}

set

{

_columns = value;

ViewState[_vskColumns] = value;

}

}

public String Name

{

get

{

if (_name == null)

{

_name = ClientID;

ViewStateHelper.Get(ViewState, _vskName, ref _name);

}

return _name;

}

set

{

_name = value;

ViewState[_vskName] = value;

}

}

public String ScriptPath

{

get

{

if (_scriptPath == null)

{

_scriptPath = "~/SyntaxHighlighter/";

ViewStateHelper.Get(ViewState, _vskScriptPath, ref _scriptPath);

}

// TODO: Need to add path correction logic here.

return _scriptPath;

}

set

{

_scriptPath = value;

ViewState[_vskScriptPath] = value;

}

}

/// <summary>i think i might want to push this out into a template.

/// the vs code editor doesn't like the notion of xml code in a textarea at all.

/// gonna need to look into some cdata magic or something</summary>

protected override void AddParsedSubObject(Object obj)

{

if (obj is LiteralControl)

{

_controlBody = ((LiteralControl)obj).Text;

}

else

{

throw new InvalidOperationException("just code please.");

}

}

/// i'll push these strings out later. this method won't last another iteration

protected override void OnInit(EventArgs e)

{

base.OnInit(e);

String url = Page.ResolveClientUrl(ScriptPath + "SyntaxHighlighter.css");

String link = "<link type=\"text/css\" rel=\"stylesheet\" href=\"" + url + "\"></link>";

LiteralControl cssLink = new LiteralControl(link);

cssLink.ID = "_cssLink";

HtmlHead pageHead = Page.Header;

if (pageHead.FindControl("_cssLink") == null)

pageHead.Controls.Add(cssLink);

}

/// i'll push these strings out later. this method won't last another iteration

protected override void OnPreRender(EventArgs e)

{

base.OnPreRender(e);

ClientScriptManager scripts = Page.ClientScript;

CodeLanguage language = Language;

String name = Name;

if(!scripts.IsClientScriptIncludeRegistered("core"))

scripts.RegisterClientScriptInclude("core", Page.ResolveClientUrl(ScriptPath + "shCore.js"));

switch (language)

{

case CodeLanguage.csharp:

if (!scripts.IsClientScriptIncludeRegistered("csharp"))

scripts.RegisterClientScriptInclude("csharp", Page.ResolveClientUrl(ScriptPath + "shBrushCSharp.js"));

break;

case CodeLanguage.delphi:

if (!scripts.IsClientScriptIncludeRegistered("delphi"))

scripts.RegisterClientScriptInclude("delphi", Page.ResolveClientUrl(ScriptPath + "shBrushDelphi.js"));

break;

case CodeLanguage.BLOCKED SCRIPT

if (!scripts.IsClientScriptIncludeRegistered("javascript"))

scripts.RegisterClientScriptInclude("javascript", Page.ResolveClientUrl(ScriptPath + "shBrushJScript.js"));

break;

case CodeLanguage.php:

if (!scripts.IsClientScriptIncludeRegistered("php"))

scripts.RegisterClientScriptInclude("php", Page.ResolveClientUrl(ScriptPath + "shBrushPhp.js"));

break;

case CodeLanguage.python:

if (!scripts.IsClientScriptIncludeRegistered("python"))

scripts.RegisterClientScriptInclude("python", Page.ResolveClientUrl(ScriptPath + "shBrushPython.js"));

break;

case CodeLanguage.sql:

if (!scripts.IsClientScriptIncludeRegistered("sql"))

scripts.RegisterClientScriptInclude("sql", Page.ResolveClientUrl(ScriptPath + "shBrushSql.js"));

break;

case CodeLanguage.vbnet:

if (!scripts.IsClientScriptIncludeRegistered("vb"))

scripts.RegisterClientScriptInclude("vb", Page.ResolveClientUrl(ScriptPath + "shBrushVb.js"));

break;

case CodeLanguage.xml:

if (!scripts.IsClientScriptIncludeRegistered("xml"))

scripts.RegisterClientScriptInclude("xml", Page.ResolveClientUrl(ScriptPath + "shBrushXml.js"));

break;

default:

break;

}

String script = String.Format(

"<script language=\"javascript\">dp.SyntaxHighlighter.HighlightAll('{0}');</script>",

name);

if (!scripts.IsStartupScriptRegistered(typeof(SyntaxHighlighter), "init" + name))

scripts.RegisterStartupScript(typeof(SyntaxHighlighter), "init" + name, script);

}

/// i'll push these strings out later. this method won't last another iteration

protected override void Render(HtmlTextWriter writer)

{

writer.WriteBeginTag("textarea");

writer.WriteAttribute("name", Name);

writer.WriteAttribute("class", BuildClassValue());

writer.WriteAttribute("rows", Rows.ToString());

writer.WriteAttribute("columns", Columns.ToString());

writer.Write(HtmlTextWriter.TagRightChar);

writer.WriteLine();

writer.Write(_controlBody);

writer.WriteLine();

writer.WriteEndTag("textarea");

}

/// <summary>builds the class attribute value for the rendered textarea</summary>

private String BuildClassValue()

{

StringBuilder builder = new StringBuilder();

Boolean exitEarly = false;

 

switch (Language)

{

case CodeLanguage.csharp:

builder.Append(CodeLanguage.csharp);

break;

case CodeLanguage.delphi:

builder.Append(CodeLanguage.delphi);

break;

case CodeLanguage.BLOCKED SCRIPT

builder.Append(CodeLanguage.javascript);

break;

case CodeLanguage.php:

builder.Append(CodeLanguage.php);

break;

case CodeLanguage.python:

builder.Append(CodeLanguage.python);

break;

case CodeLanguage.sql:

builder.Append(CodeLanguage.sql);

break;

case CodeLanguage.vbnet:

builder.Append(CodeLanguage.vbnet);

break;

case CodeLanguage.xml:

builder.Append(CodeLanguage.xml);

break;

default:

exitEarly = true;

break;

}

if (exitEarly) return String.Empty;

if (NoControls) builder.Append(_cvNoControls);

if (NoGutter) builder.Append(_cvNoGutter);

if (Collapse) builder.Append(_cvCollapse);

builder.AppendFormat(_cvFirstLine, FirstLine);

return builder.ToString();

}

}

#region CodeLanguage Enumeration

/// <summary>This enum will be replaced with a type tree.</summary>

public enum CodeLanguage

{

csharp,

vbnet,

delphi,

javascript,

php,

python,

sql,

xml,

Unknown

}

#endregion

#region ViewStateHelper Class

internal static class ViewStateHelper

{

internal static void Get<T>(StateBag bag, String key, ref T defaultValue)

{

Object o = bag[key];

if (o != null) defaultValue = (T)o;

}

}

#endregion

}

Sponsor
Published Thursday, January 05, 2006 1:47 AM by pmurphy

Comments

No Comments
Anonymous comments are disabled