static XshdSpan ParseSpan(XmlReader reader) { XshdSpan span = new XshdSpan(); SetPosition(span, reader); span.BeginRegex = reader.GetAttribute("begin"); span.EndRegex = reader.GetAttribute("end"); span.Multiline = reader.GetBoolAttribute("multiline") ?? false; span.SpanColorReference = ParseColorReference(reader); span.RuleSetReference = ParseRuleSetReference(reader); if (!reader.IsEmptyElement) { reader.Read(); while (reader.NodeType != XmlNodeType.EndElement) { Debug.Assert(reader.NodeType == XmlNodeType.Element); switch (reader.Name) { case "Begin": if (span.BeginRegex != null) throw Error(reader, "Duplicate Begin regex"); span.BeginColorReference = ParseColorReference(reader); span.BeginRegex = reader.ReadElementString(); span.BeginRegexType = XshdRegexType.IgnorePatternWhitespace; break; case "End": if (span.EndRegex != null) throw Error(reader, "Duplicate End regex"); span.EndColorReference = ParseColorReference(reader); span.EndRegex = reader.ReadElementString(); span.EndRegexType = XshdRegexType.IgnorePatternWhitespace; break; case "RuleSet": if (span.RuleSetReference.ReferencedElement != null) throw Error(reader, "Cannot specify both inline RuleSet and RuleSet reference"); span.RuleSetReference = new XshdReference<XshdRuleSet>(ParseRuleSet(reader)); reader.Read(); break; default: throw new NotSupportedException("Unknown element " + reader.Name); } } } return span; }
object IXshdVisitor.VisitSpan(XshdSpan span) { writer.WriteStartElement("Span", Namespace); WriteColorReference(span.SpanColorReference); if (span.BeginRegexType == XshdRegexType.Default && span.BeginRegex != null) writer.WriteAttributeString("begin", span.BeginRegex); if (span.EndRegexType == XshdRegexType.Default && span.EndRegex != null) writer.WriteAttributeString("end", span.EndRegex); WriteRuleSetReference(span.RuleSetReference); if (span.Multiline) writer.WriteAttributeString("multiline", "true"); if (span.BeginRegexType == XshdRegexType.IgnorePatternWhitespace) WriteBeginEndElement("Begin", span.BeginRegex, span.BeginColorReference); if (span.EndRegexType == XshdRegexType.IgnorePatternWhitespace) WriteBeginEndElement("End", span.EndRegex, span.EndColorReference); if (span.RuleSetReference.InlineElement != null) span.RuleSetReference.InlineElement.AcceptVisitor(this); writer.WriteEndElement(); return null; }
XshdSpan ImportSpan(XmlElement element) { XshdSpan span = new XshdSpan(); if (element.HasAttribute("rule")) { span.RuleSetReference = new XshdReference<XshdRuleSet>(null, element.GetAttribute("rule")); } char escapeCharacter = ruleSetEscapeCharacter; if (element.HasAttribute("escapecharacter")) { escapeCharacter = element.GetAttribute("escapecharacter")[0]; } span.Multiline = !(element.GetBoolAttribute("stopateol") ?? false); span.SpanColorReference = GetColorReference(element); span.BeginRegexType = XshdRegexType.IgnorePatternWhitespace; span.BeginRegex = ImportRegex(element["Begin"].InnerText, element["Begin"].GetBoolAttribute("singleword") ?? false, element["Begin"].GetBoolAttribute("startofline")); span.BeginColorReference = GetColorReference(element["Begin"]); string endElementText = string.Empty; if (element["End"] != null) { span.EndRegexType = XshdRegexType.IgnorePatternWhitespace; endElementText = element["End"].InnerText; span.EndRegex = ImportRegex(endElementText, element["End"].GetBoolAttribute("singleword") ?? false, null); span.EndColorReference = GetColorReference(element["End"]); } if (escapeCharacter != '\0') { XshdRuleSet ruleSet = new XshdRuleSet(); if (endElementText.Length == 1 && endElementText[0] == escapeCharacter) { // ""-style escape ruleSet.Elements.Add(new XshdSpan { BeginRegex = Regex.Escape(endElementText + endElementText), EndRegex = "" }); } else { // \"-style escape ruleSet.Elements.Add(new XshdSpan { BeginRegex = Regex.Escape(escapeCharacter.ToString()), EndRegex = "." }); } if (span.RuleSetReference.ReferencedElement != null) { ruleSet.Elements.Add(new XshdImport { RuleSetReference = span.RuleSetReference }); } span.RuleSetReference = new XshdReference<XshdRuleSet>(ruleSet); } return span; }