Esempio n. 1
0
        /// <summary>
        /// Creates the tokens that describe an element from a <see cref="XmlReader"/> is positioned on an element
        /// node.
        /// </summary>
        /// <param name="reader">
        /// The reader.
        /// </param>
        /// <returns>
        /// The newly created <see cref="FragmentToken"/>.
        /// </returns>
        private IEnumerable <FragmentToken> CreateElementTokens(XmlReader reader)
        {
            var elementName  = reader.Name;
            var tokenDetails = new ElementTokenDetails(reader.XmlSpace, reader.IsEmptyElement);

            yield return(new FragmentToken(FragmentType.Element, elementName, tokenDetails));

            var attributeTokens = new List <FragmentToken>();

            while (reader.MoveToNextAttribute())
            {
                ++tokenDetails.AttributeCount;
                attributeTokens.Add(XmlTokenizer.CreateAttributeToken(reader));
            }

            var comparer = this.attributeOrderOverride.Any()
                ? new AttributeNameComparer(this.attributeOrderOverride)
                : XmlTokenizer.AttributeNameComparer;

            foreach (var token in attributeTokens.OrderBy(item => item.Name, comparer))
            {
                yield return(token);
            }

            this.attributeOrderOverride.Clear();

            yield return(new FragmentToken(FragmentType.CloseElement, elementName, tokenDetails));

            if (tokenDetails.IsEmptyElement)
            {
                yield return(new FragmentToken(FragmentType.EndElement, elementName, string.Empty));
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Tokenizes the XML in a <see cref="XmlReader"/> to a sequence of <see cref="FragmentToken"/>.
        /// </summary>
        /// <param name="reader">
        /// The reader.
        /// </param>
        /// <returns>
        /// A sequence of <see cref="FragmentToken"/> representing the XML.
        /// </returns>
        /// <exception cref="InvalidOperationException">
        /// An unknown node type is encountered.
        /// </exception>
        public IEnumerable <FragmentToken> Tokenize(XmlReader reader)
        {
            var result = new List <FragmentToken>();

            while (reader.Read())
            {
                switch (reader.NodeType)
                {
                case XmlNodeType.Comment:
                    result.Add(this.CreateCommentToken(reader));
                    break;

                case XmlNodeType.Whitespace:
                case XmlNodeType.SignificantWhitespace:
                case XmlNodeType.Text:
                case XmlNodeType.EndElement:
                case XmlNodeType.ProcessingInstruction:
                case XmlNodeType.XmlDeclaration:
                    result.Add(XmlTokenizer.CreateToken(reader));
                    break;

                case XmlNodeType.Element:
                    result.AddRange(this.CreateElementTokens(reader));
                    break;

                default:
                    throw new InvalidOperationException($"Unknown XmlNodeType '{reader.NodeType}'");
                }
            }

            return(result);
        }
Esempio n. 3
0
        /// <summary>
        /// Creates a token that describe an attribute from a <see cref="XmlReader"/> is positioned on an attribute
        /// node.
        /// </summary>
        /// <param name="reader">
        /// The reader.
        /// </param>
        /// <returns>
        /// The newly created <see cref="FragmentToken"/>.
        /// </returns>
        private static FragmentToken CreateAttributeToken(XmlReader reader)
        {
            IMarkupExtensionInfo markup;

            if (XmlTokenizer.MarkupExtensionParser.TryParse(reader.Value, out markup))
            {
                return(new FragmentToken(FragmentType.Attribute, reader.Name, markup));
            }

            return(XmlTokenizer.CreateToken(reader));
        }
Esempio n. 4
0
        /// <summary>
        /// Formats a XAML document.
        /// </summary>
        /// <param name="obj">
        /// A string containing the XAML document to format.
        /// </param>
        /// <param name="builder">
        /// The string builder to which the formatter outputs.
        /// </param>
        public void Format(object obj, StringBuilder builder)
        {
            if (obj == null)
            {
                throw new ArgumentNullException(nameof(obj));
            }

            if (builder == null)
            {
                throw new ArgumentNullException(nameof(builder));
            }

            var xaml = obj as string;

            if (xaml == null)
            {
                throw new ArgumentException(@"Parameter must be of type string", nameof(obj));
            }

            using (var stringReader = new StringReader(xaml))
            {
                try
                {
                    using (var xmlReader = XmlReader.Create(stringReader, new XmlReaderSettings {
                        CloseInput = false
                    }))
                    {
                        var tokens = new XmlTokenizer()
                                     .Tokenize(xmlReader)
                                     .SkipWhile(candidate => candidate.Type == FragmentType.WhiteSpace);

                        this.context.TokenSource = new FragmentTokenSource(tokens);

                        var ignore = this.context.TokenSource
                                     .LookAhead
                                     .TakeWhile(item => item.Type == FragmentType.Comment || item.Type == FragmentType.WhiteSpace)
                                     .Any(item => XamlFormatter.Ignore.IsMatch(item.ContentString));

                        if (ignore)
                        {
                            throw new WarningException("Document has been ignored");
                        }

                        while (this.context.TokenSource.MoveNext())
                        {
                            this.context
                            .Create(this.context.TokenSource.Token.Type)
                            .Format(this.context.TokenSource.Token, builder);
                        }
                    }
                }
                catch (Exception ex)
                {
                    Debug.WriteLine("Failed to format the document: {0}{1}", ex.Message, null);

                    throw;
                }
            }

            builder.RemoveEndWhile(char.IsWhiteSpace);
        }