Inheritance: MarkdownBlock
        /// <summary>
        /// Renders a code element.
        /// </summary>
        /// <param name="element"></param>
        /// <param name="blockUIElementCollection"></param>
        /// <param name="context"></param>
        private void RenderCode(CodeBlock element, UIElementCollection blockUIElementCollection, RenderContext context)
        {
            var textBlock = CreateTextBlock(context);
            textBlock.FontFamily = CodeFontFamily ?? FontFamily;
            textBlock.Foreground = CodeForeground ?? context.Foreground;
            textBlock.LineHeight = FontSize * 1.4;
            textBlock.Text = element.Text;

            var border = new Border();
            border.Background = CodeBackground;
            border.BorderBrush = CodeBorderBrush;
            border.BorderThickness = CodeBorderThickness;
            border.Padding = CodePadding;
            border.Margin = CodeMargin;
            border.HorizontalAlignment = HorizontalAlignment.Left;
            border.Child = textBlock;

            // Add it to the blocks
            blockUIElementCollection.Add(border);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Parses a code block.
        /// </summary>
        /// <param name="markdown"> The markdown text. </param>
        /// <param name="start"> The location of the first character in the block. </param>
        /// <param name="maxEnd"> The location to stop parsing. </param>
        /// <param name="quoteDepth"> The current nesting level for block quoting. </param>
        /// <param name="actualEnd"> Set to the end of the block when the return value is non-null. </param>
        /// <returns> A parsed code block, or <c>null</c> if this is not a code block. </returns>
        internal static CodeBlock Parse(string markdown, int start, int maxEnd, int quoteDepth, out int actualEnd)
        {
            var           lines = new List <string>();
            StringBuilder code  = null;

            actualEnd = start;

            bool first = true;
            bool startWithTripleBackQuote = false;

            foreach (var lineInfo in Common.ParseLines(markdown, start, maxEnd, quoteDepth))
            {
                // Add every line that starts with a tab character or at least 4 spaces.
                int pos = lineInfo.StartOfLine;

                // Start code with triple backquote
                if (first)
                {
                    var firstLine = markdown.Substring(lineInfo.StartOfLine, lineInfo.EndOfLine - lineInfo.StartOfLine);
                    if (firstLine.Trim() == "```")
                    {
                        startWithTripleBackQuote = true;
                    }
                    first = false;
                    continue;
                }

                // End code with triple backquote
                if (startWithTripleBackQuote)
                {
                    if (markdown.Substring(lineInfo.StartOfLine, lineInfo.EndOfLine - lineInfo.StartOfLine).Trim() == "```")
                    {
                        actualEnd = lineInfo.StartOfNextLine;
                        break;
                    }
                }
                else
                {
                    // Start code with tab or 4 spaces
                    if (pos < maxEnd && markdown[pos] == '\t')
                    {
                        // tab
                        pos++;
                    }
                    else
                    {
                        // 4 spaces
                        int spaceCount = 0;
                        while (pos < maxEnd && spaceCount < 4)
                        {
                            if (markdown[pos] == ' ')
                            {
                                spaceCount++;
                            }
                            else if (markdown[pos] == '\t')
                            {
                                spaceCount += 4;
                            }
                            else
                            {
                                break;
                            }
                            pos++;
                        }

                        // NOT code scope
                        if (spaceCount < 4)
                        {
                            // We found a line that doesn't start with a tab or 4 spaces.
                            // But don't end the code block until we find a non-blank line.
                            if (lineInfo.IsLineBlank == false)
                            {
                                break;
                            }
                        }
                    }
                }

                // Separate each line of the code text.
                if (code == null)
                {
                    code = new StringBuilder();
                }
                else
                {
                    lines.Add(code.ToString());
                    code.Clear();
                }

                if (lineInfo.IsLineBlank == false)
                {
                    // Append the code text, excluding the first tab/4 spaces, and convert tab characters into spaces.
                    string lineText       = markdown.Substring(pos, lineInfo.EndOfLine - pos);
                    int    startOfLinePos = code.Length;
                    for (int i = 0; i < lineText.Length; i++)
                    {
                        char c = lineText[i];
                        if (c == '\t')
                        {
                            code.Append(' ', 4 - ((code.Length - startOfLinePos) % 4));
                        }
                        else
                        {
                            code.Append(c);
                        }
                    }
                }

                // Update the end position.
                actualEnd = lineInfo.StartOfNextLine;
            }

            if (code == null)
            {
                // Not a valid code block.
                actualEnd = start;
                return(null);
            }
            else
            {
                if (code.Length > 0)
                {
                    lines.Add(code.ToString());
                    code.Clear();
                }
            }

            // Blank lines should be trimmed from the start and end.
            var codeBlock = new CodeBlock();

            codeBlock.Lines = lines;
            return(codeBlock);
        }
        /// <summary>
        /// Renders a code element.
        /// </summary>
        /// <param name="element"></param>
        /// <param name="currentBlocks"></param>
        private void RenderCode(CodeBlock element, BlockCollection currentBlocks)
        {
            // Make the new code paragraph
            Paragraph codePara = new Paragraph();
            codePara.Margin = new Thickness(12 * element.CodeIndent, 0, 0, 0);
            codePara.Foreground = new SolidColorBrush(Color.FromArgb(180, 255, 255, 255));
            codePara.FontFamily = new FontFamily("Courier New");

            // Add it to the blocks
            currentBlocks.Add(codePara);

            // Render the children into the para inline.
            bool trimTextStart = true;
            RenderInlineChildren(element, codePara.Inlines, ref trimTextStart);
        }