コード例 #1
0
        private static ContainerOrTerminalNode ParseBlock(ContainerBlock block, CharacterPositionFinder finder, TextProvider textProvider)
        {
            var name         = GetName(block, textProvider);
            var type         = GetType(block);
            var locationSpan = GetLocationSpan(block, finder);

            var container = new Container
            {
                Type         = type,
                Name         = name,
                LocationSpan = locationSpan,
                HeaderSpan   = GetHeaderSpan(block),
                FooterSpan   = GetFooterSpan(block),
            };

            if (block is ListBlock list)
            {
                foreach (var listItem in list)
                {
                    var item = ParseBlock(listItem, finder, textProvider);
                    container.Children.Add(item);
                }
            }

            // TODO: RKN
            // - Table
            // - ListBlock

            // check whether we can use a terminal node instead
            var child = FinalAdjustAfterParsingComplete(container);

            return(child);
        }
コード例 #2
0
 public static void Fill(File file, CharacterPositionFinder finder)
 {
     foreach (var root in file.Children)
     {
         AdjustChildren(root, finder);
     }
 }
コード例 #3
0
        private static LocationSpan GetLocationSpan(MarkdownObject mdo, CharacterPositionFinder finder)
        {
            var span  = mdo.Span;
            var start = finder.GetLineInfo(span.Start);
            var end   = finder.GetLineInfo(span.End);

            return(new LocationSpan(start, end));
        }
コード例 #4
0
        private static void AdjustChildren(Container container, CharacterPositionFinder finder)
        {
            var children = container.Children;

            for (var index = 0; index < children.Count; index++)
            {
                AdjustNode(children, index, finder);
            }
        }
コード例 #5
0
        private static ContainerOrTerminalNode ParseBlock(Block block, CharacterPositionFinder finder, TextProvider textProvider)
        {
            switch (block)
            {
            case LeafBlock leaf:
                return(ParseBlock(leaf, finder, textProvider));

            case ContainerBlock container:
                return(ParseBlock(container, finder, textProvider));

            default:
                throw new NotSupportedException("unknown block: " + block.GetType().Name);
            }
        }
コード例 #6
0
        private static TerminalNode ParseBlock(LeafBlock block, CharacterPositionFinder finder, TextProvider textProvider)
        {
            var name         = GetName(block, textProvider);
            var type         = GetType(block);
            var locationSpan = GetLocationSpan(block, finder);
            var span         = GetCharacterSpan(block);

            return(new TerminalNode
            {
                Type = type,
                Name = name,
                LocationSpan = locationSpan,
                Span = span,
            });
        }
コード例 #7
0
        public static File Parse(string filePath, string encoding)
        {
            var encodingToUse = Encoding.GetEncoding(encoding);

            File file;

            using (var finder = CharacterPositionFinder.CreateFrom(filePath, encodingToUse))
            {
                file = ParseCore(filePath, finder, encodingToUse);

                Resorter.Resort(file);

                GapFiller.Fill(file, finder);
            }

            return(file);
        }
コード例 #8
0
        public static File ParseCore(string filePath, CharacterPositionFinder finder, Encoding encoding)
        {
            var text = SystemFile.ReadAllText(filePath, encoding);

            var file = new File
            {
                Name       = filePath,
                FooterSpan = new CharacterSpan(0, -1),                // there is no footer
            };

            try
            {
                var pipeline = new MarkdownPipelineBuilder().UseAdvancedExtensions().Build();
                var document = MarkdownParser.Parse(text, pipeline);

                var textProvider = new TextProvider(text);

                var locationSpan = GetLocationSpan(document, finder);

                var rootBlock = new Container
                {
                    Type         = "markdown",
                    Name         = string.Empty,
                    LocationSpan = locationSpan,
                    HeaderSpan   = new CharacterSpan(0, 0),                             // there is no header
                    FooterSpan   = new CharacterSpan(text.Length - 1, text.Length - 1), // there is no footer
                };
                file.Children.Add(rootBlock);

                // Parse the file and display the text content of each of the elements.
                var blocks = document.Where(_ => !_.Span.IsEmpty).ToList();
                foreach (var block in blocks)
                {
                    var parsedBlock = ParseBlock(block, finder, textProvider);
                    rootBlock.Children.Add(parsedBlock);
                }

                file.LocationSpan = locationSpan;
            }
            catch (Exception ex)
            {
                // try to adjust location span to include full file content
                // but ignore empty files as parsing errors
                var lines = SystemFile.ReadLines(filePath).Count();
                if (lines == 0)
                {
                    file.LocationSpan = new LocationSpan(new LineInfo(0, -1), new LineInfo(0, -1));
                }
                else
                {
                    file.ParsingErrors.Add(new ParsingError
                    {
                        ErrorMessage = ex.Message,
                        Location     = new LineInfo(0, -1),
                    });

                    file.LocationSpan = new LocationSpan(new LineInfo(1, 0), new LineInfo(lines + 1, 0));
                }
            }

            return(file);
        }
コード例 #9
0
        private static void AdjustNode(IList <ContainerOrTerminalNode> parentChildren, int indexInParentChildren, CharacterPositionFinder finder)
        {
            var child = parentChildren[indexInParentChildren];

            if (indexInParentChildren < parentChildren.Count - 1)
            {
                var nextSibling = parentChildren[indexInParentChildren + 1];

                var indexBefore = finder.GetCharacterPosition(nextSibling.LocationSpan.Start) - 1;
                var newEndPos   = finder.GetLineInfo(indexBefore);

                child.LocationSpan = new LocationSpan(child.LocationSpan.Start, newEndPos);
            }

            if (child is Container c)
            {
                var start = c.HeaderSpan.End + 1;

                AdjustChildren(c, finder);

                var end = finder.GetCharacterPosition(c.LocationSpan.End);
                c.FooterSpan = new CharacterSpan(start, end);
            }
            else if (child is TerminalNode t)
            {
                var start = finder.GetCharacterPosition(t.LocationSpan.Start);
                var end   = finder.GetCharacterPosition(t.LocationSpan.End);
                t.Span = new CharacterSpan(start, end);
            }
        }