AngleSharp by AngleSharp

<PackageReference Include="AngleSharp" Version="1.0.2-alpha-274" />

 MinifyMarkupFormatter

Represents the an HTML5 markup formatter with a normalization scheme.
using AngleSharp.Dom; using AngleSharp.Html.Dom; using AngleSharp.Io; using AngleSharp.Text; using System; using System.Collections.Generic; using System.Linq; using System.Runtime.CompilerServices; using System.Text; namespace AngleSharp.Html { [System.Runtime.CompilerServices.NullableContext(1)] [System.Runtime.CompilerServices.Nullable(0)] public class MinifyMarkupFormatter : HtmlMarkupFormatter { private IEnumerable<string> _preservedTags = new string[2] { TagNames.Pre, TagNames.Textarea }; public IEnumerable<string> PreservedTags { get { return _preservedTags ?? Array.Empty<string>(); } set { _preservedTags = value; } } public bool ShouldKeepStandardElements { get; set; } public bool ShouldKeepComments { get; set; } public bool ShouldKeepAttributeQuotes { get; set; } public bool ShouldKeepEmptyAttributes { get; set; } public bool ShouldKeepImpliedEndTag { get; set; } public override string Comment(IComment comment) { if (!ShouldKeepComments) return string.Empty; return base.Comment(comment); } public override string Text(ICharacterData text) { if (text.Parent is IHtmlHeadElement || text.Parent is IHtmlHtmlElement) return string.Empty; string text2 = base.Text(text); if (!PreservedTags.Contains(text.ParentElement?.LocalName)) { StringBuilder stringBuilder = StringBuilderPool.Obtain(); bool flag = false; bool flag2 = true; foreach (char c in text2) { if (c.IsWhiteSpaceCharacter()) { if (!flag) { stringBuilder.Append(' '); flag = true; } } else { stringBuilder.Append(c); flag2 = false; flag = false; } } if (!flag2 || ShouldOutput(text)) return stringBuilder.ToPool(); stringBuilder.ReturnToPool(); return string.Empty; } return text2; } public override string OpenTag(IElement element, bool selfClosing) { if (!CanBeRemoved(element)) { StringBuilder stringBuilder = StringBuilderPool.Obtain(); stringBuilder.Append('<'); if (!string.IsNullOrEmpty(element.Prefix)) stringBuilder.Append(element.Prefix).Append(':'); stringBuilder.Append(element.LocalName); foreach (IAttr attribute in element.Attributes) { if (ShouldKeep(element, attribute)) { if (!element.IsBooleanAttribute(attribute.Name)) { string value = Attribute(attribute); if (!string.IsNullOrEmpty(value)) stringBuilder.Append(' ').Append(value); } else stringBuilder.Append(' ').Append(attribute.Name); } } if (stringBuilder[stringBuilder.Length - 1] == '/') stringBuilder.Append(' '); stringBuilder.Append('>'); return stringBuilder.ToPool(); } return string.Empty; } public override string CloseTag(IElement element, bool selfClosing) { if (!CanBeRemoved(element) && !CanBeSkipped(element)) return base.CloseTag(element, selfClosing); return string.Empty; } protected override string Attribute(IAttr attr) { string value = attr.Value; if (ShouldKeepEmptyAttributes || !string.IsNullOrEmpty(value)) { StringBuilder stringBuilder = StringBuilderPool.Obtain(); HtmlMarkupFormatter.WriteAttributeName(attr, stringBuilder); if (value != null) { stringBuilder.Append('='); bool num = ShouldKeepAttributeQuotes || value.Any(MustBeQuotedAttributeValue); if (num) stringBuilder.Append('"'); HtmlMarkupFormatter.WriteAttributeValue(attr, stringBuilder); if (num) stringBuilder.Append('"'); } return stringBuilder.ToPool(); } return string.Empty; } private bool CanBeRemoved(IElement element) { if (!ShouldKeepStandardElements && element.Attributes.Length == 0) return element.LocalName.IsOneOf(TagNames.Html, TagNames.Head, TagNames.Body); return false; } private bool CanBeSkipped(IElement element) { if (!ShouldKeepImpliedEndTag && element.Flags.HasFlag(NodeFlags.ImpliedEnd)) { if (element.NextElementSibling != null) return element.NextElementSibling.LocalName == element.LocalName; return true; } return false; } private static bool ShouldOutput(ICharacterData text) { if (text.Parent is HtmlBodyElement) { if (text.NextSibling != null) return text.PreviousSibling != null; return false; } return true; } private static bool ShouldKeep(IElement element, IAttr attribute) { if (!IsStandardScript(element, attribute)) return !IsStandardStyle(element, attribute); return false; } private static bool IsStandardScript(IElement element, IAttr attr) { if (element is HtmlScriptElement && attr.Name.Is(AttributeNames.Type)) return attr.Value.Is(MimeTypeNames.DefaultJavaScript); return false; } private static bool IsStandardStyle(IElement element, IAttr attr) { if (element is HtmlStyleElement && attr.Name.Is(AttributeNames.Type)) return attr.Value.Is(MimeTypeNames.Css); return false; } private static bool MustBeQuotedAttributeValue(char c) { if (!c.IsWhiteSpaceCharacter() && c != '"' && c != '\'' && c != '=' && c != '>' && c != '<') return c == '`'; return true; } } }