/// <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)
        {
            if (!(context is InlineRenderContext localContext))
            {
                throw new RenderContextIncorrectException();
            }

            // Create the text run
            var 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)
        {
            if (!(context is InlineRenderContext localContext))
            {
                throw new RenderContextIncorrectException();
            }

            // Create the text run
            var 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 paragraph element.
        /// </summary>
        protected override void RenderParagraph(ParagraphBlock element, IRenderContext context)
        {
            var paragraph = new Paragraph
            {
                Margin = ParagraphMargin
            };

            var childContext = new InlineRenderContext(paragraph.Inlines, context)
            {
                Parent = paragraph
            };

            RenderInlineChildren(element.Inlines, childContext);

            var textBlock = CreateOrReuseRichTextBlock(context);

            textBlock.Blocks.Add(paragraph);
        }
        /// <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)
        {
            if (!(context is InlineRenderContext localContext))
            {
                throw new RenderContextIncorrectException();
            }

            var 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 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)
        {
            if (!(context is InlineRenderContext localContext))
            {
                throw new RenderContextIncorrectException();
            }

            // Regular ol' hyperlink.
            var link = new Hyperlink();

            // Register the link
            LinkRegister.RegisterNewHyperLink(link, element.Url);

            // 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);
        }
        /// <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 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);
        }
        protected override void RenderSpoiler(SpoilerTextInline element, IRenderContext context)
        {
            if (!(context is InlineRenderContext localContext))
            {
                throw new RenderContextIncorrectException();
            }

            // TODO (maybe): make this shit actually work?

            if (localContext.Parent is Hyperlink)
            {
                // In case of Hyperlink, break glass (or add a run).

                var span         = new Span();
                var childContext = new InlineRenderContext(span.Inlines, context)
                {
                    Parent = span
                };

                // Render the children into the inline.
                RenderInlineChildren(element.Inlines, childContext);

                // Add it to the current inlines
                localContext.InlineCollection.Add(span);
            }
            else
            {
                var text         = CreateTextBlock(localContext);
                var childContext = new InlineRenderContext(text.Inlines, context)
                {
                    Parent = text
                };

                RenderInlineChildren(element.Inlines, childContext);

                if (localContext.WithinItalics)
                {
                    text.FontStyle = FontStyle.Italic;
                }

                if (localContext.WithinBold)
                {
                    text.FontWeight = FontWeights.Bold;
                }

                var borderthickness = InlineCodeBorderThickness;
                var padding         = InlineCodePadding;
                var spacingoffset   = -(borderthickness.Bottom + padding.Bottom);
                var margin          = new Thickness(0, spacingoffset, 0, spacingoffset);

                var border = new Border
                {
                    BorderThickness = borderthickness,
                    BorderBrush     = InlineCodeBorderBrush,
                    Background      = InlineCodeBackground,
                    Child           = text,
                    Padding         = padding,
                    Margin          = margin
                };

                // Aligns content in InlineUI, see https://social.msdn.microsoft.com/Forums/silverlight/en-US/48b5e91e-efc5-4768-8eaf-f897849fcf0b/richtextbox-inlineuicontainer-vertical-alignment-issue?forum=silverlightarchieve
                border.RenderTransform = new TranslateTransform
                {
                    Y = 4
                };

                if (App.RoamingSettings.Read(Constants.ENABLE_SPOILERS, true))
                {
                    text.Opacity   = 0;
                    border.Tapped += (o, e) =>
                    {
                        text.Opacity = 1;
                    };
                }

                var inlineUIContainer = new InlineUIContainer
                {
                    Child = border,
                };

                RootElement.Margin = new Thickness(0, 0, 0, 4);

                // Add it to the current inlines
                localContext.InlineCollection.Add(inlineUIContainer);
            }
        }