Custom Skins in SubText

Comments [0]

I emailed Phil Haack trying to figure out how to use dp.SyntaxHighlighter in SubText, and he pointed out the custom skins. I'm still working on the highlighting, but I seem to be running into a problem. When I restart IIS, it seems SubText is trying to add the custom skin styles more than once and crashing with a duplicate key:


Description:
An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details:
System.ArgumentException: An item with the same key has already been added.

Source Error:
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

Stack Trace:
[ArgumentException: An item with the same key has already been added.]
    System.ThrowHelper.ThrowArgumentException(ExceptionResource resource) +48
    System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add) +2635580
    Subtext.Framework.UI.Skinning.SkinTemplates.GetTemplate(String skinKey) +166
    Subtext.Web.UI.Pages.ScriptElementCollectionRenderer.RenderScriptElementCollection(String skinKey) +47
    Subtext.Web.UI.Pages.SubtextMasterPage.InitializeBlogPage() +1136
    Subtext.Web.UI.Pages.SubtextMasterPage.OnInit(EventArgs e) +13
    System.Web.UI.Control.InitRecursive(Control namingContainer) +321
    System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +692

Comment Section

Comments are closed.


NOTE: This was written back in 2007 discussing code written even earlier. This code is different than Date.toISOString() in at least two major respects:

  1. It prints local time instead of UTC time.
  2. It uses "+00:00" instead of "Z" (Zulu time) for UTC.

A couple of years ago I had to print dates in JavaScript in UTC (ISO-8601) format (yyyy-MM-ddTHH:mm:ss.fff[+-]ZZ:ZZ). Here is the function that I developed. It assumes the date object has the correct time zone offset and uses the time zone offset from the object.

I also developed server-side C# code for formatting dates in ASP.NET pages which I'll post soon.

function pad(value, digits, padtext) {
  if (!padtext) padtext = "00000000";
  if ((digits == null) || (typeof(digits) == "undefined")) return value;
  if ((value == null) || (typeof(value) == "undefined")) return value;
  var length = value.toString().length;
  if ((length < digits) && (digits < padtext.length))
    return padtext.substr(0, digits - length) + value.toString();
  else
    return value;
}

function toUTCDateTime(date) {
  var tz = date.getTimezoneOffset();
  var offset = ((tz <= 0) ? "+" : "-");
  tz = Math.abs(tz);
  offset += pad(Math.floor(tz / 60), 2) + ":" + pad(tz % 60, 2);

  var result = date.getFullYear() + "-" +
    pad(date.getMonth() + 1, 2) + "-" +
    pad(date.getDate(), 2) + "T" +
    pad(date.getHours(), 2) + ":" +
    pad(date.getMinutes(), 2) + ":" +
    pad(date.getSeconds(), 2) + "." +
    pad(date.getMilliseconds(), 3) +
    offset;

  return result;
}

Comment Section

Comments are closed.


Well I'm still trying to figure out how to enable syntax highlighting with dp.SyntaxHighlighter in Subtext. I wrote a simple syntax highlighter in VB a long time ago that output HTML with CSS styles for operators, keywords, strings, and numbers but it was a static application. The dp.SyntaxHighlighter component is able to dynamic parse the syntax and highlight the code. In comparison, the static parser output plain HTML that could easily be pasted into a blog. There are advantages to each method, but the highlighting in dp.SyntaxHighlighter is pretty cool.


Comment Section

Comments are closed.


I wrote a little VBA the other day to save an Excel Worksheet as an ADODB.Recordset XML file. I decided to see how hard it would be to do the exact same thing in C#. The idea is that I might start using C# Script instead of JavaScript for little utilities in the future.

using ADODB;
using Excel;
using System;
using System.Collections.Generic;
using System.Data;
using System.Reflection;
using System.Runtime.InteropServices;

namespace ExcelUtility
{
    public class ExcelExport
    {
        public const string EXCEL_PROG_ID = "Excel.Application";

        public static Excel.Application ExcelApplication
        {
            get
            {
                Excel.Application app = null;

                try
                {
                    // http://msmvps.com/blogs/pauldomag/archive/2006/03/15/86417.aspx
                    app = Marshal.GetActiveObject(EXCEL_PROG_ID) as Excel.Application;
                }
                catch (Exception ex)
                {
                    System.Diagnostics.Trace.WriteLine(ex.ToString());
                }

                if (app == null)
                {
                    try
                    {
                        app = new Excel.ApplicationClass();
                    }
                    catch (Exception ex)
                    {
                        System.Diagnostics.Trace.WriteLine(ex.ToString());
                    }
                }

                return app;
            }
        }

