a DotNetStyling - .Net World by Armen Ayvazyan : Append new line in StringBuilder: AppendLine, AppendFormatLine, JavaScriptBuilder
Welcome to DotNetStyling Sign in | Join | Help
Add to Technorati Favorites Add to Google Reader or Homepage Add to My AOL Subscribe in FeedLounge Subscribe in Bloglines Add to Excite MIX Add to flurry Add to Pageflakes Subscribe in NewsGator Online


Append new line in StringBuilder: AppendLine, AppendFormatLine, JavaScriptBuilder

It is a common technique in ASP.NET to generate JavaScript code from the web page's code behind file (.aspx.cs, .aspx.vb). Unfortunately it is a problem to read and sustain rendered JavaScript code because it usually renders all JavaScript code in one line. So, to have it readable developer tries to break those lines to have code a little bit more readable. But downside is more "mess" in code which builds JavaScript.


Before I'll continue I hope you are familiar that the best and the fastest way how to build a strings in .Net is using StringBuilder. If no read here why.


This is how usually we do concatenation with StringBuilder:

 

StringBuilder sb = new StringBuilder(128);
sb.Append("Using standard StringBuilder.Append()\n");

sb.Append("Line number 1");

sb.Append(Environment.NewLine);

sb.Append("Line number 2");

sb.Append(Environment.NewLine);

 

Output:

image

 

 

AppendLine

Fortunately, StringBuilder contains AppendLine method which is basically doing the same Append and plus adding new line (Environment.NewLine) automatically.

So, if we rewrite the same code we will have this:

 

StringBuilder sb = new StringBuilder(128);

sb.AppendLine("Using standard StringBuilder.Append()");

sb.AppendLine("Line number 1");

sb.AppendLine("Line number 2");

As you can see no need to add a code to break lines.

 

 

AppendFormatLine

Unfortunately StringBuilder does not contain similar method for adding formatted text (AppendFormat). But we could achieve that by implementing small 2 lines of code method, AppendFormatLine;

 

private static void AppendFormatLine(

              ref StringBuilder sb,

              string format,

              params object[] args)

{

       sb.AppendFormat(format, args);

       sb.Append(Environment.NewLine);

}

 

Now we can append formatted text and add automatically Environmen.NewLine.

 

StringBuilder sb = new StringBuilder(128);

sb.AppendLine("Using AppendFormatLine()");

AppendFormatLine(ref sb, "Line number {0}", 1);

AppendFormatLine(ref sb, "Line number {0}", 2);

Output:

image

 

Let's return to JavaScript code.

This is how I usually see the code which creates JavaScript from codebehind (It is really simplified example, the real world is much complicated :) )

StringBuilder sb = new StringBuilder();

sb.Append("function MakeAlert()\n");

sb.Append("{\n");

sb.AppendFormat("var functionCreatedDate = '{0}';",

       DateTime.Now.ToShortDateString());

sb.Append(Environment.NewLine);

sb.Append("alert('MakeAlert function was created at ' + functionCreatedDate);");

sb.Append("\n");

sb.Append("}");

 

Output:

image

 

Now let's use AppendLine and AppendFormatLine methods instead of Append and AppendFormat accordingly:

 

StringBuilder sb = new StringBuilder();

sb.AppendLine("function MakeAlert()");

sb.AppendLine("{");

AppendFormatLine(ref sb, "var functionCreatedDate = '{0}';",

                 DateTime.Now.ToShortDateString());

sb.AppendLine("alert('MakeAlert function was created at ' + functionCreatedDate);");

sb.AppendLine("}");

Console.WriteLine(sb.ToString());

The result is:

  • Used twice less  line of codes
  • More or less readable then previous version
  • Got rid of '\n' Escape character

 

 

JavaScriptBuilder

If you experience this problem in a big application where generates a lot of JavaScript code, I am suggesting to create some "help" class or utility which will do all formatting (and not only) for you and will be more user(developer) friendly.

I created on the fly (during 15 minutes) such helper class: JavaScriptBuilder. It is not a perfect solution but shows a direction of what I am talking about.

Note: You can download the source code at the end of this blog post.

What class does:

  • It creates instance of StringBuilder itself with specifying capacity (bigger then default one).
  • It contains self descriptive operations which corresponding to common used JavaScript statements.
  • It adds new lines internally. No need to use AppendLine or other technique.
  • It adds open / close braces for you
  • Adds offset to have code easy readable in rendered HTML file.

 

public class JavaScriptBuilder

{

       private const string OFFSET = "\t";

       private int currentOffsetDepth = 0;

       private bool isFunction = false;

       private StringBuilder sb = new StringBuilder(128);

      

public JavaScriptBuilder()

       {

             

       }

 

       public JavaScriptBuilder(string functionName)

       {

              AppendFormatLine("function {0}()", functionName);

              sb.AppendLine("{");

 

              currentOffsetDepth++;

              isFunction = true;

       }

 

       public JavaScriptBuilder(string functionName, params string[] inputParameters)

       {

              sb.AppendFormat("function {0}(", functionName);

 

              foreach (string s in inputParameters)

              {

                     sb.AppendFormat("{0},", s);

              }

 

              sb.Remove(sb.Length - 1, 1);

              sb.AppendLine(")");

              sb.AppendLine("{");

 

              currentOffsetDepth++;

              isFunction = true;

       }

 

       public string GenerateCode()

       {

              if(isFunction)

              {

                     sb.AppendLine("}");

                     currentOffsetDepth--;

              }

 

              return sb.ToString();

       }

 

       public void AddCodeLine(string code)

       {

              AppendOffset();

              sb.AppendLine(code);

       }

      

       public void AddCodeLine(string format, params object[] args)

       {

              AppendOffset();

              AppendFormatLine(format, args);

       }

 

       public void AddAlertBox(string message)

       {

              AppendOffset();

              AppendFormatLine("alert({0});", message);                    

       }

 

       public void AddAlertBox(string formattedMessage, params object[] args)

       {

              AppendOffset();

              AppendFormatLine("alert(" + formattedMessage + ");", args);

       }

 

       private void AppendFormatLine(string format, params object[] args)

       {

              sb.AppendFormat(format, args);

              sb.Append(Environment.NewLine);

       }

 

       private void AppendOffset()

       {

             for (int i = 0; i < currentOffsetDepth; i++)
             {

                     sb.Append(OFFSET);

             }

       }

}

 

By using JavaScriptBuilder we can rewrite our JavaScript example in a different way:

 

JavaScriptBuilder jsb = new JavaScriptBuilder("MakeAlert");

jsb.AddCodeLine("var functionCreateDate = '{0}';",

DateTime.Now.ToShortDateString());

jsb.AddAlertBox("'MakeAlert function was created at ' + functionCreatedDate");

Console.WriteLine(jsb.GenerateCode());

 

Output:

image

 

What we achieved?

  • Number of code lines reduced from original 9 lines to 3 lines.
  • Rendered code is readable.
  • Class can be reused in different parts of application.
  • Optimization done in JavaScriptBuilder in a future will reflect in all places where it is used.
  • Using JavaScriptBuilder commands (AddAlertBox or AddIfStatement, AddSwichStatement, etc) which correspond to some JavaScript operation could be useful for none JavaScript experts.

 

 

kick it on DotNetKicks.com Digg!

Technorati Tags: , ,

Share this post :
Posted: 13. listopadu 2007 10:57 by Armen Ayvazyan
Filed under: ,

Comments

New Comments to this post are disabled