public ObservableCollection <HeaderItem> CreateDocumentOutline(string md) { if (string.IsNullOrEmpty(md)) { return(null); } var syntax = Markdig.Markdown.Parse(md); var lines = StringUtils.GetLines(md); bool inFrontMatter = false; var list = new ObservableCollection <HeaderItem>(); foreach (var item in syntax) { var line = item.Line; var content = lines[line].TrimStart(' ', '#');; if (line == 0 && content == "---") { inFrontMatter = true; continue; } if (inFrontMatter && content == "---") { inFrontMatter = false; continue; } if (inFrontMatter) { continue; } if (item is HeadingBlock) { var heading = item as HeadingBlock; if (heading.Level > AppModel.Configuration.MaxDocumentOutlineLevel) { continue; } // underlined format if (line > 0 && (content.StartsWith("---") || content.StartsWith("==="))) { line--; content = lines[line].TrimStart(' ', '#'); } var headerItem = new HeaderItem() { Text = $"{content}", Level = heading.Level, Line = line, LinkId = LinkHelper.UrilizeAsGfm(content.TrimEnd()) }; list.Add(headerItem); } } return(list); }
public ObservableCollection <HeaderItem> CreateDocumentOutline(string md) { if (string.IsNullOrEmpty(md)) { return(null); } // create a full pipeline to strip out front matter/yaml var parser = new MarkdownParserMarkdig(); var builder = parser.CreatePipelineBuilder(); var syntax = Markdig.Markdown.Parse(md, builder.Build()); var list = new ObservableCollection <HeaderItem>(); foreach (var item in syntax) { var line = item.Line; if (item is HeadingBlock) { var heading = item as HeadingBlock; var inline = heading?.Inline?.FirstChild; if (inline == null) { continue; } StringBuilder sb = new StringBuilder(); foreach (var inl in heading.Inline) { if (inl is HtmlEntityInline) { var htmlEntity = inl as HtmlEntityInline; sb.Append(WebUtility.HtmlDecode(htmlEntity.Transcoded.ToString())); } else if (inl is CodeInline) { var codeInline = inl as CodeInline; sb.Append(WebUtility.HtmlDecode(codeInline.Content)); } else if (inl is LinkInline) { var link = inl as LinkInline; var textInline = link?.FirstOrDefault(l => l is LiteralInline)?.ToString(); if (textInline == null) { textInline = "-- non-text header --"; } sb.Append(WebUtility.HtmlDecode(textInline)); } else { sb.Append(inl.ToString()); } } var content = sb.ToString(); if (content.Contains("\n")) { continue; } if (heading.Level > AppModel.Configuration.MaxDocumentOutlineLevel) { continue; } var headerItem = new HeaderItem() { Text = content, Level = heading.Level, Line = line, LinkId = LinkHelper.UrilizeAsGfm(content.TrimEnd()) }; list.Add(headerItem); } } return(list); }