        public static System.Data.DataTable SaveWorksheetAsDataTable()
        {
            Excel.Application app = ExcelApplication;
            Excel.Workbook book = app.ActiveWorkbook as Excel.Workbook;
            Excel.Worksheet sheet = app.ActiveSheet as Excel.Worksheet;
            int col, colcount;
            int row, rowcount;

            if (sheet == null)
                return null;

            // Get the current sheet range
            Excel.Range range = sheet.Cells;
            colcount = sheet.UsedRange.Columns.Count;
            rowcount = sheet.UsedRange.Rows.Count;

            // Get the header row
            row = 1;
            System.Data.DataTable dt = new System.Data.DataTable(sheet.Name);
            for (col = 1; col <= colcount; ++col)
            {
                string text = (string)(range[row, col] as Excel.Range).Text;
                dt.Columns.Add(text, typeof(string));
            }

            // Get all of the data
            for (row = 2; row <= rowcount; ++row)
            {
                DataRow dr = dt.NewRow();
                for (col = 0; col < colcount; ++col)
                {
                    string text = (string)(range[row, col + 1] as Excel.Range).Text;
                    if (text.Length > 0)
                        dr[col] = text;
                }
                dt.Rows.Add(dr);
            }

            // Save the data
            dt.WriteXml(book.Path + "\\" + sheet.Name + ".xml");

            // Clean up
            app = null;
            return dt;
        }

        public static ADODB.Recordset SaveWorksheetAsRecordset()
        {
            Excel.Application app = ExcelApplication;
            Excel.Worksheet sheet = app.ActiveSheet as Excel.Worksheet;
            int col, colcount;
            int row, rowcount;

            if (sheet == null)
                return null;

            // Get the current sheet range
            Excel.Range range = sheet.Cells;
            colcount = sheet.UsedRange.Columns.Count;
            rowcount = sheet.UsedRange.Rows.Count;

            // Get the header row
            row = 1;
            ADODB.Recordset rst = new ADODB.RecordsetClass();
            for (col = 1; col <= colcount; ++col)
            {
                string text = (string)(range[row, col] as Excel.Range).Text;
                rst.Fields.Append(text, ADODB.DataTypeEnum.adVarChar, 255, ADODB.FieldAttributeEnum.adFldMayBeNull, null);
            }
            rst.Open(null, null, CursorTypeEnum.adOpenUnspecified, LockTypeEnum.adLockUnspecified, -1);

            ADODB.Field[] fields = new ADODB.Field[colcount];
            for (col = 0; col < colcount; ++col)
                fields[col] = rst.Fields[col];

            // Get all of the data
            for (row = 2; row <= rowcount; ++row)
            {
                rst.AddNew(null, null);
                for (col = 0; col < colcount; ++col)
                {
                    string text = (string)(range[row, col + 1] as Excel.Range).Text;
                    if (text.Length > 0)
                        fields[col].Value = text;
                }
                rst.Update(null, null);
            }

            // Save the data
            string filename = book.Path + "\\" + sheet.Name + ".xml";
            rst.Save(filename, PersistFormatEnum.adPersistXML);

            // Clean up
            app = null;
            return dt;
        }
    }
}

Comment Section

Comments are closed.


This weekend I was working on a spreadsheet and I needed to save the data as a recordset. Unfortunately there didn't seem to be a way to do it easily without VBA macros. So I wrote this macro to save the current worksheet as an ADODB.Recordset XML file. Remember to add a reference to Microsoft.ActiveX Data Object 2.8 Library in the Excel Visual Basic Editor.

Public Sub CreateAdoRecordsetXml()
    Dim rst As New ADODB.Recordset
	Dim sheet As Worksheet
	Dim col As Long, colcount As Long
	Dim row As Long, rowcount As Long
	Dim Filename As String

	Filename = ActiveWorkbook.Path + "\" + ActiveSheet.Name + ".xml"
	Set sheet = ActiveSheet
	colcount = sheet.UsedRange.Columns.count
	rowcount = sheet.UsedRange.Rows.count
	col = 1
	row = 1
	Do While col <= colcount
		Call rst.Fields.Append(sheet.Cells(row, col).Text, adVarChar, 255, adFldMayBeNull)
		col = col + 1
	Loop
	rst.Open
	row = 2
	Do While row <= rowcount
		col = 1
		Call rst.AddNew
		With rst.Fields
			Do While col <= colcount
				If sheet.Cells(row, col).Text <> "" Then
					.Item(col - 1).Value = sheet.Cells(row, col).Text
				End If col = col + 1
			Loop
		End With
		Call rst.Update row = row + 1
	Loop
	Call rst.Save(Filename, adPersistXML)
End Sub

Comment Section

Comments are closed.


<< Older Posts | Newer Posts >>