XhtmlMarkupFormatter
Represents the standard XHTML markup formatter.
using AngleSharp.Dom;
using AngleSharp.Extensions;
using AngleSharp.Html;
using System.Text;
namespace AngleSharp.XHtml
{
public sealed class XhtmlMarkupFormatter : IMarkupFormatter
{
public static readonly IMarkupFormatter Instance = new XhtmlMarkupFormatter();
string IMarkupFormatter.CloseTag(IElement element, bool selfClosing)
{
string prefix = element.Prefix;
string localName = element.LocalName;
string str = (!string.IsNullOrEmpty(prefix)) ? (prefix + ":" + localName) : localName;
if (!selfClosing && element.HasChildNodes)
return "</" + str + ">";
return string.Empty;
}
string IMarkupFormatter.Comment(IComment comment)
{
return "<!--" + comment.Data + "-->";
}
string IMarkupFormatter.Doctype(IDocumentType doctype)
{
string publicIdentifier = doctype.PublicIdentifier;
string systemIdentifier = doctype.SystemIdentifier;
string str = (string.IsNullOrEmpty(publicIdentifier) && string.IsNullOrEmpty(systemIdentifier)) ? string.Empty : (" " + (string.IsNullOrEmpty(publicIdentifier) ? ("SYSTEM \"" + systemIdentifier + "\"") : ("PUBLIC \"" + publicIdentifier + "\" \"" + systemIdentifier + "\"")));
return "<!DOCTYPE " + doctype.Name + str + ">";
}
string IMarkupFormatter.OpenTag(IElement element, bool selfClosing)
{
string prefix = element.Prefix;
StringBuilder stringBuilder = Pool.NewStringBuilder();
stringBuilder.Append('<');
if (!string.IsNullOrEmpty(prefix))
stringBuilder.Append(prefix).Append(':');
stringBuilder.Append(element.LocalName);
foreach (IAttr attribute in element.Attributes) {
stringBuilder.Append(" ").Append(Instance.Attribute(attribute));
}
if (selfClosing || !element.HasChildNodes)
stringBuilder.Append(" /");
stringBuilder.Append('>');
return stringBuilder.ToPool();
}
string IMarkupFormatter.Processing(IProcessingInstruction processing)
{
string str = processing.Target + " " + processing.Data;
return "<?" + str + "?>";
}
string IMarkupFormatter.Text(string text)
{
StringBuilder stringBuilder = Pool.NewStringBuilder();
for (int i = 0; i < text.Length; i++) {
switch (text[i]) {
case '&':
stringBuilder.Append("&");
break;
case ' ':
stringBuilder.Append(" ");
break;
case '>':
stringBuilder.Append(">");
break;
case '<':
stringBuilder.Append("<");
break;
default:
stringBuilder.Append(text[i]);
break;
}
}
return stringBuilder.ToPool();
}
string IMarkupFormatter.Attribute(IAttr attribute)
{
string namespaceUri = attribute.NamespaceUri;
string localName = attribute.LocalName;
string value = attribute.Value;
StringBuilder stringBuilder = Pool.NewStringBuilder();
if (string.IsNullOrEmpty(namespaceUri))
stringBuilder.Append(localName);
else if (namespaceUri.Is(NamespaceNames.XmlUri)) {
stringBuilder.Append(NamespaceNames.XmlPrefix).Append(':').Append(localName);
} else if (namespaceUri.Is(NamespaceNames.XLinkUri)) {
stringBuilder.Append(NamespaceNames.XLinkPrefix).Append(':').Append(localName);
} else if (namespaceUri.Is(NamespaceNames.XmlNsUri)) {
stringBuilder.Append(XmlNamespaceLocalName(localName));
} else {
stringBuilder.Append(attribute.Name);
}
stringBuilder.Append('=').Append('"');
for (int i = 0; i < value.Length; i++) {
switch (value[i]) {
case '&':
stringBuilder.Append("&");
break;
case ' ':
stringBuilder.Append(" ");
break;
case '<':
stringBuilder.Append("<");
break;
case '"':
stringBuilder.Append(""");
break;
default:
stringBuilder.Append(value[i]);
break;
}
}
return stringBuilder.Append('"').ToPool();
}
private static string XmlNamespaceLocalName(string name)
{
if (!(name != NamespaceNames.XmlNsPrefix))
return name;
return NamespaceNames.XmlNsPrefix + ":";
}
}
}