DotNet 4.8.1 build of DotNetBar
This commit is contained in:
256
PROMS/DotNetBar Source Code/TextMarkup/MarkupParser.cs
Normal file
256
PROMS/DotNetBar Source Code/TextMarkup/MarkupParser.cs
Normal file
@@ -0,0 +1,256 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
using System.Collections;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
#if AdvTree
|
||||
namespace DevComponents.Tree.TextMarkup
|
||||
#elif DOTNETBAR
|
||||
namespace DevComponents.DotNetBar.TextMarkup
|
||||
#elif SUPERGRID
|
||||
namespace DevComponents.SuperGrid.TextMarkup
|
||||
#elif LAYOUT
|
||||
namespace DevComponents.DotNetBar.Layout.TextMarkup
|
||||
#endif
|
||||
{
|
||||
internal class MarkupParser
|
||||
{
|
||||
#region Private Variables
|
||||
private static string TextElementName = "text";
|
||||
private static string BodyTag = "body";
|
||||
#endregion
|
||||
|
||||
#region Internal Implementation
|
||||
public static BodyElement Parse(string text)
|
||||
{
|
||||
StringBuilder plainText = new StringBuilder(text.Length);
|
||||
BodyElement root = new BodyElement();
|
||||
root.HasExpandElement = false;
|
||||
MarkupElement currentParent = root;
|
||||
Stack openTags = new Stack();
|
||||
openTags.Push(root);
|
||||
// Input text is not wrapped into the container tag so we wrap it here
|
||||
text = text.Replace(" ", "{ent_nbsp}");
|
||||
text = text.Replace("&zwsp;", "{ent_zwsp}");
|
||||
text = text.Replace("<", "{ent_lt}");
|
||||
text = text.Replace(">", "{ent_gt}");
|
||||
text = text.Replace("&", "{ent_amp}");
|
||||
text = text.Replace("|", "{ent_l}");
|
||||
text = text.Replace("&", "|");
|
||||
text = text.Replace("{ent_nbsp}", " ");
|
||||
text = text.Replace("{ent_zwsp}", "&zwsp;");
|
||||
text = text.Replace("{ent_lt}", "<");
|
||||
text = text.Replace("{ent_gt}", ">");
|
||||
StringReader sr = new StringReader("<"+BodyTag+">" + text + "</"+BodyTag+">");
|
||||
#if !DEBUG
|
||||
try
|
||||
#endif
|
||||
{
|
||||
XmlTextReader reader = new XmlTextReader(sr);
|
||||
//reader.EntityHandling = EntityHandling.ExpandCharEntities;
|
||||
while (reader.Read())
|
||||
{
|
||||
if (reader.NodeType == XmlNodeType.Element)
|
||||
{
|
||||
if (reader.Name == BodyTag)
|
||||
continue;
|
||||
MarkupElement el = CreateMarkupElement(reader.Name);
|
||||
if (el == null)
|
||||
{
|
||||
reader.Skip();
|
||||
continue;
|
||||
}
|
||||
else if (el is ExpandElement)
|
||||
root.HasExpandElement = true;
|
||||
|
||||
if (el is IActiveMarkupElement)
|
||||
root.ActiveElements.Add(el);
|
||||
|
||||
// Parse any attributes here
|
||||
if (reader.AttributeCount > 0)
|
||||
{
|
||||
el.ReadAttributes(reader);
|
||||
reader.MoveToElement();
|
||||
}
|
||||
|
||||
currentParent.Elements.Add(el);
|
||||
|
||||
if (el is ContainerElement)
|
||||
currentParent = el;
|
||||
|
||||
if (!reader.IsEmptyElement)
|
||||
openTags.Push(el);
|
||||
}
|
||||
else if (reader.NodeType == XmlNodeType.Text)
|
||||
{
|
||||
if (reader.Value.Length == 1)
|
||||
{
|
||||
TextElement el = CreateMarkupElement(TextElementName) as TextElement;
|
||||
if (reader.Value == " ")
|
||||
{
|
||||
el.TrailingSpace = true;
|
||||
plainText.Append(' ');
|
||||
}
|
||||
else
|
||||
{
|
||||
el.Text = reader.Value;
|
||||
el.Text = el.Text.Replace("|", "&");
|
||||
el.Text = el.Text.Replace("{ent_l}", "|");
|
||||
el.Text = el.Text.Replace("{ent_amp}", "&&");
|
||||
plainText.Append(el.Text+" ");
|
||||
}
|
||||
currentParent.Elements.Add(el);
|
||||
}
|
||||
else
|
||||
{
|
||||
string s = reader.Value;
|
||||
if (s.StartsWith("\r\n"))
|
||||
s = s.TrimStart(new char[] { '\r', '\n' });
|
||||
s = s.Replace("\r\n", " ");
|
||||
string[] words = s.Split(' ');
|
||||
bool space = false;
|
||||
if (currentParent.Elements.Count > 0 && currentParent.Elements[currentParent.Elements.Count - 1] is NewLine)
|
||||
space = true;
|
||||
for (int i = 0; i < words.Length; i++)
|
||||
{
|
||||
if (words[i].Length == 0)
|
||||
{
|
||||
if (space)
|
||||
continue;
|
||||
space = true;
|
||||
}
|
||||
else
|
||||
space = false;
|
||||
|
||||
TextElement el = CreateMarkupElement(TextElementName) as TextElement;
|
||||
el.Text = words[i].Replace("|","&");
|
||||
el.Text = el.Text.Replace("{ent_l}", "|");
|
||||
el.Text = el.Text.Replace("{ent_amp}", "&&");
|
||||
plainText.Append(el.Text + " ");
|
||||
if (i < words.Length - 1)
|
||||
{
|
||||
el.TrailingSpace = true;
|
||||
space = true;
|
||||
}
|
||||
|
||||
currentParent.Elements.Add(el);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (reader.NodeType == XmlNodeType.Whitespace)
|
||||
{
|
||||
if (reader.Value.IndexOf(' ') >= 0)
|
||||
{
|
||||
TextElement el = CreateMarkupElement(TextElementName) as TextElement;
|
||||
el.TrailingSpace = true;
|
||||
currentParent.Elements.Add(el);
|
||||
}
|
||||
}
|
||||
else if (reader.NodeType == XmlNodeType.EntityReference)
|
||||
{
|
||||
TextElement el = CreateMarkupElement(TextElementName) as TextElement;
|
||||
if (reader.Name == "nbsp")
|
||||
{
|
||||
el.TrailingSpace = true;
|
||||
}
|
||||
else if (reader.Name == "zwsp")
|
||||
{
|
||||
el.TrailingSpace = false;
|
||||
}
|
||||
else
|
||||
el.Text = reader.Name;
|
||||
el.EnablePrefixHandling = false;
|
||||
currentParent.Elements.Add(el);
|
||||
}
|
||||
else if (reader.NodeType == XmlNodeType.EndElement)
|
||||
{
|
||||
MarkupElement el = openTags.Pop() as MarkupElement;
|
||||
if (el != currentParent)
|
||||
{
|
||||
currentParent.Elements.Add(new EndMarkupElement(el));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (currentParent != root)
|
||||
currentParent = currentParent.Parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#if !DEBUG
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
#endif
|
||||
root.PlainText = plainText.ToString();
|
||||
return root;
|
||||
}
|
||||
|
||||
public static MarkupElement CreateMarkupElement(string elementName)
|
||||
{
|
||||
if (elementName == "b" || elementName == "strong")
|
||||
return new Strong();
|
||||
else if (elementName == "i" || elementName == "em")
|
||||
return new Italic();
|
||||
else if (elementName == "u")
|
||||
return new Underline();
|
||||
else if (elementName == "br")
|
||||
return new NewLine();
|
||||
else if (elementName == "expand")
|
||||
return new ExpandElement();
|
||||
else if (elementName == "a")
|
||||
return new HyperLink();
|
||||
else if (elementName == "p")
|
||||
return new Paragraph();
|
||||
else if (elementName == "div")
|
||||
return new Div();
|
||||
else if (elementName == "span")
|
||||
return new Span();
|
||||
else if (elementName == "img")
|
||||
return new ImageElement();
|
||||
else if (elementName == "h1")
|
||||
return new Heading();
|
||||
else if (elementName == "h2")
|
||||
return new Heading(2);
|
||||
else if (elementName == "h3")
|
||||
return new Heading(3);
|
||||
else if (elementName == "h4")
|
||||
return new Heading(4);
|
||||
else if (elementName == "h5")
|
||||
return new Heading(5);
|
||||
else if (elementName == "h6")
|
||||
return new Heading(6);
|
||||
else if (elementName == "font")
|
||||
return new FontElement();
|
||||
else if (elementName == "s" || elementName == "strike")
|
||||
return new Strike();
|
||||
else if (elementName == TextElementName)
|
||||
return new TextElement();
|
||||
else if (elementName == "symbol")
|
||||
return new SymbolElement();
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests whether input text could be markup text.
|
||||
/// </summary>
|
||||
/// <param name="text">Text to test.</param>
|
||||
/// <returns>true if text could be markup, otherwise false</returns>
|
||||
public static bool IsMarkup(ref string text)
|
||||
{
|
||||
if (text == null || text.IndexOf("</") < 0 && text.IndexOf("/>") < 0)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
internal static string RemoveExpand(string text)
|
||||
{
|
||||
return Regex.Replace(text, "<expand.*?>", "", RegexOptions.IgnoreCase);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user