diff --git a/ZenCoding.Test/Html/LoremPixel.cs b/ZenCoding.Test/Html/LoremPixel.cs
index 8f6c7c8..c0cc9ec 100644
--- a/ZenCoding.Test/Html/LoremPixel.cs
+++ b/ZenCoding.Test/Html/LoremPixel.cs
@@ -14,7 +14,7 @@ public void Initialize()
}
[TestMethod]
- public void LoremPixel1()
+ public void LoremPixelBasic()
{
string result = _parser.Parse("pix", ZenType.HTML);
string expected = "";
@@ -23,7 +23,7 @@ public void LoremPixel1()
}
[TestMethod]
- public void LoremPixel2()
+ public void LoremPixelGrayScale()
{
string result = _parser.Parse("pix-g", ZenType.HTML);
string expected = "";
@@ -32,7 +32,16 @@ public void LoremPixel2()
}
[TestMethod]
- public void LoremPixel3()
+ public void LoremPixelSingleDimension()
+ {
+ string result = _parser.Parse("pix-40", ZenType.HTML);
+ string expected = "";
+
+ Assert.AreEqual(expected, result);
+ }
+
+ [TestMethod]
+ public void LoremPixelCategory()
{
string result = _parser.Parse("pix-120x1879-sports-SomeRandomText", ZenType.HTML);
string expectedStart = "http://lorempixel.com/120/1879/sports/";
@@ -43,7 +52,7 @@ public void LoremPixel3()
}
[TestMethod]
- public void LoremPixel4()
+ public void LoremPixelText()
{
string result = _parser.Parse("pix-g-999x1920-animals-SomeRandomText", ZenType.HTML);
@@ -55,7 +64,7 @@ public void LoremPixel4()
}
[TestMethod]
- public void LoremPixel5()
+ public void LoremPixelOverflowedDimensions()
{
string result = _parser.Parse("pix-20000x3599-SomeRandomText", ZenType.HTML);
string expected = ""; // the allowed bound is 0-1920
@@ -64,13 +73,12 @@ public void LoremPixel5()
}
[TestMethod]
- public void LoremPixelWithAttributes()
+ public void LoremPixelWithAttributesWithMarkup()
{
string result = _parser.Parse("pix[alt=\"tag's here\" title=\"picture title\" data-foo=\"bar\"]", ZenType.HTML);
string expected = "";
Assert.AreEqual(expected, result);
}
-
}
}
diff --git a/ZenCoding.Test/Html/Placehold.cs b/ZenCoding.Test/Html/Placehold.cs
index b074795..8f15e38 100644
--- a/ZenCoding.Test/Html/Placehold.cs
+++ b/ZenCoding.Test/Html/Placehold.cs
@@ -14,7 +14,7 @@ public void Initialize()
}
[TestMethod]
- public void PlaceHold1()
+ public void PlaceHoldBasic()
{
string result = _parser.Parse("place", ZenType.HTML);
string expected = "";
@@ -23,7 +23,7 @@ public void PlaceHold1()
}
[TestMethod]
- public void PlaceHold2()
+ public void PlaceHoldFormat()
{
string result = _parser.Parse("place-30-png", ZenType.HTML);
string expected = "";
@@ -32,26 +32,26 @@ public void PlaceHold2()
}
[TestMethod]
- public void PlaceHold3()
+ public void PlaceHoldText()
{
- string result = _parser.Parse("place-120x1879-jpeg-t=SomeRandomText", ZenType.HTML);
- string expected = "http://placehold.it/120x1879/jpeg/&text=SomeRandomText";
+ string result = _parser.Parse("place-120x1879-jpeg-t=Some%20Random%20Text=", ZenType.HTML);
+ string expected = "http://placehold.it/120x1879/jpeg/&text=Some%20Random%20Text="; // Text is: "Some Random Text="
StringAssert.Contains(result, expected);
}
[TestMethod]
- public void PlaceHold4()
+ public void PlaceHoldColors()
{
- string result = _parser.Parse("place-999x1920-EEE-FFFFFF-t=Some%20Random%20Text", ZenType.HTML);
+ string result = _parser.Parse("place-999x1920-EEE-FFFFFF-t=Some%20Random%20Text!", ZenType.HTML);
- string expected = "http://placehold.it/999x1920/EEE/FFFFFF/&text=Some%20Random%20Text";
+ string expected = "http://placehold.it/999x1920/EEE/FFFFFF/&text=Some%20Random%20Text!";
StringAssert.Contains(result, expected);
}
[TestMethod]
- public void PlaceHold5()
+ public void PlaceHoldOverflowedDimensions()
{
string result = _parser.Parse("place-20000x3599-t=SomeRandomText", ZenType.HTML);
string expected = ""; // the allowed bound is 0-1920
diff --git a/ZenCoding/Commons/IParser.cs b/ZenCoding/Commons/IParser.cs
new file mode 100644
index 0000000..531ce16
--- /dev/null
+++ b/ZenCoding/Commons/IParser.cs
@@ -0,0 +1,7 @@
+namespace ZenCoding
+{
+ interface IZenParser
+ {
+ string Parse(string zenSyntax);
+ }
+}
\ No newline at end of file
diff --git a/ZenCoding/Css/CssParser.cs b/ZenCoding/Css/CssParser.cs
index c8f5dae..0d6dde8 100644
--- a/ZenCoding/Css/CssParser.cs
+++ b/ZenCoding/Css/CssParser.cs
@@ -2,7 +2,7 @@
namespace ZenCoding
{
- public class CssParser
+ public class CssParser : IZenParser
{
public string Parse(string zenSyntax)
{
diff --git a/ZenCoding/Helpers/Extensions.cs b/ZenCoding/Helpers/Extensions.cs
index 87a6b13..3a13dbb 100644
--- a/ZenCoding/Helpers/Extensions.cs
+++ b/ZenCoding/Helpers/Extensions.cs
@@ -1,5 +1,4 @@
-
-namespace ZenCoding
+namespace ZenCoding
{
public static class Extensions
{
@@ -10,4 +9,4 @@ public static bool IsHex(this char value)
(value >= 'A' && value <= 'F');
}
}
-}
+}
\ No newline at end of file
diff --git a/ZenCoding/Html/CustomHtmlAnchor.cs b/ZenCoding/Html/CustomHtmlAnchor.cs
index 3518a6a..257cb31 100644
--- a/ZenCoding/Html/CustomHtmlAnchor.cs
+++ b/ZenCoding/Html/CustomHtmlAnchor.cs
@@ -2,7 +2,7 @@
using System.Web.UI;
using System.Web.UI.HtmlControls;
-namespace ZenCoding.Html
+namespace ZenCoding
{
public class CustomHtmlAnchor : HtmlAnchor
{
diff --git a/ZenCoding/Html/CustomHtmlImage.cs b/ZenCoding/Html/CustomHtmlImage.cs
index 16e34ce..f4d92fe 100644
--- a/ZenCoding/Html/CustomHtmlImage.cs
+++ b/ZenCoding/Html/CustomHtmlImage.cs
@@ -2,7 +2,7 @@
using System.Web.UI;
using System.Web.UI.HtmlControls;
-namespace ZenCoding.Html
+namespace ZenCoding
{
public class CustomHtmlImage : HtmlImage
{
diff --git a/ZenCoding/Html/CustomHtmlTextArea.cs b/ZenCoding/Html/CustomHtmlTextArea.cs
index 41b2ec4..d752849 100644
--- a/ZenCoding/Html/CustomHtmlTextArea.cs
+++ b/ZenCoding/Html/CustomHtmlTextArea.cs
@@ -2,7 +2,7 @@
using System.Web.UI;
using System.Web.UI.HtmlControls;
-namespace ZenCoding.Html
+namespace ZenCoding
{
class CustomHtmlTextArea : HtmlTextArea
{
diff --git a/ZenCoding/Html/HtmlElementFactory.cs b/ZenCoding/Html/HtmlElementFactory.cs
index e2a1dc7..76973ae 100644
--- a/ZenCoding/Html/HtmlElementFactory.cs
+++ b/ZenCoding/Html/HtmlElementFactory.cs
@@ -5,7 +5,6 @@
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
-using ZenCoding.Html;
namespace ZenCoding
{
@@ -84,6 +83,16 @@ public static HtmlControl Create(string tagName, Type type, bool isClone)
if (tagName == null)
return null;
+ HtmlControl control = TryCreateSepcialControl(tagName, type, isClone);
+
+ if (control != null)
+ return control;
+
+ return new BlockHtmlControl(tagName);
+ }
+
+ private static HtmlControl TryCreateSepcialControl(string tagName, Type type, bool isClone)
+ {
if (tagName.StartsWith("lorem", System.StringComparison.Ordinal) ||
(type == typeof(LoremControl) && isClone))
{
@@ -98,6 +107,11 @@ public static HtmlControl Create(string tagName, Type type, bool isClone)
return new PlaceHold(tagName);
}
+ return TryCreateFromStateMachine(tagName);
+ }
+
+ private static HtmlControl TryCreateFromStateMachine(string tagName)
+ {
switch (tagName)
{
case "":
@@ -267,10 +281,10 @@ public static HtmlControl Create(string tagName, Type type, bool isClone)
return new HtmlGenericSelfClosing(tagName);
}
- return new BlockHtmlControl(tagName);
+ return null;
}
- public static Control CreateDoctypes(string part, ref List current)
+ public static Control CreateDoctypes(string part, ref IEnumerable current)
{
if (part == null)
return null;
@@ -306,7 +320,7 @@ public static Control CreateDoctypes(string part, ref List current)
using (HtmlControl body = HtmlElementFactory.Create("body"))
{
html.Controls.Add(body);
- current = new List() { body };
+ current = new Control[] { body };
}
return root;
}
diff --git a/ZenCoding/Html/HtmlParser.cs b/ZenCoding/Html/HtmlParser.cs
index ded1cf5..ed8af20 100644
--- a/ZenCoding/Html/HtmlParser.cs
+++ b/ZenCoding/Html/HtmlParser.cs
@@ -10,7 +10,7 @@
namespace ZenCoding
{
- public class HtmlParser
+ public class HtmlParser : IZenParser
{
private static char[] _attr = new[] { '#', '.', '[', '{' };
private static char[] _elem = new[] { '>', '+', '^' };
@@ -20,25 +20,27 @@ public class HtmlParser
public static bool IsValid(string zenSyntax)
{
- if (zenSyntax == null || zenSyntax.Length == 0 || zenSyntax.StartsWith("asp:", StringComparison.OrdinalIgnoreCase))
+ if (string.IsNullOrEmpty(zenSyntax) || zenSyntax.StartsWith("asp:", StringComparison.OrdinalIgnoreCase))
return false;
int indexSpace = zenSyntax.IndexOf(' ');
+
if (indexSpace > -1 && (indexSpace < zenSyntax.IndexOfAny(new[] { '[', '{', '"' }) || indexSpace > zenSyntax.LastIndexOfAny(new[] { ']', '}', '"' })))
return false;
- if (zenSyntax.Contains("{") || zenSyntax.Contains("}"))
- {
- if (zenSyntax.Count(c => c == '{') != zenSyntax.Count(c => c == '}'))
- return false;
- }
+ if ((zenSyntax.Contains("{") || zenSyntax.Contains("}")) && (zenSyntax.Count(c => c == '{') != zenSyntax.Count(c => c == '}')))
+ return false;
if (zenSyntax.Contains("<") || zenSyntax.Contains("|") || zenSyntax.Contains("@"))
return false;
- char last = zenSyntax.Last();
- if (!char.IsLetterOrDigit(last) && last != ']' && last != '}' && last != '+' && !char.IsWhiteSpace(last))
- return false;
+ if (!zenSyntax.StartsWith("place", StringComparison.CurrentCultureIgnoreCase))
+ {
+ char last = zenSyntax.Last();
+
+ if (!char.IsLetterOrDigit(last) && last != ']' && last != '}' && last != '+' && !char.IsWhiteSpace(last))
+ return false;
+ }
if (zenSyntax.Count(z => z == ']') != zenSyntax.Count(z => z == '['))
return false;
@@ -114,13 +116,13 @@ public static string ParseGroup(string zenSyntax)
if (!IsValidHtmlElements(parts))
return string.Empty;
- List current = new List() { root };
+ IEnumerable current = new Control[] { root };
HandleDoctypes(ref root, parts, ref current);
if (root == null) return null;
- BuildControlTree(CloneStack(parts), current[0], -1);
+ BuildControlTree(CloneStack(parts), current.First(), -1);
return RenderControl(root);
}
@@ -133,7 +135,7 @@ public static string ParseGroup(string zenSyntax)
}
}
- private static void HandleDoctypes(ref Control root, List parts, ref List current)
+ private static void HandleDoctypes(ref Control root, List parts, ref IEnumerable current)
{
if (parts[0] == "html:4t" || parts[0] == "html:4s" || parts[0] == "html:xt" || parts[0] == "html:xs" || parts[0] == "html:xxs" || parts[0] == "html:5")
{
@@ -154,7 +156,7 @@ private static void AdjustImplicitTagNames(List parts)
currentDefault = "span";
else if (i != 0 && parts[i - 1] == "table" && parts[i][0] == '>')
currentDefault = "tr";
- else if (i != 0 && (parts[i - 1] == "tr" || parts[i - 1].StartsWith(">tr")) && parts[i][0] == '>')
+ else if (i != 0 && (parts[i - 1] == "tr" || parts[i - 1].StartsWith(">tr", StringComparison.CurrentCultureIgnoreCase)) && parts[i][0] == '>')
currentDefault = "td";
else if ((parts[i][0] == '>' && currentDefault == "td") || (currentDefault != "div" && parts[i][0] == '^'))
currentDefault = "div";
@@ -415,7 +417,7 @@ private static int GetCountAndName(string part, out string cleanPart, char[] sym
int index = part.IndexOf('*');
int count = 1;
- if (index > -1 && part.Length > index && !char.IsNumber(part[index + 1]))
+ if (index > -1 && part.Length > index + 1 && !char.IsNumber(part[index + 1]))
index = -1;
if (index > -1 && int.TryParse(part.Substring(index + 1), out count))
diff --git a/ZenCoding/Html/LoremPixel.cs b/ZenCoding/Html/LoremPixel.cs
index b562f98..1e301ae 100644
--- a/ZenCoding/Html/LoremPixel.cs
+++ b/ZenCoding/Html/LoremPixel.cs
@@ -1,7 +1,6 @@
using System;
using System.Linq;
using System.Text;
-using ZenCoding.Html;
namespace ZenCoding
{
@@ -26,50 +25,47 @@ public override void Generate(string pixText)
parts = pixText == null ? new string[] { } : pixText.Split('-');
- try
+ if (parts.Length > 1)
{
- if (parts.Length > 1)
+ if (parts[1].Equals("g"))
{
- if (parts[1].Equals("g"))
- {
- this.IsGray = true;
+ this.IsGray = true;
+
+ if (parts.Length > 2)
dimensions = parts[2];
- }
- else
- {
- dimensions = parts[1];
- }
+ }
+ else
+ {
+ dimensions = parts[1];
+ }
- SetDimensions(dimensions);
+ SetDimensions(dimensions);
- if (parts.Length > 2)
+ if (parts.Length > 2)
+ {
+ if (this.IsGray)
{
- if (this.IsGray)
+ category = parts[3];
+ if (parts.Length > 4)
{
- category = parts[3];
- if (parts.Length > 4)
- {
- text = parts[4];
- }
+ text = parts[4];
}
- else
- {
- category = parts[2];
- if (parts.Length > 3)
- {
- text = parts[3];
- }
- }
- if (_categories.Contains(category))
+ }
+ else
+ {
+ category = parts[2];
+ if (parts.Length > 3)
{
- this.Category = category;
- this.Text = text;
+ text = parts[3];
}
}
+ if (_categories.Contains(category))
+ {
+ this.Category = category;
+ this.Text = text;
+ }
}
}
- catch
- { }
this.AssetWidth = this.AssetWidth % 1921;
this.AssetHeight = this.AssetHeight % 1921;
diff --git a/ZenCoding/Html/PixelBase.cs b/ZenCoding/Html/PixelBase.cs
index b9763cc..7409264 100644
--- a/ZenCoding/Html/PixelBase.cs
+++ b/ZenCoding/Html/PixelBase.cs
@@ -2,7 +2,7 @@
using System.Globalization;
using System.Text.RegularExpressions;
-namespace ZenCoding.Html
+namespace ZenCoding
{
public abstract class PixelBase : CustomHtmlImage
{
@@ -11,7 +11,7 @@ public abstract class PixelBase : CustomHtmlImage
public int AssetWidth { get; set; }
public int AssetHeight { get; set; }
- public PixelBase()
+ protected PixelBase()
{
Initialize();
}
@@ -22,6 +22,9 @@ public PixelBase()
protected void SetDimensions(string slug)
{
+ if (string.IsNullOrEmpty(slug))
+ return;
+
var dimensions = _numberExtractor.Split(slug);
if (ValidateIntegers(dimensions))
@@ -43,7 +46,7 @@ private static bool ValidateIntegers(params string[] values)
{
Convert.ToInt32(value, CultureInfo.CurrentCulture);
}
- catch
+ catch (AggregateException)
{
return false;
}
diff --git a/ZenCoding/Html/Placehold.cs b/ZenCoding/Html/Placehold.cs
index 0de40f1..a15e22b 100644
--- a/ZenCoding/Html/Placehold.cs
+++ b/ZenCoding/Html/Placehold.cs
@@ -1,7 +1,6 @@
using System;
using System.Linq;
using System.Text;
-using ZenCoding.Html;
namespace ZenCoding
{
@@ -34,33 +33,30 @@ public override void Generate(string pixText)
string dimensions = "";
string[] parts;
- parts = pixText == null ? new string[] { } : pixText.Split('-');
+ parts = pixText == null ? new string[] { } : pixText.Trim('-').Split('-');
- try
+ if (parts.Length > 1)
{
- if (parts.Length > 1)
- {
- dimensions = parts[1];
-
- SetDimensions(dimensions);
-
- if (parts.Length > 2)
- {
- if (_formats.Contains(parts[2]))
- this.Format = parts[2];
- else
- SetTextAndColors(parts[2]);
+ dimensions = parts[1];
- if (parts.Length > 3)
- SetTextAndColors(parts[3]);
+ SetDimensions(dimensions);
- if (parts.Length > 4)
- SetTextAndColors(parts[4]);
- }
+ if (parts.Length > 2)
+ {
+ if (_formats.Contains(parts[2]))
+ this.Format = parts[2];
+ else
+ SetTextAndColors(parts[2]);
+
+ if (parts.Length > 3)
+ SetTextAndColors(parts[3]);
+ if (parts.Length > 4)
+ SetTextAndColors(parts[4]);
}
}
- catch
- { }
+
+ if (pixText.Last() == '-')
+ this.Text += '-';
this.AssetWidth = this.AssetWidth % 1921;
this.AssetHeight = this.AssetHeight % 1921;
@@ -71,7 +67,7 @@ public override void Generate(string pixText)
private void SetTextAndColors(string slug)
{
if (string.IsNullOrEmpty(this.Text) && slug.Contains("="))
- this.Text = slug.Split('=')[1];
+ this.Text = string.Join("=", slug.Split('=').Skip(1));
else if ((slug.Length == 3 || slug.Length == 6) && slug.All(c => c.IsHex()))
if (string.IsNullOrEmpty(this.Background))
this.Background = slug;
diff --git a/ZenCoding/Parser.cs b/ZenCoding/Parser.cs
index 108ba09..b77efbc 100644
--- a/ZenCoding/Parser.cs
+++ b/ZenCoding/Parser.cs
@@ -1,8 +1,9 @@
-
-namespace ZenCoding
+namespace ZenCoding
{
public class Parser
{
+ IZenParser _parser;
+
public string Parse(string zenSyntax, ZenType type)
{
if (zenSyntax == null)
@@ -11,12 +12,11 @@ public string Parse(string zenSyntax, ZenType type)
switch (type)
{
case ZenType.HTML:
- HtmlParser htmlParser = new HtmlParser();
- return htmlParser.Parse(zenSyntax.Trim());
-
+ this._parser = new HtmlParser();
+ return this._parser.Parse(zenSyntax.Trim());
case ZenType.CSS:
- CssParser cssParser = new CssParser();
- return cssParser.Parse(zenSyntax.Trim());
+ this._parser = new CssParser();
+ return this._parser.Parse(zenSyntax.Trim());
}
return null;
diff --git a/ZenCoding/ZenCoding.csproj b/ZenCoding/ZenCoding.csproj
index 524ed52..12c8225 100644
--- a/ZenCoding/ZenCoding.csproj
+++ b/ZenCoding/ZenCoding.csproj
@@ -54,6 +54,7 @@
+