/// <summary> /// Renders a bold run element. /// </summary> /// <param name="element"> The parsed inline element to render. </param> /// <param name="context"> Persistent state. </param> protected override void RenderBoldRun(BoldTextInline element, IRenderContext context) { var localContext = context as InlineRenderContext; if (localContext == null) { throw new RenderContextIncorrectException(); } // Create the text run Span boldSpan = new Span { FontWeight = FontWeights.Bold }; var childContext = new InlineRenderContext(boldSpan.Inlines, context) { Parent = boldSpan, WithinBold = true }; // Render the children into the bold inline. RenderInlineChildren(element.Inlines, childContext); // Add it to the current inlines localContext.InlineCollection.Add(boldSpan); }
/// <summary> /// Renders a text run element. /// </summary> /// <param name="element"> The parsed inline element to render. </param> /// <param name="context"> Persistent state. </param> protected override void RenderItalicRun(ItalicTextInline element, IRenderContext context) { var localContext = context as InlineRenderContext; if (localContext == null) { throw new RenderContextIncorrectException(); } // Create the text run Span italicSpan = new Span { FontStyle = FontStyle.Italic }; var childContext = new InlineRenderContext(italicSpan.Inlines, context) { Parent = italicSpan, WithinItalics = true }; // Render the children into the italic inline. RenderInlineChildren(element.Inlines, childContext); // Add it to the current inlines localContext.InlineCollection.Add(italicSpan); }
/// <summary> /// Renders a superscript element. /// </summary> /// <param name="element"> The parsed inline element to render. </param> /// <param name="context"> Persistent state. </param> protected override void RenderSuperscriptRun(SuperscriptTextInline element, IRenderContext context) { var localContext = context as InlineRenderContext; var parent = localContext?.Parent as TextElement; if (localContext == null && parent == null) { throw new RenderContextIncorrectException(); } // Le <sigh>, InlineUIContainers are not allowed within hyperlinks. if (localContext.WithinHyperlink) { RenderInlineChildren(element.Inlines, context); return; } var paragraph = new Paragraph { FontSize = parent.FontSize * 0.8, FontFamily = parent.FontFamily, FontStyle = parent.FontStyle, FontWeight = parent.FontWeight }; var childContext = new InlineRenderContext(paragraph.Inlines, context) { Parent = paragraph }; RenderInlineChildren(element.Inlines, childContext); var richTextBlock = CreateOrReuseRichTextBlock(new UIElementCollectionRenderContext(null, context)); richTextBlock.Blocks.Add(paragraph); var border = new Border { Padding = new Thickness(0, 0, 0, paragraph.FontSize * 0.2), Child = richTextBlock }; var inlineUIContainer = new InlineUIContainer { Child = border }; // Add it to the current inlines localContext.InlineCollection.Add(inlineUIContainer); }
/// <summary> /// Renders a strikethrough element. /// </summary> /// <param name="element"> The parsed inline element to render. </param> /// <param name="context"> Persistent state. </param> protected override void RenderStrikethroughRun(StrikethroughTextInline element, IRenderContext context) { var localContext = context as InlineRenderContext; if (localContext == null) { throw new RenderContextIncorrectException(); } Span span = new Span(); if (TextDecorationsSupported) { span.TextDecorations = TextDecorations.Strikethrough; } else { span.FontFamily = new FontFamily("Consolas"); } var childContext = new InlineRenderContext(span.Inlines, context) { Parent = span }; // Render the children into the inline. RenderInlineChildren(element.Inlines, childContext); if (!TextDecorationsSupported) { AlterChildRuns(span, (parentSpan, run) => { var text = run.Text; var builder = new StringBuilder(text.Length * 2); foreach (var c in text) { builder.Append((char)0x0336); builder.Append(c); } run.Text = builder.ToString(); }); } // Add it to the current inlines localContext.InlineCollection.Add(span); }
/// <summary> /// Renders a paragraph element. /// </summary> protected override void RenderParagraph(ParagraphBlock element, IRenderContext context) { var paragraph = new Paragraph { Margin = ParagraphMargin, LineHeight = ParagraphLineHeight }; var childContext = new InlineRenderContext(paragraph.Inlines, context) { Parent = paragraph }; RenderInlineChildren(element.Inlines, childContext); var textBlock = CreateOrReuseRichTextBlock(context); textBlock.Blocks.Add(paragraph); }
/// <summary> /// Renders a subscript element. /// </summary> /// <param name="element"> The parsed inline element to render. </param> /// <param name="context"> Persistent state. </param> protected override void RenderSubscriptRun(SubscriptTextInline element, IRenderContext context) { var localContext = context as InlineRenderContext; var parent = localContext?.Parent as TextElement; if (localContext == null && parent == null) { throw new RenderContextIncorrectException(); } var paragraph = new Paragraph { FontSize = parent.FontSize * 0.7, FontFamily = parent.FontFamily, FontStyle = parent.FontStyle, FontWeight = parent.FontWeight }; var childContext = new InlineRenderContext(paragraph.Inlines, context) { Parent = paragraph }; RenderInlineChildren(element.Inlines, childContext); var richTextBlock = CreateOrReuseRichTextBlock(new UIElementCollectionRenderContext(null, context)); richTextBlock.Blocks.Add(paragraph); var border = new Border { Margin = new Thickness(0, 0, 0, (-1) * (paragraph.FontSize * 0.6)), Child = richTextBlock }; var inlineUIContainer = new InlineUIContainer { Child = border }; // Add it to the current inlines localContext.InlineCollection.Add(inlineUIContainer); }
/// <summary> /// Renders a table element. /// </summary> protected override void RenderTable(TableBlock element, IRenderContext context) { if (!(context is UIElementCollectionRenderContext localContext)) { throw new RenderContextIncorrectException(); } var blockUIElementCollection = localContext.BlockUIElementCollection; var table = new MarkdownTable(element.ColumnDefinitions.Count, element.Rows.Count, TableBorderThickness, TableBorderBrush) { HorizontalAlignment = HorizontalAlignment.Left, Margin = TableMargin }; // Add each row. for (int rowIndex = 0; rowIndex < element.Rows.Count; rowIndex++) { var row = element.Rows[rowIndex]; // Add each cell. for (int cellIndex = 0; cellIndex < Math.Min(element.ColumnDefinitions.Count, row.Cells.Count); cellIndex++) { var cell = row.Cells[cellIndex]; // Cell content. var cellContent = CreateOrReuseRichTextBlock(new UIElementCollectionRenderContext(null, context)); cellContent.Margin = TableCellPadding; Grid.SetRow(cellContent, rowIndex); Grid.SetColumn(cellContent, cellIndex); switch (element.ColumnDefinitions[cellIndex].Alignment) { case ColumnAlignment.Center: cellContent.TextAlignment = TextAlignment.Center; break; case ColumnAlignment.Right: cellContent.TextAlignment = TextAlignment.Right; break; } if (rowIndex == 0) { cellContent.FontWeight = FontWeights.Bold; } var paragraph = new Paragraph(); var childContext = new InlineRenderContext(paragraph.Inlines, context) { Parent = paragraph, TrimLeadingWhitespace = true }; RenderInlineChildren(cell.Inlines, childContext); cellContent.Blocks.Add(paragraph); table.Children.Add(cellContent); } } blockUIElementCollection.Add(table); }
/// <summary> /// Renders a header element. /// </summary> protected override void RenderHeader(HeaderBlock element, IRenderContext context) { var textBlock = CreateOrReuseRichTextBlock(context); var paragraph = new Paragraph(); var childInlines = paragraph.Inlines; switch (element.HeaderLevel) { case 1: paragraph.Margin = Header1Margin; paragraph.FontSize = Header1FontSize; paragraph.FontWeight = Header1FontWeight; paragraph.Foreground = Header1Foreground; break; case 2: paragraph.Margin = Header2Margin; paragraph.FontSize = Header2FontSize; paragraph.FontWeight = Header2FontWeight; paragraph.Foreground = Header2Foreground; break; case 3: paragraph.Margin = Header3Margin; paragraph.FontSize = Header3FontSize; paragraph.FontWeight = Header3FontWeight; paragraph.Foreground = Header3Foreground; break; case 4: paragraph.Margin = Header4Margin; paragraph.FontSize = Header4FontSize; paragraph.FontWeight = Header4FontWeight; paragraph.Foreground = Header4Foreground; break; case 5: paragraph.Margin = Header5Margin; paragraph.FontSize = Header5FontSize; paragraph.FontWeight = Header5FontWeight; paragraph.Foreground = Header5Foreground; break; case 6: paragraph.Margin = Header6Margin; paragraph.FontSize = Header6FontSize; paragraph.FontWeight = Header6FontWeight; paragraph.Foreground = Header6Foreground; var underline = new Underline(); childInlines = underline.Inlines; paragraph.Inlines.Add(underline); break; } // Render the children into the para inline. var childContext = new InlineRenderContext(childInlines, context) { Parent = paragraph, TrimLeadingWhitespace = true }; RenderInlineChildren(element.Inlines, childContext); // Add it to the blocks textBlock.Blocks.Add(paragraph); }
/// <summary> /// Renders a link element /// </summary> /// <param name="element"> The parsed inline element to render. </param> /// <param name="context"> Persistent state. </param> protected override void RenderMarkdownLink(MarkdownLinkInline element, IRenderContext context) { var localContext = context as InlineRenderContext; if (localContext == null) { throw new RenderContextIncorrectException(); } // HACK: Superscript is not allowed within a hyperlink. But if we switch it around, so // that the superscript is outside the hyperlink, then it will render correctly. // This assumes that the entire hyperlink is to be rendered as superscript. if (AllTextIsSuperscript(element) == false) { // Regular ol' hyperlink. var link = new Hyperlink(); // Register the link LinkRegister.RegisterNewHyperLink(link, element.Url); // Remove superscripts. RemoveSuperscriptRuns(element, insertCaret: true); // Render the children into the link inline. var childContext = new InlineRenderContext(link.Inlines, context) { Parent = link, WithinHyperlink = true }; if (localContext.OverrideForeground) { link.Foreground = localContext.Foreground; } else if (LinkForeground != null) { link.Foreground = LinkForeground; } RenderInlineChildren(element.Inlines, childContext); context.TrimLeadingWhitespace = childContext.TrimLeadingWhitespace; ToolTipService.SetToolTip(link, element.Tooltip ?? element.Url); // Add it to the current inlines localContext.InlineCollection.Add(link); } else { // THE HACK IS ON! // Create a fake superscript element. var fakeSuperscript = new SuperscriptTextInline { Inlines = new List <MarkdownInline> { element } }; // Remove superscripts. RemoveSuperscriptRuns(element, insertCaret: false); // Now render it. RenderSuperscriptRun(fakeSuperscript, context); } }