|
|
Better Lemonade Mousetraps
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
}
Anonymous comments are disabled
|
|
|