public void ShouldWriteDocsElement()
        {
            var element = new DocsElement
            {
                Attributes = new Dictionary <string, string>
                {
                    { "a", "b" },
                    { "c", "d" },
                },
                Indentation  = " ",
                ElementLine  = 1,
                ElementLines = 1,
                Name         = "xyz"
            };

            var content = new[]
            {
                "foo",
                " bar"
            };

            new DocsElementWriter().Write(element, content)
            .ShouldBe(new[]
            {
                " [//]: # (<docs-xyz a=\"b\" c=\"d\">)",
                " foo",
                "  bar",
                " [//]: # (</docs-xyz>)"
            });
        }
Example #3
0
        public IReadOnlyList <DocsElement> Parse(IReadOnlyList <string> lines, string elementName, AttributeOptions attributeOptions)
        {
            var elements = new List <DocsElement>();

            for (var i = 0; i < lines.Count; i++)
            {
                var line  = lines[i];
                var match = Regex.Match(line, OpenPattern, RegexOptions);

                if (match.Success)
                {
                    var name = match.Groups["name"].Value;

                    if (!name.Equals(elementName))
                    {
                        continue;
                    }

                    var attributes = new Dictionary <string, string>();

                    foreach (var attribute in GetAttributes(match))
                    {
                        var key = attribute.Key;

                        if (!attributeOptions.All.Contains(key, StringComparer.OrdinalIgnoreCase))
                        {
                            throw new AppException($"invalid attribute '{key}'.");
                        }

                        if (!attributes.TryAdd(key, attribute.Value))
                        {
                            throw new AppException($"duplicate attribute '{key}'.");
                        }
                    }

                    var missingAttributes = attributeOptions.Required
                                            .Where(x => !attributes.ContainsKey(x))
                                            .ToList();
                    if (missingAttributes.Any())
                    {
                        throw new AppException($"missing attribute(s) {string.Join(", ", missingAttributes)}");
                    }

                    var element = new DocsElement
                    {
                        Attributes  = attributes,
                        Indentation = match.Groups["indentation"].Value,
                        ElementLine = i,
                        Name        = name
                    };

                    if (match.Groups["selfclosing"].Success)
                    {
                        element.ElementLines = 1;
                        elements.Add(element);
                        continue;
                    }

                    while (true)
                    {
                        if (++i == lines.Count)
                        {
                            throw new AppException($"element {element.Name}@{element.ElementLine} : closing tag not found");
                        }

                        line  = lines[i];
                        match = Regex.Match(line, ClosePattern, RegexOptions);

                        if (match.Success && match.Groups["name"].Value.Equals(element.Name, StringComparison))
                        {
                            break;
                        }
                    }

                    element.ElementLines = 1 + i - element.ElementLine;
                    elements.Add(element);
                }
            }

            return(elements);
        }