public override State PushChar(char c, IParseContext context, ref string rollback) { INamedXObject namedObject = context.Nodes.Peek() as INamedXObject; if (namedObject == null || namedObject.Name.Prefix != null) { throw new InvalidOperationException("Invalid state"); } Debug.Assert(context.CurrentStateLength > 1 || char.IsLetter(c) || c == '_', "First character pushed to a XmlTagNameState must be a letter."); Debug.Assert(context.CurrentStateLength > 1 || context.KeywordBuilder.Length == 0, "Keyword builder must be empty when state begins."); if (XmlChar.IsWhitespace(c) || c == '<' || c == '>' || c == '/' || c == '=') { rollback = string.Empty; if (context.KeywordBuilder.Length == 0) { context.LogError("Zero-length name."); } else { string s = context.KeywordBuilder.ToString(); int i = s.IndexOf(':'); if (i < 0) { namedObject.Name = new XName(s); } else { namedObject.Name = new XName(s.Substring(0, i), s.Substring(i + 1)); } } return(Parent); } if (c == ':') { if (context.KeywordBuilder.ToString().IndexOf(':') > 0) { context.LogError("Unexpected ':' in name."); } context.KeywordBuilder.Append(c); return(null); } if (XmlChar.IsNameChar(c)) { context.KeywordBuilder.Append(c); return(null); } rollback = string.Empty; context.LogError("Unexpected character '" + c + "' in name"); return(Parent); }
//TODO: implement real implicit closing logic from HTML5 spec // see http://www.w3.org/html/wg/drafts/html/master/syntax.html#syntax-tag-omission public static bool IsImplicitlyClosedBy(this XElement parent, INamedXObject current) { //inline and paragraph tags are implicitly closed by block tags and paragraph tags if (ElementTypes.IsInline(parent.Name.Name) || ElementTypes.IsParagraph(parent.Name.Name)) { return(ElementTypes.IsBlock(current.Name.Name) || ElementTypes.IsParagraph(current.Name.Name)); } return(false); }
//TODO: implement real implicit closing logic from HTML5 spec // see http://www.w3.org/html/wg/drafts/html/master/syntax.html#syntax-tag-omission public static bool IsImplicitlyClosedBy(this XElement parent, INamedXObject current) { //inline and paragraph tags are implicitly closed by block tags and paragraph tags switch (parent.Name.Name) { case "p": return(ElementTypes.IsParaOptionalClosing(current.Name.Name)); case "td": return(current.Name.Name == "td" || current.Name.Name == "th"); case "th": return(current.Name.Name == "td" || current.Name.Name == "th"); case "dt": return(current.Name.Name == "dt" || current.Name.Name == "dd"); case "dd": return(current.Name.Name == "dt" || current.Name.Name == "dd"); case "thead": return(current.Name.Name == "tbody" || current.Name.Name == "tfoot"); case "tbody": return(current.Name.Name == "tbody" || current.Name.Name == "tfoot"); case "option": return(current.Name.Name == "option" || current.Name.Name == "optgroup"); case "tr": return(current.Name.Name == "tr"); case "li": return(current.Name.Name == "li"); case "tfoot": return(current.Name.Name == "tbody"); case "optgroup": return(current.Name.Name == "optgroup"); default: return(false); } }
void CheckDeprecated(ValueInfo info, INamedXObject namedObj) { if (info.IsDeprecated) { if (string.IsNullOrEmpty(info.DeprecationMessage)) { Document.Diagnostics.Add( CoreDiagnostics.Deprecated, namedObj.NameSpan, DescriptionFormatter.GetKindNoun(info), info.Name); } else { Document.Diagnostics.Add( CoreDiagnostics.DeprecatedWithMessage, namedObj.NameSpan, DescriptionFormatter.GetKindNoun(info), info.Name, info.DeprecationMessage ); } } }
public override State PushChar(char c, IParseContext context, ref string rollback) { INamedXObject namedObject = context.Nodes.Peek() as INamedXObject; if (namedObject == null || namedObject.Name.Prefix != null) { throw new InvalidOperationException("Invalid state"); } Debug.Assert(context.CurrentStateLength > 1 || char.IsLetter(c) || c == '_', "First character pushed to a XmlTagNameState must be a letter."); Debug.Assert(context.CurrentStateLength > 1 || context.KeywordBuilder.Length == 0, "Keyword builder must be empty when state begins."); if (c == ':') { if (namedObject.Name.Name != null || context.KeywordBuilder.Length == 0) { context.LogError("Unexpected ':' in name."); return(Parent); } namedObject.Name = new XName(context.KeywordBuilder.ToString()); context.KeywordBuilder.Length = 0; return(null); } if (XmlChar.IsWhitespace(c) || c == '<' || c == '>' || c == '/' || c == '=') { rollback = string.Empty; if (context.KeywordBuilder.Length == 0) { context.LogError("Zero-length name."); } else if (namedObject.Name.Name != null) { //add prefix (and move current "name" to prefix) namedObject.Name = new XName(namedObject.Name.Name, context.KeywordBuilder.ToString()); } else { namedObject.Name = new XName(context.KeywordBuilder.ToString()); } //note: parent's MalformedTagState logs an error, so skip this //if (c == '<') //context.LogError ("Unexpected '<' in name."); return(Parent); } if (c == ':') { if (namedObject.Name.Name != null || context.KeywordBuilder.Length == 0) { context.LogError("Unexpected ':' in name."); return(Parent); } namedObject.Name = new XName(context.KeywordBuilder.ToString()); context.KeywordBuilder.Length = 0; return(null); } if (XmlChar.IsNameChar(c)) { context.KeywordBuilder.Append(c); return(null); } rollback = string.Empty; context.LogError("Unexpected character '" + c + "' in name"); return(Parent); }
public static bool ValidAndNoPrefix(this INamedXObject element) { return(element != null && element.Name.IsValid && !element.Name.HasPrefix); }
//TODO: implement real implicit closing logic from HTML5 spec // see http://www.w3.org/html/wg/drafts/html/master/syntax.html#syntax-tag-omission public static bool IsImplicitlyClosedBy (this XElement parent, INamedXObject current) { //inline and paragraph tags are implicitly closed by block tags and paragraph tags switch (parent.Name.Name) { case "p": return ElementTypes.IsParaOptionalClosing (current.Name.Name); case "td": return current.Name.Name == "td" || current.Name.Name == "th"; case "th": return current.Name.Name == "td" || current.Name.Name == "th"; case "dt": return current.Name.Name == "dt" || current.Name.Name == "dd"; case "dd": return current.Name.Name == "dt" || current.Name.Name == "dd"; case "thead": return current.Name.Name == "tbody" || current.Name.Name == "tfoot"; case "tbody": return current.Name.Name == "tbody" || current.Name.Name == "tfoot"; case "option": return current.Name.Name == "option" || current.Name.Name == "optgroup"; case "tr": return current.Name.Name == "tr"; case "li": return current.Name.Name == "li"; case "tfoot": return current.Name.Name == "tbody"; case "optgroup": return current.Name.Name == "optgroup"; default : return false; } }
public static bool NameEquals(this INamedXObject obj, string name, bool ignoreCase) { var comparison = ignoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal; return(!obj.Name.HasPrefix && string.Equals(obj.Name.Name, name, comparison)); }
//TODO: implement real implicit closing logic from HTML5 spec // see http://www.w3.org/html/wg/drafts/html/master/syntax.html#syntax-tag-omission public static bool IsImplicitlyClosedBy (this XElement parent, INamedXObject current) { //inline and paragraph tags are implicitly closed by block tags and paragraph tags if (ElementTypes.IsInline (parent.Name.Name) || ElementTypes.IsParagraph (parent.Name.Name)) return ElementTypes.IsBlock (current.Name.Name) || ElementTypes.IsParagraph (current.Name.Name); return false; }