public void Draw(TextView textView, DrawingContext drawingContext) { var ast = _abstractSyntaxTree; if (ast == null) { return; } foreach (var line in textView.VisualLines) { var rc = BackgroundGeometryBuilder.GetRectsFromVisualSegment(textView, line, 0, 1000).FirstOrDefault(); if (rc == default(Rect)) { continue; } foreach (var block in AbstractSyntaxTree.EnumerateBlocks(ast.FirstChild)) { if (block.SourcePosition + block.SourceLength <= line.StartOffset) { continue; } if (block.SourcePosition > line.LastDocumentLine.EndOffset) { break; } // Indented code does not terminate (at least in the AST) until a new // block is encountered. Thus blank lines at the end of the block are // highlighted. It looks much better if they're not highlighted. if (block.Tag == BlockTag.IndentedCode) { var length = block.SourcePosition + block.SourceLength - line.StartOffset; if (line.StartOffset + length > textView.Document.TextLength) { break; } var remainder = textView.Document.GetText(line.StartOffset, length); if (string.IsNullOrWhiteSpace(remainder)) { break; } } if (_blockTags.Any(tag => tag == block.Tag)) { Brush brush; if (_brushes.TryGetValue(block.Tag, out brush) && brush != null) { drawingContext.DrawRectangle(brush, null, new Rect(0, rc.Top, textView.ActualWidth, line.Height)); } } } } }
public static string ToHtml(string markdown) { var ast = AbstractSyntaxTree.GenerateAbstractSyntaxTree(markdown); markdown = markdown.ConvertEmojis(ast); var converter = GetMarkdownConverter(); return(converter.ConvertToHtml(markdown)); }
public static string ConvertEmojis(this string markdown, Block ast) { return(Scan.Replace(markdown, match => { if (!AbstractSyntaxTree.PositionSafeForSmartLink(ast, match.Index, match.Length)) { return match.Value; } string value; return Emojis.TryGetValue(match.Value, out value) ? $"<i class=\"_sprite {value}\"/>" : match.Value; })); }