#develop (short for SharpDevelop) is a free IDE for .NET programming languages.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

203 lines
4.3 KiB

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
namespace ICSharpCode.XamlDesigner
{
public static class XamlFormatter
{
public static char IndentChar = ' ';
public static int Indenation = 2;
public static int LengthBeforeNewLine = 60;
static StringBuilder sb;
static int currentColumn;
static int nextColumn;
public static string Format(string xaml)
{
sb = new StringBuilder();
currentColumn = 0;
nextColumn = 0;
try {
var doc = XDocument.Parse(xaml);
WalkContainer(doc);
return sb.ToString();
}
catch {
return xaml;
}
}
static void WalkContainer(XContainer node)
{
foreach (var c in node.Nodes()) {
if (c is XElement) {
WalkElement(c as XElement);
} else {
NewLine();
Append(c.ToString().Trim());
}
}
}
static void WalkElement(XElement e)
{
NewLine();
string prefix1 = e.GetPrefixOfNamespace(e.Name.Namespace);
string name1 = prefix1 == null ? e.Name.LocalName : prefix1 + ":" + e.Name.LocalName;
Append("<" + name1);
List<AttributeString> list = new List<AttributeString>();
int length = name1.Length;
foreach (var a in e.Attributes()) {
string prefix2 = e.GetPrefixOfNamespace(a.Name.Namespace);
var g = new AttributeString() { Name = a.Name, Prefix = prefix2, Value = a.Value };
list.Add(g);
length += g.FinalString.Length;
}
list.Sort(AttributeComparrer.Instance);
if (length > LengthBeforeNewLine) {
nextColumn = currentColumn + 1;
for (int i = 0; i < list.Count; i++) {
if (i > 0) {
NewLine();
}
else {
Append(" ");
}
Append(list[i].FinalString);
}
nextColumn -= name1.Length + 2;
}
else {
foreach (var a in list) {
Append(" " + a.FinalString);
}
}
if (e.Nodes().Count() > 0) {
Append(">");
nextColumn += Indenation;
WalkContainer(e);
nextColumn -= Indenation;
NewLine();
Append("</" + name1 + ">");
}
else {
Append(" />");
}
}
static void NewLine()
{
if (sb.Length > 0) {
sb.AppendLine();
sb.Append(new string(' ', nextColumn));
currentColumn = nextColumn;
}
}
static void Append(string s)
{
sb.Append(s);
currentColumn += s.Length;
}
enum AttributeLayout
{
X,
XmlnsMicrosoft,
Xmlns,
XmlnsWithClr,
SpecialOrder,
ByName,
Attached,
WithPrefix
}
class AttributeString
{
public XName Name;
public string Prefix;
public string Value;
public string LocalName {
get { return Name.LocalName; }
}
public string FinalName {
get {
return Prefix == null ? Name.LocalName : Prefix + ":" + Name.LocalName;
}
}
public string FinalString {
get {
return FinalName + "=\"" + Value + "\"";
}
}
public AttributeLayout GetAttributeLayout()
{
if (Prefix == "xmlns" || LocalName == "xmlns") {
if (Value.StartsWith("http://schemas.microsoft.com")) return AttributeLayout.XmlnsMicrosoft;
if (Value.StartsWith("clr")) return AttributeLayout.XmlnsWithClr;
return AttributeLayout.Xmlns;
}
if (Prefix == "x") return AttributeLayout.X;
if (Prefix != null) return AttributeLayout.WithPrefix;
if (LocalName.Contains(".")) return AttributeLayout.Attached;
if (AttributeComparrer.SpecialOrder.Contains(LocalName)) return AttributeLayout.SpecialOrder;
return AttributeLayout.ByName;
}
}
class AttributeComparrer : IComparer<AttributeString>
{
public static AttributeComparrer Instance = new AttributeComparrer();
public int Compare(AttributeString a1, AttributeString a2)
{
var y1 = a1.GetAttributeLayout();
var y2 = a2.GetAttributeLayout();
if (y1 == y2) {
if (y1 == AttributeLayout.SpecialOrder) {
return
Array.IndexOf(SpecialOrder, a1.LocalName).CompareTo(
Array.IndexOf(SpecialOrder, a2.LocalName));
}
return a1.FinalName.CompareTo(a2.FinalName);
}
return y1.CompareTo(y2);
}
public static string[] SpecialOrder = new string[] {
"Name",
"Content",
"Command",
"Executed",
"CanExecute",
"Width",
"Height",
"Margin",
"HorizontalAlignment",
"VerticalAlignment",
"HorizontalContentAlignment",
"VerticalContentAlignment",
"StartPoint",
"EndPoint",
"Offset",
"Color"
};
}
}
}