public void DocTypeCapture() { TestParser parser = new TestParser(CreateRootState(), true); parser.Parse(@" <!DOCTYPE html PUBLIC ""-//W3C//DTD XHTML 1.0 Strict//EN"" ""DTD/xhtml1-strict.dtd"" [ <!-- foo --> <!bar #baz> ]> <doc><foo/></doc>"); parser.AssertEmpty(); XDocument doc = (XDocument)parser.Nodes.Peek(); Assert.IsTrue(doc.FirstChild is XDocType); XDocType dt = (XDocType)doc.FirstChild; Assert.AreEqual("html", dt.RootElement.FullName); Assert.AreEqual("-//W3C//DTD XHTML 1.0 Strict//EN", dt.PublicFpi); Assert.AreEqual("DTD/xhtml1-strict.dtd", dt.Uri); Assert.AreEqual(dt.InternalDeclarationRegion.Begin.Line, 4); Assert.AreEqual(dt.InternalDeclarationRegion.End.Line, 7); parser.AssertNoErrors(); }
void CreateDocType() { DocType = new MonoDevelop.Xml.StateEngine.XDocType(TextLocation.Empty); var matches = DocTypeRegex.Match(razorDocument.PageInfo.DocType); DocType.PublicFpi = matches.Groups["fpi"].Value; DocType.Uri = matches.Groups["uri"].Value; }
protected override void ShallowCopyFrom(XObject copyFrom) { base.ShallowCopyFrom(copyFrom); XDocType copyFromDT = (XDocType)copyFrom; //immutable types RootElement = copyFromDT.RootElement; PublicFpi = copyFromDT.PublicFpi; InternalDeclarationRegion = copyFromDT.InternalDeclarationRegion; Uri = copyFromDT.Uri; }
public override IEnumerable <FoldingRegion> GenerateFolds() { if (XDocument == null) { yield break; } foreach (XNode node in XDocument.AllDescendentNodes) { if (node is XCData) { if (node.Region.End.Line - node.Region.Start.Line > 2) { yield return(new FoldingRegion("<![CDATA[ ]]>", node.Region)); } } else if (node is XComment) { if (node.Region.End.Line - node.Region.Start.Line > 2) { yield return(new FoldingRegion("<!-- -->", node.Region)); } } else if (node is XElement) { XElement el = (XElement)node; if (el.IsClosed && el.ClosingTag.Region.End.Line - el.Region.Start.Line > 2) { yield return(new FoldingRegion (string.Format("<{0}...>", el.Name.FullName), new DomRegion(el.Region.Start, el.ClosingTag.Region.End))); } } else if (node is XDocType) { XDocType dt = (XDocType)node; string id = !String.IsNullOrEmpty(dt.PublicFpi) ? dt.PublicFpi : !String.IsNullOrEmpty(dt.Uri) ? dt.Uri : null; if (id != null && dt.Region.End.Line - dt.Region.Start.Line > 2) { if (id.Length > 50) { id = id.Substring(0, 47) + "..."; } FoldingRegion fr = new FoldingRegion(string.Format("<!DOCTYPE {0}>", id), dt.Region); fr.IsFoldedByDefault = true; yield return(fr); } } } }
protected override ICompletionDataList HandleCodeCompletion(CodeCompletionContext completionContext, bool forced, ref int triggerWordLength) { ITextBuffer buf = this.Buffer; // completionChar may be a space even if the current char isn't, when ctrl-space is fired t char currentChar = completionContext.TriggerOffset < 1? ' ' : buf.GetCharAt(completionContext.TriggerOffset - 1); //char previousChar = completionContext.TriggerOffset < 2? ' ' : buf.GetCharAt (completionContext.TriggerOffset - 2); //directive names if (Tracker.Engine.CurrentState is AspNetDirectiveState) { var directive = Tracker.Engine.Nodes.Peek() as AspNetDirective; if (HasDoc && directive != null && directive.Region.BeginLine == completionContext.TriggerLine && directive.Region.BeginColumn + 3 == completionContext.TriggerLineOffset) { return(DirectiveCompletion.GetDirectives(aspDoc.Type)); } return(null); } else if (Tracker.Engine.CurrentState is S.XmlNameState && Tracker.Engine.CurrentState.Parent is AspNetDirectiveState) { var directive = Tracker.Engine.Nodes.Peek() as AspNetDirective; if (HasDoc && directive != null && directive.Region.BeginLine == completionContext.TriggerLine && directive.Region.BeginColumn + 4 == completionContext.TriggerLineOffset && char.IsLetter(currentChar)) { triggerWordLength = 1; return(DirectiveCompletion.GetDirectives(aspDoc.Type)); } return(null); } bool isAspExprState = Tracker.Engine.CurrentState is AspNetExpressionState; //non-xml tag completion if (currentChar == '<' && !(isAspExprState || Tracker.Engine.CurrentState is S.XmlFreeState)) { var list = new CompletionDataList(); AddAspBeginExpressions(list); return(list); } if (!HasDoc || aspDoc.Info.DocType == null) { //FIXME: get doctype from master page DocType = null; } else { DocType = new MonoDevelop.Xml.StateEngine.XDocType(TextLocation.Empty); var matches = DocTypeRegex.Match(aspDoc.Info.DocType); DocType.PublicFpi = matches.Groups["fpi"].Value; DocType.Uri = matches.Groups["uri"].Value; } if (Tracker.Engine.CurrentState is HtmlScriptBodyState) { var el = Tracker.Engine.Nodes.Peek() as S.XElement; if (el != null) { var att = GetHtmlAtt(el, "runat"); if (att != null && "server".Equals(att.Value, StringComparison.OrdinalIgnoreCase)) { if (documentBuilder != null) { // TODO: C# completion } } /* * else { * att = GetHtmlAtt (el, "language"); * if (att == null || "javascript".Equals (att.Value, StringComparison.OrdinalIgnoreCase)) { * att = GetHtmlAtt (el, "type"); * if (att == null || "text/javascript".Equals (att.Value, StringComparison.OrdinalIgnoreCase)) { * // TODO: JS completion * } * } * }*/ } } return(base.HandleCodeCompletion(completionContext, forced, ref triggerWordLength)); }
void CreateDocType () { DocType = new MonoDevelop.Xml.StateEngine.XDocType (TextLocation.Empty); var matches = DocTypeRegex.Match (razorDocument.PageInfo.DocType); if (matches.Success) { DocType.PublicFpi = matches.Groups ["fpi"].Value; DocType.Uri = matches.Groups ["uri"].Value; } }
public override State PushChar(char c, IParseContext context, ref string rollback) { XDocType doc = context.Nodes.Peek() as XDocType; if (doc == null) { doc = new XDocType(context.LocationMinus("<!DOCTYPE".Length + 1)); context.Nodes.Push(doc); } if (!doc.RootElement.IsValid) { if (XmlChar.IsWhitespace(c)) { return(null); } else if (XmlChar.IsFirstNameChar(c)) { rollback = ""; return(nameState); } } else if (doc.PublicFpi == null) { if (context.StateTag == 0) { if (c == 's' || c == 'S') { context.StateTag = 1; return(null); } else if (c == 'p' || c == 'P') { context.StateTag = -1; return(null); } if (XmlChar.IsWhitespace(c)) { return(null); } } else if (Math.Abs(context.StateTag) < 6) { if (context.StateTag > 0) { if ("YSTEM"[context.StateTag - 1] == c || "ystem"[context.StateTag - 1] == c) { context.StateTag++; if (context.StateTag == 6) { context.StateTag = 0; doc.PublicFpi = ""; } return(null); } } else { int absState = Math.Abs(context.StateTag) - 1; if ("UBLIC"[absState] == c || "ublic"[absState] == c) { context.StateTag--; return(null); } } } else { if (context.KeywordBuilder.Length == 0) { if (XmlChar.IsWhitespace(c)) { return(null); } else if (c == '"') { context.KeywordBuilder.Append(c); return(null); } } else { if (c == '"') { context.KeywordBuilder.Remove(0, 1); doc.PublicFpi = context.KeywordBuilder.ToString(); context.KeywordBuilder.Length = 0; context.StateTag = 0; } else { context.KeywordBuilder.Append(c); } return(null); } } } else if (doc.Uri == null) { if (context.KeywordBuilder.Length == 0) { if (XmlChar.IsWhitespace(c)) { return(null); } else if (c == '"') { context.KeywordBuilder.Append(c); return(null); } } else { if (c == '"') { context.KeywordBuilder.Remove(0, 1); doc.Uri = context.KeywordBuilder.ToString(); context.KeywordBuilder.Length = 0; } else { context.KeywordBuilder.Append(c); } return(null); } } else if (doc.InternalDeclarationRegion.EndLine <= 0) { if (XmlChar.IsWhitespace(c)) { return(null); } switch (context.StateTag) { case 0: if (c == '[') { doc.InternalDeclarationRegion = new DomRegion(context.Location, TextLocation.Empty); context.StateTag = 1; return(null); } break; case 1: if (c == '<') { context.StateTag = 2; return(null); } else if (c == ']') { context.StateTag = 0; doc.InternalDeclarationRegion = new DomRegion(doc.InternalDeclarationRegion.Begin, context.Location); return(null); } break; case 2: if (c == '>') { context.StateTag = 1; } return(null); default: throw new InvalidOperationException(); } } doc = (XDocType)context.Nodes.Pop(); if (c == '<') { rollback = string.Empty; context.LogError("Doctype ended prematurely."); } else if (c != '>') { context.LogError("Unexpected character '" + c + "' in doctype."); } if (context.BuildTree) { doc.End(context.Location); ((XContainer)context.Nodes.Peek()).AddChildNode(doc); } return(Parent); }