patterncsharpMinor
Css builder and parser
Viewed 0 times
andparsercssbuilder
Problem
As part of a larger project I've created recently a simple
```
public class CssParser
{
public static CssBuilder ParseCss(string css)
{
var builder = new CssBuilde
CssBuilder and CssParser. It's composed of three classes and can parse/build inline and block CSS. Its main purpose was to render CSS for inline styles for email formatting (which is the rest of the project (maybe another time)). I also tried to design a fluent API here.CssBuilderpublic class CssBuilder
{
public string Selector { get; set; }
public IList Declarations { get; internal set; } = new List();
public static CssBuilder Create()
{
return new CssBuilder();
}
public static CssBuilder CreateFor(string selectror)
{
return new CssBuilder { Selector = selectror };
}
public static CssBuilder CreateFrom(string css)
{
return CssParser.ParseCss(css);
}
public CssBuilder Declare(string property, string value)
{
Declarations.Add(new CssDeclaration
{
Property = property,
Value = value.TrimEnd(';')
});
return this;
}
public string BuildCss()
{
return string.IsNullOrEmpty(Selector) ? BuildInlineCss(this) : BuildBlockCss(this);
}
internal string BuildInlineCss(CssBuilder builder)
{
return builder.Declarations.Aggregate(string.Empty, (current, next) => string.IsNullOrEmpty(current) ? next.ToString() : $"{current} {next}");
}
internal string BuildBlockCss(CssBuilder builder)
{
const int indentWidth = 3;
var block = new StringBuilder();
block.Append(builder.Selector);
block.AppendLine(" {");
foreach (var declaration in builder.Declarations)
{
block.Append(string.Empty.PadLeft(indentWidth));
block.AppendLine(declaration.ToString());
}
block.Append("}");
return block.ToString();
}
}CssParser```
public class CssParser
{
public static CssBuilder ParseCss(string css)
{
var builder = new CssBuilde
Solution
CssBuilder
Instead of having a
Starting the "Data section" with
The
Using the overloaded constructor of the
you should also think about wether it would be good to have an optional parameter defining the
internal string BuildBlockCss(CssBuilder builder)
{
const int indentWidth = 3;
var block = new StringBuilder();
block.Append(builder.Selector);
block.AppendLine(" {");
foreach (var declaration in builder.Declarations)
{
block.Append(string.Empty.PadLeft(indentWidth));
block.AppendLine(declaration.ToString());
}
block.Append("}");
return block.ToString();
}Instead of having a
const int indentWidth I would prefer to have either a const string of just string. In this way you wouldn't need to call string.Empty.PadLeft(indentWidth) for each iteration of the loop. Starting the "Data section" with
block.AppendLine(" {"); and ending it with block.Append("}"); (missing leading space) will look odd in the css block. The
StringBuilder's methods are implemented fluently so you could use the returned instance of the StringBuilder.Using the overloaded constructor of the
StringBuilder which takes a capacity as an argument is better if you know that the content of the StringBuilder will exceed 16 characters, because if this initial capacity is reached the current capacity is doubled.internal string BuildBlockCss(CssBuilder builder)
{
const int indentWidth = 3;
string indentValue = string.Empty.PadLeft(indentWidth);
var block = new StringBuilder(1024);
block.Append(builder.Selector)
.AppendLine(" {")
foreach (var declaration in builder.Declarations)
{
block.Append(indentValue)
.AppendLine(declaration.ToString());
}
block.Append("}");
return block.ToString();
}you should also think about wether it would be good to have an optional parameter defining the
indentWidth instead of hardcoding it.Code Snippets
internal string BuildBlockCss(CssBuilder builder)
{
const int indentWidth = 3;
var block = new StringBuilder();
block.Append(builder.Selector);
block.AppendLine(" {");
foreach (var declaration in builder.Declarations)
{
block.Append(string.Empty.PadLeft(indentWidth));
block.AppendLine(declaration.ToString());
}
block.Append("}");
return block.ToString();
}internal string BuildBlockCss(CssBuilder builder)
{
const int indentWidth = 3;
string indentValue = string.Empty.PadLeft(indentWidth);
var block = new StringBuilder(1024);
block.Append(builder.Selector)
.AppendLine(" {")
foreach (var declaration in builder.Declarations)
{
block.Append(indentValue)
.AppendLine(declaration.ToString());
}
block.Append("}");
return block.ToString();
}Context
StackExchange Code Review Q#109383, answer score: 2
Revisions (0)
No revisions yet.