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); }
public static void Fill(File file, CharacterPositionFinder finder) { foreach (var root in file.Children) { AdjustChildren(root, finder); } }
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)); }
private static void AdjustChildren(Container container, CharacterPositionFinder finder) { var children = container.Children; for (var index = 0; index < children.Count; index++) { AdjustNode(children, index, finder); } }
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); } }
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, }); }
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); }
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); }
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); } }